SF: Layer children should call parents' onFirstRef
am: 56eb975447

Change-Id: I52e19fff3793cbcd5935cd55f4a0e4204d4ed53d
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 31e73fb..94dbebc 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -95,6 +95,7 @@
     { "gfx",        "Graphics",         ATRACE_TAG_GRAPHICS, {
         { OPT,      "events/mdss/enable" },
         { OPT,      "events/sde/enable" },
+        { OPT,      "events/mali_systrace/enable" },
     } },
     { "input",      "Input",            ATRACE_TAG_INPUT, { } },
     { "view",       "View System",      ATRACE_TAG_VIEW, { } },
@@ -118,6 +119,7 @@
     { "adb",        "ADB",              ATRACE_TAG_ADB, { } },
     { "vibrator",   "Vibrator",         ATRACE_TAG_VIBRATOR, { } },
     { "aidl",       "AIDL calls",       ATRACE_TAG_AIDL, { } },
+    { "nnapi",      "NNAPI",            ATRACE_TAG_NNAPI, { } },
     { k_coreServiceCategory, "Core services", 0, { } },
     { k_pdxServiceCategory, "PDX services", 0, { } },
     { "sched",      "CPU Scheduling",   0, {
@@ -208,6 +210,7 @@
     { "binder_driver", "Binder Kernel driver", 0, {
         { REQ,      "events/binder/binder_transaction/enable" },
         { REQ,      "events/binder/binder_transaction_received/enable" },
+        { REQ,      "events/binder/binder_transaction_alloc_buf/enable" },
         { OPT,      "events/binder/binder_set_priority/enable" },
     } },
     { "binder_lock", "Binder global lock trace", 0, {
@@ -227,8 +230,8 @@
 static bool g_compress = false;
 static bool g_nohup = false;
 static int g_initialSleepSecs = 0;
-static const char* g_categoriesFile = NULL;
-static const char* g_kernelTraceFuncs = NULL;
+static const char* g_categoriesFile = nullptr;
+static const char* g_kernelTraceFuncs = nullptr;
 static const char* g_debugAppCmdLine = "";
 static const char* g_outputFile = nullptr;
 
@@ -260,6 +263,9 @@
 static const char* k_printTgidPath =
     "options/print-tgid";
 
+static const char* k_recordTgidPath =
+    "options/record-tgid";
+
 static const char* k_funcgraphAbsTimePath =
     "options/funcgraph-abstime";
 
@@ -401,7 +407,7 @@
     for (int i = 0; i < MAX_SYS_FILES; i++) {
         const char* path = category.sysfiles[i].path;
         bool req = category.sysfiles[i].required == REQ;
-        if (path != NULL) {
+        if (path != nullptr) {
             if (req) {
                 if (!fileIsWritable(path)) {
                     return false;
@@ -426,7 +432,7 @@
     for (int i = 0; i < MAX_SYS_FILES; i++) {
         const char* path = category.sysfiles[i].path;
         bool req = category.sysfiles[i].required == REQ;
-        if (path != NULL) {
+        if (path != nullptr) {
             if (req) {
                 if (!fileExists(path)) {
                     return false;
@@ -522,9 +528,15 @@
 
 static bool setPrintTgidEnableIfPresent(bool enable)
 {
+    // Pre-4.13 this was options/print-tgid as an android-specific option.
+    // In 4.13+ this is an upstream option called options/record-tgid
+    // Both options produce the same ftrace format change
     if (fileExists(k_printTgidPath)) {
         return setKernelOptionEnable(k_printTgidPath, enable);
     }
+    if (fileExists(k_recordTgidPath)) {
+        return setKernelOptionEnable(k_recordTgidPath, enable);
+    }
     return true;
 }
 
@@ -536,10 +548,10 @@
     Vector<String16> services = sm->listServices();
     for (size_t i = 0; i < services.size(); i++) {
         sp<IBinder> obj = sm->checkService(services[i]);
-        if (obj != NULL) {
+        if (obj != nullptr) {
             Parcel data;
             if (obj->transact(IBinder::SYSPROPS_TRANSACTION, data,
-                    NULL, 0) != OK) {
+                    nullptr, 0) != OK) {
                 if (false) {
                     // XXX: For some reason this fails on tablets trying to
                     // poke the "phone" service.  It's not clear whether some
@@ -629,9 +641,9 @@
 {
     int i = 0;
     char* start = cmdline;
-    while (start != NULL) {
+    while (start != nullptr) {
         char* end = strchr(start, ',');
-        if (end != NULL) {
+        if (end != nullptr) {
             *end = '\0';
             end++;
         }
@@ -661,7 +673,7 @@
         const TracingCategory &c = k_categories[i];
         for (int j = 0; j < MAX_SYS_FILES; j++) {
             const char* path = c.sysfiles[j].path;
-            if (path != NULL && fileIsWritable(path)) {
+            if (path != nullptr && fileIsWritable(path)) {
                 ok &= setKernelOptionEnable(path, false);
             }
         }
@@ -697,7 +709,7 @@
                 ok = false;
             }
         }
-        func = strtok(NULL, ",");
+        func = strtok(nullptr, ",");
     }
     free(myFuncs);
     return ok;
@@ -708,7 +720,7 @@
 {
     bool ok = true;
 
-    if (funcs == NULL || funcs[0] == '\0') {
+    if (funcs == nullptr || funcs[0] == '\0') {
         // Disable kernel function tracing.
         if (fileIsWritable(k_currentTracerPath)) {
             ok &= writeStr(k_currentTracerPath, "nop");
@@ -730,7 +742,7 @@
         char* func = strtok(myFuncs, ",");
         while (func) {
             ok &= appendStr(k_ftraceFilterPath, func);
-            func = strtok(NULL, ",");
+            func = strtok(nullptr, ",");
         }
         free(myFuncs);
 
@@ -772,7 +784,7 @@
     if (!categories_file) {
         return true;
     }
-    Tokenizer* tokenizer = NULL;
+    Tokenizer* tokenizer = nullptr;
     if (Tokenizer::open(String8(categories_file), &tokenizer) != NO_ERROR) {
         return false;
     }
@@ -874,7 +886,7 @@
             for (int j = 0; j < MAX_SYS_FILES; j++) {
                 const char* path = c.sysfiles[j].path;
                 bool required = c.sysfiles[j].required == REQ;
-                if (path != NULL) {
+                if (path != nullptr) {
                     if (fileIsWritable(path)) {
                         ok &= setKernelOptionEnable(path, true);
                     } else if (required) {
@@ -899,7 +911,7 @@
     setTraceOverwriteEnable(true);
     setTraceBufferSizeKB(1);
     setPrintTgidEnableIfPresent(false);
-    setKernelTraceFuncs(NULL);
+    setKernelTraceFuncs(nullptr);
     setUserInitiatedTraceProperty(false);
 }
 
@@ -1057,10 +1069,10 @@
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = 0;
     sa.sa_handler = handleSignal;
-    sigaction(SIGHUP, &sa, NULL);
-    sigaction(SIGINT, &sa, NULL);
-    sigaction(SIGQUIT, &sa, NULL);
-    sigaction(SIGTERM, &sa, NULL);
+    sigaction(SIGHUP, &sa, nullptr);
+    sigaction(SIGINT, &sa, nullptr);
+    sigaction(SIGQUIT, &sa, nullptr);
+    sigaction(SIGTERM, &sa, nullptr);
 }
 
 static void listSupportedCategories()
@@ -1150,13 +1162,13 @@
         int ret;
         int option_index = 0;
         static struct option long_options[] = {
-            {"async_start",       no_argument, 0,  0 },
-            {"async_stop",        no_argument, 0,  0 },
-            {"async_dump",        no_argument, 0,  0 },
-            {"only_userspace",    no_argument, 0,  0 },
-            {"list_categories",   no_argument, 0,  0 },
-            {"stream",            no_argument, 0,  0 },
-            {           0,                  0, 0,  0 }
+            {"async_start",       no_argument, nullptr,  0 },
+            {"async_stop",        no_argument, nullptr,  0 },
+            {"async_dump",        no_argument, nullptr,  0 },
+            {"only_userspace",    no_argument, nullptr,  0 },
+            {"list_categories",   no_argument, nullptr,  0 },
+            {"stream",            no_argument, nullptr,  0 },
+            {nullptr,                       0, nullptr,  0 }
         };
 
         ret = getopt_long(argc, argv, "a:b:cf:k:ns:t:zo:",
@@ -1285,9 +1297,7 @@
         if (!onlyUserspace)
             ok = clearTrace();
 
-        if (!onlyUserspace)
-            writeClockSyncMarker();
-
+        writeClockSyncMarker();
         if (ok && !async && !traceStream) {
             // Sleep to allow the trace to be captured.
             struct timespec timeLeft;
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index d3d0711..5903656 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -19,6 +19,8 @@
     chmod 0666 /sys/kernel/tracing/options/overwrite
     chmod 0666 /sys/kernel/debug/tracing/options/print-tgid
     chmod 0666 /sys/kernel/tracing/options/print-tgid
+    chmod 0666 /sys/kernel/debug/tracing/options/record-tgid
+    chmod 0666 /sys/kernel/tracing/options/record-tgid
     chmod 0666 /sys/kernel/debug/tracing/saved_cmdlines_size
     chmod 0666 /sys/kernel/tracing/saved_cmdlines_size
     chmod 0666 /sys/kernel/debug/tracing/events/sched/sched_switch/enable
@@ -57,6 +59,8 @@
     chmod 0666 /sys/kernel/tracing/events/binder/binder_transaction/enable
     chmod 0666 /sys/kernel/debug/tracing/events/binder/binder_transaction_received/enable
     chmod 0666 /sys/kernel/tracing/events/binder/binder_transaction_received/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/binder/binder_transaction_alloc_buf/enable
+    chmod 0666 /sys/kernel/tracing/events/binder/binder_transaction_alloc_buf/enable
     chmod 0666 /sys/kernel/debug/tracing/events/binder/binder_lock/enable
     chmod 0666 /sys/kernel/tracing/events/binder/binder_lock/enable
     chmod 0666 /sys/kernel/debug/tracing/events/binder/binder_locked/enable
@@ -90,6 +94,10 @@
 
 
     # disk
+    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_get_data_block/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_get_data_block/enable
+    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_iget/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_iget/enable
     chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_enter/enable
     chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_enter/enable
     chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_exit/enable
@@ -102,6 +110,12 @@
     chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_begin/enable
     chmod 0666 /sys/kernel/tracing/events/ext4/ext4_da_write_end/enable
     chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_end/enable
+    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_es_lookup_extent_enter/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_es_lookup_extent_enter/enable
+    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_es_lookup_extent_exit/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_es_lookup_extent_exit/enable
+    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_load_inode/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_load_inode/enable
     chmod 0666 /sys/kernel/tracing/events/ext4/ext4_sync_file_enter/enable
     chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable
     chmod 0666 /sys/kernel/tracing/events/ext4/ext4_sync_file_exit/enable
@@ -125,6 +139,42 @@
     chmod 0666 /sys/kernel/debug/tracing/trace
     chmod 0666 /sys/kernel/tracing/trace
 
+# Read and truncate the per-CPU kernel trace.
+# Cannot use wildcards in .rc files. Update this if there is a phone with
+# more CPUs.
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu0/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu0/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu1/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu1/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu2/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu2/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu3/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu3/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu4/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu4/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu5/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu5/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu6/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu6/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu6/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu7/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu8/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu8/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu9/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu9/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu10/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu10/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu11/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu11/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu12/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu12/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu13/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu13/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu14/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu14/trace
+    chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu15/trace
+    chmod 0666 /sys/kernel/tracing/per_cpu/cpu15/trace
+
 on property:persist.debug.atrace.boottrace=1
     start boottrace
 
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index 48d5d4a..4238531 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -167,13 +167,6 @@
 {
     signal(SIGPIPE, SIG_IGN);
     sp<ProcessState> proc = ProcessState::self();
-    // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
-    // not allowed to spawn any additional threads, but we still spawn
-    // a binder thread from userspace when we call startThreadPool().
-    // This is safe because we only have 2 callbacks, neither of which
-    // block.
-    // See b/36066697 for rationale
-    proc->setThreadPoolMaxThreadCount(0);
     proc->startThreadPool();
 
 #if DEBUG
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index b04543b..c852df1 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -100,6 +100,32 @@
         "dumpstate.cpp",
         "main.cpp",
     ],
+    required: [
+        "atrace",
+        "df",
+        "getprop",
+        "ip",
+        "iptables",
+        "ip6tables",
+        "kill",
+        "librank",
+        "logcat",
+        "logcompressor",
+        "lsmod",
+        "lsof",
+        "netstat",
+        "parse_radio_log",
+        "printenv",
+        "procrank",
+        "screencap",
+        "showmap",
+        "ss",
+        "storaged",
+        "top",
+        "uptime",
+        "vdc",
+        "vril-dump",
+    ],
     init_rc: ["dumpstate.rc"],
 }
 
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 9d897f5..30c5b6a 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -90,7 +90,7 @@
 
 /* read before root is shed */
 static char cmdline_buf[16384] = "(unknown)";
-static const char *dump_traces_path = NULL;
+static const char *dump_traces_path = nullptr;
 
 // TODO: variables and functions below should be part of dumpstate object
 
@@ -295,7 +295,7 @@
     char path[PATH_MAX];
 
     d = opendir(driverpath);
-    if (d == NULL) {
+    if (d == nullptr) {
         return;
     }
 
@@ -333,7 +333,7 @@
     }
 
     // find anrd's pid if it is running.
-    pid = GetPidByName("/system/xbin/anrd");
+    pid = GetPidByName("/system/bin/anrd");
 
     if (pid > 0) {
         if (stat(trace_path, &st) == 0) {
@@ -587,9 +587,9 @@
 static int dump_stat_from_fd(const char *title __unused, const char *path, int fd) {
     unsigned long long fields[__STAT_NUMBER_FIELD];
     bool z;
-    char *cp, *buffer = NULL;
+    char *cp, *buffer = nullptr;
     size_t i = 0;
-    FILE *fp = fdopen(fd, "rb");
+    FILE *fp = fdopen(dup(fd), "rb");
     getline(&buffer, &i, fp);
     fclose(fp);
     if (!buffer) {
@@ -926,53 +926,6 @@
     RunCommand("IP6TABLES RAW", {"ip6tables", "-t", "raw", "-L", "-nvx"});
 }
 
-static void AddGlobalAnrTraceFile(const bool add_to_zip, const std::string& anr_traces_file,
-                                  const std::string& anr_traces_dir) {
-    std::string dump_traces_dir;
-
-    if (dump_traces_path != nullptr) {
-        if (add_to_zip) {
-            dump_traces_dir = dirname(dump_traces_path);
-            MYLOGD("Adding ANR traces (directory %s) to the zip file\n", dump_traces_dir.c_str());
-            ds.AddDir(dump_traces_dir, true);
-        } else {
-            MYLOGD("Dumping current ANR traces (%s) to the main bugreport entry\n",
-                   dump_traces_path);
-            ds.DumpFile("VM TRACES JUST NOW", dump_traces_path);
-        }
-    }
-
-
-    // Make sure directory is not added twice.
-    // TODO: this is an overzealous check because it's relying on dump_traces_path - which is
-    // generated by dump_traces() -  and anr_traces_path - which is retrieved from a system
-    // property - but in reality they're the same path (although the former could be nullptr).
-    // Anyways, once dump_traces() is refactored as a private Dumpstate function, this logic should
-    // be revisited.
-    bool already_dumped = anr_traces_dir == dump_traces_dir;
-
-    MYLOGD("AddGlobalAnrTraceFile(): dump_traces_dir=%s, anr_traces_dir=%s, already_dumped=%d\n",
-           dump_traces_dir.c_str(), anr_traces_dir.c_str(), already_dumped);
-
-    android::base::unique_fd fd(TEMP_FAILURE_RETRY(
-        open(anr_traces_file.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)));
-    if (fd.get() < 0) {
-        printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_file.c_str(), strerror(errno));
-    } else {
-        if (add_to_zip) {
-            if (!already_dumped) {
-                MYLOGD("Adding dalvik ANR traces (directory %s) to the zip file\n",
-                       anr_traces_dir.c_str());
-                ds.AddDir(anr_traces_dir, true);
-            }
-        } else {
-            MYLOGD("Dumping last ANR traces (%s) to the main bugreport entry\n",
-                   anr_traces_file.c_str());
-            dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_file.c_str(), fd.get());
-        }
-    }
-}
-
 static void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_dir) {
     MYLOGD("AddAnrTraceDir(): dump_traces_file=%s, anr_traces_dir=%s\n", dump_traces_path,
            anr_traces_dir.c_str());
@@ -1015,50 +968,22 @@
 static void AddAnrTraceFiles() {
     const bool add_to_zip = ds.IsZipping() && ds.version_ == VERSION_SPLIT_ANR;
 
-    std::string anr_traces_file;
-    std::string anr_traces_dir;
-    bool is_global_trace_file = true;
+    std::string anr_traces_dir = "/data/anr";
 
-    // First check whether the stack-trace-dir property is set. When it's set,
-    // each ANR trace will be written to a separate file and not to a global
-    // stack trace file.
-    anr_traces_dir = android::base::GetProperty("dalvik.vm.stack-trace-dir", "");
-    if (anr_traces_dir.empty()) {
-        anr_traces_file = android::base::GetProperty("dalvik.vm.stack-trace-file", "");
-        if (!anr_traces_file.empty()) {
-            anr_traces_dir = dirname(anr_traces_file.c_str());
-        }
-    } else {
-        is_global_trace_file = false;
-    }
+    AddAnrTraceDir(add_to_zip, anr_traces_dir);
 
-    // We have neither configured a global trace file nor a trace directory,
-    // there will be nothing to dump.
-    if (anr_traces_file.empty() && anr_traces_dir.empty()) {
-        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
-        return;
-    }
-
-    if (is_global_trace_file) {
-        AddGlobalAnrTraceFile(add_to_zip, anr_traces_file, anr_traces_dir);
-    } else {
-        AddAnrTraceDir(add_to_zip, anr_traces_dir);
-    }
-
-    /* slow traces for slow operations */
+    // Slow traces for slow operations.
     struct stat st;
-    if (!anr_traces_dir.empty()) {
-        int i = 0;
-        while (true) {
-            const std::string slow_trace_path =
-                anr_traces_dir + android::base::StringPrintf("slow%02d.txt", i);
-            if (stat(slow_trace_path.c_str(), &st)) {
-                // No traces file at this index, done with the files.
-                break;
-            }
-            ds.DumpFile("VM TRACES WHEN SLOW", slow_trace_path.c_str());
-            i++;
+    int i = 0;
+    while (true) {
+        const std::string slow_trace_path =
+            anr_traces_dir + android::base::StringPrintf("slow%02d.txt", i);
+        if (stat(slow_trace_path.c_str(), &st)) {
+            // No traces file at this index, done with the files.
+            break;
         }
+        ds.DumpFile("VM TRACES WHEN SLOW", slow_trace_path.c_str());
+        i++;
     }
 }
 
@@ -1314,10 +1239,12 @@
     RunCommand("LIBRANK", {"librank"}, CommandOptions::AS_ROOT);
 
     if (ds.IsZipping()) {
-        RunCommand("HARDWARE HALS", {"lshal"}, CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
+        RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z"},
+                   CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
         DumpHals();
     } else {
-        RunCommand("HARDWARE HALS", {"lshal", "--debug"}, CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
+        RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z", "--debug"},
+                   CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
     }
 
     RunCommand("PRINTENV", {"printenv"});
@@ -1759,7 +1686,7 @@
             | O_CLOEXEC | O_NOFOLLOW)));
     if (fd == -1) {
         MYLOGE("open(%s): %s\n", filepath.c_str(), strerror(errno));
-        return NULL;
+        return nullptr;
     }
 
     SHA256_CTX ctx;
@@ -1772,7 +1699,7 @@
             break;
         } else if (bytes_read == -1) {
             MYLOGE("read(%s): %s\n", filepath.c_str(), strerror(errno));
-            return NULL;
+            return nullptr;
         }
 
         SHA256_Update(&ctx, buffer.data(), bytes_read);
@@ -1821,7 +1748,7 @@
     int do_add_date = 0;
     int do_zip_file = 0;
     int do_vibrate = 1;
-    char* use_outfile = 0;
+    char* use_outfile = nullptr;
     int use_socket = 0;
     int use_control_socket = 0;
     int do_fb = 0;
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 022f4fc..77f09b7 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -525,13 +525,13 @@
     if (PropertiesHelper::IsDryRun()) return;
 
     /* Get size of kernel buffer */
-    int size = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
+    int size = klogctl(KLOG_SIZE_BUFFER, nullptr, 0);
     if (size <= 0) {
         printf("Unexpected klogctl return value: %d\n\n", size);
         return;
     }
     char *buf = (char *) malloc(size + 1);
-    if (buf == NULL) {
+    if (buf == nullptr) {
         printf("memory allocation failed\n\n");
         return;
     }
@@ -598,7 +598,7 @@
     DurationReporter duration_reporter(title);
     DIR *dirp;
     struct dirent *d;
-    char *newpath = NULL;
+    char *newpath = nullptr;
     const char *slash = "/";
     int retval = 0;
 
@@ -611,7 +611,7 @@
         ++slash;
     }
     dirp = opendir(dir);
-    if (dirp == NULL) {
+    if (dirp == nullptr) {
         retval = -errno;
         MYLOGE("%s: %s\n", dir, strerror(errno));
         return retval;
@@ -620,7 +620,7 @@
     if (!dump_from_fd) {
         dump_from_fd = dump_file_from_fd;
     }
-    for (; ((d = readdir(dirp))); free(newpath), newpath = NULL) {
+    for (; ((d = readdir(dirp))); free(newpath), newpath = nullptr) {
         if ((d->d_name[0] == '.')
          && (((d->d_name[1] == '.') && (d->d_name[2] == '\0'))
           || (d->d_name[1] == '\0'))) {
@@ -648,7 +648,7 @@
             printf("*** %s: %s\n", newpath, strerror(errno));
             continue;
         }
-        (*dump_from_fd)(NULL, newpath, fd.get());
+        (*dump_from_fd)(nullptr, newpath, fd.get());
     }
     closedir(dirp);
     if (!title.empty()) {
@@ -779,29 +779,11 @@
     _redirect_to_file(redirect, path, O_APPEND);
 }
 
-const char* DumpTraces(const std::string& traces_path);
-const char* DumpTracesTombstoned(const std::string& traces_dir);
-
-/* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
-const char *dump_traces() {
+// Dump Dalvik and native stack traces, return the trace file location (nullptr if none).
+const char* dump_traces() {
     DurationReporter duration_reporter("DUMP TRACES");
 
-    const std::string traces_dir = android::base::GetProperty("dalvik.vm.stack-trace-dir", "");
-    if (!traces_dir.empty()) {
-        return DumpTracesTombstoned(traces_dir);
-    }
-
-    const std::string traces_file = android::base::GetProperty("dalvik.vm.stack-trace-file", "");
-    if (!traces_file.empty()) {
-        return DumpTraces(traces_file);
-    }
-
-    return nullptr;
-}
-
-const char* DumpTracesTombstoned(const std::string& traces_dir) {
-    const std::string temp_file_pattern = traces_dir + "/dumptrace_XXXXXX";
-
+    const std::string temp_file_pattern = "/data/anr/dumptrace_XXXXXX";
     const size_t buf_size = temp_file_pattern.length() + 1;
     std::unique_ptr<char[]> file_name_buf(new char[buf_size]);
     memcpy(file_name_buf.get(), temp_file_pattern.c_str(), buf_size);
@@ -902,156 +884,6 @@
     return file_name_buf.release();
 }
 
-const char* DumpTraces(const std::string& traces_path) {
-    const char* result = NULL;
-    /* move the old traces.txt (if any) out of the way temporarily */
-    std::string anrtraces_path = traces_path + ".anr";
-    if (rename(traces_path.c_str(), anrtraces_path.c_str()) && errno != ENOENT) {
-        MYLOGE("rename(%s, %s): %s\n", traces_path.c_str(), anrtraces_path.c_str(), strerror(errno));
-        return nullptr;  // Can't rename old traces.txt -- no permission? -- leave it alone instead
-    }
-
-    /* create a new, empty traces.txt file to receive stack dumps */
-    int fd = TEMP_FAILURE_RETRY(
-        open(traces_path.c_str(), O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
-             0666)); /* -rw-rw-rw- */
-    if (fd < 0) {
-        MYLOGE("%s: %s\n", traces_path.c_str(), strerror(errno));
-        return nullptr;
-    }
-    int chmod_ret = fchmod(fd, 0666);
-    if (chmod_ret < 0) {
-        MYLOGE("fchmod on %s failed: %s\n", traces_path.c_str(), strerror(errno));
-        close(fd);
-        return nullptr;
-    }
-
-    /* Variables below must be initialized before 'goto' statements */
-    int dalvik_found = 0;
-    int ifd, wfd = -1;
-    std::set<int> hal_pids = get_interesting_hal_pids();
-
-    /* walk /proc and kill -QUIT all Dalvik processes */
-    DIR *proc = opendir("/proc");
-    if (proc == NULL) {
-        MYLOGE("/proc: %s\n", strerror(errno));
-        goto error_close_fd;
-    }
-
-    /* use inotify to find when processes are done dumping */
-    ifd = inotify_init();
-    if (ifd < 0) {
-        MYLOGE("inotify_init: %s\n", strerror(errno));
-        goto error_close_fd;
-    }
-
-    wfd = inotify_add_watch(ifd, traces_path.c_str(), IN_CLOSE_WRITE);
-    if (wfd < 0) {
-        MYLOGE("inotify_add_watch(%s): %s\n", traces_path.c_str(), strerror(errno));
-        goto error_close_ifd;
-    }
-
-    struct dirent *d;
-    while ((d = readdir(proc))) {
-        int pid = atoi(d->d_name);
-        if (pid <= 0) continue;
-
-        char path[PATH_MAX];
-        char data[PATH_MAX];
-        snprintf(path, sizeof(path), "/proc/%d/exe", pid);
-        ssize_t len = readlink(path, data, sizeof(data) - 1);
-        if (len <= 0) {
-            continue;
-        }
-        data[len] = '\0';
-
-        if (!strncmp(data, "/system/bin/app_process", strlen("/system/bin/app_process"))) {
-            /* skip zygote -- it won't dump its stack anyway */
-            snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
-            int cfd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC));
-            len = read(cfd, data, sizeof(data) - 1);
-            close(cfd);
-            if (len <= 0) {
-                continue;
-            }
-            data[len] = '\0';
-            if (!strncmp(data, "zygote", strlen("zygote"))) {
-                continue;
-            }
-
-            ++dalvik_found;
-            uint64_t start = Nanotime();
-            if (kill(pid, SIGQUIT)) {
-                MYLOGE("kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
-                continue;
-            }
-
-            /* wait for the writable-close notification from inotify */
-            struct pollfd pfd = { ifd, POLLIN, 0 };
-            int ret = poll(&pfd, 1, TRACE_DUMP_TIMEOUT_MS);
-            if (ret < 0) {
-                MYLOGE("poll: %s\n", strerror(errno));
-            } else if (ret == 0) {
-                MYLOGE("warning: timed out dumping pid %d\n", pid);
-            } else {
-                struct inotify_event ie;
-                read(ifd, &ie, sizeof(ie));
-            }
-
-            if (lseek(fd, 0, SEEK_END) < 0) {
-                MYLOGE("lseek: %s\n", strerror(errno));
-            } else {
-                dprintf(fd, "[dump dalvik stack %d: %.3fs elapsed]\n", pid,
-                        (float)(Nanotime() - start) / NANOS_PER_SEC);
-            }
-        } else if (should_dump_native_traces(data) ||
-                   hal_pids.find(pid) != hal_pids.end()) {
-            /* dump native process if appropriate */
-            if (lseek(fd, 0, SEEK_END) < 0) {
-                MYLOGE("lseek: %s\n", strerror(errno));
-            } else {
-                static uint16_t timeout_failures = 0;
-                uint64_t start = Nanotime();
-
-                /* If 3 backtrace dumps fail in a row, consider debuggerd dead. */
-                if (timeout_failures == 3) {
-                    dprintf(fd, "too many stack dump failures, skipping...\n");
-                } else if (dump_backtrace_to_file_timeout(
-                        pid, kDebuggerdNativeBacktrace, 20, fd) == -1) {
-                    dprintf(fd, "dumping failed, likely due to a timeout\n");
-                    timeout_failures++;
-                } else {
-                    timeout_failures = 0;
-                }
-                dprintf(fd, "[dump native stack %d: %.3fs elapsed]\n", pid,
-                        (float)(Nanotime() - start) / NANOS_PER_SEC);
-            }
-        }
-    }
-
-    if (dalvik_found == 0) {
-        MYLOGE("Warning: no Dalvik processes found to dump stacks\n");
-    }
-
-    static std::string dumptraces_path = android::base::StringPrintf(
-        "%s/bugreport-%s", dirname(traces_path.c_str()), basename(traces_path.c_str()));
-    if (rename(traces_path.c_str(), dumptraces_path.c_str())) {
-        MYLOGE("rename(%s, %s): %s\n", traces_path.c_str(), dumptraces_path.c_str(),
-               strerror(errno));
-        goto error_close_ifd;
-    }
-    result = dumptraces_path.c_str();
-
-    /* replace the saved [ANR] traces.txt file */
-    rename(anrtraces_path.c_str(), traces_path.c_str());
-
-error_close_ifd:
-    close(ifd);
-error_close_fd:
-    close(fd);
-    return result;
-}
-
 void dump_route_tables() {
     DurationReporter duration_reporter("DUMP ROUTE TABLES");
     if (PropertiesHelper::IsDryRun()) return;
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index 5029352..8f60881 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -74,7 +74,7 @@
     explicit WriteOnFdAction(const std::string& output) : output_(output) {
     }
     virtual Result Perform(const ArgumentTuple& args) {
-        int fd = ::std::tr1::get<0>(args);
+        int fd = ::testing::get<0>(args);
         android::base::WriteStringToFd(output_, fd);
     }
 
diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp
index d5b3372..62d2fa1 100644
--- a/cmds/flatland/GLHelper.cpp
+++ b/cmds/flatland/GLHelper.cpp
@@ -29,7 +29,7 @@
     mContext(EGL_NO_CONTEXT),
     mDummySurface(EGL_NO_SURFACE),
     mConfig(0),
-    mShaderPrograms(NULL),
+    mShaderPrograms(nullptr),
     mDitherTexture(0) {
 }
 
@@ -101,12 +101,12 @@
 }
 
 void GLHelper::tearDown() {
-    if (mShaderPrograms != NULL) {
+    if (mShaderPrograms != nullptr) {
         delete[] mShaderPrograms;
-        mShaderPrograms = NULL;
+        mShaderPrograms = nullptr;
     }
 
-    if (mSurfaceComposerClient != NULL) {
+    if (mSurfaceComposerClient != nullptr) {
         mSurfaceComposerClient->dispose();
         mSurfaceComposerClient.clear();
     }
@@ -210,7 +210,7 @@
     glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
 
     sp<ANativeWindow> anw = new Surface(producer);
-    EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL);
+    EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), nullptr);
     if (s == EGL_NO_SURFACE) {
         fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError());
         return false;
@@ -223,7 +223,7 @@
 
 bool GLHelper::computeWindowScale(uint32_t w, uint32_t h, float* scale) {
     sp<IBinder> dpy = mSurfaceComposerClient->getBuiltInDisplay(0);
-    if (dpy == NULL) {
+    if (dpy == nullptr) {
         fprintf(stderr, "SurfaceComposer::getBuiltInDisplay failed.\n");
         return false;
     }
@@ -247,7 +247,7 @@
     bool result;
     status_t err;
 
-    if (mSurfaceComposerClient == NULL) {
+    if (mSurfaceComposerClient == nullptr) {
         mSurfaceComposerClient = new SurfaceComposerClient;
     }
     err = mSurfaceComposerClient->initCheck();
@@ -258,7 +258,7 @@
 
     sp<SurfaceControl> sc = mSurfaceComposerClient->createSurface(
             String8("Benchmark"), w, h, PIXEL_FORMAT_RGBA_8888, 0);
-    if (sc == NULL || !sc->isValid()) {
+    if (sc == nullptr || !sc->isValid()) {
         fprintf(stderr, "Failed to create SurfaceControl.\n");
         return false;
     }
@@ -275,7 +275,7 @@
             .apply();
 
     sp<ANativeWindow> anw = sc->getSurface();
-    EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL);
+    EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), nullptr);
     if (s == EGL_NO_SURFACE) {
         fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError());
         return false;
@@ -294,7 +294,7 @@
         return false;
     }
 
-    glShaderSource(shader, 1, &src, NULL);
+    glShaderSource(shader, 1, &src, nullptr);
     glCompileShader(shader);
 
     GLint compiled = 0;
@@ -305,7 +305,7 @@
         if (infoLen) {
             char* buf = new char[infoLen];
             if (buf) {
-                glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                glGetShaderInfoLog(shader, infoLen, nullptr, buf);
                 fprintf(stderr, "Shader compile log:\n%s\n", buf);
                 delete[] buf;
             }
@@ -318,21 +318,21 @@
 }
 
 static void printShaderSource(const char* const* src) {
-    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) {
+    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
         fprintf(stderr, "%3zu: %s\n", i+1, src[i]);
     }
 }
 
 static const char* makeShaderString(const char* const* src) {
     size_t len = 0;
-    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) {
+    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
         // The +1 is for the '\n' that will be added.
         len += strlen(src[i]) + 1;
     }
 
     char* result = new char[len+1];
     char* end = result;
-    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) {
+    for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != nullptr; i++) {
         strcpy(end, src[i]);
         end += strlen(src[i]);
         *end = '\n';
@@ -376,7 +376,7 @@
         if (bufLength) {
             char* buf = new char[bufLength];
             if (buf) {
-                glGetProgramInfoLog(program, bufLength, NULL, buf);
+                glGetProgramInfoLog(program, bufLength, nullptr, buf);
                 fprintf(stderr, "Program link log:\n%s\n", buf);
                 delete[] buf;
             }
diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp
index 3d7cac0..7ceb397 100644
--- a/cmds/flatland/Main.cpp
+++ b/cmds/flatland/Main.cpp
@@ -284,7 +284,7 @@
 public:
 
     Layer() :
-        mGLHelper(NULL),
+        mGLHelper(nullptr),
         mSurface(EGL_NO_SURFACE) {
     }
 
@@ -316,23 +316,23 @@
     }
 
     void tearDown() {
-        if (mComposer != NULL) {
+        if (mComposer != nullptr) {
             mComposer->tearDown();
             delete mComposer;
-            mComposer = NULL;
+            mComposer = nullptr;
         }
 
-        if (mRenderer != NULL) {
+        if (mRenderer != nullptr) {
             mRenderer->tearDown();
             delete mRenderer;
-            mRenderer = NULL;
+            mRenderer = nullptr;
         }
 
         if (mSurface != EGL_NO_SURFACE) {
             mGLHelper->destroySurface(&mSurface);
             mGLConsumer->abandon();
         }
-        mGLHelper = NULL;
+        mGLHelper = nullptr;
         mGLConsumer.clear();
     }
 
@@ -377,7 +377,7 @@
         mDesc(desc),
         mInstance(instance),
         mNumLayers(countLayers(desc)),
-        mGLHelper(NULL),
+        mGLHelper(nullptr),
         mSurface(EGL_NO_SURFACE),
         mWindowSurface(EGL_NO_SURFACE) {
     }
@@ -443,7 +443,7 @@
             mLayers[i].tearDown();
         }
 
-        if (mGLHelper != NULL) {
+        if (mGLHelper != nullptr) {
             if (mWindowSurface != EGL_NO_SURFACE) {
                 mGLHelper->destroySurface(&mWindowSurface);
             }
@@ -453,7 +453,7 @@
             mSurfaceControl.clear();
             mGLHelper->tearDown();
             delete mGLHelper;
-            mGLHelper = NULL;
+            mGLHelper = nullptr;
         }
     }
 
@@ -553,7 +553,7 @@
     static size_t countLayers(const BenchmarkDesc& desc) {
         size_t i;
         for (i = 0; i < MAX_NUM_LAYERS; i++) {
-            if (desc.layers[i].rendererFactory == NULL) {
+            if (desc.layers[i].rendererFactory == nullptr) {
                 break;
             }
         }
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 9615a75..0fd2dd4 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "installed"
+#define LOG_TAG "installd"
 
 #include <array>
 #include <fcntl.h>
@@ -773,7 +773,8 @@
     }
 
     // program name, reference profile fd, the final NULL and the profile fds
-    const char* argv[3 + profile_args.size() + apk_args.size() + (copy_and_update ? 1 : 0)];
+    const char* argv[3 + profile_args.size() + apk_args.size()
+            + dex_location_args.size() + (copy_and_update ? 1 : 0)];
     int i = 0;
     argv[i++] = profman_bin;
     argv[i++] = reference_profile_arg.c_str();
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 96d8c47..7291ef3 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -88,6 +88,12 @@
               "DEXOPT_MASK unexpected.");
 
 
+template<typename T>
+static constexpr bool IsPowerOfTwo(T x) {
+  static_assert(std::is_integral<T>::value, "T must be integral");
+  // TODO: assert unsigned. There is currently many uses with signed values.
+  return (x & (x - 1)) == 0;
+}
 
 template<typename T>
 static constexpr T RoundDown(T x, typename std::decay<T>::type n) {
diff --git a/cmds/installd/tests/Android.bp b/cmds/installd/tests/Android.bp
index 7438d3d..739f33f 100644
--- a/cmds/installd/tests/Android.bp
+++ b/cmds/installd/tests/Android.bp
@@ -1,6 +1,7 @@
 // Build the unit tests for installd
 cc_test {
     name: "installd_utils_test",
+    test_suites: ["device-tests"],
     clang: true,
     srcs: ["installd_utils_test.cpp"],
     cflags: ["-Wall", "-Werror"],
@@ -18,6 +19,7 @@
 
 cc_test {
     name: "installd_cache_test",
+    test_suites: ["device-tests"],
     clang: true,
     srcs: ["installd_cache_test.cpp"],
     cflags: ["-Wall", "-Werror"],
@@ -39,6 +41,7 @@
 
 cc_test {
     name: "installd_service_test",
+    test_suites: ["device-tests"],
     clang: true,
     srcs: ["installd_service_test.cpp"],
     cflags: ["-Wall", "-Werror"],
@@ -60,6 +63,7 @@
 
 cc_test {
     name: "installd_dexopt_test",
+    test_suites: ["device-tests"],
     clang: true,
     srcs: ["installd_dexopt_test.cpp"],
     cflags: ["-Wall", "-Werror"],
@@ -81,6 +85,7 @@
 
 cc_test {
     name: "installd_otapreopt_test",
+    test_suites: ["device-tests"],
     clang: true,
     srcs: ["installd_otapreopt_test.cpp"],
     cflags: ["-Wall", "-Werror"],
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
index dd8812d..0952db6 100644
--- a/cmds/lshal/DebugCommand.cpp
+++ b/cmds/lshal/DebugCommand.cpp
@@ -59,8 +59,8 @@
 
     auto pair = splitFirst(mInterfaceName, '/');
 
-    FQName fqName(pair.first);
-    if (!fqName.isValid() || fqName.isIdentifier() || !fqName.isFullyQualified()) {
+    FQName fqName;
+    if (!FQName::parse(pair.first, &fqName) || fqName.isIdentifier() || !fqName.isFullyQualified()) {
         mLshal.err() << "Invalid fully-qualified name '" << pair.first << "'\n\n";
         return USAGE;
     }
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index ff22048..8d5f0d2 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -18,14 +18,17 @@
 
 #include <getopt.h>
 
+#include <algorithm>
 #include <fstream>
+#include <functional>
 #include <iomanip>
 #include <iostream>
 #include <map>
-#include <sstream>
 #include <regex>
+#include <sstream>
 
 #include <android-base/file.h>
+#include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl-hash/Hash.h>
@@ -54,6 +57,19 @@
     return (p == Partition::SYSTEM) ? vintf::SchemaType::FRAMEWORK : vintf::SchemaType::DEVICE;
 }
 
+Partition toPartition(vintf::SchemaType t) {
+    switch (t) {
+        case vintf::SchemaType::FRAMEWORK: return Partition::SYSTEM;
+        // TODO(b/71555570): Device manifest does not distinguish HALs from vendor or ODM.
+        case vintf::SchemaType::DEVICE: return Partition::VENDOR;
+    }
+    return Partition::UNKNOWN;
+}
+
+std::string getPackageAndVersion(const std::string& fqInstance) {
+    return splitFirst(fqInstance, ':').first;
+}
+
 NullableOStream<std::ostream> ListCommand::out() const {
     return mLshal.out();
 }
@@ -74,6 +90,8 @@
 }
 
 const std::string &ListCommand::getCmdline(pid_t pid) {
+    static const std::string kEmptyString{};
+    if (pid == NO_PID) return kEmptyString;
     auto pair = mCmdlines.find(pid);
     if (pair != mCmdlines.end()) {
         return pair->second;
@@ -90,6 +108,7 @@
 }
 
 Partition ListCommand::getPartition(pid_t pid) {
+    if (pid == NO_PID) return Partition::UNKNOWN;
     auto it = mPartitions.find(pid);
     if (it != mPartitions.end()) {
         return it->second;
@@ -101,21 +120,19 @@
 
 // Give sensible defaults when nothing can be inferred from runtime.
 // process: Partition inferred from executable location or cmdline.
-Partition ListCommand::resolvePartition(Partition process, const FQName& fqName) const {
-    if (fqName.inPackage("vendor") ||
-        fqName.inPackage("com")) {
+Partition ListCommand::resolvePartition(Partition process, const FqInstance& fqInstance) const {
+    if (fqInstance.inPackage("vendor") || fqInstance.inPackage("com")) {
         return Partition::VENDOR;
     }
 
-    if (fqName.inPackage("android.frameworks") ||
-        fqName.inPackage("android.system") ||
-        fqName.inPackage("android.hidl")) {
+    if (fqInstance.inPackage("android.frameworks") || fqInstance.inPackage("android.system") ||
+        fqInstance.inPackage("android.hidl")) {
         return Partition::SYSTEM;
     }
 
     // Some android.hardware HALs are served from system. Check the value from executable
     // location / cmdline first.
-    if (fqName.inPackage("android.hardware")) {
+    if (fqInstance.inPackage("android.hardware")) {
         if (process != Partition::UNKNOWN) {
             return process;
         }
@@ -125,6 +142,67 @@
     return process;
 }
 
+bool match(const vintf::ManifestInstance& instance, const FqInstance& fqInstance,
+           vintf::TransportArch ta) {
+    // For hwbinder libs, allow missing arch in manifest.
+    // For passthrough libs, allow missing interface/instance in table.
+    return (ta.transport == instance.transport()) &&
+            (ta.transport == vintf::Transport::HWBINDER ||
+             vintf::contains(instance.arch(), ta.arch)) &&
+            (!fqInstance.hasInterface() || fqInstance.getInterface() == instance.interface()) &&
+            (!fqInstance.hasInstance() || fqInstance.getInstance() == instance.instance());
+}
+
+bool match(const vintf::MatrixInstance& instance, const FqInstance& fqInstance,
+           vintf::TransportArch /* ta */) {
+    return (!fqInstance.hasInterface() || fqInstance.getInterface() == instance.interface()) &&
+            (!fqInstance.hasInstance() || instance.matchInstance(fqInstance.getInstance()));
+}
+
+template <typename ObjectType>
+VintfInfo getVintfInfo(const std::shared_ptr<const ObjectType>& object,
+                       const FqInstance& fqInstance, vintf::TransportArch ta, VintfInfo value) {
+    bool found = false;
+    (void)object->forEachInstanceOfVersion(fqInstance.getPackage(), fqInstance.getVersion(),
+                                           [&](const auto& instance) {
+                                               found = match(instance, fqInstance, ta);
+                                               return !found; // continue if not found
+                                           });
+    return found ? value : VINTF_INFO_EMPTY;
+}
+
+std::shared_ptr<const vintf::HalManifest> ListCommand::getDeviceManifest() const {
+    return vintf::VintfObject::GetDeviceHalManifest();
+}
+
+std::shared_ptr<const vintf::CompatibilityMatrix> ListCommand::getDeviceMatrix() const {
+    return vintf::VintfObject::GetDeviceCompatibilityMatrix();
+}
+
+std::shared_ptr<const vintf::HalManifest> ListCommand::getFrameworkManifest() const {
+    return vintf::VintfObject::GetFrameworkHalManifest();
+}
+
+std::shared_ptr<const vintf::CompatibilityMatrix> ListCommand::getFrameworkMatrix() const {
+    return vintf::VintfObject::GetFrameworkCompatibilityMatrix();
+}
+
+VintfInfo ListCommand::getVintfInfo(const std::string& fqInstanceName,
+                                    vintf::TransportArch ta) const {
+    FqInstance fqInstance;
+    if (!fqInstance.setTo(fqInstanceName) &&
+        // Ignore interface / instance for passthrough libs
+        !fqInstance.setTo(getPackageAndVersion(fqInstanceName))) {
+        err() << "Warning: Cannot parse '" << fqInstanceName << "'; no VINTF info." << std::endl;
+        return VINTF_INFO_EMPTY;
+    }
+
+    return lshal::getVintfInfo(getDeviceManifest(), fqInstance, ta, DEVICE_MANIFEST) |
+            lshal::getVintfInfo(getFrameworkManifest(), fqInstance, ta, FRAMEWORK_MANIFEST) |
+            lshal::getVintfInfo(getDeviceMatrix(), fqInstance, ta, DEVICE_MATRIX) |
+            lshal::getVintfInfo(getFrameworkMatrix(), fqInstance, ta, FRAMEWORK_MATRIX);
+}
+
 static bool scanBinderContext(pid_t pid,
         const std::string &contextName,
         std::function<void(const std::string&)> eachLine) {
@@ -221,16 +299,40 @@
     return &pair.first->second;
 }
 
-// Must process hwbinder services first, then passthrough services.
+bool ListCommand::shouldFetchHalType(const HalType &type) const {
+    return (std::find(mFetchTypes.begin(), mFetchTypes.end(), type) != mFetchTypes.end());
+}
+
+Table* ListCommand::tableForType(HalType type) {
+    switch (type) {
+        case HalType::BINDERIZED_SERVICES:
+            return &mServicesTable;
+        case HalType::PASSTHROUGH_CLIENTS:
+            return &mPassthroughRefTable;
+        case HalType::PASSTHROUGH_LIBRARIES:
+            return &mImplementationsTable;
+        case HalType::VINTF_MANIFEST:
+            return &mManifestHalsTable;
+        case HalType::LAZY_HALS:
+            return &mLazyHalsTable;
+        default:
+            LOG(FATAL) << "Unknown HAL type " << static_cast<int64_t>(type);
+            return nullptr;
+    }
+}
+const Table* ListCommand::tableForType(HalType type) const {
+    return const_cast<ListCommand*>(this)->tableForType(type);
+}
+
 void ListCommand::forEachTable(const std::function<void(Table &)> &f) {
-    f(mServicesTable);
-    f(mPassthroughRefTable);
-    f(mImplementationsTable);
+    for (const auto& type : mListTypes) {
+        f(*tableForType(type));
+    }
 }
 void ListCommand::forEachTable(const std::function<void(const Table &)> &f) const {
-    f(mServicesTable);
-    f(mPassthroughRefTable);
-    f(mImplementationsTable);
+    for (const auto& type : mListTypes) {
+        f(*tableForType(type));
+    }
 }
 
 void ListCommand::postprocess() {
@@ -246,22 +348,25 @@
             }
         }
         for (TableEntry& entry : table) {
-            entry.partition = getPartition(entry.serverPid);
+            if (entry.partition == Partition::UNKNOWN) {
+                entry.partition = getPartition(entry.serverPid);
+            }
+            entry.vintfInfo = getVintfInfo(entry.interfaceName, {entry.transport, entry.arch});
         }
     });
     // use a double for loop here because lshal doesn't care about efficiency.
     for (TableEntry &packageEntry : mImplementationsTable) {
         std::string packageName = packageEntry.interfaceName;
-        FQName fqPackageName{packageName.substr(0, packageName.find("::"))};
-        if (!fqPackageName.isValid()) {
+        FQName fqPackageName;
+        if (!FQName::parse(packageName.substr(0, packageName.find("::")), &fqPackageName)) {
             continue;
         }
         for (TableEntry &interfaceEntry : mPassthroughRefTable) {
-            if (interfaceEntry.arch != ARCH_UNKNOWN) {
+            if (interfaceEntry.arch != vintf::Arch::ARCH_EMPTY) {
                 continue;
             }
-            FQName interfaceName{splitFirst(interfaceEntry.interfaceName, '/').first};
-            if (!interfaceName.isValid()) {
+            FQName interfaceName;
+            if (!FQName::parse(splitFirst(interfaceEntry.interfaceName, '/').first, &interfaceName)) {
                 continue;
             }
             if (interfaceName.getPackageAndVersion() == fqPackageName) {
@@ -282,158 +387,156 @@
     mImplementationsTable.setDescription(
             "All available passthrough implementations (all -impl.so files).\n"
             "These may return subclasses through their respective HIDL_FETCH_I* functions.");
+    mManifestHalsTable.setDescription(
+            "All HALs that are in VINTF manifest.");
+    mLazyHalsTable.setDescription(
+            "All HALs that are declared in VINTF manifest:\n"
+            "   - as hwbinder HALs but are not registered to hwservicemanager, and\n"
+            "   - as hwbinder/passthrough HALs with no implementation.");
 }
 
-static inline bool findAndBumpVersion(vintf::ManifestHal* hal, const vintf::Version& version) {
-    for (vintf::Version& v : hal->versions) {
-        if (v.majorVer == version.majorVer) {
-            v.minorVer = std::max(v.minorVer, version.minorVer);
-            return true;
-        }
+bool ListCommand::addEntryWithInstance(const TableEntry& entry,
+                                       vintf::HalManifest* manifest) const {
+    FqInstance fqInstance;
+    if (!fqInstance.setTo(entry.interfaceName)) {
+        err() << "Warning: '" << entry.interfaceName << "' is not a valid FqInstance." << std::endl;
+        return false;
     }
-    return false;
+
+    if (fqInstance.getPackage() == gIBaseFqName.package()) {
+        return true; // always remove IBase from manifest
+    }
+
+    Partition partition = resolvePartition(entry.partition, fqInstance);
+
+    if (partition == Partition::UNKNOWN) {
+        err() << "Warning: Cannot guess the partition of FqInstance " << fqInstance.string()
+              << std::endl;
+        return false;
+    }
+
+    if (partition != mVintfPartition) {
+        return true; // strip out instances that is in a different partition.
+    }
+
+    vintf::Arch arch;
+    if (entry.transport == vintf::Transport::HWBINDER) {
+        arch = vintf::Arch::ARCH_EMPTY; // no need to specify arch in manifest
+    } else if (entry.transport == vintf::Transport::PASSTHROUGH) {
+        if (entry.arch == vintf::Arch::ARCH_EMPTY) {
+            err() << "Warning: '" << entry.interfaceName << "' doesn't have bitness info.";
+            return false;
+        }
+        arch = entry.arch;
+    } else {
+        err() << "Warning: '" << entry.transport << "' is not a valid transport." << std::endl;
+        return false;
+    }
+
+    std::string e;
+    if (!manifest->insertInstance(fqInstance, entry.transport, arch, vintf::HalFormat::HIDL, &e)) {
+        err() << "Warning: Cannot insert '" << fqInstance.string() << ": " << e << std::endl;
+        return false;
+    }
+    return true;
+}
+
+bool ListCommand::addEntryWithoutInstance(const TableEntry& entry,
+                                          const vintf::HalManifest* manifest) const {
+    const auto& packageAndVersion = splitFirst(getPackageAndVersion(entry.interfaceName), '@');
+    const auto& package = packageAndVersion.first;
+    vintf::Version version;
+    if (!vintf::parse(packageAndVersion.second, &version)) {
+        err() << "Warning: Cannot parse version '" << packageAndVersion.second << "' for entry '"
+              << entry.interfaceName << "'" << std::endl;
+        return false;
+    }
+
+    bool found = false;
+    (void)manifest->forEachInstanceOfVersion(package, version, [&found](const auto&) {
+        found = true;
+        return false; // break
+    });
+    return found;
 }
 
 void ListCommand::dumpVintf(const NullableOStream<std::ostream>& out) const {
     using vintf::operator|=;
     using vintf::operator<<;
+    using namespace std::placeholders;
 
     vintf::HalManifest manifest;
     manifest.setType(toSchemaType(mVintfPartition));
-    forEachTable([this, &manifest] (const Table &table) {
-        for (const TableEntry &entry : table) {
 
-            std::string fqInstanceName = entry.interfaceName;
+    std::vector<std::string> error;
+    for (const TableEntry& entry : mServicesTable)
+        if (!addEntryWithInstance(entry, &manifest)) error.push_back(entry.interfaceName);
+    for (const TableEntry& entry : mPassthroughRefTable)
+        if (!addEntryWithInstance(entry, &manifest)) error.push_back(entry.interfaceName);
+    for (const TableEntry& entry : mManifestHalsTable)
+        if (!addEntryWithInstance(entry, &manifest)) error.push_back(entry.interfaceName);
 
-            if (&table == &mImplementationsTable) {
-                // Quick hack to work around *'s
-                replaceAll(&fqInstanceName, '*', 'D');
-            }
-            auto splittedFqInstanceName = splitFirst(fqInstanceName, '/');
-            FQName fqName(splittedFqInstanceName.first);
-            if (!fqName.isValid()) {
-                err() << "Warning: '" << splittedFqInstanceName.first
-                     << "' is not a valid FQName." << std::endl;
-                continue;
-            }
+    std::vector<std::string> passthrough;
+    for (const TableEntry& entry : mImplementationsTable)
+        if (!addEntryWithoutInstance(entry, &manifest)) passthrough.push_back(entry.interfaceName);
 
-            if (fqName.package() == gIBaseFqName.package()) {
-                continue; // always remove IBase from manifest
-            }
-
-            Partition partition = resolvePartition(entry.partition, fqName);
-
-            if (partition == Partition::UNKNOWN) {
-                err() << "Warning: Cannot guess the partition of instance " << fqInstanceName
-                      << ". It is removed from the generated manifest." << std::endl;
-                continue;
-            }
-
-            if (partition != mVintfPartition) {
-                continue; // strip out instances that is in a different partition.
-            }
-
-            std::string interfaceName =
-                    &table == &mImplementationsTable ? "" : fqName.name();
-            std::string instanceName =
-                    &table == &mImplementationsTable ? "" : splittedFqInstanceName.second;
-
-            vintf::Version version{fqName.getPackageMajorVersion(),
-                                   fqName.getPackageMinorVersion()};
-            vintf::Transport transport;
-            vintf::Arch arch;
-            if (entry.transport == "hwbinder") {
-                transport = vintf::Transport::HWBINDER;
-                arch = vintf::Arch::ARCH_EMPTY;
-            } else if (entry.transport == "passthrough") {
-                transport = vintf::Transport::PASSTHROUGH;
-                switch (entry.arch) {
-                    case lshal::ARCH32:
-                        arch = vintf::Arch::ARCH_32;    break;
-                    case lshal::ARCH64:
-                        arch = vintf::Arch::ARCH_64;    break;
-                    case lshal::ARCH_BOTH:
-                        arch = vintf::Arch::ARCH_32_64; break;
-                    case lshal::ARCH_UNKNOWN: // fallthrough
-                    default:
-                        err() << "Warning: '" << fqName.package()
-                             << "' doesn't have bitness info, assuming 32+64." << std::endl;
-                        arch = vintf::Arch::ARCH_32_64;
-                }
-            } else {
-                err() << "Warning: '" << entry.transport << "' is not a valid transport." << std::endl;
-                continue;
-            }
-
-            bool done = false;
-            for (vintf::ManifestHal *hal : manifest.getHals(fqName.package())) {
-                if (hal->transport() != transport) {
-                    if (transport != vintf::Transport::PASSTHROUGH) {
-                        err() << "Fatal: should not reach here. Generated result may be wrong for '"
-                             << hal->name << "'."
-                             << std::endl;
-                    }
-                    done = true;
-                    break;
-                }
-                if (findAndBumpVersion(hal, version)) {
-                    if (&table != &mImplementationsTable) {
-                        hal->insertLegacyInstance(interfaceName, instanceName);
-                    }
-                    hal->transportArch.arch |= arch;
-                    done = true;
-                    break;
-                }
-            }
-            if (done) {
-                continue; // to next TableEntry
-            }
-            vintf::ManifestHal manifestHal{
-                    vintf::HalFormat::HIDL,
-                    std::string{fqName.package()},
-                    {version},
-                    {transport, arch},
-                    {}};
-            if (&table != &mImplementationsTable) {
-                manifestHal.insertLegacyInstance(interfaceName, instanceName);
-            }
-            if (!manifest.add(std::move(manifestHal))) {
-                err() << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
-            }
-        }
-    });
     out << "<!-- " << std::endl
-         << "    This is a skeleton " << manifest.type() << " manifest. Notes: " << std::endl
-         << INIT_VINTF_NOTES
-         << "-->" << std::endl;
-    out << vintf::gHalManifestConverter(manifest, vintf::SerializeFlag::HALS_NO_FQNAME);
+        << "    This is a skeleton " << manifest.type() << " manifest. Notes: " << std::endl
+        << INIT_VINTF_NOTES;
+    if (!error.empty()) {
+        out << std::endl << "    The following HALs are not added; see warnings." << std::endl;
+        for (const auto& e : error) {
+            out << "        " << e << std::endl;
+        }
+    }
+    if (!passthrough.empty()) {
+        out << std::endl
+            << "    The following HALs are passthrough and no interface or instance " << std::endl
+            << "    names can be inferred." << std::endl;
+        for (const auto& e : passthrough) {
+            out << "        " << e << std::endl;
+        }
+    }
+    out << "-->" << std::endl;
+    out << vintf::gHalManifestConverter(manifest, vintf::SerializeFlag::HALS_ONLY);
 }
 
 std::string ListCommand::INIT_VINTF_NOTES{
-    "    1. If a HAL is supported in both hwbinder and passthrough transport, \n"
+    "    1. If a HAL is supported in both hwbinder and passthrough transport,\n"
     "       only hwbinder is shown.\n"
     "    2. It is likely that HALs in passthrough transport does not have\n"
     "       <interface> declared; users will have to write them by hand.\n"
     "    3. A HAL with lower minor version can be overridden by a HAL with\n"
     "       higher minor version if they have the same name and major version.\n"
+    "    4. This output is intended for launch devices.\n"
+    "       Upgrading devices should not use this tool to generate device\n"
+    "       manifest and replace the existing manifest directly, but should\n"
+    "       edit the existing manifest manually.\n"
+    "       Specifically, devices which launched at Android O-MR1 or earlier\n"
+    "       should not use the 'fqname' format for required HAL entries and\n"
+    "       should instead use the legacy package, name, instance-name format\n"
+    "       until they are updated.\n"
 };
 
-static Architecture fromBaseArchitecture(::android::hidl::base::V1_0::DebugInfo::Architecture a) {
+static vintf::Arch fromBaseArchitecture(::android::hidl::base::V1_0::DebugInfo::Architecture a) {
     switch (a) {
         case ::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT:
-            return ARCH64;
+            return vintf::Arch::ARCH_64;
         case ::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT:
-            return ARCH32;
+            return vintf::Arch::ARCH_32;
         case ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN: // fallthrough
         default:
-            return ARCH_UNKNOWN;
+            return vintf::Arch::ARCH_EMPTY;
     }
 }
 
 void ListCommand::dumpTable(const NullableOStream<std::ostream>& out) const {
     if (mNeat) {
-        MergedTable({&mServicesTable, &mPassthroughRefTable, &mImplementationsTable})
-            .createTextTable().dump(out.buf());
+        std::vector<const Table*> tables;
+        forEachTable([&tables](const Table &table) {
+            tables.push_back(&table);
+        });
+        MergedTable(std::move(tables)).createTextTable().dump(out.buf());
         return;
     }
 
@@ -481,24 +584,13 @@
     return OK;
 }
 
-void ListCommand::putEntry(TableEntrySource source, TableEntry &&entry) {
-    Table *table = nullptr;
-    switch (source) {
-        case HWSERVICEMANAGER_LIST :
-            table = &mServicesTable; break;
-        case PTSERVICEMANAGER_REG_CLIENT :
-            table = &mPassthroughRefTable; break;
-        case LIST_DLLIB :
-            table = &mImplementationsTable; break;
-        default:
-            err() << "Error: Unknown source of entry " << source << std::endl;
-    }
-    if (table) {
-        table->add(std::forward<TableEntry>(entry));
-    }
+void ListCommand::putEntry(HalType type, TableEntry &&entry) {
+    tableForType(type)->add(std::forward<TableEntry>(entry));
 }
 
 Status ListCommand::fetchAllLibraries(const sp<IServiceManager> &manager) {
+    if (!shouldFetchHalType(HalType::PASSTHROUGH_LIBRARIES)) { return OK; }
+
     using namespace ::android::hardware;
     using namespace ::android::hidl::manager::V1_0;
     using namespace ::android::hidl::base::V1_0;
@@ -510,12 +602,12 @@
                     std::string{info.instanceName.c_str()};
             entries.emplace(interfaceName, TableEntry{
                 .interfaceName = interfaceName,
-                .transport = "passthrough",
+                .transport = vintf::Transport::PASSTHROUGH,
                 .clientPids = info.clientPids,
             }).first->second.arch |= fromBaseArchitecture(info.arch);
         }
         for (auto &&pair : entries) {
-            putEntry(LIST_DLLIB, std::move(pair.second));
+            putEntry(HalType::PASSTHROUGH_LIBRARIES, std::move(pair.second));
         }
     });
     if (!ret.isOk()) {
@@ -527,6 +619,8 @@
 }
 
 Status ListCommand::fetchPassthrough(const sp<IServiceManager> &manager) {
+    if (!shouldFetchHalType(HalType::PASSTHROUGH_CLIENTS)) { return OK; }
+
     using namespace ::android::hardware;
     using namespace ::android::hardware::details;
     using namespace ::android::hidl::manager::V1_0;
@@ -536,11 +630,11 @@
             if (info.clientPids.size() <= 0) {
                 continue;
             }
-            putEntry(PTSERVICEMANAGER_REG_CLIENT, {
+            putEntry(HalType::PASSTHROUGH_CLIENTS, {
                 .interfaceName =
                         std::string{info.interfaceName.c_str()} + "/" +
                         std::string{info.instanceName.c_str()},
-                .transport = "passthrough",
+                .transport = vintf::Transport::PASSTHROUGH,
                 .serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID,
                 .clientPids = info.clientPids,
                 .arch = fromBaseArchitecture(info.arch)
@@ -556,8 +650,11 @@
 }
 
 Status ListCommand::fetchBinderized(const sp<IServiceManager> &manager) {
-    const std::string mode = "hwbinder";
+    using vintf::operator<<;
 
+    if (!shouldFetchHalType(HalType::BINDERIZED_SERVICES)) { return OK; }
+
+    const vintf::Transport mode = vintf::Transport::HWBINDER;
     hidl_vec<hidl_string> fqInstanceNames;
     // copying out for timeoutIPC
     auto listRet = timeoutIPC(manager, &IServiceManager::list, [&] (const auto &names) {
@@ -576,12 +673,13 @@
         TableEntry& entry = allTableEntries[fqInstanceName];
         entry.interfaceName = fqInstanceName;
         entry.transport = mode;
+        entry.serviceStatus = ServiceStatus::NON_RESPONSIVE;
 
         status |= fetchBinderizedEntry(manager, &entry);
     }
 
     for (auto& pair : allTableEntries) {
-        putEntry(HWSERVICEMANAGER_LIST, std::move(pair.second));
+        putEntry(HalType::BINDERIZED_SERVICES, std::move(pair.second));
     }
     return status;
 }
@@ -681,9 +779,100 @@
             handleError(TRANSACTION_ERROR, "getHashChain failed: " + hashRet.description());
         }
     } while (0);
+    if (status == OK) {
+        entry->serviceStatus = ServiceStatus::ALIVE;
+    }
     return status;
 }
 
+Status ListCommand::fetchManifestHals() {
+    if (!shouldFetchHalType(HalType::VINTF_MANIFEST)) { return OK; }
+    Status status = OK;
+
+    for (auto manifest : {getDeviceManifest(), getFrameworkManifest()}) {
+        if (manifest == nullptr) {
+            status |= VINTF_ERROR;
+            continue;
+        }
+
+        std::map<std::string, TableEntry> entries;
+
+        manifest->forEachInstance([&] (const vintf::ManifestInstance& manifestInstance) {
+            TableEntry entry{
+                .interfaceName = manifestInstance.getFqInstance().string(),
+                .transport = manifestInstance.transport(),
+                .arch = manifestInstance.arch(),
+                // TODO(b/71555570): Device manifest does not distinguish HALs from vendor or ODM.
+                .partition = toPartition(manifest->type()),
+                .serviceStatus = ServiceStatus::DECLARED};
+            std::string key = entry.interfaceName;
+            entries.emplace(std::move(key), std::move(entry));
+            return true;
+        });
+
+        for (auto&& pair : entries)
+            mManifestHalsTable.add(std::move(pair.second));
+    }
+    return status;
+}
+
+Status ListCommand::fetchLazyHals() {
+    using vintf::operator<<;
+
+    if (!shouldFetchHalType(HalType::LAZY_HALS)) { return OK; }
+    Status status = OK;
+
+    for (const TableEntry& manifestEntry : mManifestHalsTable) {
+        if (manifestEntry.transport == vintf::Transport::HWBINDER) {
+            if (!hasHwbinderEntry(manifestEntry)) {
+                mLazyHalsTable.add(TableEntry(manifestEntry));
+            }
+            continue;
+        }
+        if (manifestEntry.transport == vintf::Transport::PASSTHROUGH) {
+            if (!hasPassthroughEntry(manifestEntry)) {
+                mLazyHalsTable.add(TableEntry(manifestEntry));
+            }
+            continue;
+        }
+        err() << "Warning: unrecognized transport in VINTF manifest: "
+              << manifestEntry.transport;
+        status |= VINTF_ERROR;
+    }
+    return status;
+}
+
+bool ListCommand::hasHwbinderEntry(const TableEntry& entry) const {
+    for (const TableEntry& existing : mServicesTable) {
+        if (existing.interfaceName == entry.interfaceName) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool ListCommand::hasPassthroughEntry(const TableEntry& entry) const {
+    FqInstance entryFqInstance;
+    if (!entryFqInstance.setTo(entry.interfaceName)) {
+        return false; // cannot parse, so add it anyway.
+    }
+    for (const TableEntry& existing : mImplementationsTable) {
+        FqInstance existingFqInstance;
+        if (!existingFqInstance.setTo(getPackageAndVersion(existing.interfaceName))) {
+            continue;
+        }
+
+        // For example, manifest may say graphics.mapper@2.1 but passthroughServiceManager
+        // can only list graphics.mapper@2.0.
+        if (entryFqInstance.getPackage() == existingFqInstance.getPackage() &&
+            vintf::Version{entryFqInstance.getVersion()}
+                .minorAtLeast(vintf::Version{existingFqInstance.getVersion()})) {
+            return true;
+        }
+    }
+    return false;
+}
+
 Status ListCommand::fetch() {
     Status status = OK;
     auto bManager = mLshal.serviceManager();
@@ -703,9 +892,27 @@
     } else {
         status |= fetchAllLibraries(pManager);
     }
+    status |= fetchManifestHals();
+    status |= fetchLazyHals();
     return status;
 }
 
+void ListCommand::initFetchTypes() {
+    // TODO: refactor to do polymorphism on each table (so that dependency graph is not hardcoded).
+    static const std::map<HalType, std::set<HalType>> kDependencyGraph{
+        {HalType::LAZY_HALS, {HalType::BINDERIZED_SERVICES,
+                              HalType::PASSTHROUGH_LIBRARIES,
+                              HalType::VINTF_MANIFEST}},
+    };
+    mFetchTypes.insert(mListTypes.begin(), mListTypes.end());
+    for (HalType listType : mListTypes) {
+        auto it = kDependencyGraph.find(listType);
+        if (it != kDependencyGraph.end()) {
+            mFetchTypes.insert(it->second.begin(), it->second.end());
+        }
+    }
+}
+
 void ListCommand::registerAllOptions() {
     int v = mOptions.size();
     // A list of acceptable command line options
@@ -721,7 +928,7 @@
     mOptions.push_back({'l', "released", no_argument, v++, [](ListCommand* thiz, const char*) {
         thiz->mSelectedColumns.push_back(TableColumnType::RELEASED);
         return OK;
-    }, "print the 'is released?' column\n(Y=released, empty=unreleased or unknown)"});
+    }, "print the 'is released?' column\n(Y=released, N=unreleased, ?=unknown)"});
     mOptions.push_back({'t', "transport", no_argument, v++, [](ListCommand* thiz, const char*) {
         thiz->mSelectedColumns.push_back(TableColumnType::TRANSPORT);
         return OK;
@@ -761,6 +968,23 @@
     }, "Emit debug info from\nIBase::debug with empty options. Cannot be used with --neat.\n"
         "Writes to specified file if 'arg' is provided, otherwise stdout."});
 
+    mOptions.push_back({'V', "vintf", no_argument, v++, [](ListCommand* thiz, const char*) {
+        thiz->mSelectedColumns.push_back(TableColumnType::VINTF);
+        return OK;
+    }, "print VINTF info. This column contains a comma-separated list of:\n"
+       "    - DM: device manifest\n"
+       "    - DC: device compatibility matrix\n"
+       "    - FM: framework manifest\n"
+       "    - FC: framework compatibility matrix"});
+    mOptions.push_back({'S', "service-status", no_argument, v++, [](ListCommand* thiz, const char*) {
+        thiz->mSelectedColumns.push_back(TableColumnType::SERVICE_STATUS);
+        return OK;
+    }, "print service status column. Possible values are:\n"
+       "    - alive: alive and running hwbinder service;\n"
+       "    - registered;dead: registered to hwservicemanager but is not responsive;\n"
+       "    - declared: only declared in VINTF manifest but is not registered to hwservicemanager;\n"
+       "    - N/A: no information for passthrough HALs."});
+
     // long options without short alternatives
     mOptions.push_back({'\0', "init-vintf", no_argument, v++, [](ListCommand* thiz, const char* arg) {
         thiz->mVintf = true;
@@ -791,6 +1015,46 @@
         thiz->mNeat = true;
         return OK;
     }, "output is machine parsable (no explanatory text).\nCannot be used with --debug."});
+    mOptions.push_back({'\0', "types", required_argument, v++, [](ListCommand* thiz, const char* arg) {
+        if (!arg) { return USAGE; }
+
+        static const std::map<std::string, HalType> kHalTypeMap {
+            {"binderized", HalType::BINDERIZED_SERVICES},
+            {"b", HalType::BINDERIZED_SERVICES},
+            {"passthrough_clients", HalType::PASSTHROUGH_CLIENTS},
+            {"c", HalType::PASSTHROUGH_CLIENTS},
+            {"passthrough_libs", HalType::PASSTHROUGH_LIBRARIES},
+            {"l", HalType::PASSTHROUGH_LIBRARIES},
+            {"vintf", HalType::VINTF_MANIFEST},
+            {"v", HalType::VINTF_MANIFEST},
+            {"lazy", HalType::LAZY_HALS},
+            {"z", HalType::LAZY_HALS},
+        };
+
+        std::vector<std::string> halTypesArgs = split(std::string(arg), ',');
+        for (const auto& halTypeArg : halTypesArgs) {
+            if (halTypeArg.empty()) continue;
+
+            const auto& halTypeIter = kHalTypeMap.find(halTypeArg);
+            if (halTypeIter == kHalTypeMap.end()) {
+
+                thiz->err() << "Unrecognized HAL type: " << halTypeArg << std::endl;
+                return USAGE;
+            }
+
+            // Append unique (non-repeated) HAL types to the reporting list
+            HalType halType = halTypeIter->second;
+            if (std::find(thiz->mListTypes.begin(), thiz->mListTypes.end(), halType) ==
+                thiz->mListTypes.end()) {
+                thiz->mListTypes.push_back(halType);
+            }
+        }
+
+        if (thiz->mListTypes.empty()) { return USAGE; }
+        return OK;
+    }, "comma-separated list of one or more sections.\nThe output is restricted to the selected "
+       "section(s). Valid options\nare: (b|binderized), (c|passthrough_clients), (l|"
+       "passthrough_libs), and (v|vintf).\nDefault is `bcl`."});
 }
 
 // Create 'longopts' argument to getopt_long. Caller is responsible for maintaining
@@ -809,9 +1073,9 @@
         i++;
     }
     // getopt_long last option has all zeros
-    ret[i].name = NULL;
+    ret[i].name = nullptr;
     ret[i].has_arg = 0;
-    ret[i].flag = NULL;
+    ret[i].flag = nullptr;
     ret[i].val = 0;
 
     return ret;
@@ -829,6 +1093,7 @@
 }
 
 Status ListCommand::parseArgs(const Arg &arg) {
+    mListTypes.clear();
 
     if (mOptions.empty()) {
         registerAllOptions();
@@ -901,6 +1166,13 @@
         }
     }
 
+    // By default, list all HAL types
+    if (mListTypes.empty()) {
+        mListTypes = {HalType::BINDERIZED_SERVICES, HalType::PASSTHROUGH_CLIENTS,
+                      HalType::PASSTHROUGH_LIBRARIES};
+    }
+    initFetchTypes();
+
     forEachTable([this] (Table& table) {
         table.setSelectedColumns(this->mSelectedColumns);
     });
@@ -919,22 +1191,6 @@
     return status;
 }
 
-static std::vector<std::string> splitString(const std::string &s, char c) {
-    std::vector<std::string> components;
-
-    size_t startPos = 0;
-    size_t matchPos;
-    while ((matchPos = s.find(c, startPos)) != std::string::npos) {
-        components.push_back(s.substr(startPos, matchPos - startPos));
-        startPos = matchPos + 1;
-    }
-
-    if (startPos <= s.length()) {
-        components.push_back(s.substr(startPos));
-    }
-    return components;
-}
-
 const std::string& ListCommand::RegisteredOption::getHelpMessageForArgument() const {
     static const std::string empty{};
     static const std::string optional{"[=<arg>]"};
@@ -954,7 +1210,7 @@
     err() << "list:" << std::endl
           << "    lshal" << std::endl
           << "    lshal list" << std::endl
-          << "        List all hals with default ordering and columns (`lshal list -riepc`)" << std::endl
+          << "        List all hals with default ordering and columns (`lshal list -liepc`)" << std::endl
           << "    lshal list [-h|--help]" << std::endl
           << "        -h, --help: Print help message for list (`lshal help list`)" << std::endl
           << "    lshal [list] [OPTIONS...]" << std::endl;
@@ -970,7 +1226,7 @@
         if (!e.longOption.empty())
             err() << "--" << e.longOption << e.getHelpMessageForArgument();
         err() << ": ";
-        std::vector<std::string> lines = splitString(e.help, '\n');
+        std::vector<std::string> lines = split(e.help, '\n');
         for (const auto& line : lines) {
             if (&line != &lines.front())
                 err() << "            ";
diff --git a/cmds/lshal/ListCommand.h b/cmds/lshal/ListCommand.h
index 1e85ea0..3f7321d 100644
--- a/cmds/lshal/ListCommand.h
+++ b/cmds/lshal/ListCommand.h
@@ -26,7 +26,9 @@
 
 #include <android-base/macros.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
-#include <hidl-util/FQName.h>
+#include <hidl-util/FqInstance.h>
+#include <vintf/HalManifest.h>
+#include <vintf/VintfObject.h>
 
 #include "Command.h"
 #include "NullableOStream.h"
@@ -45,6 +47,14 @@
     uint32_t threadCount; // number of threads total
 };
 
+enum class HalType {
+    BINDERIZED_SERVICES = 0,
+    PASSTHROUGH_CLIENTS,
+    PASSTHROUGH_LIBRARIES,
+    VINTF_MANIFEST,
+    LAZY_HALS,
+};
+
 class ListCommand : public Command {
 public:
     ListCommand(Lshal &lshal) : Command(lshal) {}
@@ -80,13 +90,17 @@
 
 protected:
     Status parseArgs(const Arg &arg);
+    // Retrieve first-hand information
     Status fetch();
+    // Retrieve derived information base on existing table
     virtual void postprocess();
     Status dump();
-    void putEntry(TableEntrySource source, TableEntry &&entry);
+    void putEntry(HalType type, TableEntry &&entry);
     Status fetchPassthrough(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
     Status fetchBinderized(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
     Status fetchAllLibraries(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
+    Status fetchManifestHals();
+    Status fetchLazyHals();
 
     Status fetchBinderizedEntry(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager,
                                 TableEntry *entry);
@@ -113,19 +127,43 @@
     void removeDeadProcesses(Pids *pids);
 
     virtual Partition getPartition(pid_t pid);
-    Partition resolvePartition(Partition processPartition, const FQName& fqName) const;
+    Partition resolvePartition(Partition processPartition, const FqInstance &fqInstance) const;
+
+    VintfInfo getVintfInfo(const std::string &fqInstanceName, vintf::TransportArch ta) const;
+    // Allow to mock these functions for testing.
+    virtual std::shared_ptr<const vintf::HalManifest> getDeviceManifest() const;
+    virtual std::shared_ptr<const vintf::CompatibilityMatrix> getDeviceMatrix() const;
+    virtual std::shared_ptr<const vintf::HalManifest> getFrameworkManifest() const;
+    virtual std::shared_ptr<const vintf::CompatibilityMatrix> getFrameworkMatrix() const;
 
     void forEachTable(const std::function<void(Table &)> &f);
     void forEachTable(const std::function<void(const Table &)> &f) const;
+    Table* tableForType(HalType type);
+    const Table* tableForType(HalType type) const;
 
     NullableOStream<std::ostream> err() const;
     NullableOStream<std::ostream> out() const;
 
     void registerAllOptions();
 
+    // helper functions to dumpVintf.
+    bool addEntryWithInstance(const TableEntry &entry, vintf::HalManifest *manifest) const;
+    bool addEntryWithoutInstance(const TableEntry &entry, const vintf::HalManifest *manifest) const;
+
+    // Helper function. Whether to fetch entries corresponding to a given HAL type.
+    bool shouldFetchHalType(const HalType &type) const;
+
+    void initFetchTypes();
+
+    // Helper functions ti add HALs that are listed in VINTF manifest to LAZY_HALS table.
+    bool hasHwbinderEntry(const TableEntry& entry) const;
+    bool hasPassthroughEntry(const TableEntry& entry) const;
+
     Table mServicesTable{};
     Table mPassthroughRefTable{};
     Table mImplementationsTable{};
+    Table mManifestHalsTable{};
+    Table mLazyHalsTable{};
 
     std::string mFileOutputPath;
     TableEntryCompare mSortColumn = nullptr;
@@ -139,6 +177,11 @@
     // If true, explanatory text are not emitted.
     bool mNeat = false;
 
+    // Type(s) of HAL associations to list.
+    std::vector<HalType> mListTypes{};
+    // Type(s) of HAL associations to fetch.
+    std::set<HalType> mFetchTypes{};
+
     // If an entry does not exist, need to ask /proc/{pid}/cmdline to get it.
     // If an entry exist but is an empty string, process might have died.
     // If an entry exist and not empty, it contains the cached content of /proc/{pid}/cmdline.
diff --git a/cmds/lshal/PipeRelay.cpp b/cmds/lshal/PipeRelay.cpp
index fc40749..3a17e03 100644
--- a/cmds/lshal/PipeRelay.cpp
+++ b/cmds/lshal/PipeRelay.cpp
@@ -16,7 +16,6 @@
 
 #include "PipeRelay.h"
 
-#include <sys/socket.h>
 #include <utils/Thread.h>
 
 namespace android {
@@ -58,7 +57,7 @@
 
 PipeRelay::PipeRelay(std::ostream &os)
     : mInitCheck(NO_INIT) {
-    int res = socketpair(AF_UNIX, SOCK_STREAM, 0 /* protocol */, mFds);
+    int res = pipe(mFds);
 
     if (res < 0) {
         mInitCheck = -errno;
@@ -77,21 +76,13 @@
 }
 
 PipeRelay::~PipeRelay() {
-    if (mFds[1] >= 0) {
-        shutdown(mFds[1], SHUT_WR);
-    }
+    CloseFd(&mFds[1]);
+    CloseFd(&mFds[0]);
 
-    if (mFds[0] >= 0) {
-        shutdown(mFds[0], SHUT_RD);
-    }
-
-    if (mThread != NULL) {
+    if (mThread != nullptr) {
         mThread->join();
         mThread.clear();
     }
-
-    CloseFd(&mFds[1]);
-    CloseFd(&mFds[0]);
 }
 
 status_t PipeRelay::initCheck() const {
diff --git a/cmds/lshal/TableEntry.cpp b/cmds/lshal/TableEntry.cpp
index e8792a4..8e21975 100644
--- a/cmds/lshal/TableEntry.cpp
+++ b/cmds/lshal/TableEntry.cpp
@@ -16,7 +16,11 @@
 #define LOG_TAG "lshal"
 #include <android-base/logging.h>
 
+#include <map>
+
+#include <android-base/strings.h>
 #include <hidl-hash/Hash.h>
+#include <vintf/parse_string.h>
 
 #include "TableEntry.h"
 
@@ -26,19 +30,19 @@
 namespace android {
 namespace lshal {
 
-static const std::string &getArchString(Architecture arch) {
+static const std::string &getArchString(vintf::Arch arch) {
     static const std::string sStr64 = "64";
     static const std::string sStr32 = "32";
     static const std::string sStrBoth = "32+64";
-    static const std::string sStrUnknown = "";
+    static const std::string sStrUnknown = "?";
     switch (arch) {
-        case ARCH64:
+        case vintf::Arch::ARCH_64:
             return sStr64;
-        case ARCH32:
+        case vintf::Arch::ARCH_32:
             return sStr32;
-        case ARCH_BOTH:
+        case vintf::Arch::ARCH_32_64:
             return sStrBoth;
-        case ARCH_UNKNOWN: // fall through
+        case vintf::Arch::ARCH_EMPTY: // fall through
         default:
             return sStrUnknown;
     }
@@ -57,6 +61,8 @@
         case TableColumnType::THREADS:          return "Thread Use";
         case TableColumnType::RELEASED:         return "R";
         case TableColumnType::HASH:             return "Hash";
+        case TableColumnType::VINTF:            return "VINTF";
+        case TableColumnType::SERVICE_STATUS:   return "Status";
         default:
             LOG(FATAL) << __func__ << "Should not reach here. " << static_cast<int>(type);
             return "";
@@ -68,7 +74,7 @@
         case TableColumnType::INTERFACE_NAME:
             return interfaceName;
         case TableColumnType::TRANSPORT:
-            return transport;
+            return vintf::to_string(transport);
         case TableColumnType::SERVER_PID:
             return serverPid == NO_PID ? "N/A" : std::to_string(serverPid);
         case TableColumnType::SERVER_CMD:
@@ -87,6 +93,10 @@
             return isReleased();
         case TableColumnType::HASH:
             return hash;
+        case TableColumnType::VINTF:
+            return getVintfInfo();
+        case TableColumnType::SERVICE_STATUS:
+            return lshal::to_string(serviceStatus);
         default:
             LOG(FATAL) << __func__ << "Should not reach here. " << static_cast<int>(type);
             return "";
@@ -96,12 +106,44 @@
 std::string TableEntry::isReleased() const {
     static const std::string unreleased = Hash::hexString(Hash::kEmptyHash);
 
-    if (hash.empty() || hash == unreleased) {
-        return " "; // unknown or unreleased
+    if (hash.empty()) {
+        return "?";
+    }
+    if (hash == unreleased) {
+        return "N"; // unknown or unreleased
     }
     return "Y"; // released
 }
 
+std::string TableEntry::getVintfInfo() const {
+    static const std::map<VintfInfo, std::string> values{
+            {DEVICE_MANIFEST, "DM"},
+            {DEVICE_MATRIX, "DC"},
+            {FRAMEWORK_MANIFEST, "FM"},
+            {FRAMEWORK_MATRIX, "FC"},
+    };
+    std::vector<std::string> ret;
+    for (const auto& pair : values) {
+        if (vintfInfo & pair.first) {
+            ret.push_back(pair.second);
+        }
+    }
+    auto joined = base::Join(ret, ',');
+    return joined.empty() ? "X" : joined;
+}
+
+std::string to_string(ServiceStatus s) {
+    switch (s) {
+        case ServiceStatus::ALIVE: return "alive";
+        case ServiceStatus::NON_RESPONSIVE: return "non-responsive";
+        case ServiceStatus::DECLARED: return "declared";
+        case ServiceStatus::UNKNOWN: return "N/A";
+    }
+
+    LOG(FATAL) << __func__ << "Should not reach here." << static_cast<int>(s);
+    return "";
+}
+
 TextTable Table::createTextTable(bool neat,
     const std::function<std::string(const std::string&)>& emitDebugInfo) const {
 
@@ -152,6 +194,7 @@
 }
 
 std::string TableEntry::to_string() const {
+    using vintf::operator<<;
     std::stringstream ss;
     ss << "name=" << interfaceName << ";transport=" << transport << ";thread=" << getThreadUsage()
        << ";server=" << serverPid
diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h
index 24ea438..7294b0a 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -24,6 +24,8 @@
 #include <iostream>
 
 #include <procpartition/procpartition.h>
+#include <vintf/Arch.h>
+#include <vintf/Transport.h>
 
 #include "TextTable.h"
 
@@ -33,21 +35,6 @@
 using android::procpartition::Partition;
 using Pids = std::vector<int32_t>;
 
-enum : unsigned int {
-    HWSERVICEMANAGER_LIST, // through defaultServiceManager()->list()
-    PTSERVICEMANAGER_REG_CLIENT, // through registerPassthroughClient
-    LIST_DLLIB, // through listing dynamic libraries
-};
-using TableEntrySource = unsigned int;
-
-enum : unsigned int {
-    ARCH_UNKNOWN = 0,
-    ARCH32       = 1 << 0,
-    ARCH64       = 1 << 1,
-    ARCH_BOTH    = ARCH32 | ARCH64
-};
-using Architecture = unsigned int;
-
 enum class TableColumnType : unsigned int {
     INTERFACE_NAME,
     TRANSPORT,
@@ -60,16 +47,35 @@
     THREADS,
     RELEASED,
     HASH,
+    VINTF,
+    SERVICE_STATUS,
 };
 
+enum : unsigned int {
+    VINTF_INFO_EMPTY = 0,
+    DEVICE_MANIFEST = 1 << 0,
+    DEVICE_MATRIX = 1 << 1,
+    FRAMEWORK_MANIFEST = 1 << 2,
+    FRAMEWORK_MATRIX = 1 << 3,
+};
+using VintfInfo = unsigned int;
+
 enum {
     NO_PID = -1,
     NO_PTR = 0
 };
 
+enum class ServiceStatus {
+    UNKNOWN, // For passthrough
+    ALIVE,
+    NON_RESPONSIVE, // registered but not respond to calls
+    DECLARED, // in VINTF manifest
+};
+std::string to_string(ServiceStatus s);
+
 struct TableEntry {
     std::string interfaceName{};
-    std::string transport{};
+    vintf::Transport transport{vintf::Transport::EMPTY};
     int32_t serverPid{NO_PID};
     uint32_t threadUsage{0};
     uint32_t threadCount{0};
@@ -77,10 +83,13 @@
     uint64_t serverObjectAddress{NO_PTR};
     Pids clientPids{};
     std::vector<std::string> clientCmdlines{};
-    Architecture arch{ARCH_UNKNOWN};
+    vintf::Arch arch{vintf::Arch::ARCH_EMPTY};
     // empty: unknown, all zeros: unreleased, otherwise: released
     std::string hash{};
     Partition partition{Partition::UNKNOWN};
+    VintfInfo vintfInfo{VINTF_INFO_EMPTY};
+    // true iff hwbinder and service started
+    ServiceStatus serviceStatus{ServiceStatus::UNKNOWN};
 
     static bool sortByInterfaceName(const TableEntry &a, const TableEntry &b) {
         return a.interfaceName < b.interfaceName;
@@ -99,6 +108,8 @@
 
     std::string isReleased() const;
 
+    std::string getVintfInfo() const;
+
     std::string getField(TableColumnType type) const;
 
     bool operator==(const TableEntry& other) const;
diff --git a/cmds/lshal/Timeout.h b/cmds/lshal/Timeout.h
index c940404..58119a6 100644
--- a/cmds/lshal/Timeout.h
+++ b/cmds/lshal/Timeout.h
@@ -57,7 +57,7 @@
     BackgroundTaskState &state = *static_cast<BackgroundTaskState *>(data);
     state();
     state.notify();
-    return NULL;
+    return nullptr;
 }
 
 template<class R, class P>
@@ -65,7 +65,7 @@
     auto now = std::chrono::system_clock::now();
     BackgroundTaskState state{std::forward<decltype(func)>(func)};
     pthread_t thread;
-    if (pthread_create(&thread, NULL, callAndNotify, &state)) {
+    if (pthread_create(&thread, nullptr, callAndNotify, &state)) {
         std::cerr << "FATAL: could not create background thread." << std::endl;
         return false;
     }
@@ -73,7 +73,7 @@
     if (!success) {
         pthread_kill(thread, SIGINT);
     }
-    pthread_join(thread, NULL);
+    pthread_join(thread, nullptr);
     return success;
 }
 
diff --git a/cmds/lshal/libprocpartition/procpartition.cpp b/cmds/lshal/libprocpartition/procpartition.cpp
index 8ca458a..9645f3a 100644
--- a/cmds/lshal/libprocpartition/procpartition.cpp
+++ b/cmds/lshal/libprocpartition/procpartition.cpp
@@ -50,7 +50,7 @@
                                          false /* follow symlinks */)) {
         return "";
     }
-    return content;
+    return std::string{content.c_str()};
 }
 
 Partition parsePartition(const std::string& s) {
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index 4fa941e..8d7405b 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -44,6 +44,13 @@
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
+using android::vintf::Arch;
+using android::vintf::CompatibilityMatrix;
+using android::vintf::gCompatibilityMatrixConverter;
+using android::vintf::gHalManifestConverter;
+using android::vintf::HalManifest;
+using android::vintf::Transport;
+using android::vintf::VintfObject;
 
 using InstanceDebugInfo = IServiceManager::InstanceDebugInfo;
 
@@ -207,6 +214,11 @@
     MOCK_CONST_METHOD2(getPidInfo, bool(pid_t, PidInfo*));
     MOCK_CONST_METHOD1(parseCmdline, std::string(pid_t));
     MOCK_METHOD1(getPartition, Partition(pid_t));
+
+    MOCK_CONST_METHOD0(getDeviceManifest, std::shared_ptr<const vintf::HalManifest>());
+    MOCK_CONST_METHOD0(getDeviceMatrix, std::shared_ptr<const vintf::CompatibilityMatrix>());
+    MOCK_CONST_METHOD0(getFrameworkManifest, std::shared_ptr<const vintf::HalManifest>());
+    MOCK_CONST_METHOD0(getFrameworkMatrix, std::shared_ptr<const vintf::CompatibilityMatrix>());
 };
 
 class ListParseArgsTest : public ::testing::Test {
@@ -214,12 +226,13 @@
     void SetUp() override {
         mockLshal = std::make_unique<NiceMock<MockLshal>>();
         mockList = std::make_unique<MockListCommand>(mockLshal.get());
+        ON_CALL(*mockLshal, err()).WillByDefault(Return(NullableOStream<std::ostream>(err)));
         // ListCommand::parseArgs should parse arguments from the second element
         optind = 1;
     }
     std::unique_ptr<MockLshal> mockLshal;
     std::unique_ptr<MockListCommand> mockList;
-    std::stringstream output;
+    std::stringstream err;
 };
 
 TEST_F(ListParseArgsTest, Args) {
@@ -229,6 +242,7 @@
                                    TableColumnType::SERVER_ADDR, TableColumnType::CLIENT_PIDS}),
                   table.getSelectedColumns());
     });
+    EXPECT_EQ("", err.str());
 }
 
 TEST_F(ListParseArgsTest, Cmds) {
@@ -243,12 +257,12 @@
         EXPECT_THAT(table.getSelectedColumns(), Contains(TableColumnType::CLIENT_CMDS))
                 << "should print client cmds with -m";
     });
+    EXPECT_EQ("", err.str());
 }
 
 TEST_F(ListParseArgsTest, DebugAndNeat) {
-    ON_CALL(*mockLshal, err()).WillByDefault(Return(NullableOStream<std::ostream>(output)));
     EXPECT_NE(0u, mockList->parseArgs(createArg({"lshal", "--neat", "-d"})));
-    EXPECT_THAT(output.str(), StrNe(""));
+    EXPECT_THAT(err.str(), HasSubstr("--neat should not be used with --debug."));
 }
 
 /// Fetch Test
@@ -313,7 +327,7 @@
 
 class ListTest : public ::testing::Test {
 public:
-    void SetUp() override {
+    virtual void SetUp() override {
         initMockServiceManager();
         lshal = std::make_unique<Lshal>(out, err, serviceManager, passthruManager);
         initMockList();
@@ -335,6 +349,15 @@
             });
         }));
         ON_CALL(*mockList, getPartition(_)).WillByDefault(Return(Partition::VENDOR));
+
+        ON_CALL(*mockList, getDeviceManifest())
+                .WillByDefault(Return(std::make_shared<HalManifest>()));
+        ON_CALL(*mockList, getDeviceMatrix())
+                .WillByDefault(Return(std::make_shared<CompatibilityMatrix>()));
+        ON_CALL(*mockList, getFrameworkManifest())
+                .WillByDefault(Return(std::make_shared<HalManifest>()));
+        ON_CALL(*mockList, getFrameworkMatrix())
+                .WillByDefault(Return(std::make_shared<CompatibilityMatrix>()));
     }
 
     void initMockServiceManager() {
@@ -388,92 +411,76 @@
 }
 
 TEST_F(ListTest, Fetch) {
-    EXPECT_EQ(0u, mockList->fetch());
-    std::array<std::string, 6> transports{{"hwbinder", "hwbinder", "passthrough",
-                                          "passthrough", "passthrough", "passthrough"}};
-    std::array<Architecture, 6> archs{{ARCH64, ARCH64, ARCH32, ARCH32, ARCH32, ARCH32}};
-    int id = 1;
+    optind = 1; // mimic Lshal::parseArg()
+    ASSERT_EQ(0u, mockList->parseArgs(createArg({"lshal"})));
+    ASSERT_EQ(0u, mockList->fetch());
+    vintf::TransportArch hwbinder{Transport::HWBINDER, Arch::ARCH_64};
+    vintf::TransportArch passthrough{Transport::PASSTHROUGH, Arch::ARCH_32};
+    std::array<vintf::TransportArch, 6> transportArchs{{hwbinder, hwbinder, passthrough,
+                                                        passthrough, passthrough, passthrough}};
+    int i = 0;
     mockList->forEachTable([&](const Table& table) {
-        ASSERT_EQ(2u, table.size());
         for (const auto& entry : table) {
-            const auto& transport = transports[id - 1];
+            if (i >= transportArchs.size()) {
+                break;
+            }
+
+            int id = i + 1;
+            auto transport = transportArchs.at(i).transport;
             TableEntry expected{
                 .interfaceName = getFqInstanceName(id),
                 .transport = transport,
-                .serverPid = transport == "hwbinder" ? id : NO_PID,
-                .threadUsage = transport == "hwbinder" ? getPidInfoFromId(id).threadUsage : 0,
-                .threadCount = transport == "hwbinder" ? getPidInfoFromId(id).threadCount : 0,
+                .serverPid = transport == Transport::HWBINDER ? id : NO_PID,
+                .threadUsage =
+                        transport == Transport::HWBINDER ? getPidInfoFromId(id).threadUsage : 0,
+                .threadCount =
+                        transport == Transport::HWBINDER ? getPidInfoFromId(id).threadCount : 0,
                 .serverCmdline = {},
-                .serverObjectAddress = transport == "hwbinder" ? getPtr(id) : NO_PTR,
+                .serverObjectAddress = transport == Transport::HWBINDER ? getPtr(id) : NO_PTR,
                 .clientPids = getClients(id),
                 .clientCmdlines = {},
-                .arch = archs[id - 1],
+                .arch = transportArchs.at(i).arch,
             };
             EXPECT_EQ(expected, entry) << expected.to_string() << " vs. " << entry.to_string();
 
-            ++id;
+            ++i;
         }
     });
 
+    EXPECT_EQ(transportArchs.size(), i) << "Not all entries are tested.";
+
 }
 
 TEST_F(ListTest, DumpVintf) {
-    const std::string expected =
-        "<!-- \n"
-        "    This is a skeleton device manifest. Notes: \n" + ListCommand::INIT_VINTF_NOTES +
-        "-->\n"
-        "<manifest version=\"1.0\" type=\"device\">\n"
-        "    <hal format=\"hidl\">\n"
-        "        <name>a.h.foo1</name>\n"
-        "        <transport>hwbinder</transport>\n"
-        "        <version>1.0</version>\n"
-        "        <interface>\n"
-        "            <name>IFoo</name>\n"
-        "            <instance>1</instance>\n"
-        "        </interface>\n"
-        "    </hal>\n"
-        "    <hal format=\"hidl\">\n"
-        "        <name>a.h.foo2</name>\n"
-        "        <transport>hwbinder</transport>\n"
-        "        <version>2.0</version>\n"
-        "        <interface>\n"
-        "            <name>IFoo</name>\n"
-        "            <instance>2</instance>\n"
-        "        </interface>\n"
-        "    </hal>\n"
-        "    <hal format=\"hidl\">\n"
-        "        <name>a.h.foo3</name>\n"
-        "        <transport arch=\"32\">passthrough</transport>\n"
-        "        <version>3.0</version>\n"
-        "        <interface>\n"
-        "            <name>IFoo</name>\n"
-        "            <instance>3</instance>\n"
-        "        </interface>\n"
-        "    </hal>\n"
-        "    <hal format=\"hidl\">\n"
-        "        <name>a.h.foo4</name>\n"
-        "        <transport arch=\"32\">passthrough</transport>\n"
-        "        <version>4.0</version>\n"
-        "        <interface>\n"
-        "            <name>IFoo</name>\n"
-        "            <instance>4</instance>\n"
-        "        </interface>\n"
-        "    </hal>\n"
-        "    <hal format=\"hidl\">\n"
-        "        <name>a.h.foo5</name>\n"
-        "        <transport arch=\"32\">passthrough</transport>\n"
-        "        <version>5.0</version>\n"
-        "    </hal>\n"
-        "    <hal format=\"hidl\">\n"
-        "        <name>a.h.foo6</name>\n"
-        "        <transport arch=\"32\">passthrough</transport>\n"
-        "        <version>6.0</version>\n"
-        "    </hal>\n"
-        "</manifest>\n";
+    const std::string expected = "<manifest version=\"1.0\" type=\"device\">\n"
+                                 "    <hal format=\"hidl\">\n"
+                                 "        <name>a.h.foo1</name>\n"
+                                 "        <transport>hwbinder</transport>\n"
+                                 "        <fqname>@1.0::IFoo/1</fqname>\n"
+                                 "    </hal>\n"
+                                 "    <hal format=\"hidl\">\n"
+                                 "        <name>a.h.foo2</name>\n"
+                                 "        <transport>hwbinder</transport>\n"
+                                 "        <fqname>@2.0::IFoo/2</fqname>\n"
+                                 "    </hal>\n"
+                                 "    <hal format=\"hidl\">\n"
+                                 "        <name>a.h.foo3</name>\n"
+                                 "        <transport arch=\"32\">passthrough</transport>\n"
+                                 "        <fqname>@3.0::IFoo/3</fqname>\n"
+                                 "    </hal>\n"
+                                 "    <hal format=\"hidl\">\n"
+                                 "        <name>a.h.foo4</name>\n"
+                                 "        <transport arch=\"32\">passthrough</transport>\n"
+                                 "        <fqname>@4.0::IFoo/4</fqname>\n"
+                                 "    </hal>\n"
+                                 "</manifest>";
 
     optind = 1; // mimic Lshal::parseArg()
     EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--init-vintf"})));
-    EXPECT_EQ(expected, out.str());
+    auto output = out.str();
+    EXPECT_THAT(output, HasSubstr(expected));
+    EXPECT_THAT(output, HasSubstr("a.h.foo5@5.0::IFoo/5"));
+    EXPECT_THAT(output, HasSubstr("a.h.foo6@6.0::IFoo/6"));
     EXPECT_EQ("", err.str());
 
     vintf::HalManifest m;
@@ -487,18 +494,18 @@
     const std::string expected =
         "[fake description 0]\n"
         "R Interface            Thread Use Server Clients\n"
-        "  a.h.foo1@1.0::IFoo/1 11/21      1      2 4\n"
+        "N a.h.foo1@1.0::IFoo/1 11/21      1      2 4\n"
         "Y a.h.foo2@2.0::IFoo/2 12/22      2      3 5\n"
         "\n"
         "[fake description 1]\n"
         "R Interface            Thread Use Server Clients\n"
-        "  a.h.foo3@3.0::IFoo/3 N/A        N/A    4 6\n"
-        "  a.h.foo4@4.0::IFoo/4 N/A        N/A    5 7\n"
+        "? a.h.foo3@3.0::IFoo/3 N/A        N/A    4 6\n"
+        "? a.h.foo4@4.0::IFoo/4 N/A        N/A    5 7\n"
         "\n"
         "[fake description 2]\n"
         "R Interface            Thread Use Server Clients\n"
-        "  a.h.foo5@5.0::IFoo/5 N/A        N/A    6 8\n"
-        "  a.h.foo6@6.0::IFoo/6 N/A        N/A    7 9\n"
+        "? a.h.foo5@5.0::IFoo/5 N/A        N/A    6 8\n"
+        "? a.h.foo6@6.0::IFoo/6 N/A        N/A    7 9\n"
         "\n";
 
     optind = 1; // mimic Lshal::parseArg()
@@ -511,18 +518,18 @@
     const std::string expected =
         "[fake description 0]\n"
         "Interface            R Hash\n"
-        "a.h.foo1@1.0::IFoo/1   0000000000000000000000000000000000000000000000000000000000000000\n"
+        "a.h.foo1@1.0::IFoo/1 N 0000000000000000000000000000000000000000000000000000000000000000\n"
         "a.h.foo2@2.0::IFoo/2 Y 0202020202020202020202020202020202020202020202020202020202020202\n"
         "\n"
         "[fake description 1]\n"
         "Interface            R Hash\n"
-        "a.h.foo3@3.0::IFoo/3   \n"
-        "a.h.foo4@4.0::IFoo/4   \n"
+        "a.h.foo3@3.0::IFoo/3 ? \n"
+        "a.h.foo4@4.0::IFoo/4 ? \n"
         "\n"
         "[fake description 2]\n"
         "Interface            R Hash\n"
-        "a.h.foo5@5.0::IFoo/5   \n"
-        "a.h.foo6@6.0::IFoo/6   \n"
+        "a.h.foo5@5.0::IFoo/5 ? \n"
+        "a.h.foo6@6.0::IFoo/6 ? \n"
         "\n";
 
     optind = 1; // mimic Lshal::parseArg()
@@ -594,6 +601,225 @@
     EXPECT_EQ("", err.str());
 }
 
+TEST_F(ListTest, DumpSingleHalType) {
+    const std::string expected =
+        "[fake description 0]\n"
+        "Interface            Transport Arch Thread Use Server PTR              Clients\n"
+        "a.h.foo1@1.0::IFoo/1 hwbinder  64   11/21      1      0000000000002711 2 4\n"
+        "a.h.foo2@2.0::IFoo/2 hwbinder  64   12/22      2      0000000000002712 3 5\n"
+        "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=binderized"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpReorderedHalTypes) {
+    const std::string expected =
+        "[fake description 0]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo3@3.0::IFoo/3 passthrough 32   N/A        N/A    N/A 4 6\n"
+        "a.h.foo4@4.0::IFoo/4 passthrough 32   N/A        N/A    N/A 5 7\n"
+        "\n"
+        "[fake description 1]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo5@5.0::IFoo/5 passthrough 32   N/A        N/A    N/A 6 8\n"
+        "a.h.foo6@6.0::IFoo/6 passthrough 32   N/A        N/A    N/A 7 9\n"
+        "\n"
+        "[fake description 2]\n"
+        "Interface            Transport Arch Thread Use Server PTR              Clients\n"
+        "a.h.foo1@1.0::IFoo/1 hwbinder  64   11/21      1      0000000000002711 2 4\n"
+        "a.h.foo2@2.0::IFoo/2 hwbinder  64   12/22      2      0000000000002712 3 5\n"
+        "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=passthrough_clients",
+                                            "--types=passthrough_libs", "--types=binderized"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpAbbreviatedHalTypes) {
+    const std::string expected =
+        "[fake description 0]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo3@3.0::IFoo/3 passthrough 32   N/A        N/A    N/A 4 6\n"
+        "a.h.foo4@4.0::IFoo/4 passthrough 32   N/A        N/A    N/A 5 7\n"
+        "\n"
+        "[fake description 1]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo5@5.0::IFoo/5 passthrough 32   N/A        N/A    N/A 6 8\n"
+        "a.h.foo6@6.0::IFoo/6 passthrough 32   N/A        N/A    N/A 7 9\n"
+        "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,l"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpEmptyAndDuplicateHalTypes) {
+    const std::string expected =
+        "[fake description 0]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo3@3.0::IFoo/3 passthrough 32   N/A        N/A    N/A 4 6\n"
+        "a.h.foo4@4.0::IFoo/4 passthrough 32   N/A        N/A    N/A 5 7\n"
+        "\n"
+        "[fake description 1]\n"
+        "Interface            Transport   Arch Thread Use Server PTR Clients\n"
+        "a.h.foo5@5.0::IFoo/5 passthrough 32   N/A        N/A    N/A 6 8\n"
+        "a.h.foo6@6.0::IFoo/6 passthrough 32   N/A        N/A    N/A 7 9\n"
+        "\n";
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,l,,,l,l,c,",
+                                            "--types=passthrough_libs,passthrough_clients"})));
+    EXPECT_EQ(expected, out.str());
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, UnknownHalType) {
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(1u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,a"})));
+    EXPECT_THAT(err.str(), HasSubstr("Unrecognized HAL type: a"));
+}
+
+TEST_F(ListTest, Vintf) {
+    std::string deviceManifestXml =
+            "<manifest version=\"1.0\" type=\"device\">\n"
+            "    <hal>\n"
+            "        <name>a.h.foo1</name>\n"
+            "        <transport>hwbinder</transport>\n"
+            "        <fqname>@1.0::IFoo/1</fqname>\n"
+            "    </hal>\n"
+            "    <hal>\n"
+            "        <name>a.h.foo3</name>\n"
+            "        <transport arch=\"32+64\">passthrough</transport>\n"
+            "        <fqname>@3.0::IFoo/3</fqname>\n"
+            "    </hal>\n"
+            "</manifest>\n";
+    std::string frameworkManifestXml =
+            "<manifest version=\"1.0\" type=\"framework\">\n"
+            "    <hal>\n"
+            "        <name>a.h.foo5</name>\n"
+            "        <transport arch=\"32\">passthrough</transport>\n"
+            "        <fqname>@5.0::IFoo/5</fqname>\n"
+            "    </hal>\n"
+            "</manifest>\n";
+    std::string deviceMatrixXml =
+            "<compatibility-matrix version=\"1.0\" type=\"device\">\n"
+            "    <hal>\n"
+            "        <name>a.h.foo5</name>\n"
+            "        <version>5.0</version>\n"
+            "        <interface>\n"
+            "            <name>IFoo</name>\n"
+            "            <instance>5</instance>\n"
+            "        </interface>\n"
+            "    </hal>\n"
+            "</compatibility-matrix>\n";
+    std::string frameworkMatrixXml =
+            "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+            "    <hal>\n"
+            "        <name>a.h.foo1</name>\n"
+            "        <version>1.0</version>\n"
+            "        <interface>\n"
+            "            <name>IFoo</name>\n"
+            "            <instance>1</instance>\n"
+            "        </interface>\n"
+            "    </hal>\n"
+            "    <hal>\n"
+            "        <name>a.h.foo3</name>\n"
+            "        <version>3.0</version>\n"
+            "        <interface>\n"
+            "            <name>IFoo</name>\n"
+            "            <instance>3</instance>\n"
+            "        </interface>\n"
+            "    </hal>\n"
+            "</compatibility-matrix>\n";
+
+    std::string expected = "DM,FC a.h.foo1@1.0::IFoo/1\n"
+                           "X     a.h.foo2@2.0::IFoo/2\n"
+                           "DM,FC a.h.foo3@3.0::IFoo/3\n"
+                           "X     a.h.foo4@4.0::IFoo/4\n"
+                           "DC,FM a.h.foo5@5.0::IFoo/5\n"
+                           "X     a.h.foo6@6.0::IFoo/6\n";
+
+    auto deviceManifest = std::make_shared<HalManifest>();
+    auto frameworkManifest = std::make_shared<HalManifest>();
+    auto deviceMatrix = std::make_shared<CompatibilityMatrix>();
+    auto frameworkMatrix = std::make_shared<CompatibilityMatrix>();
+
+    ASSERT_TRUE(gHalManifestConverter(deviceManifest.get(), deviceManifestXml));
+    ASSERT_TRUE(gHalManifestConverter(frameworkManifest.get(), frameworkManifestXml));
+    ASSERT_TRUE(gCompatibilityMatrixConverter(deviceMatrix.get(), deviceMatrixXml));
+    ASSERT_TRUE(gCompatibilityMatrixConverter(frameworkMatrix.get(), frameworkMatrixXml));
+
+    ON_CALL(*mockList, getDeviceManifest()).WillByDefault(Return(deviceManifest));
+    ON_CALL(*mockList, getDeviceMatrix()).WillByDefault(Return(deviceMatrix));
+    ON_CALL(*mockList, getFrameworkManifest()).WillByDefault(Return(frameworkManifest));
+    ON_CALL(*mockList, getFrameworkMatrix()).WillByDefault(Return(frameworkMatrix));
+
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-Vi", "--neat"})));
+    EXPECT_THAT(out.str(), HasSubstr(expected));
+    EXPECT_EQ("", err.str());
+}
+
+class ListVintfTest : public ListTest {
+public:
+    virtual void SetUp() override {
+        ListTest::SetUp();
+        const std::string mockManifestXml =
+                "<manifest version=\"1.0\" type=\"device\">\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>a.h.foo1</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <fqname>@1.0::IFoo/1</fqname>\n"
+                "    </hal>\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>a.h.bar1</name>\n"
+                "        <transport>hwbinder</transport>\n"
+                "        <fqname>@1.0::IBar/1</fqname>\n"
+                "    </hal>\n"
+                "    <hal format=\"hidl\">\n"
+                "        <name>a.h.bar2</name>\n"
+                "        <transport arch=\"32+64\">passthrough</transport>\n"
+                "        <fqname>@2.0::IBar/2</fqname>\n"
+                "    </hal>\n"
+                "</manifest>";
+        auto manifest = std::make_shared<HalManifest>();
+        EXPECT_TRUE(gHalManifestConverter(manifest.get(), mockManifestXml));
+        EXPECT_CALL(*mockList, getDeviceManifest())
+            .Times(AnyNumber())
+            .WillRepeatedly(Return(manifest));
+    }
+};
+
+TEST_F(ListVintfTest, ManifestHals) {
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-iStr", "--types=v", "--neat"})));
+    EXPECT_THAT(out.str(), HasSubstr("a.h.bar1@1.0::IBar/1 declared hwbinder    ?"));
+    EXPECT_THAT(out.str(), HasSubstr("a.h.bar2@2.0::IBar/2 declared passthrough 32+64"));
+    EXPECT_THAT(out.str(), HasSubstr("a.h.foo1@1.0::IFoo/1 declared hwbinder    ?"));
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListVintfTest, Lazy) {
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-iStr", "--types=z", "--neat"})));
+    EXPECT_THAT(out.str(), HasSubstr("a.h.bar1@1.0::IBar/1 declared hwbinder    ?"));
+    EXPECT_THAT(out.str(), HasSubstr("a.h.bar2@2.0::IBar/2 declared passthrough 32+64"));
+    EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListVintfTest, NoLazy) {
+    optind = 1; // mimic Lshal::parseArg()
+    EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-iStr", "--types=b,c,l", "--neat"})));
+    EXPECT_THAT(out.str(), Not(HasSubstr("IBar")));
+    EXPECT_EQ("", err.str());
+}
+
 class HelpTest : public ::testing::Test {
 public:
     void SetUp() override {
diff --git a/cmds/lshal/utils.h b/cmds/lshal/utils.h
index c09e8b1..240155e 100644
--- a/cmds/lshal/utils.h
+++ b/cmds/lshal/utils.h
@@ -46,6 +46,8 @@
     TRANSACTION_ERROR                       = 1 << 8,
     // No transaction error, but return value is unexpected.
     BAD_IMPL                                = 1 << 9,
+    // Cannot fetch VINTF data.
+    VINTF_ERROR                             = 1 << 10,
 };
 using Status = unsigned int;
 
diff --git a/cmds/rawbu/Android.bp b/cmds/rawbu/Android.bp
new file mode 100644
index 0000000..363ffc1
--- /dev/null
+++ b/cmds/rawbu/Android.bp
@@ -0,0 +1,14 @@
+// Copyright 2009 The Android Open Source Project
+
+cc_binary {
+    name: "rawbu",
+
+    srcs: ["backup.cpp"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    shared_libs: ["libcutils"],
+}
diff --git a/cmds/rawbu/Android.mk b/cmds/rawbu/Android.mk
deleted file mode 100644
index 9322151..0000000
--- a/cmds/rawbu/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= backup.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := libcutils libc
-
-LOCAL_MODULE:= rawbu
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/rawbu/backup.cpp b/cmds/rawbu/backup.cpp
index 0072281..8b20e3e 100644
--- a/cmds/rawbu/backup.cpp
+++ b/cmds/rawbu/backup.cpp
@@ -38,7 +38,7 @@
 static struct stat statBuffer;
 
 static char copyBuffer[8192];
-static char *backupFilePath = NULL;
+static char *backupFilePath = nullptr;
 
 static uint32_t inputFileVersion;
 
@@ -58,7 +58,7 @@
     { "/data/system/batterystats.bin", SPECIAL_NO_TOUCH },
     { "/data/system/location", SPECIAL_NO_TOUCH },
     { "/data/dalvik-cache", SPECIAL_NO_BACKUP },
-    { NULL, 0 },
+    { nullptr, 0 },
 };
 
 /* This is just copied from the shell's built-in wipe command. */
@@ -71,7 +71,7 @@
 
     dir = opendir(path);
 
-    if (dir == NULL) {
+    if (dir == nullptr) {
         fprintf (stderr, "Error opendir'ing %s: %s\n",
                     path, strerror(errno));
         return 0;
@@ -87,7 +87,7 @@
     for (;;) {
         de = readdir(dir);
 
-        if (de == NULL) {
+        if (de == nullptr) {
             break;
         }
 
@@ -115,7 +115,7 @@
             }
         }
         
-        if (!noBackup && SKIP_PATHS[i].path != NULL) {
+        if (!noBackup && SKIP_PATHS[i].path != nullptr) {
             // This is a SPECIAL_NO_TOUCH directory.
             continue;
         }
@@ -203,7 +203,7 @@
         int amt = size > (off_t)sizeof(copyBuffer) ? sizeof(copyBuffer) : (int)size;
         int readLen = fread(copyBuffer, 1, amt, src);
         if (readLen <= 0) {
-            if (srcName != NULL) {
+            if (srcName != nullptr) {
                 fprintf(stderr, "unable to read source (%d of %ld bytes) file '%s': %s\n",
                     amt, origSize, srcName, errno != 0 ? strerror(errno) : "unexpected EOF");
             } else {
@@ -214,7 +214,7 @@
         }
         int writeLen = fwrite(copyBuffer, 1, readLen, dest); 
         if (writeLen != readLen) {
-            if (destName != NULL) {
+            if (destName != nullptr) {
                 fprintf(stderr, "unable to write file (%d of %d bytes) '%s': '%s'\n",
                     writeLen, readLen, destName, strerror(errno));
             } else {
@@ -256,14 +256,14 @@
 {
     DIR *dir;
     struct dirent *de;
-    char* fullPath = NULL;
+    char* fullPath = nullptr;
     int srcLen = strlen(srcPath);
     int result = 1;
     int i;
     
     dir = opendir(srcPath);
 
-    if (dir == NULL) {
+    if (dir == nullptr) {
         fprintf (stderr, "error opendir'ing '%s': %s\n",
                     srcPath, strerror(errno));
         return 0;
@@ -272,7 +272,7 @@
     for (;;) {
         de = readdir(dir);
 
-        if (de == NULL) {
+        if (de == nullptr) {
             break;
         }
 
@@ -283,7 +283,7 @@
             continue;
         }
 
-        if (fullPath != NULL) {
+        if (fullPath != nullptr) {
             free(fullPath);
         }
         fullPath = (char*)malloc(srcLen + strlen(de->d_name) + 2);
@@ -298,7 +298,7 @@
                     break;
                 }
             }
-            if (SKIP_PATHS[i].path != NULL) {
+            if (SKIP_PATHS[i].path != nullptr) {
                 continue;
             }
         }
@@ -343,14 +343,14 @@
             }
             
             FILE* src = fopen(fullPath, "r");
-            if (src == NULL) {
+            if (src == nullptr) {
                 fprintf(stderr, "unable to open source file '%s': %s\n",
                     fullPath, strerror(errno));
                 result = 0;
                 goto done;
             }
             
-            int copyres = copy_file(fh, src, size, NULL, fullPath);
+            int copyres = copy_file(fh, src, size, nullptr, fullPath);
             fclose(src);
             if (!copyres) {
                 result = 0;
@@ -360,7 +360,7 @@
     }
 
 done:
-    if (fullPath != NULL) {
+    if (fullPath != nullptr) {
         free(fullPath);
     }
     
@@ -374,7 +374,7 @@
     int res = -1;
     
     FILE* fh = fopen(destPath, "w");
-    if (fh == NULL) {
+    if (fh == nullptr) {
         fprintf(stderr, "unable to open destination '%s': %s\n",
                 destPath, strerror(errno));
         return -1;
@@ -504,7 +504,7 @@
     int res = -1;
     
     FILE* fh = fopen(srcPath, "r");
-    if (fh == NULL) {
+    if (fh == nullptr) {
         fprintf(stderr, "Unable to open source '%s': %s\n",
                 srcPath, strerror(errno));
         return -1;
@@ -534,7 +534,7 @@
 
     while (1) {
         int type;
-        char* path = NULL;
+        char* path = nullptr;
         if (read_header(fh, &type, &path, &statBuffer) == 0) {
             goto done;
         }
@@ -570,14 +570,14 @@
             printf("Restoring file %s...\n", path);
             
             FILE* dest = fopen(path, "w");
-            if (dest == NULL) {
+            if (dest == nullptr) {
                 fprintf(stderr, "unable to open destination file '%s': %s\n",
                     path, strerror(errno));
                 free(path);
                 goto done;
             }
             
-            int copyres = copy_file(dest, fh, size, path, NULL);
+            int copyres = copy_file(dest, fh, size, path, nullptr);
             fclose(dest);
             if (!copyres) {
                 free(path);
diff --git a/cmds/service/service.cpp b/cmds/service/service.cpp
index bc11256..34a3fdc 100644
--- a/cmds/service/service.cpp
+++ b/cmds/service/service.cpp
@@ -30,7 +30,7 @@
 
 void writeString16(Parcel& parcel, const char* string)
 {
-    if (string != NULL)
+    if (string != nullptr)
     {
         parcel.writeString16(String16(string));
     }
@@ -43,7 +43,7 @@
 // get the name of the generic interface we hold a reference to
 static String16 get_interface_name(sp<IBinder> service)
 {
-    if (service != NULL) {
+    if (service != nullptr) {
         Parcel data, reply;
         status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);
         if (err == NO_ERROR) {
@@ -93,7 +93,7 @@
 #endif
     sp<IServiceManager> sm = defaultServiceManager();
     fflush(stdout);
-    if (sm == NULL) {
+    if (sm == nullptr) {
         aerr << "service: Unable to get default service manager!" << endl;
         return 20;
     }
@@ -106,7 +106,7 @@
             if (optind < argc) {
                 sp<IBinder> service = sm->checkService(String16(argv[optind]));
                 aout << "Service " << argv[optind] <<
-                    (service == NULL ? ": not found" : ": found") << endl;
+                    (service == nullptr ? ": not found" : ": found") << endl;
             } else {
                 aerr << "service: No service specified for check" << endl;
                 wantsUsage = true;
@@ -131,7 +131,7 @@
                 sp<IBinder> service = sm->checkService(String16(argv[optind++]));
                 String16 ifName = get_interface_name(service);
                 int32_t code = atoi(argv[optind++]);
-                if (service != NULL && ifName.size() > 0) {
+                if (service != nullptr && ifName.size() > 0) {
                     Parcel data, reply;
 
                     // the interface name is first
@@ -186,28 +186,28 @@
                             data.writeDouble(atof(argv[optind++]));
                         } else if (strcmp(argv[optind], "null") == 0) {
                             optind++;
-                            data.writeStrongBinder(NULL);
+                            data.writeStrongBinder(nullptr);
                         } else if (strcmp(argv[optind], "intent") == 0) {
                         	
-                        	char* action = NULL;
-                        	char* dataArg = NULL;
-                        	char* type = NULL;
+                        	char* action = nullptr;
+                        	char* dataArg = nullptr;
+                        	char* type = nullptr;
                         	int launchFlags = 0;
-                        	char* component = NULL;
+                        	char* component = nullptr;
                         	int categoryCount = 0;
                         	char* categories[16];
                         	
-                        	char* context1 = NULL;
+                        	char* context1 = nullptr;
                         	
                             optind++;
                             
                         	while (optind < argc)
                         	{
                         		char* key = strtok_r(argv[optind], "=", &context1);
-                        		char* value = strtok_r(NULL, "=", &context1);
+                        		char* value = strtok_r(nullptr, "=", &context1);
                                 
                                 // we have reached the end of the XXX=XXX args.
-                                if (key == NULL) break;
+                                if (key == nullptr) break;
                         		
                         		if (strcmp(key, "action") == 0)
                         		{
@@ -231,14 +231,14 @@
                         		}
                         		else if (strcmp(key, "categories") == 0)
                         		{
-                        			char* context2 = NULL;
+                        			char* context2 = nullptr;
                         			int categoryCount = 0;
                         			categories[categoryCount] = strtok_r(value, ",", &context2);
                         			
-                        			while (categories[categoryCount] != NULL)
+                        			while (categories[categoryCount] != nullptr)
                         			{
                         				categoryCount++;
-                        				categories[categoryCount] = strtok_r(NULL, ",", &context2);
+                        				categories[categoryCount] = strtok_r(nullptr, ",", &context2);
                         			}
                         		}
                                 
diff --git a/cmds/surfacereplayer/replayer/Android.bp b/cmds/surfacereplayer/replayer/Android.bp
index 5caceec..7632311 100644
--- a/cmds/surfacereplayer/replayer/Android.bp
+++ b/cmds/surfacereplayer/replayer/Android.bp
@@ -1,6 +1,5 @@
 cc_library_shared {
     name: "libsurfacereplayer",
-    clang: true,
     srcs: [
         "BufferQueueScheduler.cpp",
         "Event.cpp",
@@ -16,7 +15,6 @@
 	"-Wno-float-equal",
 	"-Wno-sign-conversion",
 	"-Wno-padded",
-	"-std=c++14",
     ],
     static_libs: [
         "libtrace_proto",
@@ -41,7 +39,6 @@
 
 cc_binary {
     name: "surfacereplayer",
-    clang: true,
     srcs: [
         "Main.cpp",
     ],
@@ -61,6 +58,5 @@
 	"-Wno-float-conversion",
 	"-Wno-disabled-macro-expansion",
 	"-Wno-float-equal",
-	"-std=c++14",
     ],
 }
diff --git a/cmds/surfacereplayer/replayer/Main.cpp b/cmds/surfacereplayer/replayer/Main.cpp
index 7090bdb..fbfcacf 100644
--- a/cmds/surfacereplayer/replayer/Main.cpp
+++ b/cmds/surfacereplayer/replayer/Main.cpp
@@ -94,7 +94,7 @@
     }
 
     char** input = argv + optind;
-    if (input[0] == NULL) {
+    if (input[0] == nullptr) {
         std::cerr << "No trace file provided...exiting" << std::endl;
         abort();
     }
diff --git a/data/etc/android.hardware.usb.accessory.xml b/data/etc/android.hardware.usb.accessory.xml
index 80a0904..29df966 100644
--- a/data/etc/android.hardware.usb.accessory.xml
+++ b/data/etc/android.hardware.usb.accessory.xml
@@ -17,6 +17,4 @@
 <!-- This is the standard feature indicating that the device supports USB accessories. -->
 <permissions>
     <feature name="android.hardware.usb.accessory" />
-    <library name="com.android.future.usb.accessory"
-            file="/system/framework/com.android.future.usb.accessory.jar" />
 </permissions>
diff --git a/include/android/choreographer.h b/include/android/choreographer.h
index 43346fe..d75de1e 100644
--- a/include/android/choreographer.h
+++ b/include/android/choreographer.h
@@ -30,8 +30,6 @@
 
 __BEGIN_DECLS
 
-#if __ANDROID_API__ >= 24
-
 struct AChoreographer;
 typedef struct AChoreographer AChoreographer;
 
@@ -45,25 +43,29 @@
  */
 typedef void (*AChoreographer_frameCallback)(long frameTimeNanos, void* data);
 
+#if __ANDROID_API__ >= 24
+
 /**
  * Get the AChoreographer instance for the current thread. This must be called
  * on an ALooper thread.
  */
-AChoreographer* AChoreographer_getInstance();
+AChoreographer* AChoreographer_getInstance() __INTRODUCED_IN(24);
 
 /**
  * Post a callback to be run on the next frame. The data pointer provided will
  * be passed to the callback function when it's called.
  */
 void AChoreographer_postFrameCallback(AChoreographer* choreographer,
-                AChoreographer_frameCallback callback, void* data);
+                AChoreographer_frameCallback callback, void* data) __INTRODUCED_IN(24);
+
 /**
  * Post a callback to be run on the frame following the specified delay. The
  * data pointer provided will be passed to the callback function when it's
  * called.
  */
 void AChoreographer_postFrameCallbackDelayed(AChoreographer* choreographer,
-                AChoreographer_frameCallback callback, void* data, long delayMillis);
+                AChoreographer_frameCallback callback, void* data,
+                long delayMillis) __INTRODUCED_IN(24);
 
 #endif /* __ANDROID_API__ >= 24 */
 
diff --git a/include/android/configuration.h b/include/android/configuration.h
index 6287332..ef6c5a2 100644
--- a/include/android/configuration.h
+++ b/include/android/configuration.h
@@ -30,6 +30,10 @@
 
 #include <android/asset_manager.h>
 
+#if !defined(__INTRODUCED_IN)
+#define __INTRODUCED_IN(__api_level) /* nothing */
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -676,34 +680,34 @@
  * Return the current configuration screen width in dp units, or
  * ACONFIGURATION_SCREEN_WIDTH_DP_ANY if not set.
  */
-int32_t AConfiguration_getScreenWidthDp(AConfiguration* config);
+int32_t AConfiguration_getScreenWidthDp(AConfiguration* config) __INTRODUCED_IN(13);
 
 /**
  * Set the configuration's current screen width in dp units.
  */
-void AConfiguration_setScreenWidthDp(AConfiguration* config, int32_t value);
+void AConfiguration_setScreenWidthDp(AConfiguration* config, int32_t value) __INTRODUCED_IN(13);
 
 /**
  * Return the current configuration screen height in dp units, or
  * ACONFIGURATION_SCREEN_HEIGHT_DP_ANY if not set.
  */
-int32_t AConfiguration_getScreenHeightDp(AConfiguration* config);
+int32_t AConfiguration_getScreenHeightDp(AConfiguration* config) __INTRODUCED_IN(13);
 
 /**
  * Set the configuration's current screen width in dp units.
  */
-void AConfiguration_setScreenHeightDp(AConfiguration* config, int32_t value);
+void AConfiguration_setScreenHeightDp(AConfiguration* config, int32_t value) __INTRODUCED_IN(13);
 
 /**
  * Return the configuration's smallest screen width in dp units, or
  * ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY if not set.
  */
-int32_t AConfiguration_getSmallestScreenWidthDp(AConfiguration* config);
+int32_t AConfiguration_getSmallestScreenWidthDp(AConfiguration* config) __INTRODUCED_IN(13);
 
 /**
  * Set the configuration's smallest screen width in dp units.
  */
-void AConfiguration_setSmallestScreenWidthDp(AConfiguration* config, int32_t value);
+void AConfiguration_setSmallestScreenWidthDp(AConfiguration* config, int32_t value) __INTRODUCED_IN(13);
 #endif /* __ANDROID_API__ >= 13 */
 
 #if __ANDROID_API__ >= 17
@@ -711,12 +715,12 @@
  * Return the configuration's layout direction, or
  * ACONFIGURATION_LAYOUTDIR_ANY if not set.
  */
-int32_t AConfiguration_getLayoutDirection(AConfiguration* config);
+int32_t AConfiguration_getLayoutDirection(AConfiguration* config) __INTRODUCED_IN(17);
 
 /**
  * Set the configuration's layout direction.
  */
-void AConfiguration_setLayoutDirection(AConfiguration* config, int32_t value);
+void AConfiguration_setLayoutDirection(AConfiguration* config, int32_t value) __INTRODUCED_IN(17);
 #endif /* __ANDROID_API__ >= 17 */
 
 /**
diff --git a/include/android/input.h b/include/android/input.h
index 0829989..6810901 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -56,6 +56,10 @@
 #include <android/keycodes.h>
 #include <android/looper.h>
 
+#if !defined(__INTRODUCED_IN)
+#define __INTRODUCED_IN(__api_level) /* nothing */
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -984,7 +988,7 @@
 
 #if __ANDROID_API__ >= 14
 /** Get the button state of all buttons that are pressed. */
-int32_t AMotionEvent_getButtonState(const AInputEvent* motion_event);
+int32_t AMotionEvent_getButtonState(const AInputEvent* motion_event) __INTRODUCED_IN(14);
 #endif
 
 /**
@@ -1056,7 +1060,7 @@
  * The tool type indicates the type of tool used to make contact such as a
  * finger or stylus, if known.
  */
-int32_t AMotionEvent_getToolType(const AInputEvent* motion_event, size_t pointer_index);
+int32_t AMotionEvent_getToolType(const AInputEvent* motion_event, size_t pointer_index) __INTRODUCED_IN(14);
 #endif
 
 /**
@@ -1150,7 +1154,7 @@
 #if __ANDROID_API__ >= 13
 /** Get the value of the request axis for the given pointer index. */
 float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
-        int32_t axis, size_t pointer_index);
+        int32_t axis, size_t pointer_index) __INTRODUCED_IN(13);
 #endif
 
 /**
@@ -1288,7 +1292,7 @@
  * that occurred between this event and the previous motion event.
  */
 float AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event,
-        int32_t axis, size_t pointer_index, size_t history_index);
+        int32_t axis, size_t pointer_index, size_t history_index) __INTRODUCED_IN(13);
 #endif
 
 
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index 97892f8..4d24680 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
+/**
+ * @addtogroup Networking
+ * @{
+ */
+
+/**
+ * @file multinetwork.h
+ */
+
 #ifndef ANDROID_MULTINETWORK_H
 #define ANDROID_MULTINETWORK_H
 
@@ -51,7 +60,7 @@
  * on failure with an appropriate errno value set.
  */
 
-#if __ANDROID_API__ >= 24
+#if __ANDROID_API__ >= 23
 
 /**
  * Set the network to be used by the given socket file descriptor.
@@ -61,7 +70,7 @@
  * This is the equivalent of: [android.net.Network#bindSocket()](https://developer.android.com/reference/android/net/Network.html#bindSocket(java.net.Socket))
  *
  */
-int android_setsocknetwork(net_handle_t network, int fd);
+int android_setsocknetwork(net_handle_t network, int fd) __INTRODUCED_IN(23);
 
 
 /**
@@ -78,7 +87,7 @@
  * This is the equivalent of: [android.net.ConnectivityManager#setProcessDefaultNetwork()](https://developer.android.com/reference/android/net/ConnectivityManager.html#setProcessDefaultNetwork(android.net.Network))
  *
  */
-int android_setprocnetwork(net_handle_t network);
+int android_setprocnetwork(net_handle_t network) __INTRODUCED_IN(23);
 
 
 /**
@@ -97,10 +106,12 @@
  */
 int android_getaddrinfofornetwork(net_handle_t network,
         const char *node, const char *service,
-        const struct addrinfo *hints, struct addrinfo **res);
+        const struct addrinfo *hints, struct addrinfo **res) __INTRODUCED_IN(23);
 
-#endif /* __ANDROID_API__ >= 24 */
+#endif /* __ANDROID_API__ >= 23 */
 
 __END_DECLS
 
 #endif  // ANDROID_MULTINETWORK_H
+
+/** @} */
diff --git a/include/android/native_window_jni.h b/include/android/native_window_jni.h
index 23b39aa..0c196b9 100644
--- a/include/android/native_window_jni.h
+++ b/include/android/native_window_jni.h
@@ -44,16 +44,6 @@
  */
 ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);
 
-#if __ANDROID_API__ >= 13
-/**
- * Return the ANativeWindow associated with a Java SurfaceTexture object,
- * for interacting with it through native code.  This acquires a reference
- * on the ANativeWindow that is returned; be sure to use ANativeWindow_release()
- * when done with it so that it doesn't leak.
- */
-ANativeWindow* ANativeWindow_fromSurfaceTexture(JNIEnv* env, jobject surfaceTexture);
-#endif
-
 #if __ANDROID_API__ >= 26
 /**
  * Return a Java Surface object derived from the ANativeWindow, for interacting
@@ -62,7 +52,7 @@
  * and will automatically release the reference when the Java object gets garbage
  * collected.
  */
-jobject ANativeWindow_toSurface(JNIEnv* env, ANativeWindow* window);
+jobject ANativeWindow_toSurface(JNIEnv* env, ANativeWindow* window) __INTRODUCED_IN(26);
 #endif
 
 #ifdef __cplusplus
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 191777c..005564d 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -472,13 +472,13 @@
  *     ASensorManager* sensorManager = ASensorManager_getInstance();
  *
  */
-#if __ANDROID_API__ >= __ANDROID_API_O__
+#if __ANDROID_API__ >= 26
 __attribute__ ((deprecated)) ASensorManager* ASensorManager_getInstance();
 #else
 ASensorManager* ASensorManager_getInstance();
 #endif
 
-#if __ANDROID_API__ >= __ANDROID_API_O__
+#if __ANDROID_API__ >= 26
 /**
  * Get a reference to the sensor manager. ASensorManager is a singleton
  * per package as different packages may have access to different sensors.
@@ -488,7 +488,7 @@
  *     ASensorManager* sensorManager = ASensorManager_getInstanceForPackage("foo.bar.baz");
  *
  */
-ASensorManager* ASensorManager_getInstanceForPackage(const char* packageName);
+ASensorManager* ASensorManager_getInstanceForPackage(const char* packageName) __INTRODUCED_IN(26);
 #endif
 
 /**
@@ -507,7 +507,7 @@
  * Returns the default sensor with the given type and wakeUp properties or NULL if no sensor
  * of this type and wakeUp properties exists.
  */
-ASensor const* ASensorManager_getDefaultSensorEx(ASensorManager* manager, int type, bool wakeUp);
+ASensor const* ASensorManager_getDefaultSensorEx(ASensorManager* manager, int type, bool wakeUp) __INTRODUCED_IN(21);
 #endif
 
 /**
@@ -525,7 +525,7 @@
  */
 int ASensorManager_destroyEventQueue(ASensorManager* manager, ASensorEventQueue* queue);
 
-#if __ANDROID_API__ >= __ANDROID_API_O__
+#if __ANDROID_API__ >= 26
 /**
  * Create direct channel based on shared memory
  *
@@ -542,7 +542,7 @@
  *         {@link ASensorManager_destroyDirectChannel} and
  *         {@link ASensorManager_configureDirectReport}, or value less or equal to 0 for failures.
  */
-int ASensorManager_createSharedMemoryDirectChannel(ASensorManager* manager, int fd, size_t size);
+int ASensorManager_createSharedMemoryDirectChannel(ASensorManager* manager, int fd, size_t size) __INTRODUCED_IN(26);
 
 /**
  * Create direct channel based on AHardwareBuffer
@@ -560,7 +560,7 @@
  *         {@link ASensorManager_configureDirectReport}, or value less or equal to 0 for failures.
  */
 int ASensorManager_createHardwareBufferDirectChannel(
-        ASensorManager* manager, AHardwareBuffer const * buffer, size_t size);
+        ASensorManager* manager, AHardwareBuffer const * buffer, size_t size) __INTRODUCED_IN(26);
 
 /**
  * Destroy a direct channel
@@ -575,7 +575,7 @@
  *                  {@link ASensorManager_createSharedMemoryDirectChannel} or
  *                  {@link ASensorManager_createHardwareBufferDirectChannel}.
  */
-void ASensorManager_destroyDirectChannel(ASensorManager* manager, int channelId);
+void ASensorManager_destroyDirectChannel(ASensorManager* manager, int channelId) __INTRODUCED_IN(26);
 
 /**
  * Configure direct report on channel
@@ -612,9 +612,9 @@
  *
  * \return positive token for success or negative error code.
  */
-int ASensorManager_configureDirectReport(
-        ASensorManager* manager, ASensor const* sensor, int channelId, int rate);
-#endif
+int ASensorManager_configureDirectReport(ASensorManager* manager,
+        ASensor const* sensor, int channelId, int rate) __INTRODUCED_IN(26);
+#endif /* __ANDROID_API__ >= 26 */
 
 /*****************************************************************************/
 
@@ -738,30 +738,30 @@
  * Returns the maximum size of batches for this sensor. Batches will often be
  * smaller, as the hardware fifo might be used for other sensors.
  */
-int ASensor_getFifoMaxEventCount(ASensor const* sensor);
+int ASensor_getFifoMaxEventCount(ASensor const* sensor) __INTRODUCED_IN(21);
 
 /**
  * Returns the hardware batch fifo size reserved to this sensor.
  */
-int ASensor_getFifoReservedEventCount(ASensor const* sensor);
+int ASensor_getFifoReservedEventCount(ASensor const* sensor) __INTRODUCED_IN(21);
 
 /**
  * Returns this sensor's string type.
  */
-const char* ASensor_getStringType(ASensor const* sensor);
+const char* ASensor_getStringType(ASensor const* sensor) __INTRODUCED_IN(21);
 
 /**
  * Returns the reporting mode for this sensor. One of AREPORTING_MODE_* constants.
  */
-int ASensor_getReportingMode(ASensor const* sensor);
+int ASensor_getReportingMode(ASensor const* sensor) __INTRODUCED_IN(21);
 
 /**
  * Returns true if this is a wake up sensor, false otherwise.
  */
-bool ASensor_isWakeUpSensor(ASensor const* sensor);
+bool ASensor_isWakeUpSensor(ASensor const* sensor) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-#if __ANDROID_API__ >= __ANDROID_API_O__
+#if __ANDROID_API__ >= 26
 /**
  * Test if sensor supports a certain type of direct channel.
  *
@@ -771,7 +771,8 @@
  *                     or {@link ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER}.
  * \returns true if sensor supports the specified direct channel type.
  */
-bool ASensor_isDirectChannelTypeSupported(ASensor const* sensor, int channelType);
+bool ASensor_isDirectChannelTypeSupported(ASensor const* sensor, int channelType) __INTRODUCED_IN(26);
+
 /**
  * Get the highest direct rate level that a sensor support.
  *
@@ -781,8 +782,8 @@
  *         If return value is {@link ASENSOR_DIRECT_RATE_STOP}, it means the sensor
  *         does not support direct report.
  */
-int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor);
-#endif
+int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor) __INTRODUCED_IN(26);
+#endif /* __ANDROID_API__ >= 26 */
 
 #ifdef __cplusplus
 };
diff --git a/include/android/sharedmem.h b/include/android/sharedmem.h
index 46d2f4b..8c3ff74 100644
--- a/include/android/sharedmem.h
+++ b/include/android/sharedmem.h
@@ -21,12 +21,14 @@
 
 /**
  * @file sharedmem.h
+ * @brief Shared memory buffers that can be shared across process.
  */
 
 #ifndef ANDROID_SHARED_MEMORY_H
 #define ANDROID_SHARED_MEMORY_H
 
 #include <stddef.h>
+#include <sys/cdefs.h>
 
 /******************************************************************
  *
@@ -44,15 +46,11 @@
  *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
  */
 
-/**
- * Structures and functions for a shared memory buffer that can be shared across process.
- */
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if __ANDROID_API__ >= __ANDROID_API_O__
+#if __ANDROID_API__ >= 26
 
 /**
  * Create a shared memory region.
@@ -63,19 +61,23 @@
  *
  * Use close() to release the shared memory region.
  *
+ * Available since API level 26.
+ *
  * \param name an optional name.
  * \param size size of the shared memory region
  * \return file descriptor that denotes the shared memory; error code on failure.
  */
-int ASharedMemory_create(const char *name, size_t size);
+int ASharedMemory_create(const char *name, size_t size) __INTRODUCED_IN(26);
 
 /**
  * Get the size of the shared memory region.
  *
+ * Available since API level 26.
+ *
  * \param fd file descriptor of the shared memory region
  * \return size in bytes; 0 if fd is not a valid shared memory file descriptor.
  */
-size_t ASharedMemory_getSize(int fd);
+size_t ASharedMemory_getSize(int fd) __INTRODUCED_IN(26);
 
 /**
  * Restrict access of shared memory region.
@@ -101,14 +103,16 @@
  *
  *     // share fd with another process here and the other process can only map with PROT_READ.
  *
+ * Available since API level 26.
+ *
  * \param fd   file descriptor of the shared memory region.
  * \param prot any bitwise-or'ed combination of PROT_READ, PROT_WRITE, PROT_EXEC denoting
  *             updated access. Note access can only be removed, but not added back.
  * \return 0 for success, error code on failure.
  */
-int ASharedMemory_setProt(int fd, int prot);
+int ASharedMemory_setProt(int fd, int prot) __INTRODUCED_IN(26);
 
-#endif
+#endif // __ANDROID_API__ >= 26
 
 #ifdef __cplusplus
 };
diff --git a/include/android/sharedmem_jni.h b/include/android/sharedmem_jni.h
index 85ac78f..13e56e6 100644
--- a/include/android/sharedmem_jni.h
+++ b/include/android/sharedmem_jni.h
@@ -21,6 +21,7 @@
 
 /**
  * @file sharedmem_jni.h
+ * @brief Shared memory buffers that can be shared across process.
  */
 
 #ifndef ANDROID_SHARED_MEMORY_JNI_H
@@ -29,6 +30,7 @@
 #include <jni.h>
 #include <android/sharedmem.h>
 #include <stddef.h>
+#include <sys/cdefs.h>
 
 /******************************************************************
  *
@@ -46,15 +48,11 @@
  *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
  */
 
-/**
- * Structures and functions for a shared memory buffer that can be shared across process.
- */
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if __ANDROID_API__ >= __ANDROID_API_O_MR1__
+#if __ANDROID_API__ >= 27
 
 /**
  * Returns a dup'd FD from the given Java android.os.SharedMemory object. The returned file
@@ -64,15 +62,17 @@
  *
  * Use close() to release the shared memory region.
  *
+ * Available since API level 27.
+ *
  * \param env The JNIEnv* pointer
  * \param sharedMemory The Java android.os.SharedMemory object
  * \return file descriptor that denotes the shared memory; -1 if the shared memory object is
  *      already closed, if the JNIEnv or jobject is NULL, or if there are too many open file
  *      descriptors (errno=EMFILE)
  */
-int ASharedMemory_dupFromJava(JNIEnv* env, jobject sharedMemory);
+int ASharedMemory_dupFromJava(JNIEnv* env, jobject sharedMemory) __INTRODUCED_IN(27);
 
-#endif
+#endif // __ANDROID_API__ >= 27
 
 #ifdef __cplusplus
 };
diff --git a/include/android/surface_texture.h b/include/android/surface_texture.h
index 56b3342..540d23a 100644
--- a/include/android/surface_texture.h
+++ b/include/android/surface_texture.h
@@ -43,6 +43,7 @@
  */
 
 #include <stdint.h>
+#include <sys/cdefs.h>
 
 #include <android/native_window.h>
 
@@ -58,13 +59,15 @@
  */
 typedef struct ASurfaceTexture ASurfaceTexture;
 
+#if __ANDROID_API__ >= 28
+
 /**
  * Release the reference to the native ASurfaceTexture acquired with
  * ASurfaceTexture_fromSurfaceTexture().
  * Failing to do so will result in leaked memory and graphic resources.
  * \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
  */
-void ASurfaceTexture_release(ASurfaceTexture* st);
+void ASurfaceTexture_release(ASurfaceTexture* st) __INTRODUCED_IN(28);
 
 /**
  * Returns a reference to an ANativeWindow (i.e. the Producer) for this SurfaceTexture.
@@ -73,9 +76,9 @@
  * \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
  * @return A reference to an ANativeWindow. This reference MUST BE released when no longer needed
  * using ANativeWindow_release(). Failing to do so will result in leaked resources. nullptr is
- * returned if \st is null or if it's not an instance of android.graphics.SurfaceTexture
+ * returned if \p st is null or if it's not an instance of android.graphics.SurfaceTexture
  */
-ANativeWindow* ASurfaceTexture_acquireANativeWindow(ASurfaceTexture* st);
+ANativeWindow* ASurfaceTexture_acquireANativeWindow(ASurfaceTexture* st) __INTRODUCED_IN(28);
 
 /**
  * Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread.  A
@@ -92,7 +95,7 @@
  * must be unusued in the OpenGL ES context that is current on the calling thread.
  * \return 0 on success, negative posix error code otherwise (see <errno.h>)
  */
-int ASurfaceTexture_attachToGLContext(ASurfaceTexture* st, uint32_t texName);
+int ASurfaceTexture_attachToGLContext(ASurfaceTexture* st, uint32_t texName) __INTRODUCED_IN(28);
 
 /**
  * Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object.
@@ -108,7 +111,7 @@
  * \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
  * \return 0 on success, negative posix error code otherwise (see <errno.h>)
  */
-int ASurfaceTexture_detachFromGLContext(ASurfaceTexture* st);
+int ASurfaceTexture_detachFromGLContext(ASurfaceTexture* st) __INTRODUCED_IN(28);
 
 /**
  * Update the texture image to the most recent frame from the image stream.  This may only be
@@ -118,7 +121,7 @@
  * \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
  * \return 0 on success, negative posix error code otherwise (see <errno.h>)
  */
-int ASurfaceTexture_updateTexImage(ASurfaceTexture* st);
+int ASurfaceTexture_updateTexImage(ASurfaceTexture* st) __INTRODUCED_IN(28);
 
 /**
  * Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by
@@ -136,7 +139,7 @@
  * \param mtx the array into which the 4x4 matrix will be stored.  The array must have exactly
  *     16 elements.
  */
-void ASurfaceTexture_getTransformMatrix(ASurfaceTexture* st, float mtx[16]);
+void ASurfaceTexture_getTransformMatrix(ASurfaceTexture* st, float mtx[16]) __INTRODUCED_IN(28);
 
 /**
  * Retrieve the timestamp associated with the texture image set by the most recent call to
@@ -155,7 +158,9 @@
  *
  * \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
  */
-int64_t ASurfaceTexture_getTimestamp(ASurfaceTexture* st);
+int64_t ASurfaceTexture_getTimestamp(ASurfaceTexture* st) __INTRODUCED_IN(28);
+
+#endif /* __ANDROID_API__ >= 28 */
 
 __END_DECLS
 
diff --git a/include/android/trace.h b/include/android/trace.h
index d3b1fb6..aa24995 100644
--- a/include/android/trace.h
+++ b/include/android/trace.h
@@ -15,11 +15,18 @@
  */
 
 /**
+ * @addtogroup Tracing
+ * @{
+ */
+
+/**
  * @file trace.h
  * @brief Writes trace events to the system trace buffer.
  *
  * These trace events can be collected and visualized using the Systrace tool.
  * For information about using the Systrace tool, read <a href="https://developer.android.com/studio/profile/systrace.html">Analyzing UI Performance with Systrace</a>.
+ *
+ * Available since API level 23.
  */
 
 #ifndef ANDROID_NATIVE_TRACE_H
@@ -35,28 +42,34 @@
 #if __ANDROID_API__ >= 23
 
 /**
- * Returns true if tracing is enabled. Use this signal to avoid expensive computation only necessary
+ * Returns true if tracing is enabled. Use this to avoid expensive computation only necessary
  * when tracing is enabled.
+ *
+ * Available since API level 23.
  */
-bool ATrace_isEnabled();
+bool ATrace_isEnabled() __INTRODUCED_IN(23);
 
 /**
  * Writes a tracing message to indicate that the given section of code has begun. This call must be
- * followed by a corresponding call to endSection() on the same thread.
+ * followed by a corresponding call to {@link ATrace_endSection} on the same thread.
  *
- * Note: At this time the vertical bar character '|' and newline character '\n' are used internally
- * by the tracing mechanism. If sectionName contains these characters they will be replaced with a
+ * Note: At this time the vertical bar character '|' and newline character '\\n' are used internally
+ * by the tracing mechanism. If \p sectionName contains these characters they will be replaced with a
  * space character in the trace.
+ *
+ * Available since API level 23.
  */
-void ATrace_beginSection(const char* sectionName);
+void ATrace_beginSection(const char* sectionName) __INTRODUCED_IN(23);
 
 /**
  * Writes a tracing message to indicate that a given section of code has ended. This call must be
- * preceeded by a corresponding call to beginSection(char*) on the same thread. Calling this method
+ * preceeded by a corresponding call to {@link ATrace_beginSection} on the same thread. Calling this method
  * will mark the end of the most recently begun section of code, so care must be taken to ensure
- * that beginSection / endSection pairs are properly nested and called from the same thread.
+ * that {@link ATrace_beginSection}/{@link ATrace_endSection} pairs are properly nested and called from the same thread.
+ *
+ * Available since API level 23.
  */
-void ATrace_endSection();
+void ATrace_endSection() __INTRODUCED_IN(23);
 
 #endif /* __ANDROID_API__ >= 23 */
 
@@ -65,3 +78,5 @@
 #endif
 
 #endif // ANDROID_NATIVE_TRACE_H
+
+/** @} */
diff --git a/include/batteryservice b/include/batteryservice
deleted file mode 120000
index 2178c32..0000000
--- a/include/batteryservice
+++ /dev/null
@@ -1 +0,0 @@
-../services/batteryservice/include/batteryservice/
\ No newline at end of file
diff --git a/libs/binder/ActivityManager.cpp b/libs/binder/ActivityManager.cpp
index 2728f35..28d0e4f 100644
--- a/libs/binder/ActivityManager.cpp
+++ b/libs/binder/ActivityManager.cpp
@@ -34,16 +34,16 @@
     std::lock_guard<Mutex> scoped_lock(mLock);
     int64_t startTime = 0;
     sp<IActivityManager> service = mService;
-    while (service == NULL || !IInterface::asBinder(service)->isBinderAlive()) {
+    while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
         sp<IBinder> binder = defaultServiceManager()->checkService(String16("activity"));
-        if (binder == NULL) {
+        if (binder == nullptr) {
             // Wait for the activity service to come back...
             if (startTime == 0) {
                 startTime = uptimeMillis();
                 ALOGI("Waiting for activity service");
             } else if ((uptimeMillis() - startTime) > 1000000) {
                 ALOGW("Waiting too long for activity service, giving up");
-                service = NULL;
+                service = nullptr;
                 break;
             }
             usleep(25000);
@@ -58,7 +58,7 @@
 int ActivityManager::openContentUri(const String16& stringUri)
 {
     sp<IActivityManager> service = getService();
-    return service != NULL ? service->openContentUri(stringUri) : -1;
+    return service != nullptr ? service->openContentUri(stringUri) : -1;
 }
 
 void ActivityManager::registerUidObserver(const sp<IUidObserver>& observer,
@@ -67,7 +67,7 @@
                                           const String16& callingPackage)
 {
     sp<IActivityManager> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         service->registerUidObserver(observer, event, cutpoint, callingPackage);
     }
 }
@@ -75,7 +75,7 @@
 void ActivityManager::unregisterUidObserver(const sp<IUidObserver>& observer)
 {
     sp<IActivityManager> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         service->unregisterUidObserver(observer);
     }
 }
@@ -83,7 +83,7 @@
 bool ActivityManager::isUidActive(const uid_t uid, const String16& callingPackage)
 {
     sp<IActivityManager> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         return service->isUidActive(uid, callingPackage);
     }
     return false;
@@ -91,7 +91,7 @@
 
 status_t ActivityManager::linkToDeath(const sp<IBinder::DeathRecipient>& recipient) {
     sp<IActivityManager> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         return IInterface::asBinder(service)->linkToDeath(recipient);
     }
     return INVALID_OPERATION;
@@ -99,7 +99,7 @@
 
 status_t ActivityManager::unlinkToDeath(const sp<IBinder::DeathRecipient>& recipient) {
     sp<IActivityManager> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         return IInterface::asBinder(service)->unlinkToDeath(recipient);
     }
     return INVALID_OPERATION;
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 7c1eaaf..6a30956 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -28,7 +28,7 @@
     ],
 }
 
-cc_library {
+cc_library_shared {
     name: "libbinder",
 
     // for vndbinder
@@ -36,6 +36,7 @@
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
 
     srcs: [
         "ActivityManager.cpp",
@@ -62,6 +63,7 @@
         "MemoryDealer.cpp",
         "MemoryHeapBase.cpp",
         "Parcel.cpp",
+        "ParcelFileDescriptor.cpp",
         "PermissionCache.cpp",
         "PermissionController.cpp",
         "PersistableBundle.cpp",
diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp
index 62c8987..a494e22 100644
--- a/libs/binder/AppOpsManager.cpp
+++ b/libs/binder/AppOpsManager.cpp
@@ -42,7 +42,7 @@
 
 static const sp<IBinder>& getToken(const sp<IAppOpsService>& service) {
     pthread_mutex_lock(&gTokenMutex);
-    if (gToken == NULL || gToken->pingBinder() != NO_ERROR) {
+    if (gToken == nullptr || gToken->pingBinder() != NO_ERROR) {
         gToken = service->getToken(new BBinder());
     }
     pthread_mutex_unlock(&gTokenMutex);
@@ -63,16 +63,16 @@
     std::lock_guard<Mutex> scoped_lock(mLock);
     int64_t startTime = 0;
     sp<IAppOpsService> service = mService;
-    while (service == NULL || !IInterface::asBinder(service)->isBinderAlive()) {
+    while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
         sp<IBinder> binder = defaultServiceManager()->checkService(_appops);
-        if (binder == NULL) {
+        if (binder == nullptr) {
             // Wait for the app ops service to come back...
             if (startTime == 0) {
                 startTime = uptimeMillis();
                 ALOGI("Waiting for app ops service");
             } else if ((uptimeMillis()-startTime) > 10000) {
                 ALOGW("Waiting too long for app ops service, giving up");
-                service = NULL;
+                service = nullptr;
                 break;
             }
             sleep(1);
@@ -88,14 +88,14 @@
 int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage)
 {
     sp<IAppOpsService> service = getService();
-    return service != NULL
+    return service != nullptr
             ? service->checkOperation(op, uid, callingPackage)
             : APP_OPS_MANAGER_UNAVAILABLE_MODE;
 }
 
 int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) {
     sp<IAppOpsService> service = getService();
-    return service != NULL
+    return service != nullptr
             ? service->noteOperation(op, uid, callingPackage)
             : APP_OPS_MANAGER_UNAVAILABLE_MODE;
 }
@@ -103,14 +103,14 @@
 int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
         bool startIfModeDefault) {
     sp<IAppOpsService> service = getService();
-    return service != NULL
+    return service != nullptr
             ? service->startOperation(getToken(service), op, uid, callingPackage,
                     startIfModeDefault) : APP_OPS_MANAGER_UNAVAILABLE_MODE;
 }
 
 void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) {
     sp<IAppOpsService> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         service->finishOperation(getToken(service), op, uid, callingPackage);
     }
 }
@@ -118,21 +118,21 @@
 void AppOpsManager::startWatchingMode(int32_t op, const String16& packageName,
         const sp<IAppOpsCallback>& callback) {
     sp<IAppOpsService> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         service->startWatchingMode(op, packageName, callback);
     }
 }
 
 void AppOpsManager::stopWatchingMode(const sp<IAppOpsCallback>& callback) {
     sp<IAppOpsService> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         service->stopWatchingMode(callback);
     }
 }
 
 int32_t AppOpsManager::permissionToOpCode(const String16& permission) {
     sp<IAppOpsService> service = getService();
-    if (service != NULL) {
+    if (service != nullptr) {
         return service->permissionToOpCode(permission);
     }
     return -1;
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index a81f44e..1bd7c4f 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -43,17 +43,17 @@
 
 sp<IInterface>  IBinder::queryLocalInterface(const String16& /*descriptor*/)
 {
-    return NULL;
+    return nullptr;
 }
 
 BBinder* IBinder::localBinder()
 {
-    return NULL;
+    return nullptr;
 }
 
 BpBinder* IBinder::remoteBinder()
 {
-    return NULL;
+    return nullptr;
 }
 
 bool IBinder::checkSubclass(const void* /*subclassID*/) const
@@ -76,8 +76,8 @@
     for (size_t i = 0; i < numArgs; i++) {
         send.writeString16(args[i]);
     }
-    send.writeStrongBinder(callback != NULL ? IInterface::asBinder(callback) : NULL);
-    send.writeStrongBinder(resultReceiver != NULL ? IInterface::asBinder(resultReceiver) : NULL);
+    send.writeStrongBinder(callback != nullptr ? IInterface::asBinder(callback) : nullptr);
+    send.writeStrongBinder(resultReceiver != nullptr ? IInterface::asBinder(resultReceiver) : nullptr);
     return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
 }
 
@@ -130,7 +130,7 @@
             break;
     }
 
-    if (reply != NULL) {
+    if (reply != nullptr) {
         reply->setDataPosition(0);
     }
 
@@ -171,7 +171,7 @@
             delete e;
             e = expected;  // Filled in by CAS
         }
-        if (e == 0) return; // out of memory
+        if (e == nullptr) return; // out of memory
     }
 
     AutoMutex _l(e->mLock);
@@ -181,7 +181,7 @@
 void* BBinder::findObject(const void* objectID) const
 {
     Extras* e = mExtras.load(std::memory_order_acquire);
-    if (!e) return NULL;
+    if (!e) return nullptr;
 
     AutoMutex _l(e->mLock);
     return e->mObjects.find(objectID);
@@ -246,7 +246,7 @@
             (void)out;
             (void)err;
 
-            if (resultReceiver != NULL) {
+            if (resultReceiver != nullptr) {
                 resultReceiver->send(INVALID_OPERATION);
             }
 
@@ -273,7 +273,7 @@
 };
 
 BpRefBase::BpRefBase(const sp<IBinder>& o)
-    : mRemote(o.get()), mRefs(NULL), mState(0)
+    : mRemote(o.get()), mRefs(nullptr), mState(0)
 {
     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
 
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 449a9e9..7342126 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -80,7 +80,7 @@
 void* BpBinder::ObjectManager::find(const void* objectID) const
 {
     const ssize_t i = mObjects.indexOfKey(objectID);
-    if (i < 0) return NULL;
+    if (i < 0) return nullptr;
     return mObjects.valueAt(i).object;
 }
 
@@ -95,7 +95,7 @@
     ALOGV("Killing %zu objects in manager %p", N, this);
     for (size_t i=0; i<N; i++) {
         const entry_t& e = mObjects.valueAt(i);
-        if (e.func != NULL) {
+        if (e.func != nullptr) {
             e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
         }
     }
@@ -139,7 +139,7 @@
     : mHandle(handle)
     , mAlive(1)
     , mObitsSent(0)
-    , mObituaries(NULL)
+    , mObituaries(nullptr)
     , mTrackedUid(trackedUid)
 {
     ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
@@ -228,7 +228,7 @@
     ob.cookie = cookie;
     ob.flags = flags;
 
-    LOG_ALWAYS_FATAL_IF(recipient == NULL,
+    LOG_ALWAYS_FATAL_IF(recipient == nullptr,
                         "linkToDeath(): recipient must be non-NULL");
 
     {
@@ -268,9 +268,9 @@
     for (size_t i=0; i<N; i++) {
         const Obituary& obit = mObituaries->itemAt(i);
         if ((obit.recipient == recipient
-                    || (recipient == NULL && obit.cookie == cookie))
+                    || (recipient == nullptr && obit.cookie == cookie))
                 && obit.flags == flags) {
-            if (outRecipient != NULL) {
+            if (outRecipient != nullptr) {
                 *outRecipient = mObituaries->itemAt(i).recipient;
             }
             mObituaries->removeAt(i);
@@ -280,7 +280,7 @@
                 self->clearDeathNotification(mHandle, this);
                 self->flushCommands();
                 delete mObituaries;
-                mObituaries = NULL;
+                mObituaries = nullptr;
             }
             return NO_ERROR;
         }
@@ -299,12 +299,12 @@
 
     mLock.lock();
     Vector<Obituary>* obits = mObituaries;
-    if(obits != NULL) {
+    if(obits != nullptr) {
         ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
         IPCThreadState* self = IPCThreadState::self();
         self->clearDeathNotification(mHandle, this);
         self->flushCommands();
-        mObituaries = NULL;
+        mObituaries = nullptr;
     }
     mObitsSent = 1;
     mLock.unlock();
@@ -312,7 +312,7 @@
     ALOGV("Reporting death of proxy %p for %zu recipients\n",
         this, obits ? obits->size() : 0U);
 
-    if (obits != NULL) {
+    if (obits != nullptr) {
         const size_t N = obits->size();
         for (size_t i=0; i<N; i++) {
             reportOneDeath(obits->itemAt(i));
@@ -326,7 +326,7 @@
 {
     sp<DeathRecipient> recipient = obit.recipient.promote();
     ALOGV("Reporting death to recipient: %p\n", recipient.get());
-    if (recipient == NULL) return;
+    if (recipient == nullptr) return;
 
     recipient->binderDied(this);
 }
@@ -386,13 +386,13 @@
 
     mLock.lock();
     Vector<Obituary>* obits = mObituaries;
-    if(obits != NULL) {
+    if(obits != nullptr) {
         if (ipc) ipc->clearDeathNotification(mHandle, this);
-        mObituaries = NULL;
+        mObituaries = nullptr;
     }
     mLock.unlock();
 
-    if (obits != NULL) {
+    if (obits != nullptr) {
         // XXX Should we tell any remaining DeathRecipient
         // objects that the last strong ref has gone away, so they
         // are no longer linked?
diff --git a/libs/binder/BufferedTextOutput.cpp b/libs/binder/BufferedTextOutput.cpp
index 30e70b0..d516eb1 100644
--- a/libs/binder/BufferedTextOutput.cpp
+++ b/libs/binder/BufferedTextOutput.cpp
@@ -25,6 +25,7 @@
 
 #include <private/binder/Static.h>
 
+#include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -36,7 +37,7 @@
 {
     explicit BufferState(int32_t _seq)
         : seq(_seq)
-        , buffer(NULL)
+        , buffer(nullptr)
         , bufferPos(0)
         , bufferSize(0)
         , atFront(true)
@@ -87,7 +88,7 @@
     Vector<sp<BufferedTextOutput::BufferState> > states;
 };
 
-static mutex_t          gMutex;
+static pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER;
 
 static thread_store_t   tls;
 
@@ -113,7 +114,7 @@
 {
     int32_t res = -1;
     
-    mutex_lock(&gMutex);
+    pthread_mutex_lock(&gMutex);
     
     if (gFreeBufferIndex >= 0) {
         res = gFreeBufferIndex;
@@ -125,17 +126,17 @@
         gTextBuffers.add(-1);
     }
 
-    mutex_unlock(&gMutex);
+    pthread_mutex_unlock(&gMutex);
     
     return res;
 }
 
 static void freeBufferIndex(int32_t idx)
 {
-    mutex_lock(&gMutex);
+    pthread_mutex_lock(&gMutex);
     gTextBuffers.editItemAt(idx) = gFreeBufferIndex;
     gFreeBufferIndex = idx;
-    mutex_unlock(&gMutex);
+    pthread_mutex_unlock(&gMutex);
 }
 
 // ---------------------------------------------------------------------------
@@ -266,13 +267,13 @@
     if ((mFlags&MULTITHREADED) != 0) {
         ThreadState* ts = getThreadState();
         if (ts) {
-            while (ts->states.size() <= (size_t)mIndex) ts->states.add(NULL);
+            while (ts->states.size() <= (size_t)mIndex) ts->states.add(nullptr);
             BufferState* bs = ts->states[mIndex].get();
-            if (bs != NULL && bs->seq == mSeq) return bs;
+            if (bs != nullptr && bs->seq == mSeq) return bs;
             
             ts->states.editItemAt(mIndex) = new BufferState(mIndex);
             bs = ts->states[mIndex].get();
-            if (bs != NULL) return bs;
+            if (bs != nullptr) return bs;
         }
     }
     
diff --git a/libs/binder/Debug.cpp b/libs/binder/Debug.cpp
index 4ac61a3..f38bbb2 100644
--- a/libs/binder/Debug.cpp
+++ b/libs/binder/Debug.cpp
@@ -165,13 +165,13 @@
         else if (bytesPerLine >= 8) alignment = 2;
         else alignment = 1;
     }
-    if (func == NULL) func = defaultPrintFunc;
+    if (func == nullptr) func = defaultPrintFunc;
 
     size_t offset;
 
     unsigned char *pos = (unsigned char *)buf;
 
-    if (pos == NULL) {
+    if (pos == nullptr) {
         if (singleLineBytesCutoff < 0) func(cookie, "\n");
         func(cookie, "(NULL)");
         return;
@@ -297,7 +297,7 @@
 
 ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf) {
     sp<ProcessState> proc = ProcessState::selfOrNull();
-    if (proc.get() == NULL) {
+    if (proc.get() == nullptr) {
         return 0;
     }
 
diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp
index 9c76350..068664b 100644
--- a/libs/binder/IAppOpsService.cpp
+++ b/libs/binder/IAppOpsService.cpp
@@ -109,7 +109,7 @@
         data.writeStrongBinder(clientToken);
         remote()->transact(GET_TOKEN_TRANSACTION, data, &reply);
         // fail on exception
-        if (reply.readExceptionCode() != 0) return NULL;
+        if (reply.readExceptionCode() != 0) return nullptr;
         return reply.readStrongBinder();
     }
 
diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp
index 2fcd3d9..6b77291 100644
--- a/libs/binder/IInterface.cpp
+++ b/libs/binder/IInterface.cpp
@@ -32,14 +32,14 @@
 // static
 sp<IBinder> IInterface::asBinder(const IInterface* iface)
 {
-    if (iface == NULL) return NULL;
+    if (iface == nullptr) return nullptr;
     return const_cast<IInterface*>(iface)->onAsBinder();
 }
 
 // static
 sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface)
 {
-    if (iface == NULL) return NULL;
+    if (iface == nullptr) return nullptr;
     return iface->onAsBinder();
 }
 
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index 5c1a4f4..7afec45 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -130,7 +130,7 @@
 public:
     explicit BpMemory(const sp<IBinder>& impl);
     virtual ~BpMemory();
-    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const;
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=nullptr, size_t* size=nullptr) const;
 
 private:
     mutable sp<IMemoryHeap> mHeap;
@@ -145,22 +145,22 @@
     sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder);
     void* const base = realHeap->base();
     if (base == MAP_FAILED)
-        return 0;
+        return nullptr;
     return static_cast<char*>(base) + offset;
 }
 
 void* IMemory::pointer() const {
     ssize_t offset;
     sp<IMemoryHeap> heap = getMemory(&offset);
-    void* const base = heap!=0 ? heap->base() : MAP_FAILED;
+    void* const base = heap!=nullptr ? heap->base() : MAP_FAILED;
     if (base == MAP_FAILED)
-        return 0;
+        return nullptr;
     return static_cast<char*>(base) + offset;
 }
 
 size_t IMemory::size() const {
     size_t size;
-    getMemory(NULL, &size);
+    getMemory(nullptr, &size);
     return size;
 }
 
@@ -183,16 +183,16 @@
 
 sp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const
 {
-    if (mHeap == 0) {
+    if (mHeap == nullptr) {
         Parcel data, reply;
         data.writeInterfaceToken(IMemory::getInterfaceDescriptor());
         if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) {
             sp<IBinder> heap = reply.readStrongBinder();
             ssize_t o = reply.readInt32();
             size_t s = reply.readInt32();
-            if (heap != 0) {
+            if (heap != nullptr) {
                 mHeap = interface_cast<IMemoryHeap>(heap);
-                if (mHeap != 0) {
+                if (mHeap != nullptr) {
                     size_t heapSize = mHeap->getSize();
                     if (s <= heapSize
                             && o >= 0
@@ -202,7 +202,7 @@
                     } else {
                         // Hm.
                         android_errorWriteWithInfoLog(0x534e4554,
-                            "26877992", -1, NULL, 0);
+                            "26877992", -1, nullptr, 0);
                         mOffset = 0;
                         mSize = 0;
                     }
@@ -212,7 +212,7 @@
     }
     if (offset) *offset = mOffset;
     if (size) *size = mSize;
-    return (mSize > 0) ? mHeap : 0;
+    return (mSize > 0) ? mHeap : nullptr;
 }
 
 // ---------------------------------------------------------------------------
@@ -334,7 +334,7 @@
                 access |= PROT_WRITE;
             }
             mRealHeap = true;
-            mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
+            mBase = mmap(nullptr, size, access, MAP_SHARED, fd, offset);
             if (mBase == MAP_FAILED) {
                 ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)",
                         IInterface::asBinder(this).get(), size, fd, strerror(errno));
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index fd552b4..b2217b5 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -289,7 +289,7 @@
 
     if (gShutdown) {
         ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
-        return NULL;
+        return nullptr;
     }
 
     pthread_mutex_lock(&gTLSMutex);
@@ -299,7 +299,7 @@
             pthread_mutex_unlock(&gTLSMutex);
             ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
                     strerror(key_create_value));
-            return NULL;
+            return nullptr;
         }
         gHaveTLS = true;
     }
@@ -314,7 +314,7 @@
         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
         return st;
     }
-    return NULL;
+    return nullptr;
 }
 
 void IPCThreadState::shutdown()
@@ -326,7 +326,7 @@
         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
         if (st) {
             delete st;
-            pthread_setspecific(gTLS, NULL);
+            pthread_setspecific(gTLS, nullptr);
         }
         pthread_key_delete(gTLS);
         gHaveTLS = false;
@@ -608,7 +608,7 @@
 
     LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
         (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
-    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
+    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
 
     if (err != NO_ERROR) {
         if (reply) reply->setError(err);
@@ -645,7 +645,7 @@
             else alog << "(none requested)" << endl;
         }
     } else {
-        err = waitForResponse(NULL, NULL);
+        err = waitForResponse(nullptr, nullptr);
     }
 
     return err;
@@ -755,7 +755,7 @@
     err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
     if (err < NO_ERROR) return err;
 
-    return waitForResponse(NULL, NULL);
+    return waitForResponse(nullptr, nullptr);
 }
 
 status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
@@ -815,14 +815,14 @@
                             freeBuffer, this);
                     } else {
                         err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
-                        freeBuffer(NULL,
+                        freeBuffer(nullptr,
                             reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                             tr.data_size,
                             reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                             tr.offsets_size/sizeof(binder_size_t), this);
                     }
                 } else {
-                    freeBuffer(NULL,
+                    freeBuffer(nullptr,
                         reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                         tr.data_size,
                         reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
@@ -1217,7 +1217,7 @@
         alog << "Writing BC_FREE_BUFFER for " << data << endl;
     }
     ALOG_ASSERT(data != NULL, "Called with NULL data");
-    if (parcel != NULL) parcel->closeFileDescriptors();
+    if (parcel != nullptr) parcel->closeFileDescriptors();
     IPCThreadState* state = self();
     state->mOut.writeInt32(BC_FREE_BUFFER);
     state->mOut.writePointer((uintptr_t)data);
diff --git a/libs/binder/IResultReceiver.cpp b/libs/binder/IResultReceiver.cpp
index 646809e..14b5259 100644
--- a/libs/binder/IResultReceiver.cpp
+++ b/libs/binder/IResultReceiver.cpp
@@ -40,7 +40,7 @@
         Parcel data;
         data.writeInterfaceToken(IResultReceiver::getInterfaceDescriptor());
         data.writeInt32(resultCode);
-        remote()->transact(OP_SEND, data, NULL, IBinder::FLAG_ONEWAY);
+        remote()->transact(OP_SEND, data, nullptr, IBinder::FLAG_ONEWAY);
     }
 };
 
@@ -56,7 +56,7 @@
             CHECK_INTERFACE(IResultReceiver, data, reply);
             int32_t resultCode = data.readInt32();
             send(resultCode);
-            if (reply != NULL) {
+            if (reply != nullptr) {
                 reply->writeNoException();
             }
             return NO_ERROR;
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 4896f68..d0ed31e 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -37,14 +37,14 @@
 
 sp<IServiceManager> defaultServiceManager()
 {
-    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
+    if (gDefaultServiceManager != nullptr) return gDefaultServiceManager;
 
     {
         AutoMutex _l(gDefaultServiceManagerLock);
-        while (gDefaultServiceManager == NULL) {
+        while (gDefaultServiceManager == nullptr) {
             gDefaultServiceManager = interface_cast<IServiceManager>(
-                ProcessState::self()->getContextObject(NULL));
-            if (gDefaultServiceManager == NULL)
+                ProcessState::self()->getContextObject(nullptr));
+            if (gDefaultServiceManager == nullptr)
                 sleep(1);
         }
     }
@@ -57,7 +57,7 @@
 
 bool checkCallingPermission(const String16& permission)
 {
-    return checkCallingPermission(permission, NULL, NULL);
+    return checkCallingPermission(permission, nullptr, nullptr);
 }
 
 static String16 _permission("permission");
@@ -83,7 +83,7 @@
     int64_t startTime = 0;
 
     while (true) {
-        if (pc != NULL) {
+        if (pc != nullptr) {
             bool res = pc->checkPermission(permission, pid, uid);
             if (res) {
                 if (startTime != 0) {
@@ -104,14 +104,14 @@
             // Object is dead!
             gDefaultServiceManagerLock.lock();
             if (gPermissionController == pc) {
-                gPermissionController = NULL;
+                gPermissionController = nullptr;
             }
             gDefaultServiceManagerLock.unlock();
         }
 
         // Need to retrieve the permission controller.
         sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
-        if (binder == NULL) {
+        if (binder == nullptr) {
             // Wait for the permission controller to come back...
             if (startTime == 0) {
                 startTime = uptimeMillis();
@@ -144,7 +144,7 @@
     virtual sp<IBinder> getService(const String16& name) const
     {
         sp<IBinder> svc = checkService(name);
-        if (svc != NULL) return svc;
+        if (svc != nullptr) return svc;
 
         const bool isVendorService =
             strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
@@ -170,10 +170,10 @@
             usleep(1000*sleepTime);
 
             sp<IBinder> svc = checkService(name);
-            if (svc != NULL) return svc;
+            if (svc != nullptr) return svc;
         }
         ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
-        return NULL;
+        return nullptr;
     }
 
     virtual sp<IBinder> checkService( const String16& name) const
diff --git a/libs/binder/IShellCallback.cpp b/libs/binder/IShellCallback.cpp
index 23b83a6..dd4a65e 100644
--- a/libs/binder/IShellCallback.cpp
+++ b/libs/binder/IShellCallback.cpp
@@ -68,7 +68,7 @@
             String16 seLinuxContext(data.readString16());
             String16 mode(data.readString16());
             int fd = openFile(path, seLinuxContext, mode);
-            if (reply != NULL) {
+            if (reply != nullptr) {
                 reply->writeNoException();
                 if (fd >= 0) {
                     reply->writeInt32(1);
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
index 1cfe02a..eacad3b 100644
--- a/libs/binder/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -52,8 +52,8 @@
     NODE*  mLast;
 
 public:
-                LinkedList() : mFirst(0), mLast(0) { }
-    bool        isEmpty() const { return mFirst == 0; }
+                LinkedList() : mFirst(nullptr), mLast(nullptr) { }
+    bool        isEmpty() const { return mFirst == nullptr; }
     NODE const* head() const { return mFirst; }
     NODE*       head() { return mFirst; }
     NODE const* tail() const { return mLast; }
@@ -62,7 +62,7 @@
     void insertAfter(NODE* node, NODE* newNode) {
         newNode->prev = node;
         newNode->next = node->next;
-        if (node->next == 0) mLast = newNode;
+        if (node->next == nullptr) mLast = newNode;
         else                 node->next->prev = newNode;
         node->next = newNode;
     }
@@ -70,17 +70,17 @@
     void insertBefore(NODE* node, NODE* newNode) {
          newNode->prev = node->prev;
          newNode->next = node;
-         if (node->prev == 0)   mFirst = newNode;
+         if (node->prev == nullptr)   mFirst = newNode;
          else                   node->prev->next = newNode;
          node->prev = newNode;
     }
 
     void insertHead(NODE* newNode) {
-        if (mFirst == 0) {
+        if (mFirst == nullptr) {
             mFirst = mLast = newNode;
-            newNode->prev = newNode->next = 0;
+            newNode->prev = newNode->next = nullptr;
         } else {
-            newNode->prev = 0;
+            newNode->prev = nullptr;
             newNode->next = mFirst;
             mFirst->prev = newNode;
             mFirst = newNode;
@@ -99,9 +99,9 @@
     }
 
     NODE* remove(NODE* node) {
-        if (node->prev == 0)    mFirst = node->next;
+        if (node->prev == nullptr)    mFirst = node->next;
         else                    node->prev->next = node->next;
-        if (node->next == 0)    mLast = node->prev;
+        if (node->next == nullptr)    mLast = node->prev;
         else                    node->next->prev = node->prev;
         return node;
     }
@@ -141,7 +141,7 @@
 
     struct chunk_t {
         chunk_t(size_t start, size_t size)
-        : start(start), size(size), free(1), prev(0), next(0) {
+        : start(start), size(size), free(1), prev(nullptr), next(nullptr) {
         }
         size_t              start;
         size_t              size : 28;
@@ -329,7 +329,7 @@
         return 0;
     }
     size = (size + kMemoryAlign-1) / kMemoryAlign;
-    chunk_t* free_chunk = 0;
+    chunk_t* free_chunk = nullptr;
     chunk_t* cur = mList.head();
 
     size_t pagesize = getpagesize();
@@ -418,7 +418,7 @@
         }
         cur = cur->next;
     }
-    return 0;
+    return nullptr;
 }
 
 void SimpleBestFitAllocator::dump(const char* what) const
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 03f00be..9850ad9 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -36,17 +36,17 @@
 
 MemoryHeapBase::MemoryHeapBase()
     : mFD(-1), mSize(0), mBase(MAP_FAILED),
-      mDevice(NULL), mNeedUnmap(false), mOffset(0)
+      mDevice(nullptr), mNeedUnmap(false), mOffset(0)
 {
 }
 
 MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
     : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
-      mDevice(0), mNeedUnmap(false), mOffset(0)
+      mDevice(nullptr), mNeedUnmap(false), mOffset(0)
 {
     const size_t pagesize = getpagesize();
     size = ((size + pagesize-1) & ~(pagesize-1));
-    int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
+    int fd = ashmem_create_region(name == nullptr ? "MemoryHeapBase" : name, size);
     ALOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
     if (fd >= 0) {
         if (mapfd(fd, size) == NO_ERROR) {
@@ -59,7 +59,7 @@
 
 MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
     : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
-      mDevice(0), mNeedUnmap(false), mOffset(0)
+      mDevice(nullptr), mNeedUnmap(false), mOffset(0)
 {
     int open_flags = O_RDWR;
     if (flags & NO_CACHING)
@@ -78,7 +78,7 @@
 
 MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags, uint32_t offset)
     : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
-      mDevice(0), mNeedUnmap(false), mOffset(0)
+      mDevice(nullptr), mNeedUnmap(false), mOffset(0)
 {
     const size_t pagesize = getpagesize();
     size = ((size + pagesize-1) & ~(pagesize-1));
@@ -109,7 +109,7 @@
     }
 
     if ((mFlags & DONT_MAP_LOCALLY) == 0) {
-        void* base = (uint8_t*)mmap(0, size,
+        void* base = (uint8_t*)mmap(nullptr, size,
                 PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
         if (base == MAP_FAILED) {
             ALOGE("mmap(fd=%d, size=%u) failed (%s)",
@@ -121,7 +121,7 @@
         mBase = base;
         mNeedUnmap = true;
     } else  {
-        mBase = 0; // not MAP_FAILED
+        mBase = nullptr; // not MAP_FAILED
         mNeedUnmap = false;
     }
     mFD = fd;
@@ -143,7 +143,7 @@
             //ALOGD("munmap(fd=%d, base=%p, size=%lu)", fd, mBase, mSize);
             munmap(mBase, mSize);
         }
-        mBase = 0;
+        mBase = nullptr;
         mSize = 0;
         close(fd);
     }
diff --git a/libs/binder/OWNERS b/libs/binder/OWNERS
new file mode 100644
index 0000000..350994a
--- /dev/null
+++ b/libs/binder/OWNERS
@@ -0,0 +1,5 @@
+arve@google.com
+ctate@google.com
+hackbod@google.com
+maco@google.com
+smoreland@google.com
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 2e7edd7..b3ae09b 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -117,7 +117,7 @@
             return;
         case BINDER_TYPE_HANDLE: {
             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
-            if (b != NULL) {
+            if (b != nullptr) {
                 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
                 b->incStrong(who);
             }
@@ -125,11 +125,11 @@
         }
         case BINDER_TYPE_WEAK_HANDLE: {
             const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
-            if (b != NULL) b.get_refs()->incWeak(who);
+            if (b != nullptr) b.get_refs()->incWeak(who);
             return;
         }
         case BINDER_TYPE_FD: {
-            if ((obj.cookie != 0) && (outAshmemSize != NULL) && ashmem_valid(obj.handle)) {
+            if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
                 // If we own an ashmem fd, keep track of how much memory it refers to.
                 int size = ashmem_get_size_region(obj.handle);
                 if (size > 0) {
@@ -146,7 +146,7 @@
 void acquire_object(const sp<ProcessState>& proc,
     const flat_binder_object& obj, const void* who)
 {
-    acquire_object(proc, obj, who, NULL);
+    acquire_object(proc, obj, who, nullptr);
 }
 
 static void release_object(const sp<ProcessState>& proc,
@@ -165,7 +165,7 @@
             return;
         case BINDER_TYPE_HANDLE: {
             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
-            if (b != NULL) {
+            if (b != nullptr) {
                 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
                 b->decStrong(who);
             }
@@ -173,12 +173,12 @@
         }
         case BINDER_TYPE_WEAK_HANDLE: {
             const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
-            if (b != NULL) b.get_refs()->decWeak(who);
+            if (b != nullptr) b.get_refs()->decWeak(who);
             return;
         }
         case BINDER_TYPE_FD: {
             if (obj.cookie != 0) { // owned
-                if ((outAshmemSize != NULL) && ashmem_valid(obj.handle)) {
+                if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
                     int size = ashmem_get_size_region(obj.handle);
                     if (size > 0) {
                         *outAshmemSize -= size;
@@ -197,7 +197,7 @@
 void release_object(const sp<ProcessState>& proc,
     const flat_binder_object& obj, const void* who)
 {
-    release_object(proc, obj, who, NULL);
+    release_object(proc, obj, who, nullptr);
 }
 
 inline static status_t finish_flatten_binder(
@@ -219,11 +219,11 @@
         obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;
     }
 
-    if (binder != NULL) {
+    if (binder != nullptr) {
         IBinder *local = binder->localBinder();
         if (!local) {
             BpBinder *proxy = binder->remoteBinder();
-            if (proxy == NULL) {
+            if (proxy == nullptr) {
                 ALOGE("null proxy");
             }
             const int32_t handle = proxy ? proxy->handle() : 0;
@@ -251,13 +251,13 @@
     flat_binder_object obj;
 
     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-    if (binder != NULL) {
+    if (binder != nullptr) {
         sp<IBinder> real = binder.promote();
-        if (real != NULL) {
+        if (real != nullptr) {
             IBinder *local = real->localBinder();
             if (!local) {
                 BpBinder *proxy = real->remoteBinder();
-                if (proxy == NULL) {
+                if (proxy == nullptr) {
                     ALOGE("null proxy");
                 }
                 const int32_t handle = proxy ? proxy->handle() : 0;
@@ -284,13 +284,13 @@
         obj.hdr.type = BINDER_TYPE_BINDER;
         obj.binder = 0;
         obj.cookie = 0;
-        return finish_flatten_binder(NULL, obj, out);
+        return finish_flatten_binder(nullptr, obj, out);
 
     } else {
         obj.hdr.type = BINDER_TYPE_BINDER;
         obj.binder = 0;
         obj.cookie = 0;
-        return finish_flatten_binder(NULL, obj, out);
+        return finish_flatten_binder(nullptr, obj, out);
     }
 }
 
@@ -310,7 +310,7 @@
         switch (flat->hdr.type) {
             case BINDER_TYPE_BINDER:
                 *out = reinterpret_cast<IBinder*>(flat->cookie);
-                return finish_unflatten_binder(NULL, *flat, in);
+                return finish_unflatten_binder(nullptr, *flat, in);
             case BINDER_TYPE_HANDLE:
                 *out = proc->getStrongProxyForHandle(flat->handle);
                 return finish_unflatten_binder(
@@ -329,16 +329,16 @@
         switch (flat->hdr.type) {
             case BINDER_TYPE_BINDER:
                 *out = reinterpret_cast<IBinder*>(flat->cookie);
-                return finish_unflatten_binder(NULL, *flat, in);
+                return finish_unflatten_binder(nullptr, *flat, in);
             case BINDER_TYPE_WEAK_BINDER:
                 if (flat->binder != 0) {
                     out->set_object_and_refs(
                         reinterpret_cast<IBinder*>(flat->cookie),
                         reinterpret_cast<RefBase::weakref_type*>(flat->binder));
                 } else {
-                    *out = NULL;
+                    *out = nullptr;
                 }
-                return finish_unflatten_binder(NULL, *flat, in);
+                return finish_unflatten_binder(nullptr, *flat, in);
             case BINDER_TYPE_HANDLE:
             case BINDER_TYPE_WEAK_HANDLE:
                 *out = proc->getWeakProxyForHandle(flat->handle);
@@ -526,7 +526,7 @@
             if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY;   // overflow
             binder_size_t *objects =
                 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
-            if (objects == (binder_size_t*)0) {
+            if (objects == (binder_size_t*)nullptr) {
                 return NO_MEMORY;
             }
             mObjects = objects;
@@ -614,7 +614,7 @@
                               IPCThreadState* threadState) const
 {
     int32_t strictPolicy = readInt32();
-    if (threadState == NULL) {
+    if (threadState == nullptr) {
         threadState = IPCThreadState::self();
     }
     if ((threadState->getLastTransactionBinderFlags() &
@@ -722,14 +722,14 @@
     if (len > INT32_MAX) {
         // don't accept size_t values which may have come from an
         // inadvertent conversion from a negative int.
-        return NULL;
+        return nullptr;
     }
 
     const size_t padded = pad_size(len);
 
     // sanity check for integer overflow
     if (mDataPos+padded < mDataPos) {
-        return NULL;
+        return nullptr;
     }
 
     if ((mDataPos+padded) <= mDataCapacity) {
@@ -760,7 +760,7 @@
 
     status_t err = growData(padded);
     if (err == NO_ERROR) goto restart_write;
-    return NULL;
+    return nullptr;
 }
 
 status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
@@ -1063,7 +1063,7 @@
 
 status_t Parcel::writeString16(const char16_t* str, size_t len)
 {
-    if (str == NULL) return writeInt32(-1);
+    if (str == nullptr) return writeInt32(-1);
 
     status_t err = writeInt32(len);
     if (err == NO_ERROR) {
@@ -1180,6 +1180,19 @@
     return writeFileDescriptor(fd, takeOwnership);
 }
 
+status_t Parcel::writeDupParcelFileDescriptor(int fd)
+{
+    int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
+    if (dupFd < 0) {
+        return -errno;
+    }
+    status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
+    if (err != OK) {
+        close(dupFd);
+    }
+    return err;
+}
+
 status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
     return writeDupFileDescriptor(fd.get());
 }
@@ -1221,7 +1234,7 @@
     if (result < 0) {
         status = result;
     } else {
-        void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+        void* ptr = ::mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
         if (ptr == MAP_FAILED) {
             status = -errno;
         } else {
@@ -1278,10 +1291,10 @@
 
     // payload
     void* const buf = this->writeInplace(len);
-    if (buf == NULL)
+    if (buf == nullptr)
         return BAD_VALUE;
 
-    int* fds = NULL;
+    int* fds = nullptr;
     if (fd_count) {
         fds = new (std::nothrow) int[fd_count];
         if (fds == nullptr) {
@@ -1337,7 +1350,7 @@
         size_t newSize = ((mObjectsSize+2)*3)/2;
         if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY;   // overflow
         binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
-        if (objects == NULL) return NO_MEMORY;
+        if (objects == nullptr) return NO_MEMORY;
         mObjects = objects;
         mObjectsCapacity = newSize;
     }
@@ -1383,7 +1396,7 @@
 
 status_t Parcel::writeNullableMap(const std::unique_ptr<binder::Map>& map)
 {
-    if (map == NULL) {
+    if (map == nullptr) {
         return writeInt32(-1);
     }
 
@@ -1555,7 +1568,7 @@
     if (len > INT32_MAX) {
         // don't accept size_t values which may have come from an
         // inadvertent conversion from a negative int.
-        return NULL;
+        return nullptr;
     }
 
     if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
@@ -1566,7 +1579,7 @@
                 // Still increment the data position by the expected length
                 mDataPos += pad_size(len);
                 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
-                return NULL;
+                return nullptr;
             }
         }
 
@@ -1575,7 +1588,7 @@
         ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
         return data;
     }
-    return NULL;
+    return nullptr;
 }
 
 template<class T>
@@ -2025,7 +2038,7 @@
             return str;
         }
     }
-    return NULL;
+    return nullptr;
 }
 
 String8 Parcel::readString8() const
@@ -2056,7 +2069,7 @@
         return OK;
     }
     const char* str = (const char*)readInplace(size + 1);
-    if (str == NULL) {
+    if (str == nullptr) {
         return BAD_VALUE;
     }
     pArg->setTo(str, size);
@@ -2115,12 +2128,12 @@
     if (size >= 0 && size < INT32_MAX) {
         *outLen = size;
         const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
-        if (str != NULL) {
+        if (str != nullptr) {
             return str;
         }
     }
     *outLen = 0;
-    return NULL;
+    return nullptr;
 }
 
 status_t Parcel::readStrongBinder(sp<IBinder>* val) const
@@ -2182,13 +2195,13 @@
     int numFds, numInts;
     status_t err;
     err = readInt32(&numFds);
-    if (err != NO_ERROR) return 0;
+    if (err != NO_ERROR) return nullptr;
     err = readInt32(&numInts);
-    if (err != NO_ERROR) return 0;
+    if (err != NO_ERROR) return nullptr;
 
     native_handle* h = native_handle_create(numFds, numInts);
     if (!h) {
-        return 0;
+        return nullptr;
     }
 
     for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
@@ -2198,14 +2211,14 @@
                 close(h->data[j]);
             }
             native_handle_delete(h);
-            return 0;
+            return nullptr;
         }
     }
     err = read(h->data + numFds, sizeof(int)*numInts);
     if (err != NO_ERROR) {
         native_handle_close(h);
         native_handle_delete(h);
-        h = 0;
+        h = nullptr;
     }
     return h;
 }
@@ -2249,6 +2262,22 @@
     return OK;
 }
 
+status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
+{
+    int got = readParcelFileDescriptor();
+
+    if (got == BAD_TYPE) {
+        return BAD_TYPE;
+    }
+
+    val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
+
+    if (val->get() < 0) {
+        return BAD_VALUE;
+    }
+
+    return OK;
+}
 
 status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
     return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
@@ -2278,7 +2307,7 @@
     int fd = readFileDescriptor();
     if (fd == int(BAD_TYPE)) return BAD_VALUE;
 
-    void* ptr = ::mmap(NULL, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
+    void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
             MAP_SHARED, fd, 0);
     if (ptr == MAP_FAILED) return NO_MEMORY;
 
@@ -2300,10 +2329,10 @@
 
     // payload
     void const* const buf = this->readInplace(pad_size(len));
-    if (buf == NULL)
+    if (buf == nullptr)
         return BAD_VALUE;
 
-    int* fds = NULL;
+    int* fds = nullptr;
     if (fd_count) {
         fds = new (std::nothrow) int[fd_count];
         if (fds == nullptr) {
@@ -2394,7 +2423,7 @@
         ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
              this, DPOS);
     }
-    return NULL;
+    return nullptr;
 }
 
 void Parcel::closeFileDescriptors()
@@ -2604,7 +2633,7 @@
     ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
 
     free(mObjects);
-    mObjects = NULL;
+    mObjects = nullptr;
     mObjectsSize = mObjectsCapacity = 0;
     mNextObjectHint = 0;
     mObjectsSorted = false;
@@ -2652,7 +2681,7 @@
             mError = NO_MEMORY;
             return NO_MEMORY;
         }
-        binder_size_t* objects = NULL;
+        binder_size_t* objects = nullptr;
 
         if (objectsSize) {
             objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
@@ -2679,7 +2708,7 @@
         }
         //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
-        mOwner = NULL;
+        mOwner = nullptr;
 
         LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
         pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
@@ -2754,7 +2783,7 @@
             return NO_MEMORY;
         }
 
-        if(!(mDataCapacity == 0 && mObjects == NULL
+        if(!(mDataCapacity == 0 && mObjects == nullptr
              && mObjectsCapacity == 0)) {
             ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
         }
@@ -2779,13 +2808,13 @@
 {
     LOG_ALLOC("Parcel %p: initState", this);
     mError = NO_ERROR;
-    mData = 0;
+    mData = nullptr;
     mDataSize = 0;
     mDataCapacity = 0;
     mDataPos = 0;
     ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
     ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
-    mObjects = NULL;
+    mObjects = nullptr;
     mObjectsSize = 0;
     mObjectsCapacity = 0;
     mNextObjectHint = 0;
@@ -2793,7 +2822,7 @@
     mHasFds = false;
     mFdsKnown = true;
     mAllowFds = true;
-    mOwner = NULL;
+    mOwner = nullptr;
     mOpenAshmemSize = 0;
 
     // racing multiple init leads only to multiple identical write
@@ -2840,7 +2869,7 @@
 // --- Parcel::Blob ---
 
 Parcel::Blob::Blob() :
-        mFd(-1), mData(NULL), mSize(0), mMutable(false) {
+        mFd(-1), mData(nullptr), mSize(0), mMutable(false) {
 }
 
 Parcel::Blob::~Blob() {
@@ -2863,7 +2892,7 @@
 
 void Parcel::Blob::clear() {
     mFd = -1;
-    mData = NULL;
+    mData = nullptr;
     mSize = 0;
     mMutable = false;
 }
diff --git a/libs/binder/ParcelFileDescriptor.cpp b/libs/binder/ParcelFileDescriptor.cpp
new file mode 100644
index 0000000..4f8b76f
--- /dev/null
+++ b/libs/binder/ParcelFileDescriptor.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 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 <binder/ParcelFileDescriptor.h>
+
+namespace android {
+namespace os {
+
+ParcelFileDescriptor::ParcelFileDescriptor() = default;
+
+ParcelFileDescriptor::ParcelFileDescriptor(android::base::unique_fd fd) : mFd(std::move(fd)) {}
+
+ParcelFileDescriptor::~ParcelFileDescriptor() = default;
+
+status_t ParcelFileDescriptor::writeToParcel(Parcel* parcel) const {
+    return parcel->writeDupParcelFileDescriptor(mFd.get());
+}
+
+status_t ParcelFileDescriptor::readFromParcel(const Parcel* parcel) {
+    return parcel->readUniqueParcelFileDescriptor(&mFd);
+}
+
+} // namespace os
+} // namespace android
diff --git a/libs/binder/PermissionCache.cpp b/libs/binder/PermissionCache.cpp
index a503be8..a4c28ad 100644
--- a/libs/binder/PermissionCache.cpp
+++ b/libs/binder/PermissionCache.cpp
@@ -75,7 +75,7 @@
 }
 
 bool PermissionCache::checkCallingPermission(const String16& permission) {
-    return PermissionCache::checkCallingPermission(permission, NULL, NULL);
+    return PermissionCache::checkCallingPermission(permission, nullptr, nullptr);
 }
 
 bool PermissionCache::checkCallingPermission(
diff --git a/libs/binder/PermissionController.cpp b/libs/binder/PermissionController.cpp
index 96df33c..34b2ca5 100644
--- a/libs/binder/PermissionController.cpp
+++ b/libs/binder/PermissionController.cpp
@@ -41,7 +41,7 @@
                 ALOGI("Waiting for permission service");
             } else if ((uptimeMillis() - startTime) > 10000) {
                 ALOGW("Waiting too long for permission service, giving up");
-                service = NULL;
+                service = nullptr;
                 break;
             }
             sleep(1);
@@ -56,13 +56,13 @@
 bool PermissionController::checkPermission(const String16& permission, int32_t pid, int32_t uid)
 {
     sp<IPermissionController> service = getService();
-    return service != NULL ? service->checkPermission(permission, pid, uid) : false;
+    return service != nullptr ? service->checkPermission(permission, pid, uid) : false;
 }
 
 int32_t PermissionController::noteOp(const String16& op, int32_t uid, const String16& packageName)
 {
     sp<IPermissionController> service = getService();
-    return service != NULL ? service->noteOp(op, uid, packageName) : MODE_ERRORED;
+    return service != nullptr ? service->noteOp(op, uid, packageName) : MODE_ERRORED;
 }
 
 void PermissionController::getPackagesForUid(const uid_t uid, Vector<String16> &packages)
diff --git a/libs/binder/ProcessInfoService.cpp b/libs/binder/ProcessInfoService.cpp
index 8939d9c..5cb2033 100644
--- a/libs/binder/ProcessInfoService.cpp
+++ b/libs/binder/ProcessInfoService.cpp
@@ -36,7 +36,7 @@
 
     for (int i = 0; i < BINDER_ATTEMPT_LIMIT; i++) {
 
-        if (pis != NULL) {
+        if (pis != nullptr) {
             err = pis->getProcessStatesFromPids(length, /*in*/ pids, /*out*/ states);
             if (err == NO_ERROR) return NO_ERROR; // success
             if (IInterface::asBinder(pis)->isBinderAlive()) return err;
@@ -68,7 +68,7 @@
 
     for (int i = 0; i < BINDER_ATTEMPT_LIMIT; i++) {
 
-        if (pis != NULL) {
+        if (pis != nullptr) {
             err = pis->getProcessStatesAndOomScoresFromPids(length,
                     /*in*/ pids, /*out*/ states, /*out*/ scores);
             if (err == NO_ERROR) return NO_ERROR; // success
@@ -93,7 +93,7 @@
 
 void ProcessInfoService::updateBinderLocked() {
     const sp<IServiceManager> sm(defaultServiceManager());
-    if (sm != NULL) {
+    if (sm != nullptr) {
         const String16 name("processinfo");
         mProcessInfoService = interface_cast<IProcessInfoService>(sm->checkService(name));
     }
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index d1c6f84..53f8ddd 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -43,6 +43,12 @@
 #define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
 #define DEFAULT_MAX_BINDER_THREADS 15
 
+#ifdef __ANDROID_VNDK__
+const char* kDefaultDriver = "/dev/vndbinder";
+#else
+const char* kDefaultDriver = "/dev/binder";
+#endif
+
 // -------------------------------------------------------------------------
 
 namespace android {
@@ -68,17 +74,17 @@
 sp<ProcessState> ProcessState::self()
 {
     Mutex::Autolock _l(gProcessMutex);
-    if (gProcess != NULL) {
+    if (gProcess != nullptr) {
         return gProcess;
     }
-    gProcess = new ProcessState("/dev/binder");
+    gProcess = new ProcessState(kDefaultDriver);
     return gProcess;
 }
 
 sp<ProcessState> ProcessState::initWithDriver(const char* driver)
 {
     Mutex::Autolock _l(gProcessMutex);
-    if (gProcess != NULL) {
+    if (gProcess != nullptr) {
         // Allow for initWithDriver to be called repeatedly with the same
         // driver.
         if (!strcmp(gProcess->getDriverName().c_str(), driver)) {
@@ -122,18 +128,18 @@
 {
     mLock.lock();
     sp<IBinder> object(
-        mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
+        mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : nullptr);
     mLock.unlock();
     
     //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
     
-    if (object != NULL) return object;
+    if (object != nullptr) return object;
 
     // Don't attempt to retrieve contexts if we manage them
     if (mManagesContexts) {
         ALOGE("getContextObject(%s) failed, but we manage the contexts!\n",
             String8(name).string());
-        return NULL;
+        return nullptr;
     }
     
     IPCThreadState* ipc = IPCThreadState::self();
@@ -150,7 +156,7 @@
     
     ipc->flushCommands();
     
-    if (object != NULL) setContextObject(object, name);
+    if (object != nullptr) setContextObject(object, name);
     return object;
 }
 
@@ -180,8 +186,8 @@
         if (result == 0) {
             mManagesContexts = true;
         } else if (result == -1) {
-            mBinderContextCheckFunc = NULL;
-            mBinderContextUserData = NULL;
+            mBinderContextCheckFunc = nullptr;
+            mBinderContextUserData = nullptr;
             ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
         }
     }
@@ -207,7 +213,7 @@
 
     binder_node_debug_info info = {};
 
-    uintptr_t* end = buf ? buf + buf_count : NULL;
+    uintptr_t* end = buf ? buf + buf_count : nullptr;
     size_t count = 0;
 
     do {
@@ -233,10 +239,10 @@
     const size_t N=mHandleToObject.size();
     if (N <= (size_t)handle) {
         handle_entry e;
-        e.binder = NULL;
-        e.refs = NULL;
+        e.binder = nullptr;
+        e.refs = nullptr;
         status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
-        if (err < NO_ERROR) return NULL;
+        if (err < NO_ERROR) return nullptr;
     }
     return &mHandleToObject.editItemAt(handle);
 }
@@ -249,12 +255,12 @@
 
     handle_entry* e = lookupHandleLocked(handle);
 
-    if (e != NULL) {
+    if (e != nullptr) {
         // We need to create a new BpBinder if there isn't currently one, OR we
         // are unable to acquire a weak reference on this current one.  See comment
         // in getWeakProxyForHandle() for more info about this.
         IBinder* b = e->binder;
-        if (b == NULL || !e->refs->attemptIncWeak(this)) {
+        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
             if (handle == 0) {
                 // Special case for context manager...
                 // The context manager is the only object for which we create
@@ -277,9 +283,9 @@
 
                 Parcel data;
                 status_t status = IPCThreadState::self()->transact(
-                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
+                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);
                 if (status == DEAD_OBJECT)
-                   return NULL;
+                   return nullptr;
             }
 
             b = BpBinder::create(handle);
@@ -306,7 +312,7 @@
 
     handle_entry* e = lookupHandleLocked(handle);
 
-    if (e != NULL) {        
+    if (e != nullptr) {        
         // We need to create a new BpBinder if there isn't currently one, OR we
         // are unable to acquire a weak reference on this current one.  The
         // attemptIncWeak() is safe because we know the BpBinder destructor will always
@@ -315,7 +321,7 @@
         // releasing a reference on this BpBinder, and a new reference on its handle
         // arriving from the driver.
         IBinder* b = e->binder;
-        if (b == NULL || !e->refs->attemptIncWeak(this)) {
+        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
             b = BpBinder::create(handle);
             result = b;
             e->binder = b;
@@ -338,7 +344,7 @@
     // This handle may have already been replaced with a new BpBinder
     // (if someone failed the AttemptIncWeak() above); we don't want
     // to overwrite it.
-    if (e && e->binder == binder) e->binder = NULL;
+    if (e && e->binder == binder) e->binder = nullptr;
 }
 
 String8 ProcessState::makeBinderThreadName() {
@@ -416,14 +422,14 @@
     , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
     , mStarvationStartTimeMs(0)
     , mManagesContexts(false)
-    , mBinderContextCheckFunc(NULL)
-    , mBinderContextUserData(NULL)
+    , mBinderContextCheckFunc(nullptr)
+    , mBinderContextUserData(nullptr)
     , mThreadPoolStarted(false)
     , mThreadPoolSeq(1)
 {
     if (mDriverFD >= 0) {
         // mmap the binder, providing a chunk of virtual address space to receive transactions.
-        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
+        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
         if (mVMStart == MAP_FAILED) {
             // *sigh*
             ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
index d6d0340..bd0e6f9 100644
--- a/libs/binder/Static.cpp
+++ b/libs/binder/Static.cpp
@@ -75,21 +75,6 @@
 Mutex& gProcessMutex = *new Mutex;
 sp<ProcessState> gProcess;
 
-class LibBinderIPCtStatics
-{
-public:
-    LibBinderIPCtStatics()
-    {
-    }
-    
-    ~LibBinderIPCtStatics()
-    {
-        IPCThreadState::shutdown();
-    }
-};
-
-static LibBinderIPCtStatics gIPCStatics;
-
 // ------------ IServiceManager.cpp
 
 Mutex gDefaultServiceManagerLock;
diff --git a/libs/binder/Value.cpp b/libs/binder/Value.cpp
index 85cd739..a28a618 100644
--- a/libs/binder/Value.cpp
+++ b/libs/binder/Value.cpp
@@ -143,12 +143,12 @@
 
 // ====================================================================
 
-Value::Value() : mContent(NULL)
+Value::Value() : mContent(nullptr)
 {
 }
 
 Value::Value(const Value& value)
-    : mContent(value.mContent ? value.mContent->clone() : NULL)
+    : mContent(value.mContent ? value.mContent->clone() : nullptr)
 {
 }
 
@@ -165,8 +165,8 @@
         return true;
     }
 
-    if ( (lhs.mContent == NULL)
-      || (rhs.mContent == NULL)
+    if ( (lhs.mContent == nullptr)
+      || (rhs.mContent == nullptr)
     ) {
         return false;
     }
@@ -186,25 +186,25 @@
         delete mContent;
         mContent = rhs.mContent
             ? rhs.mContent->clone()
-            : NULL;
+            : nullptr;
     }
     return *this;
 }
 
 bool Value::empty() const
 {
-    return mContent == NULL;
+    return mContent == nullptr;
 }
 
 void Value::clear()
 {
     delete mContent;
-    mContent = NULL;
+    mContent = nullptr;
 }
 
 int32_t Value::parcelType() const
 {
-    const void* t_info(mContent ? mContent->type_ptr() : NULL);
+    const void* t_info(mContent ? mContent->type_ptr() : nullptr);
 
     if (t_info == internal_type_ptr<bool>()) return VAL_BOOLEAN;
     if (t_info == internal_type_ptr<uint8_t>()) return VAL_BYTE;
@@ -229,7 +229,7 @@
 #ifdef LIBBINDER_VALUE_SUPPORTS_TYPE_INFO
 const std::type_info& Value::type() const
 {
-    return mContent != NULL
+    return mContent != nullptr
         ? mContent->type()
         : typeid(void);
 }
@@ -306,7 +306,7 @@
 
 #define BEGIN_HANDLE_WRITE()                                                                      \
     do {                                                                                          \
-        const void* t_info(mContent?mContent->type_ptr():NULL);                                   \
+        const void* t_info(mContent?mContent->type_ptr():nullptr);                                \
         if (false) { }
 #define HANDLE_WRITE_TYPE(T, TYPEVAL, TYPEMETHOD)                                                 \
     else if (t_info == internal_type_ptr<T>()) {                                                  \
@@ -381,7 +381,7 @@
     int32_t value_type = VAL_NULL;
 
     delete mContent;
-    mContent = NULL;
+    mContent = nullptr;
 
     RETURN_IF_FAILED(parcel->readInt32(&value_type));
 
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 3404881..0b60b4e 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -40,13 +40,13 @@
                                     uint32_t flags = 0);
 
     virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
-                                    void* cookie = NULL,
+                                    void* cookie = nullptr,
                                     uint32_t flags = 0);
 
     virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
-                                        void* cookie = NULL,
+                                        void* cookie = nullptr,
                                         uint32_t flags = 0,
-                                        wp<DeathRecipient>* outRecipient = NULL);
+                                        wp<DeathRecipient>* outRecipient = nullptr);
 
     virtual void        attachObject(   const void* objectID,
                                         void* object,
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 8bd297b..c4c8ba3 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -47,12 +47,12 @@
                                     uint32_t flags = 0);
 
     virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
-                                    void* cookie = NULL,
+                                    void* cookie = nullptr,
                                     uint32_t flags = 0);
     virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
-                                        void* cookie = NULL,
+                                        void* cookie = nullptr,
                                         uint32_t flags = 0,
-                                        wp<DeathRecipient>* outRecipient = NULL);
+                                        wp<DeathRecipient>* outRecipient = nullptr);
 
     virtual void        attachObject(   const void* objectID,
                                         void* object,
diff --git a/libs/binder/include/binder/Debug.h b/libs/binder/include/binder/Debug.h
index be0266c..58e2b32 100644
--- a/libs/binder/include/binder/Debug.h
+++ b/libs/binder/include/binder/Debug.h
@@ -31,12 +31,12 @@
 typedef void (*debugPrintFunc)(void* cookie, const char* txt);
 
 void printTypeCode(uint32_t typeCode,
-    debugPrintFunc func = 0, void* cookie = 0);
+    debugPrintFunc func = nullptr, void* cookie = nullptr);
 
 void printHexData(int32_t indent, const void *buf, size_t length,
     size_t bytesPerLine=16, int32_t singleLineBytesCutoff=16,
     size_t alignment=0, bool cArrayStyle=false,
-    debugPrintFunc func = 0, void* cookie = 0);
+    debugPrintFunc func = nullptr, void* cookie = nullptr);
 
 
 ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf);
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 2e62957..318070a 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -132,7 +132,7 @@
      * directly do with it now that it has passed on.)
      */
     virtual status_t        linkToDeath(const sp<DeathRecipient>& recipient,
-                                        void* cookie = NULL,
+                                        void* cookie = nullptr,
                                         uint32_t flags = 0) = 0;
 
     /**
@@ -143,9 +143,9 @@
      * added with that cookie will be unlinked.
      */
     virtual status_t        unlinkToDeath(  const wp<DeathRecipient>& recipient,
-                                            void* cookie = NULL,
+                                            void* cookie = nullptr,
                                             uint32_t flags = 0,
-                                            wp<DeathRecipient>* outRecipient = NULL) = 0;
+                                            wp<DeathRecipient>* outRecipient = nullptr) = 0;
 
     virtual bool            checkSubclass(const void* subclassID) const;
 
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index 0f1fe5b..5ec02b1 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -72,12 +72,18 @@
 // ----------------------------------------------------------------------
 
 #define DECLARE_META_INTERFACE(INTERFACE)                               \
+public:                                                                 \
     static const ::android::String16 descriptor;                        \
     static ::android::sp<I##INTERFACE> asInterface(                     \
             const ::android::sp<::android::IBinder>& obj);              \
     virtual const ::android::String16& getInterfaceDescriptor() const;  \
     I##INTERFACE();                                                     \
     virtual ~I##INTERFACE();                                            \
+    static bool setDefaultImpl(std::unique_ptr<I##INTERFACE> impl);     \
+    static const std::unique_ptr<I##INTERFACE>& getDefaultImpl();       \
+private:                                                                \
+    static std::unique_ptr<I##INTERFACE> default_impl;                  \
+public:                                                                 \
 
 
 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
@@ -90,16 +96,29 @@
             const ::android::sp<::android::IBinder>& obj)               \
     {                                                                   \
         ::android::sp<I##INTERFACE> intr;                               \
-        if (obj != NULL) {                                              \
+        if (obj != nullptr) {                                           \
             intr = static_cast<I##INTERFACE*>(                          \
                 obj->queryLocalInterface(                               \
                         I##INTERFACE::descriptor).get());               \
-            if (intr == NULL) {                                         \
+            if (intr == nullptr) {                                      \
                 intr = new Bp##INTERFACE(obj);                          \
             }                                                           \
         }                                                               \
         return intr;                                                    \
     }                                                                   \
+    std::unique_ptr<I##INTERFACE> I##INTERFACE::default_impl;           \
+    bool I##INTERFACE::setDefaultImpl(std::unique_ptr<I##INTERFACE> impl)\
+    {                                                                   \
+        if (!I##INTERFACE::default_impl && impl) {                      \
+            I##INTERFACE::default_impl = std::move(impl);               \
+            return true;                                                \
+        }                                                               \
+        return false;                                                   \
+    }                                                                   \
+    const std::unique_ptr<I##INTERFACE>& I##INTERFACE::getDefaultImpl() \
+    {                                                                   \
+        return I##INTERFACE::default_impl;                              \
+    }                                                                   \
     I##INTERFACE::I##INTERFACE() { }                                    \
     I##INTERFACE::~I##INTERFACE() { }                                   \
 
@@ -116,7 +135,7 @@
         const String16& _descriptor)
 {
     if (_descriptor == INTERFACE::descriptor) return this;
-    return NULL;
+    return nullptr;
 }
 
 template<typename INTERFACE>
@@ -142,7 +161,7 @@
 {
     return remote();
 }
-    
+
 // ----------------------------------------------------------------------
 
 }; // namespace android
diff --git a/libs/binder/include/binder/IMemory.h b/libs/binder/include/binder/IMemory.h
index 15a104f..3099bf5 100644
--- a/libs/binder/include/binder/IMemory.h
+++ b/libs/binder/include/binder/IMemory.h
@@ -72,7 +72,7 @@
 public:
     DECLARE_META_INTERFACE(Memory)
 
-    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const = 0;
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset=nullptr, size_t* size=nullptr) const = 0;
 
     // helpers
     void* fastPointer(const sp<IBinder>& heap, ssize_t offset) const;
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index c1d9a9a..dce3f38 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -95,7 +95,7 @@
 
             status_t            sendReply(const Parcel& reply, uint32_t flags);
             status_t            waitForResponse(Parcel *reply,
-                                                status_t *acquireResult=NULL);
+                                                status_t *acquireResult=nullptr);
             status_t            talkWithDriver(bool doReceive=true);
             status_t            writeTransactionData(int32_t cmd,
                                                      uint32_t binderFlags,
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 197026d..a998529 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -84,7 +84,7 @@
 status_t getService(const String16& name, sp<INTERFACE>* outService)
 {
     const sp<IServiceManager> sm = defaultServiceManager();
-    if (sm != NULL) {
+    if (sm != nullptr) {
         *outService = interface_cast<INTERFACE>(sm->getService(name));
         if ((*outService) != NULL) return NO_ERROR;
     }
diff --git a/libs/binder/include/binder/MemoryDealer.h b/libs/binder/include/binder/MemoryDealer.h
index 60a624c..fe5a31d 100644
--- a/libs/binder/include/binder/MemoryDealer.h
+++ b/libs/binder/include/binder/MemoryDealer.h
@@ -34,7 +34,7 @@
 class MemoryDealer : public RefBase
 {
 public:
-    MemoryDealer(size_t size, const char* name = 0,
+    MemoryDealer(size_t size, const char* name = nullptr,
             uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ );
 
     virtual sp<IMemory> allocate(size_t size);
diff --git a/libs/binder/include/binder/MemoryHeapBase.h b/libs/binder/include/binder/MemoryHeapBase.h
index ea9b66c..5e0a382 100644
--- a/libs/binder/include/binder/MemoryHeapBase.h
+++ b/libs/binder/include/binder/MemoryHeapBase.h
@@ -52,7 +52,7 @@
     /*
      * maps memory from ashmem, with the given name for debugging
      */
-    MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = NULL);
+    MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = nullptr);
 
     virtual ~MemoryHeapBase();
 
@@ -74,7 +74,7 @@
     /* this is only needed as a workaround, use only if you know
      * what you are doing */
     status_t setDevice(const char* device) {
-        if (mDevice == 0)
+        if (mDevice == nullptr)
             mDevice = device;
         return mDevice ? NO_ERROR : ALREADY_EXISTS;
     }
@@ -83,7 +83,7 @@
             MemoryHeapBase();
     // init() takes ownership of fd
     status_t init(int fd, void *base, int size,
-            int flags = 0, const char* device = NULL);
+            int flags = 0, const char* device = nullptr);
 
 private:
     status_t mapfd(int fd, size_t size, uint32_t offset = 0);
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index dede78f..c9c273a 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -91,7 +91,7 @@
     // IPCThreadState, which as an optimization may optionally be
     // passed in.
     bool                enforceInterface(const String16& interface,
-                                         IPCThreadState* threadState = NULL) const;
+                                         IPCThreadState* threadState = nullptr) const;
     bool                checkInterface(IBinder*) const;
 
     void                freeData();
@@ -205,6 +205,10 @@
     // The Parcel does not take ownership of the given fd unless you ask it to.
     status_t            writeParcelFileDescriptor(int fd, bool takeOwnership = false);
 
+    // Place a Java "parcel file descriptor" into the parcel.  A dup of the fd is made, which will
+    // be closed once the parcel is destroyed.
+    status_t            writeDupParcelFileDescriptor(int fd);
+
     // Place a file descriptor into the parcel.  This will not affect the
     // semantics of the smart file descriptor. A new descriptor will be
     // created, and will be closed when the parcel is destroyed.
@@ -364,6 +368,9 @@
     status_t            readUniqueFileDescriptor(
                             base::unique_fd* val) const;
 
+    // Retrieve a Java "parcel file descriptor" from the parcel.
+    status_t            readUniqueParcelFileDescriptor(base::unique_fd* val) const;
+
 
     // Retrieve a vector of smart file descriptors from the parcel.
     status_t            readUniqueFileDescriptorVector(
@@ -547,7 +554,7 @@
         friend class Parcel;
     public:
         inline const void* data() const { return mData; }
-        inline void* mutableData() { return isMutable() ? mData : NULL; }
+        inline void* mutableData() { return isMutable() ? mData : nullptr; }
     };
 
     class WritableBlob : public Blob {
@@ -587,7 +594,7 @@
     }
     if (size) {
         void* buffer = writeInplace(size);
-        if (buffer == NULL)
+        if (buffer == nullptr)
             return NO_MEMORY;
         return val.flatten(buffer, size);
     }
@@ -615,7 +622,7 @@
     }
     if (size) {
         void const* buffer = readInplace(size);
-        return buffer == NULL ? NO_MEMORY :
+        return buffer == nullptr ? NO_MEMORY :
                 val.unflatten(buffer, size);
     }
     return NO_ERROR;
diff --git a/libs/binder/include/binder/ParcelFileDescriptor.h b/libs/binder/include/binder/ParcelFileDescriptor.h
new file mode 100644
index 0000000..455462b
--- /dev/null
+++ b/libs/binder/include/binder/ParcelFileDescriptor.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef ANDROID_PARCEL_FILE_DESCRIPTOR_H_
+#define ANDROID_PARCEL_FILE_DESCRIPTOR_H_
+
+#include <android-base/unique_fd.h>
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+
+namespace android {
+namespace os {
+
+/*
+ * C++ implementation of the Java class android.os.ParcelFileDescriptor
+ */
+class ParcelFileDescriptor : public android::Parcelable {
+public:
+    ParcelFileDescriptor();
+    explicit ParcelFileDescriptor(android::base::unique_fd fd);
+    ~ParcelFileDescriptor() override;
+
+    int get() const { return mFd.get(); }
+    android::base::unique_fd release() { return std::move(mFd); }
+    void reset(android::base::unique_fd fd = android::base::unique_fd()) { mFd = std::move(fd); }
+
+    // android::Parcelable override:
+    android::status_t writeToParcel(android::Parcel* parcel) const override;
+    android::status_t readFromParcel(const android::Parcel* parcel) override;
+
+private:
+    android::base::unique_fd mFd;
+};
+
+} // namespace os
+} // namespace android
+
+#endif // ANDROID_OS_PARCEL_FILE_DESCRIPTOR_H_
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index f85c261..13f67ba 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -36,9 +36,12 @@
 public:
     static  sp<ProcessState>    self();
     static  sp<ProcessState>    selfOrNull();
+
     /* initWithDriver() can be used to configure libbinder to use
      * a different binder driver dev node. It must be called *before*
-     * any call to ProcessState::self(). /dev/binder remains the default.
+     * any call to ProcessState::self(). The default is /dev/vndbinder
+     * for processes built with the VNDK and /dev/binder for those
+     * which are not.
      */
     static  sp<ProcessState>    initWithDriver(const char *driver);
 
diff --git a/libs/binder/tests/binderDriverInterfaceTest.cpp b/libs/binder/tests/binderDriverInterfaceTest.cpp
index 4f00bc1..77ebac8 100644
--- a/libs/binder/tests/binderDriverInterfaceTest.cpp
+++ b/libs/binder/tests/binderDriverInterfaceTest.cpp
@@ -36,8 +36,8 @@
 
             m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
             ASSERT_GE(m_binderFd, 0);
-            m_buffer = mmap(NULL, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
-            ASSERT_NE(m_buffer, (void *)NULL);
+            m_buffer = mmap(nullptr, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
+            ASSERT_NE(m_buffer, (void *)nullptr);
             ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
             EXPECT_EQ(0, ret);
             EnterLooper();
@@ -156,23 +156,23 @@
 }
 
 TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
-    binderTestIoctlErr1(BINDER_WRITE_READ, NULL, EFAULT);
+    binderTestIoctlErr1(BINDER_WRITE_READ, nullptr, EFAULT);
 }
 
 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
-    binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, NULL, EFAULT, EINVAL);
+    binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, nullptr, EFAULT, EINVAL);
 }
 
 TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
-    binderTestIoctlErr2(BINDER_SET_MAX_THREADS, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
+    binderTestIoctlErr2(BINDER_SET_MAX_THREADS, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
 }
 
 TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
-    binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, NULL, EFAULT, EINVAL);
+    binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, nullptr, EFAULT, EINVAL);
 }
 
 TEST_F(BinderDriverInterfaceTest, VersionNull) {
-    binderTestIoctlErr2(BINDER_VERSION, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
+    binderTestIoctlErr2(BINDER_VERSION, nullptr, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
 }
 
 TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 1611e11..73c2eba 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -65,6 +65,7 @@
     BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION,
     BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
     BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
+    BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION,
     BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION,
     BINDER_LIB_TEST_EXIT_TRANSACTION,
     BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
@@ -88,7 +89,7 @@
         strpipefd1,
         usepoll,
         binderserversuffix,
-        NULL
+        nullptr
     };
 
     ret = pipe(pipefd);
@@ -123,7 +124,7 @@
         }
     }
     if (ret < 0) {
-        wait(NULL);
+        wait(nullptr);
         return ret;
     }
     return pid;
@@ -145,7 +146,7 @@
             sp<IServiceManager> sm = defaultServiceManager();
             //printf("%s: pid %d, get service\n", __func__, m_pid);
             m_server = sm->getService(binderLibTestServiceName);
-            ASSERT_TRUE(m_server != NULL);
+            ASSERT_TRUE(m_server != nullptr);
             //printf("%s: pid %d, get service done\n", __func__, m_pid);
         }
         virtual void TearDown() {
@@ -155,7 +156,7 @@
             pid_t pid;
 
             //printf("%s: pid %d\n", __func__, m_pid);
-            if (m_server != NULL) {
+            if (m_server != nullptr) {
                 ret = m_server->transact(BINDER_LIB_TEST_GET_STATUS_TRANSACTION, data, &reply);
                 EXPECT_EQ(0, ret);
                 ret = m_server->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
@@ -192,9 +193,9 @@
             ret = m_server->transact(code, data, &reply);
             EXPECT_EQ(NO_ERROR, ret);
 
-            EXPECT_FALSE(binder != NULL);
+            EXPECT_FALSE(binder != nullptr);
             binder = reply.readStrongBinder();
-            EXPECT_TRUE(binder != NULL);
+            EXPECT_TRUE(binder != nullptr);
             ret = reply.readInt32(&id);
             EXPECT_EQ(NO_ERROR, ret);
             if (idPtr)
@@ -202,12 +203,12 @@
             return binder;
         }
 
-        sp<IBinder> addServer(int32_t *idPtr = NULL)
+        sp<IBinder> addServer(int32_t *idPtr = nullptr)
         {
             return addServerEtc(idPtr, BINDER_LIB_TEST_ADD_SERVER);
         }
 
-        sp<IBinder> addPollServer(int32_t *idPtr = NULL)
+        sp<IBinder> addPollServer(int32_t *idPtr = nullptr)
         {
             return addServerEtc(idPtr, BINDER_LIB_TEST_ADD_POLL_SERVER);
         }
@@ -274,8 +275,8 @@
         BinderLibTestEvent(void)
             : m_eventTriggered(false)
         {
-            pthread_mutex_init(&m_waitMutex, NULL);
-            pthread_cond_init(&m_waitCond, NULL);
+            pthread_mutex_init(&m_waitMutex, nullptr);
+            pthread_cond_init(&m_waitCond, nullptr);
         }
         int waitEvent(int timeout_s)
         {
@@ -315,7 +316,7 @@
     public:
         BinderLibTestCallBack()
             : m_result(NOT_ENOUGH_DATA)
-            , m_prev_end(NULL)
+            , m_prev_end(nullptr)
         {
         }
         status_t getResult(void)
@@ -413,7 +414,7 @@
     int32_t ptrsize;
     Parcel data, reply;
     sp<IBinder> server = addServer();
-    ASSERT_TRUE(server != NULL);
+    ASSERT_TRUE(server != nullptr);
     ret = server->transact(BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION, data, &reply);
     EXPECT_EQ(NO_ERROR, ret);
     ret = reply.readInt32(&ptrsize);
@@ -436,7 +437,7 @@
         BinderLibTestBundle datai;
 
         server = addServer(&serverId[i]);
-        ASSERT_TRUE(server != NULL);
+        ASSERT_TRUE(server != nullptr);
         data.writeStrongBinder(server);
         data.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
         datai.appendTo(&data);
@@ -480,7 +481,7 @@
         BinderLibTestBundle datai2;
 
         server = addServer(&serverId[i]);
-        ASSERT_TRUE(server != NULL);
+        ASSERT_TRUE(server != nullptr);
         data.writeStrongBinder(server);
         data.writeInt32(BINDER_LIB_TEST_INDIRECT_TRANSACTION);
 
@@ -546,7 +547,7 @@
 TEST_F(BinderLibTest, AddServer)
 {
     sp<IBinder> server = addServer();
-    ASSERT_TRUE(server != NULL);
+    ASSERT_TRUE(server != nullptr);
 }
 
 TEST_F(BinderLibTest, DeathNotificationNoRefs)
@@ -557,7 +558,7 @@
 
     {
         sp<IBinder> binder = addServer();
-        ASSERT_TRUE(binder != NULL);
+        ASSERT_TRUE(binder != nullptr);
         ret = binder->linkToDeath(testDeathRecipient);
         EXPECT_EQ(NO_ERROR, ret);
     }
@@ -579,7 +580,7 @@
 
     {
         sp<IBinder> binder = addServer();
-        ASSERT_TRUE(binder != NULL);
+        ASSERT_TRUE(binder != nullptr);
         ret = binder->linkToDeath(testDeathRecipient);
         EXPECT_EQ(NO_ERROR, ret);
         wbinder = binder;
@@ -602,7 +603,7 @@
 
     {
         sp<IBinder> binder = addServer();
-        ASSERT_TRUE(binder != NULL);
+        ASSERT_TRUE(binder != nullptr);
         ret = binder->linkToDeath(testDeathRecipient);
         EXPECT_EQ(NO_ERROR, ret);
         sbinder = binder;
@@ -629,13 +630,13 @@
     sp<IBinder> passiveclient[clientcount];
 
     target = addServer();
-    ASSERT_TRUE(target != NULL);
+    ASSERT_TRUE(target != nullptr);
     for (int i = 0; i < clientcount; i++) {
         {
             Parcel data, reply;
 
             linkedclient[i] = addServer();
-            ASSERT_TRUE(linkedclient[i] != NULL);
+            ASSERT_TRUE(linkedclient[i] != nullptr);
             callBack[i] = new BinderLibTestCallBack();
             data.writeStrongBinder(target);
             data.writeStrongBinder(callBack[i]);
@@ -646,7 +647,7 @@
             Parcel data, reply;
 
             passiveclient[i] = addServer();
-            ASSERT_TRUE(passiveclient[i] != NULL);
+            ASSERT_TRUE(passiveclient[i] != nullptr);
             data.writeStrongBinder(target);
             ret = passiveclient[i]->transact(BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION, data, &reply, TF_ONE_WAY);
             EXPECT_EQ(NO_ERROR, ret);
@@ -671,9 +672,9 @@
     status_t ret;
     sp<BinderLibTestCallBack> callback;
     sp<IBinder> target = addServer();
-    ASSERT_TRUE(target != NULL);
+    ASSERT_TRUE(target != nullptr);
     sp<IBinder> client = addServer();
-    ASSERT_TRUE(client != NULL);
+    ASSERT_TRUE(client != nullptr);
 
     sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
 
@@ -763,16 +764,51 @@
     close(pipefd[0]);
 }
 
+TEST_F(BinderLibTest, PassParcelFileDescriptor) {
+    const int datasize = 123;
+    std::vector<uint8_t> writebuf(datasize);
+    for (size_t i = 0; i < writebuf.size(); ++i) {
+        writebuf[i] = i;
+    }
+
+    android::base::unique_fd read_end, write_end;
+    {
+        int pipefd[2];
+        ASSERT_EQ(0, pipe2(pipefd, O_NONBLOCK));
+        read_end.reset(pipefd[0]);
+        write_end.reset(pipefd[1]);
+    }
+    {
+        Parcel data;
+        EXPECT_EQ(NO_ERROR, data.writeDupParcelFileDescriptor(write_end.get()));
+        write_end.reset();
+        EXPECT_EQ(NO_ERROR, data.writeInt32(datasize));
+        EXPECT_EQ(NO_ERROR, data.write(writebuf.data(), datasize));
+
+        Parcel reply;
+        EXPECT_EQ(NO_ERROR,
+                  m_server->transact(BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION, data,
+                                     &reply));
+    }
+    std::vector<uint8_t> readbuf(datasize);
+    EXPECT_EQ(datasize, read(read_end.get(), readbuf.data(), datasize));
+    EXPECT_EQ(writebuf, readbuf);
+
+    waitForReadData(read_end.get(), 5000); /* wait for other proccess to close pipe */
+
+    EXPECT_EQ(0, read(read_end.get(), readbuf.data(), datasize));
+}
+
 TEST_F(BinderLibTest, PromoteLocal) {
     sp<IBinder> strong = new BBinder();
     wp<IBinder> weak = strong;
     sp<IBinder> strong_from_weak = weak.promote();
-    EXPECT_TRUE(strong != NULL);
+    EXPECT_TRUE(strong != nullptr);
     EXPECT_EQ(strong, strong_from_weak);
-    strong = NULL;
-    strong_from_weak = NULL;
+    strong = nullptr;
+    strong_from_weak = nullptr;
     strong_from_weak = weak.promote();
-    EXPECT_TRUE(strong_from_weak == NULL);
+    EXPECT_TRUE(strong_from_weak == nullptr);
 }
 
 TEST_F(BinderLibTest, PromoteRemote) {
@@ -781,8 +817,8 @@
     sp<IBinder> strong = new BBinder();
     sp<IBinder> server = addServer();
 
-    ASSERT_TRUE(server != NULL);
-    ASSERT_TRUE(strong != NULL);
+    ASSERT_TRUE(server != nullptr);
+    ASSERT_TRUE(strong != nullptr);
 
     ret = data.writeWeakBinder(strong);
     EXPECT_EQ(NO_ERROR, ret);
@@ -799,7 +835,7 @@
     EXPECT_EQ(NO_ERROR, ret);
 
     const flat_binder_object *fb = reply.readObject(false);
-    ASSERT_TRUE(fb != NULL);
+    ASSERT_TRUE(fb != nullptr);
     EXPECT_EQ(BINDER_TYPE_HANDLE, fb->hdr.type);
     EXPECT_EQ(m_server, ProcessState::self()->getStrongProxyForHandle(fb->handle));
     EXPECT_EQ((binder_uintptr_t)0, fb->cookie);
@@ -810,7 +846,7 @@
     status_t ret;
 
     sp<IBinder> server = addServer();
-    ASSERT_TRUE(server != NULL);
+    ASSERT_TRUE(server != nullptr);
 
     __u32 freedHandle;
     wp<IBinder> keepFreedBinder;
@@ -881,12 +917,12 @@
     data2.writeStrongBinder(callBack2);
     data2.writeInt32(0); // delay in us
 
-    ret = pollServer->transact(BINDER_LIB_TEST_DELAYED_CALL_BACK, data, NULL, TF_ONE_WAY);
+    ret = pollServer->transact(BINDER_LIB_TEST_DELAYED_CALL_BACK, data, nullptr, TF_ONE_WAY);
     EXPECT_EQ(NO_ERROR, ret);
 
     // The delay ensures that this second transaction will end up on the async_todo list
     // (for a single-threaded server)
-    ret = pollServer->transact(BINDER_LIB_TEST_DELAYED_CALL_BACK, data2, NULL, TF_ONE_WAY);
+    ret = pollServer->transact(BINDER_LIB_TEST_DELAYED_CALL_BACK, data2, nullptr, TF_ONE_WAY);
     EXPECT_EQ(NO_ERROR, ret);
 
     // The server will ensure that the two transactions are handled in the expected order;
@@ -909,10 +945,10 @@
             : m_id(id)
             , m_nextServerId(id + 1)
             , m_serverStartRequested(false)
-            , m_callback(NULL)
+            , m_callback(nullptr)
         {
-            pthread_mutex_init(&m_serverWaitMutex, NULL);
-            pthread_cond_init(&m_serverWaitCond, NULL);
+            pthread_mutex_init(&m_serverWaitMutex, nullptr);
+            pthread_cond_init(&m_serverWaitCond, nullptr);
         }
         ~BinderLibTestService()
         {
@@ -920,11 +956,11 @@
         }
 
         void processPendingCall() {
-            if (m_callback != NULL) {
+            if (m_callback != nullptr) {
                 Parcel data;
                 data.writeInt32(NO_ERROR);
                 m_callback->transact(BINDER_LIB_TEST_CALL_BACK, data, nullptr, TF_ONE_WAY);
-                m_callback = NULL;
+                m_callback = nullptr;
             }
         }
 
@@ -943,7 +979,7 @@
                 sp<IBinder> binder;
                 id = data.readInt32();
                 binder = data.readStrongBinder();
-                if (binder == NULL) {
+                if (binder == nullptr) {
                     return BAD_VALUE;
                 }
 
@@ -993,7 +1029,7 @@
                     } else {
                         reply->writeStrongBinder(m_serverStarted);
                         reply->writeInt32(serverid);
-                        m_serverStarted = NULL;
+                        m_serverStarted = nullptr;
                         ret = NO_ERROR;
                     }
                 } else if (ret >= 0) {
@@ -1008,7 +1044,7 @@
             case BINDER_LIB_TEST_DELAYED_CALL_BACK: {
                 // Note: this transaction is only designed for use with a
                 // poll() server. See comments around epoll_wait().
-                if (m_callback != NULL) {
+                if (m_callback != nullptr) {
                     // A callback was already pending; this means that
                     // we received a second call while still processing
                     // the first one. Fail the test.
@@ -1016,7 +1052,7 @@
                     Parcel data2;
                     data2.writeInt32(UNKNOWN_ERROR);
 
-                    callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, NULL, TF_ONE_WAY);
+                    callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, nullptr, TF_ONE_WAY);
                 } else {
                     m_callback = data.readStrongBinder();
                     int32_t delayUs = data.readInt32();
@@ -1045,7 +1081,7 @@
                 Parcel data2, reply2;
                 sp<IBinder> binder;
                 binder = data.readStrongBinder();
-                if (binder == NULL) {
+                if (binder == nullptr) {
                     return BAD_VALUE;
                 }
                 data2.writeInt32(NO_ERROR);
@@ -1068,7 +1104,7 @@
                 reply->writeInt32(count);
                 for (int i = 0; i < count; i++) {
                     binder = data.readStrongBinder();
-                    if (binder == NULL) {
+                    if (binder == nullptr) {
                         return BAD_VALUE;
                     }
                     indirect_code = data.readInt32();
@@ -1101,11 +1137,11 @@
                 sp<IBinder> callback;
 
                 target = data.readStrongBinder();
-                if (target == NULL) {
+                if (target == nullptr) {
                     return BAD_VALUE;
                 }
                 callback = data.readStrongBinder();
-                if (callback == NULL) {
+                if (callback == nullptr) {
                     return BAD_VALUE;
                 }
                 ret = target->linkToDeath(testDeathRecipient);
@@ -1130,7 +1166,7 @@
                     return ret;
                 }
                 buf = data.readInplace(size);
-                if (buf == NULL) {
+                if (buf == nullptr) {
                     return BAD_VALUE;
                 }
                 ret = write(fd, buf, size);
@@ -1138,6 +1174,28 @@
                     return UNKNOWN_ERROR;
                 return NO_ERROR;
             }
+            case BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION: {
+                int ret;
+                int32_t size;
+                const void *buf;
+                android::base::unique_fd fd;
+
+                ret = data.readUniqueParcelFileDescriptor(&fd);
+                if (ret != NO_ERROR) {
+                    return ret;
+                }
+                ret = data.readInt32(&size);
+                if (ret != NO_ERROR) {
+                    return ret;
+                }
+                buf = data.readInplace(size);
+                if (buf == nullptr) {
+                    return BAD_VALUE;
+                }
+                ret = write(fd.get(), buf, size);
+                if (ret != size) return UNKNOWN_ERROR;
+                return NO_ERROR;
+            }
             case BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION: {
                 int ret;
                 wp<IBinder> weak;
@@ -1147,7 +1205,7 @@
                 sp<IBinder> server = sm->getService(binderLibTestServiceName);
 
                 weak = data.readWeakBinder();
-                if (weak == NULL) {
+                if (weak == nullptr) {
                     return BAD_VALUE;
                 }
                 strong = weak.promote();
@@ -1156,7 +1214,7 @@
                 if (ret != NO_ERROR)
                     exit(EXIT_FAILURE);
 
-                if (strong == NULL) {
+                if (strong == nullptr) {
                     reply->setError(1);
                 }
                 return NO_ERROR;
@@ -1165,7 +1223,7 @@
                 alarm(10);
                 return NO_ERROR;
             case BINDER_LIB_TEST_EXIT_TRANSACTION:
-                while (wait(NULL) != -1 || errno != ECHILD)
+                while (wait(nullptr) != -1 || errno != ECHILD)
                     ;
                 exit(EXIT_SUCCESS);
             case BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION: {
@@ -1300,4 +1358,3 @@
     ProcessState::self()->startThreadPool();
     return RUN_ALL_TESTS();
 }
-
diff --git a/libs/binder/tests/binderThroughputTest.cpp b/libs/binder/tests/binderThroughputTest.cpp
index bf41e0b..b790997 100644
--- a/libs/binder/tests/binderThroughputTest.cpp
+++ b/libs/binder/tests/binderThroughputTest.cpp
@@ -380,7 +380,7 @@
             // Caller specified the max latency in microseconds.
             // No need to run training round in this case.
             if (atoi(argv[i+1]) > 0) {
-                max_time_bucket = strtoull(argv[i+1], (char **)NULL, 10) * 1000;
+                max_time_bucket = strtoull(argv[i+1], (char **)nullptr, 10) * 1000;
                 time_per_bucket = max_time_bucket / num_buckets;
                 i++;
             } else {
diff --git a/libs/binder/tests/schd-dbg.cpp b/libs/binder/tests/schd-dbg.cpp
index 13f03b1..6cf7f36 100644
--- a/libs/binder/tests/schd-dbg.cpp
+++ b/libs/binder/tests/schd-dbg.cpp
@@ -295,7 +295,7 @@
 
   no_inherent += reply.readInt32();
   no_sync += reply.readInt32();
-  return 0;
+  return nullptr;
 }
 
 // create a fifo thread to transact and wait it to finished
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 73f2147..b29c1d5 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -23,6 +23,7 @@
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
 
     clang: true,
     cflags: [
@@ -72,9 +73,6 @@
     ],
 
     product_variables: {
-        brillo: {
-            cflags: ["-DHAVE_NO_SURFACE_FLINGER"],
-        },
         eng: {
             cppflags: [
                 "-UDEBUG_ONLY_CODE",
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 49ffc8f..7e26b0b 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -286,6 +286,35 @@
     return gbuffer->handle;
 }
 
+int AHardwareBuffer_createFromHandle(const AHardwareBuffer_Desc* desc,
+                                     const native_handle_t* handle, int32_t method,
+                                     AHardwareBuffer** outBuffer) {
+    static_assert(static_cast<int32_t>(AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_REGISTER) ==
+                  static_cast<int32_t>(GraphicBuffer::TAKE_UNREGISTERED_HANDLE));
+    static_assert(static_cast<int32_t>(AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE) ==
+                  static_cast<int32_t>(GraphicBuffer::CLONE_HANDLE));
+
+    if (!desc || !handle || !outBuffer) return BAD_VALUE;
+    if (!(method == AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_REGISTER ||
+          method == AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE))
+        return BAD_VALUE;
+    if (desc->rfu0 != 0 || desc->rfu1 != 0) return BAD_VALUE;
+    if (desc->format == AHARDWAREBUFFER_FORMAT_BLOB && desc->height != 1) return BAD_VALUE;
+
+    const int format = AHardwareBuffer_convertToPixelFormat(desc->format);
+    const uint64_t usage = AHardwareBuffer_convertToGrallocUsageBits(desc->usage);
+    const auto wrapMethod = static_cast<GraphicBuffer::HandleWrapMethod>(method);
+    sp<GraphicBuffer> gbuffer(new GraphicBuffer(handle, wrapMethod, desc->width, desc->height,
+                                                format, desc->layers, usage, desc->stride));
+    status_t err = gbuffer->initCheck();
+    if (err != 0 || gbuffer->handle == 0) return err;
+
+    *outBuffer = AHardwareBuffer_from_GraphicBuffer(gbuffer.get());
+    // Ensure the buffer doesn't get destroyed when the sp<> goes away.
+    AHardwareBuffer_acquire(*outBuffer);
+
+    return NO_ERROR;
+}
 
 // ----------------------------------------------------------------------------
 // Helpers implementation
diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp
index 765dcd9..8435dac 100644
--- a/libs/nativewindow/ANativeWindow.cpp
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -126,12 +126,12 @@
 }
 
 int32_t ANativeWindow_setBuffersDataSpace(ANativeWindow* window, int32_t dataSpace) {
-    static_assert(ADATASPACE_UNKNOWN == HAL_DATASPACE_UNKNOWN);
-    static_assert(ADATASPACE_SCRGB_LINEAR == HAL_DATASPACE_V0_SCRGB_LINEAR);
-    static_assert(ADATASPACE_SRGB == HAL_DATASPACE_V0_SRGB);
-    static_assert(ADATASPACE_SCRGB == HAL_DATASPACE_V0_SCRGB);
-    static_assert(ADATASPACE_DISPLAY_P3 == HAL_DATASPACE_DISPLAY_P3);
-    static_assert(ADATASPACE_BT2020_PQ == HAL_DATASPACE_BT2020_PQ);
+    static_assert(static_cast<int>(ADATASPACE_UNKNOWN) == static_cast<int>(HAL_DATASPACE_UNKNOWN));
+    static_assert(static_cast<int>(ADATASPACE_SCRGB_LINEAR) == static_cast<int>(HAL_DATASPACE_V0_SCRGB_LINEAR));
+    static_assert(static_cast<int>(ADATASPACE_SRGB) == static_cast<int>(HAL_DATASPACE_V0_SRGB));
+    static_assert(static_cast<int>(ADATASPACE_SCRGB) == static_cast<int>(HAL_DATASPACE_V0_SCRGB));
+    static_assert(static_cast<int>(ADATASPACE_DISPLAY_P3) == static_cast<int>(HAL_DATASPACE_DISPLAY_P3));
+    static_assert(static_cast<int>(ADATASPACE_BT2020_PQ) == static_cast<int>(HAL_DATASPACE_BT2020_PQ));
 
     if (!window || !query(window, NATIVE_WINDOW_IS_VALID) ||
             !isDataSpaceValid(window, dataSpace)) {
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 78cec41..9ca4941 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -15,6 +15,11 @@
  */
 
 /**
+ * @addtogroup NativeActivity Native Activity
+ * @{
+ */
+
+/**
  * @file hardware_buffer.h
  */
 
@@ -210,6 +215,8 @@
 
 typedef struct AHardwareBuffer AHardwareBuffer;
 
+#if __ANDROID_API__ >= 26
+
 /**
  * Allocates a buffer that backs an AHardwareBuffer using the passed
  * AHardwareBuffer_Desc.
@@ -218,25 +225,25 @@
  * any reason. The returned buffer has a reference count of 1.
  */
 int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc,
-        AHardwareBuffer** outBuffer);
+        AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
 /**
  * Acquire a reference on the given AHardwareBuffer object.  This prevents the
  * object from being deleted until the last reference is removed.
  */
-void AHardwareBuffer_acquire(AHardwareBuffer* buffer);
+void AHardwareBuffer_acquire(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
 
 /**
  * Remove a reference that was previously acquired with
  * AHardwareBuffer_acquire().
  */
-void AHardwareBuffer_release(AHardwareBuffer* buffer);
+void AHardwareBuffer_release(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
 
 /**
  * Return a description of the AHardwareBuffer in the passed
  * AHardwareBuffer_Desc struct.
  */
 void AHardwareBuffer_describe(const AHardwareBuffer* buffer,
-        AHardwareBuffer_Desc* outDesc);
+        AHardwareBuffer_Desc* outDesc) __INTRODUCED_IN(26);
 
 /**
  * Lock the AHardwareBuffer for reading or writing, depending on the usage flags
@@ -272,7 +279,7 @@
  * number of the lock fails for any reason.
  */
 int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage,
-        int32_t fence, const ARect* rect, void** outVirtualAddress);
+        int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
 
 /**
  * Unlock the AHardwareBuffer; must be called after all changes to the buffer
@@ -284,7 +291,7 @@
  * \return 0 on success, -EINVAL if \a buffer is NULL, or an error
  * number if the unlock fails for any reason.
  */
-int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence);
+int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) __INTRODUCED_IN(26);
 
 /**
  * Send the AHardwareBuffer to an AF_UNIX socket.
@@ -292,7 +299,7 @@
  * \return 0 on success, -EINVAL if \a buffer is NULL, or an error
  * number if the operation fails for any reason.
  */
-int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd);
+int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) __INTRODUCED_IN(26);
 
 /**
  * Receive the AHardwareBuffer from an AF_UNIX socket.
@@ -300,8 +307,12 @@
  * \return 0 on success, -EINVAL if \a outBuffer is NULL, or an error
  * number if the operation fails for any reason.
  */
-int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer);
+int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
+
+#endif // __ANDROID_API__ >= 26
 
 __END_DECLS
 
 #endif // ANDROID_HARDWARE_BUFFER_H
+
+/** @} */
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
index d5e5e9d..6831f91 100644
--- a/libs/nativewindow/include/android/native_window.h
+++ b/libs/nativewindow/include/android/native_window.h
@@ -178,7 +178,7 @@
  */
 int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);
 
-#if __ANDROID_API__ >= __ANDROID_API_O__
+#if __ANDROID_API__ >= 26
 
 /**
  * Set a transform that will be applied to future buffers posted to the window.
@@ -186,11 +186,11 @@
  * \param transform combination of {@link ANativeWindowTransform} flags
  * \return 0 for success, or -EINVAL if \p transform is invalid
  */
-int32_t ANativeWindow_setBuffersTransform(ANativeWindow* window, int32_t transform);
+int32_t ANativeWindow_setBuffersTransform(ANativeWindow* window, int32_t transform) __INTRODUCED_IN(26);
 
-#endif // __ANDROID_API__ >= __ANDROID_API_O__
+#endif // __ANDROID_API__ >= 26
 
-#if __ANDROID_API__ >= __ANDROID_API_P__
+#if __ANDROID_API__ >= 28
 
 /**
  * All buffers queued after this call will be associated with the dataSpace
@@ -206,16 +206,16 @@
  * \return 0 for success, -EINVAL if window is invalid or the dataspace is not
  * supported.
  */
-int32_t ANativeWindow_setBuffersDataSpace(ANativeWindow* window, int32_t dataSpace);
+int32_t ANativeWindow_setBuffersDataSpace(ANativeWindow* window, int32_t dataSpace) __INTRODUCED_IN(28);
 
 /**
  * Get the dataspace of the buffers in window.
  * \return the dataspace of buffers in window, ADATASPACE_UNKNOWN is returned if
  * dataspace is unknown, or -EINVAL if window is invalid.
  */
-int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window);
+int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) __INTRODUCED_IN(28);
 
-#endif // __ANDROID_API__ >= __ANDROID_API_P__
+#endif // __ANDROID_API__ >= 28
 
 #ifdef __cplusplus
 };
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 7a4b31f..6c9ec34 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -26,6 +26,28 @@
 
 const native_handle_t* AHardwareBuffer_getNativeHandle(const AHardwareBuffer* buffer);
 
+enum CreateFromHandleMethod {
+    // enum values chosen to match internal GraphicBuffer::HandleWrapMethod
+    AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_REGISTER = 2,
+    AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE = 3,
+};
+
+/**
+ * Create a AHardwareBuffer from a native handle.
+ *
+ * This function wraps a native handle in a AHardwareBuffer suitable for use by applications or
+ * other parts of the system. The contents of desc will be returned by AHardwareBuffer_describe().
+ *
+ * If method is AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_REGISTER, the handle is assumed to be
+ * unregistered, and it will be registered/imported before being wrapped in the AHardwareBuffer.
+ * If successful, the AHardwareBuffer will own the handle.
+ *
+ * If method is AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE, the handle will be cloned and the
+ * clone registered. The AHardwareBuffer will own the cloned handle but not the original.
+ */
+int AHardwareBuffer_createFromHandle(const AHardwareBuffer_Desc* desc,
+                                     const native_handle_t* handle, int32_t method,
+                                     AHardwareBuffer** outBuffer);
 
 /**
  * Buffer pixel formats.
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
index d2ba971..753954d 100644
--- a/libs/nativewindow/libnativewindow.map.txt
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -2,6 +2,7 @@
   global:
     AHardwareBuffer_acquire;
     AHardwareBuffer_allocate;
+    AHardwareBuffer_createFromHandle; # vndk
     AHardwareBuffer_describe;
     AHardwareBuffer_getNativeHandle; # vndk
     AHardwareBuffer_lock;
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index ff9d19e..d25ad1a 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -18,6 +18,7 @@
     vndk: {
         enabled: true,
     },
+    double_loadable: true,
 
     clang: true,
     cflags: [
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index ff53aa8..ed7ccb0b 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -109,25 +109,25 @@
         return SIGNAL_TIME_INVALID;
     }
 
-    struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd);
+    struct sync_file_info* finfo = sync_file_info(mFenceFd);
     if (finfo == NULL) {
-        ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd.get());
+        ALOGE("sync_file_info returned NULL for fd %d", mFenceFd.get());
         return SIGNAL_TIME_INVALID;
     }
     if (finfo->status != 1) {
-        sync_fence_info_free(finfo);
+        sync_file_info_free(finfo);
         return SIGNAL_TIME_PENDING;
     }
 
-    struct sync_pt_info* pinfo = NULL;
     uint64_t timestamp = 0;
-    while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) {
-        if (pinfo->timestamp_ns > timestamp) {
-            timestamp = pinfo->timestamp_ns;
+    struct sync_fence_info* pinfo = sync_get_fence_info(finfo);
+    for (size_t i = 0; i < finfo->num_fences; i++) {
+        if (pinfo[i].timestamp_ns > timestamp) {
+            timestamp = pinfo[i].timestamp_ns;
         }
     }
-    sync_fence_info_free(finfo);
 
+    sync_file_info_free(finfo);
     return nsecs_t(timestamp);
 }
 
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
index b92cbf3..37cf617 100644
--- a/libs/ui/Gralloc2.cpp
+++ b/libs/ui/Gralloc2.cpp
@@ -39,7 +39,7 @@
     static const uint64_t valid10UsageBits = []() -> uint64_t {
         using hardware::graphics::common::V1_0::BufferUsage;
         uint64_t bits = 0;
-        for (const auto bit : hardware::hidl_enum_iterator<BufferUsage>()) {
+        for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
             bits = bits | bit;
         }
         // TODO(b/72323293, b/72703005): Remove these additional bits
@@ -54,7 +54,7 @@
     static const uint64_t valid11UsageBits = []() -> uint64_t {
         using hardware::graphics::common::V1_1::BufferUsage;
         uint64_t bits = 0;
-        for (const auto bit : hardware::hidl_enum_iterator<BufferUsage>()) {
+        for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
             bits = bits | bit;
         }
         return bits;
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 254038b..0382479 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -123,7 +123,6 @@
 
 ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const
 {
-    LOG_ALWAYS_FATAL_IF(this == NULL, "getNativeBuffer() called on NULL GraphicBuffer");
     return static_cast<ANativeWindowBuffer*>(
             const_cast<GraphicBuffer*>(this));
 }
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
index 7b5ad44..69b6422 100644
--- a/libs/vr/libbufferhub/Android.bp
+++ b/libs/vr/libbufferhub/Android.bp
@@ -59,7 +59,6 @@
 }
 
 cc_test {
-    tags: ["optional"],
     srcs: ["buffer_hub-test.cpp"],
     static_libs: ["libbufferhub"],
     shared_libs: sharedLibraries,
diff --git a/libs/vr/libbufferhubqueue/benchmarks/Android.bp b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
index 8ae7a0b..5089b87 100644
--- a/libs/vr/libbufferhubqueue/benchmarks/Android.bp
+++ b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
@@ -23,5 +23,4 @@
         "-Werror",
     ],
     name: "buffer_transport_benchmark",
-    tags: ["optional"],
 }
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index ca1e7bd..a337921 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -38,7 +38,6 @@
         "-Wno-error=sign-compare", // to fix later
     ],
     name: "buffer_hub_queue-test",
-    tags: ["optional"],
 }
 
 cc_test {
@@ -55,5 +54,4 @@
         "-Werror",
     ],
     name: "buffer_hub_queue_producer-test",
-    tags: ["optional"],
 }
diff --git a/libs/vr/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp
index 192fb5d..9c67881 100644
--- a/libs/vr/libdisplay/Android.bp
+++ b/libs/vr/libdisplay/Android.bp
@@ -50,7 +50,6 @@
 ]
 
 cc_library {
-    tags: ["tests"],
     srcs: sourceFiles,
     cflags: ["-DLOG_TAG=\"libdisplay\"",
         "-DTRACE=0",
diff --git a/libs/vr/libdvrcommon/Android.bp b/libs/vr/libdvrcommon/Android.bp
index 32b793a..e751768 100644
--- a/libs/vr/libdvrcommon/Android.bp
+++ b/libs/vr/libdvrcommon/Android.bp
@@ -59,7 +59,6 @@
 
 cc_test {
     name: "libdvrcommon_test",
-    tags: ["optional"],
 
     srcs: testFiles,
     cflags: [
diff --git a/libs/vr/libpdx/private/pdx/rpc/variant.h b/libs/vr/libpdx/private/pdx/rpc/variant.h
index 2cc9664..bdcb293 100644
--- a/libs/vr/libpdx/private/pdx/rpc/variant.h
+++ b/libs/vr/libpdx/private/pdx/rpc/variant.h
@@ -292,7 +292,7 @@
 
   template <typename T>
   T& get(TypeTag<T>) {
-    return rest_.template get(TypeTag<T>{});
+    return rest_.get(TypeTag<T>{});
   }
   template <typename T>
   const T& get(TypeTag<T>) const {
@@ -300,7 +300,7 @@
   }
   template <typename T>
   constexpr std::int32_t index(TypeTag<T>) const {
-    return 1 + rest_.template index(TypeTag<T>{});
+    return 1 + rest_.index(TypeTag<T>{});
   }
 
   template <typename... Args>
diff --git a/libs/vr/libpdx/service_tests.cpp b/libs/vr/libpdx/service_tests.cpp
index e623abf..938d737 100644
--- a/libs/vr/libpdx/service_tests.cpp
+++ b/libs/vr/libpdx/service_tests.cpp
@@ -51,22 +51,24 @@
 //             method(IoVecMatcher(IoVecArray{{ptr1, size1}, {ptr2, size2}})));
 using IoVecArray = std::vector<iovec>;
 MATCHER_P(IoVecMatcher, iovec_array, "") {
+  auto local_arg = arg;
   for (const iovec& item : iovec_array) {
-    if (arg->iov_base != item.iov_base || arg->iov_len != item.iov_len)
+    if (local_arg->iov_base != item.iov_base || local_arg->iov_len != item.iov_len)
       return false;
-    arg++;
+    local_arg++;
   }
   return true;
 }
 
 using IoVecData = std::vector<std::string>;
 MATCHER_P(IoVecDataMatcher, iovec_data, "") {
+  auto local_arg = arg;
   for (const std::string& item : iovec_data) {
-    std::string data{reinterpret_cast<const char*>(arg->iov_base),
-                     arg->iov_len};
+    std::string data{reinterpret_cast<const char*>(local_arg->iov_base),
+                     local_arg->iov_len};
     if (data != item)
       return false;
-    arg++;
+    local_arg++;
   }
   return true;
 }
diff --git a/libs/vr/libvr_manager/Android.bp b/libs/vr/libvr_manager/Android.bp
index 8784877..2cd6a28 100644
--- a/libs/vr/libvr_manager/Android.bp
+++ b/libs/vr/libvr_manager/Android.bp
@@ -12,25 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-exported_include_dirs = [ "include" ]
-
-include_dirs = ["frameworks/native/include/vr/vr_manager"]
-
-src_files = [
-    "vr_manager.cpp",
-    "trusted_uids.cpp",
-]
-
-static_libs = [
-    "libutils",
-    "libbinder",
-]
-
 cc_library_static {
-    srcs: src_files,
-    include_dirs: include_dirs,
-    export_include_dirs: exported_include_dirs,
-    cflags: ["-Wall", "-Werror", "-Wunused", "-Wunreachable-code"],
-    static_libs: static_libs,
     name: "libvr_manager",
+    srcs: [
+        "vr_manager.cpp",
+        "trusted_uids.cpp",
+    ],
+    include_dirs: ["frameworks/native/include/vr/vr_manager"],
+    export_include_dirs: [ "include" ],
+    cflags: ["-Wall", "-Werror", "-Wunused", "-Wunreachable-code"],
+    shared_libs: [
+        "libutils",
+        "libbinder",
+    ],
 }
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index c65bddf..3312b03 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -1054,38 +1054,6 @@
             egl_tls_t::setContext(EGL_NO_CONTEXT);
         }
     } else {
-
-        if (cur_c != NULL) {
-            // Force return to current context for drivers that cannot handle errors
-            EGLBoolean restore_result = EGL_FALSE;
-            // get a reference to the old current objects
-            ContextRef _c2(dp.get(), cur_c);
-            SurfaceRef _d2(dp.get(), cur_c->draw);
-            SurfaceRef _r2(dp.get(), cur_c->read);
-
-            c = cur_c;
-            impl_ctx = c->context;
-            impl_draw = EGL_NO_SURFACE;
-            if (cur_c->draw != EGL_NO_SURFACE) {
-                d = get_surface(cur_c->draw);
-                impl_draw = d->surface;
-            }
-            impl_read = EGL_NO_SURFACE;
-            if (cur_c->read != EGL_NO_SURFACE) {
-                r = get_surface(cur_c->read);
-                impl_read = r->surface;
-            }
-            restore_result = dp->makeCurrent(c, cur_c,
-                    cur_c->draw, cur_c->read, cur_c->context,
-                    impl_draw, impl_read, impl_ctx);
-            if (restore_result == EGL_TRUE) {
-                _c2.acquire();
-                _r2.acquire();
-                _d2.acquire();
-            } else {
-                ALOGE("Could not restore original EGL context");
-            }
-        }
         // this will ALOGE the error
         egl_connection_t* const cnx = &gEGLImpl;
         result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
diff --git a/services/batteryservice/Android.bp b/services/batteryservice/Android.bp
index 186f399..66ee8ff 100644
--- a/services/batteryservice/Android.bp
+++ b/services/batteryservice/Android.bp
@@ -1,7 +1,8 @@
 cc_library_headers {
     name: "libbatteryservice_headers",
     vendor_available: true,
+    recovery_available: true,
     export_include_dirs: ["include"],
-    header_libs: ["libbinder_headers"],
-    export_header_lib_headers: ["libbinder_headers"],
+    header_libs: ["libutils_headers"],
+    export_header_lib_headers: ["libutils_headers"],
 }
diff --git a/services/batteryservice/include/batteryservice/BatteryService.h b/services/batteryservice/include/batteryservice/BatteryService.h
index 80ab7f3..1e8eb1e 100644
--- a/services/batteryservice/include/batteryservice/BatteryService.h
+++ b/services/batteryservice/include/batteryservice/BatteryService.h
@@ -17,7 +17,6 @@
 #ifndef ANDROID_BATTERYSERVICE_H
 #define ANDROID_BATTERYSERVICE_H
 
-#include <binder/Parcel.h>
 #include <sys/types.h>
 #include <utils/Errors.h>
 #include <utils/String8.h>
@@ -54,16 +53,10 @@
     int batteryFullCharge;
     int batteryChargeCounter;
     String8 batteryTechnology;
-
-    status_t writeToParcel(Parcel* parcel) const;
-    status_t readFromParcel(Parcel* parcel);
 };
 
 struct BatteryProperty {
     int64_t valueInt64;
-
-    status_t writeToParcel(Parcel* parcel) const;
-    status_t readFromParcel(Parcel* parcel);
 };
 
 }; // namespace android
diff --git a/services/batteryservice/include/batteryservice/IBatteryPropertiesListener.h b/services/batteryservice/include/batteryservice/IBatteryPropertiesListener.h
deleted file mode 100644
index b226dd6..0000000
--- a/services/batteryservice/include/batteryservice/IBatteryPropertiesListener.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef ANDROID_IBATTERYPROPERTIESLISTENER_H
-#define ANDROID_IBATTERYPROPERTIESLISTENER_H
-
-#include <binder/IBinder.h>
-#include <binder/IInterface.h>
-
-#include <batteryservice/BatteryService.h>
-
-namespace android {
-
-// must be kept in sync with interface defined in IBatteryPropertiesListener.aidl
-enum {
-        TRANSACT_BATTERYPROPERTIESCHANGED = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-// ----------------------------------------------------------------------------
-
-class IBatteryPropertiesListener : public IInterface {
-public:
-    DECLARE_META_INTERFACE(BatteryPropertiesListener)
-
-    virtual void batteryPropertiesChanged(struct BatteryProperties props) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnBatteryPropertiesListener: public BnInterface<IBatteryPropertiesListener> {
-public:
-    virtual status_t onTransact(uint32_t code, const Parcel& data,
-                                Parcel* reply, uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IBATTERYPROPERTIESLISTENER_H
diff --git a/services/batteryservice/include/batteryservice/IBatteryPropertiesRegistrar.h b/services/batteryservice/include/batteryservice/IBatteryPropertiesRegistrar.h
deleted file mode 100644
index a7dbea6..0000000
--- a/services/batteryservice/include/batteryservice/IBatteryPropertiesRegistrar.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef ANDROID_IBATTERYPROPERTIESREGISTRAR_H
-#define ANDROID_IBATTERYPROPERTIESREGISTRAR_H
-
-#include <binder/IInterface.h>
-#include <batteryservice/IBatteryPropertiesListener.h>
-
-namespace android {
-
-// must be kept in sync with interface defined in IBatteryPropertiesRegistrar.aidl
-enum {
-    REGISTER_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
-    UNREGISTER_LISTENER,
-    GET_PROPERTY,
-    SCHEDULE_UPDATE,
-};
-
-class IBatteryPropertiesRegistrar : public IInterface {
-public:
-    DECLARE_META_INTERFACE(BatteryPropertiesRegistrar)
-
-    virtual void registerListener(const sp<IBatteryPropertiesListener>& listener) = 0;
-    virtual void unregisterListener(const sp<IBatteryPropertiesListener>& listener) = 0;
-    virtual status_t getProperty(int id, struct BatteryProperty *val) = 0;
-    virtual void scheduleUpdate() = 0;
-};
-
-class BnBatteryPropertiesRegistrar : public BnInterface<IBatteryPropertiesRegistrar> {
-public:
-    virtual status_t onTransact(uint32_t code, const Parcel& data,
-                                Parcel* reply, uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IBATTERYPROPERTIESREGISTRAR_H
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index b1d5e61..dd19800 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -13,6 +13,7 @@
         "-Wno-unused-parameter",
     ],
     shared_libs: [
+        "libbase",
         "libcutils",
         "liblog",
         "libutils",
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 322e8a0..c511c5e 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -15,7 +15,6 @@
 cc_test {
     name: "SurfaceFlinger_test",
     defaults: ["surfaceflinger_defaults"],
-    tags: ["test"],
     test_suites: ["device-tests"],
     srcs: [
         "Stress_test.cpp",
diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp
index 5fa8a09..6ad1b87 100644
--- a/services/surfaceflinger/tests/fakehwc/Android.bp
+++ b/services/surfaceflinger/tests/fakehwc/Android.bp
@@ -1,7 +1,6 @@
 cc_test {
     name: "sffakehwc_test",
     defaults: ["surfaceflinger_defaults"],
-    tags: ["test"],
     test_suites: ["device-tests"],
     srcs: [
          "FakeComposerClient.cpp",
diff --git a/services/surfaceflinger/tests/hwc2/Android.bp b/services/surfaceflinger/tests/hwc2/Android.bp
index 0957d6a..1c8e396 100644
--- a/services/surfaceflinger/tests/hwc2/Android.bp
+++ b/services/surfaceflinger/tests/hwc2/Android.bp
@@ -15,7 +15,6 @@
 cc_test {
     name: "test-hwc2",
     defaults: ["surfaceflinger_defaults"],
-    tags: ["test"],
     cflags: [
         "-DEGL_EGLEXT_PROTOTYPES",
         "-DGL_GLEXT_PROTOTYPES",
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 4a92780..9949bfa 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -14,7 +14,6 @@
 
 cc_test {
     name: "libsurfaceflinger_unittest",
-    tags: ["test"],
     defaults: ["libsurfaceflinger_defaults"],
     test_suites: ["device-tests"],
     srcs: [
diff --git a/services/surfaceflinger/tests/vsync/Android.bp b/services/surfaceflinger/tests/vsync/Android.bp
index d04efda..6a89945 100644
--- a/services/surfaceflinger/tests/vsync/Android.bp
+++ b/services/surfaceflinger/tests/vsync/Android.bp
@@ -15,7 +15,6 @@
 cc_binary {
     name: "test-vsync-events",
     defaults: ["surfaceflinger_defaults"],
-    tags: ["test"],
     srcs: [
         "vsync.cpp",
     ],
diff --git a/services/vr/performanced/directory_reader.h b/services/vr/performanced/directory_reader.h
index b9d27c3..f8359c4 100644
--- a/services/vr/performanced/directory_reader.h
+++ b/services/vr/performanced/directory_reader.h
@@ -16,10 +16,11 @@
 class DirectoryReader {
  public:
   explicit DirectoryReader(base::unique_fd directory_fd) {
-    directory_ = fdopendir(directory_fd.get());
+    int fd = directory_fd.release();
+    directory_ = fdopendir(fd);
     error_ = errno;
-    if (directory_ != nullptr)
-      (void) directory_fd.release(); // ignore return result?
+    if (directory_ == nullptr)
+      close(fd);
   }
 
   ~DirectoryReader() {
diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp
index 513fcc1..0263481 100644
--- a/services/vr/virtual_touchpad/Android.bp
+++ b/services/vr/virtual_touchpad/Android.bp
@@ -22,14 +22,12 @@
     export_include_dirs: ["include"],
     shared_libs: shared_libs,
     header_libs: header_libraries,
-    cppflags: ["-std=c++11"],
     cflags: [
         "-DLOG_TAG=\"VrVirtualTouchpad\"",
         "-Wall",
         "-Werror",
     ],
     name: "libvirtualtouchpad",
-    tags: ["optional"],
 }
 
 // Touchpad unit tests.
@@ -52,15 +50,11 @@
         "-Wall",
         "-Werror",
     ],
-    cppflags: [
-        "-std=c++11",
-    ],
     host_ldlibs: [
         "-llog",
     ],
     name: "VirtualTouchpad_test",
     stl: "libc++_static",
-    tags: ["optional"],
 }
 
 // Service.
@@ -88,7 +82,6 @@
     static_libs: service_static_libs,
     shared_libs: service_shared_libs,
     header_libs: header_libraries,
-    cppflags: ["-std=c++11"],
     cflags: [
         "-DLOG_TAG=\"VrVirtualTouchpad\"",
         "-Wall",
@@ -96,7 +89,6 @@
     ],
     host_ldlibs: ["-llog"],
     name: "virtual_touchpad",
-    tags: ["optional"],
     init_rc: ["virtual_touchpad.rc"],
     compile_multilib: "64",
     stl: "libc++_static",
@@ -121,7 +113,6 @@
     srcs: client_src,
     shared_libs: client_shared_libs,
     header_libs: header_libraries,
-    cppflags: ["-std=c++11"],
     cflags: [
         "-DLOG_TAG=\"VirtualTouchpadClient\"",
         "-Wall",
@@ -129,6 +120,5 @@
     ],
     host_ldlibs: ["-llog"],
     name: "libvirtualtouchpadclient",
-    tags: ["optional"],
     export_include_dirs: ["include"],
 }
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index d0e8346..76eca35 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -28,7 +28,7 @@
 // API version (major.minor.patch)
 define VERSION_MAJOR 1
 define VERSION_MINOR 1
-define VERSION_PATCH 68
+define VERSION_PATCH 82
 
 // API limits
 define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
@@ -222,7 +222,7 @@
 @extension("VK_EXT_shader_subgroup_vote") define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote"
 
 // 70
-@extension("VK_KHR_maintenance1") define VK_KHR_MAINTENANCE1_SPEC_VERSION 1
+@extension("VK_KHR_maintenance1") define VK_KHR_MAINTENANCE1_SPEC_VERSION 2
 @extension("VK_KHR_maintenance1") define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1"
 
 // 71
@@ -269,6 +269,10 @@
 @extension("VK_KHR_push_descriptor") define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 2
 @extension("VK_KHR_push_descriptor") define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor"
 
+// 82
+@extension("VK_EXT_conditional_rendering") define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 1
+@extension("VK_EXT_conditional_rendering") define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering"
+
 // 84
 @extension("VK_KHR_16bit_storage") define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1
 @extension("VK_KHR_16bit_storage") define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage"
@@ -345,6 +349,10 @@
 @extension("VK_EXT_hdr_metadata") define VK_EXT_HDR_METADATA_SPEC_VERSION 1
 @extension("VK_EXT_hdr_metadata") define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata"
 
+// 110
+@extension("VK_KHR_create_renderpass2") define VK_KHR_CREATE_RENDERPASS2_SPEC_VERSION 1
+@extension("VK_KHR_create_renderpass2") define VK_KHR_CREATE_RENDERPASS2_EXTENSION_NAME "VK_KHR_create_renderpass2"
+
 // 112
 @extension("VK_KHR_shared_presentable_image") define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
 @extension("VK_KHR_shared_presentable_image") define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
@@ -377,6 +385,10 @@
 @extension("VK_KHR_variable_pointers") define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1
 @extension("VK_KHR_variable_pointers") define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers"
 
+// 122
+@extension("VK_KHR_get_display_properties2") define VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION 1
+@extension("VK_KHR_get_display_properties2") define VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_display_properties2"
+
 // 123
 @extension("VK_MVK_ios_surface") define VK_MVK_IOS_SURFACE_SPEC_VERSION 1
 @extension("VK_MVK_ios_surface") define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface"
@@ -402,7 +414,7 @@
 @extension("VK_EXT_debug_utils") define VK_EXT_DEBUG_UTILS_EXTENSION_NAME "VK_EXT_debug_utils"
 
 // 130
-@extension("VK_ANDROID_external_memory_android_hardware_buffer") define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 2
+@extension("VK_ANDROID_external_memory_android_hardware_buffer") define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 3
 @extension("VK_ANDROID_external_memory_android_hardware_buffer") define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer"
 
 // 131
@@ -477,6 +489,10 @@
 @extension("VK_EXT_validation_cache") define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1
 @extension("VK_EXT_validation_cache") define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache"
 
+// 162
+@extension("VK_EXT_descriptor_indexing") define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2
+@extension("VK_EXT_descriptor_indexing") define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
+
 // 165
 @extension("VK_EXT_shader_viewport_index_layer") define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1
 @extension("VK_EXT_shader_viewport_index_layer") define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
@@ -485,14 +501,42 @@
 @extension("VK_KHR_maintenance3") define VK_KHR_MAINTENANCE3_SPEC_VERSION 1
 @extension("VK_KHR_maintenance3") define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3"
 
+// 170
+@extension("VK_KHR_draw_indirect_count") define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
+@extension("VK_KHR_draw_indirect_count") define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count"
+
 // 175
 @extension("VK_EXT_global_priority") define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 1
 @extension("VK_EXT_global_priority") define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority"
 
+// 178
+@extension("VK_KHR_8bit_storage") define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1
+@extension("VK_KHR_8bit_storage") define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage"
+
 // 179
 @extension("VK_EXT_external_memory_host") define VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION 1
 @extension("VK_EXT_external_memory_host") define VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME "VK_EXT_external_memory_host"
 
+// 180
+@extension("VK_AMD_buffer_marker") define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1
+@extension("VK_AMD_buffer_marker") define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker"
+
+// 186
+@extension("VK_AMD_shader_core_properties") define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1
+@extension("VK_AMD_shader_core_properties") define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties"
+
+// 191
+@extension("VK_EXT_vertex_attribute_divisor") define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1
+@extension("VK_EXT_vertex_attribute_divisor") define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor"
+
+// 199
+@extension("VK_NV_shader_subgroup_partitioned") define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1
+@extension("VK_NV_shader_subgroup_partitioned") define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned"
+
+// 207
+@extension("VK_NV_device_diagnostic_checkpoints") define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2
+@extension("VK_NV_device_diagnostic_checkpoints") define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints"
+
 /////////////
 //  Types  //
 /////////////
@@ -1425,6 +1469,11 @@
     //@extension("VK_KHR_incremental_present") // 85
     VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR                       = 1000084000,
 
+    //@extension("VK_EXT_conditional_rendering") // 82
+    VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT        = 1000081001,
+    VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT                      = 1000081002,
+
     //@extension("VK_KHR_descriptor_update_template") // 86
     VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR    = 1000085000,
 
@@ -1465,6 +1514,15 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000,
     VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001,
 
+    //@extension("VK_KHR_create_renderpass2") // 110
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR              = 1000109000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR                = 1000109001,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR                 = 1000109002,
+    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR                  = 1000109003,
+    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR             = 1000109004,
+    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR                    = 1000109005,
+    VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR                      = 1000109006,
+
     //@extension("VK_EXT_hdr_metadata") // 106
     VK_STRUCTURE_TYPE_HDR_METADATA_EXT                          = 1000105000,
 
@@ -1501,6 +1559,13 @@
     //@extension("VK_KHR_variable_pointers") // 121
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = 1000120000,
 
+    //@extension("VK_KHR_display_properties2") // 122
+    VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR                  = 1000121000,
+    VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR            = 1000121001,
+    VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR             = 1000121002,
+    VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR                  = 1000121003,
+    VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR          = 1000121004,
+
     //@extension("VK_MVK_ios_surface") // 123
     VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK               = 1000122000,
 
@@ -1574,6 +1639,13 @@
     VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT                  = 1000160000,
     VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT    = 1000160001,
 
+    //@extension("VK_EXT_descriptor_indexing") // 162
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT           = 1000161000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT              = 1000161001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT            = 1000161002,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT    = 1000161003,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT   = 1000161004,
+
     //@extension("VK_KHR_maintenance3") // 169
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR      = 1000168000,
     VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR                 = 1000168001,
@@ -1581,10 +1653,24 @@
     //@extension("VK_EXT_global_priority") // 175
     VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT      = 1000174000,
 
+    //@extension("VK_KHR_8bit_storage") // 178
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR         = 1000177000,
+
     //@extension("VK_EXT_external_memory_host") // 179
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT                   = 1000178000,
     VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT                    = 1000178001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT   = 1000178002,
+
+    //@extension("VK_AMD_shader_core_properties") // 186
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD        = 1000185000,
+
+    //@extension("VK_EXT_vertex_attribute_divisor") // 191
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT   = 1000190000,
+    VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT       = 1000190001,
+
+    //@extension("VK_NV_device_diagnostic_checkpoints") // 207
+    VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV                        = 1000206000,
+    VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV     = 1000206001,
 }
 
 enum VkSubpassContents {
@@ -1652,6 +1738,9 @@
 
     //@extension("VK_KHR_external_memory") // 73
     VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR                    = 0xC4641CBD, // -1000072003
+
+    //@extension("VK_EXT_descriptor_indexing") // 162
+    VK_ERROR_FRAGMENTATION_EXT                              = 0xc462c118, // -1000161000
 }
 
 enum VkDynamicState {
@@ -1773,6 +1862,12 @@
     VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1,
 }
 
+enum VkVendorId {
+    VK_VENDOR_ID_VIV                                        = 0x10001,
+    VK_VENDOR_ID_VSI                                        = 0x10002,
+    VK_VENDOR_ID_KAZAN                                      = 0x10003,
+}
+
 @extension("VK_KHR_surface") // 1
 enum VkPresentModeKHR {
     VK_PRESENT_MODE_IMMEDIATE_KHR                           = 0x00000000,
@@ -2076,6 +2171,9 @@
 
     //@extension("VK_EXT_blend_operation_advanced") // 149
     VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT     = 0x00080000,
+
+    //@extension("VK_EXT_conditional_rendering") // 82
+    VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT            = 0x00100000,
 }
 
 /// Buffer usage flags
@@ -2090,6 +2188,9 @@
     VK_BUFFER_USAGE_INDEX_BUFFER_BIT                        = 0x00000040,    /// Can be used as source of fixed function index fetch (index buffer)
     VK_BUFFER_USAGE_VERTEX_BUFFER_BIT                       = 0x00000080,    /// Can be used as source of fixed function vertex fetch (VBO)
     VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT                     = 0x00000100,    /// Can be the source of indirect parameters (e.g. indirect buffer, parameter buffer)
+
+    //@extension("VK_EXT_conditional_rendering") // 82
+    VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT           = 0x00000200,
 }
 
 /// Buffer creation flags
@@ -2121,6 +2222,9 @@
 type VkFlags VkDescriptorPoolCreateFlags
 bitfield VkDescriptorPoolCreateFlagBits {
     VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT       = 0x00000001,
+
+    //@extension("VK_EXT_descriptor_indexing") // 162
+    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT     = 0x00000002,
 }
 
 /// Descriptor pool reset flags
@@ -2379,6 +2483,9 @@
 
     //@extension("VK_NVX_device_generated_commands") // 87
     VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX               = 0x00020000,
+
+    //@extension("VK_EXT_conditional_rendering") // 82
+    VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT         = 0x00040000,
 }
 
 /// Render pass attachment description flags
@@ -2476,6 +2583,9 @@
 bitfield VkDescriptorSetLayoutCreateFlagBits {
     //@extension("VK_KHR_push_descriptor") // 81
     VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR     = 0x00000001,
+
+    //@extension("VK_EXT_descriptor_indexing") // 162
+    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT  = 0x00000002,
 }
 
 /// Pipeline vertex input state creation flags
@@ -2581,6 +2691,9 @@
     VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT                = 0x00000020,
     VK_SUBGROUP_FEATURE_CLUSTERED_BIT                       = 0x00000040,
     VK_SUBGROUP_FEATURE_QUAD_BIT                            = 0x00000080,
+
+    //@extension("VK_NV_shader_subgroup_partitioned") // 199
+    VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV                  = 0x00000100,
 }
 
 /// Peer memory feature flags
@@ -2899,6 +3012,13 @@
     VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR                       = 0x00000001,
 }
 
+@extension("VK_EXT_conditional_rendering") // 82
+type VkFlags VkConditionalRenderingFlagsEXT
+@extension("VK_EXT_conditional_rendering") // 82
+bitfield VkConditionalRenderingFlagBitsEXT {
+    VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT                   = 0x00000001,
+}
+
 @extension("VK_KHR_descriptor_update_template") // 86
 type VkFlags VkDescriptorUpdateTemplateCreateFlagsKHR
 //@extension("VK_KHR_descriptor_update_template") // 86
@@ -3034,6 +3154,16 @@
 //bitfield VkValidationCacheCreateFlagBitsEXT {
 //}
 
+@extension("VK_EXT_descriptor_indexing") // 162
+type VkFlags VkDescriptorBindingFlagsEXT
+@extension("VK_EXT_descriptor_indexing") // 162
+bitfield VkDescriptorBindingFlagBitsEXT {
+    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT             = 0x00000001,
+    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT   = 0x00000002,
+    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT               = 0x00000004,
+    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT     = 0x00000008,
+}
+
 //////////////////
 //  Structures  //
 //////////////////
@@ -4138,6 +4268,16 @@
     u32                                         z
 }
 
+class VkBaseOutStructure {
+    VkStructureType                             sType
+    void*                                       pNext
+}
+
+class VkBaseInStructure {
+    VkStructureType                             sType
+    const void*                                 pNext
+}
+
 //@vulkan1_1 structures
 
 class VkPhysicalDeviceSubgroupProperties {
@@ -5203,7 +5343,7 @@
     VkStructureType                             sType
     const void*                                 pNext
     u32                                         disabledValidationCheckCount
-    VkValidationCheckEXT*                       pDisabledValidationChecks
+    const VkValidationCheckEXT*                 pDisabledValidationChecks
 }
 
 @extension("VK_NN_vi_surface") // 63
@@ -5455,6 +5595,30 @@
     u32                                         maxPushDescriptors
 }
 
+@extension("VK_EXT_conditional_rendering") // 82
+class VkConditionalRenderingBeginInfoEXT {
+    VkStructureType                             sType
+    const void*                                 pNext
+    VkBuffer                                    buffer
+    VkDeviceSize                                offset
+    VkConditionalRenderingFlagsEXT              flags
+}
+
+@extension("VK_EXT_conditional_rendering") // 82
+class VkPhysicalDeviceConditionalRenderingFeaturesEXT {
+    VkStructureType                             sType
+    void*                                       pNext
+    VkBool32                                    conditionalRendering
+    VkBool32                                    inheritedConditionalRendering
+}
+
+@extension("VK_EXT_conditional_rendering") // 82
+class VkCommandBufferInheritanceConditionalRenderingInfoEXT {
+    VkStructureType                             sType
+    const void*                                 pNext
+    VkBool32                                    conditionalRenderingEnable
+}
+
 @extension("VK_KHR_16bit_storage") // 84
 class VkPhysicalDevice16BitStorageFeaturesKHR {
     VkStructureType                             sType
@@ -5810,6 +5974,89 @@
     f32                                             maxFrameAverageLightLevel
 }
 
+@extension("VK_KHR_create_renderpass2") // 110
+class VkAttachmentDescription2KHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkAttachmentDescriptionFlags                    flags
+    VkFormat                                        format
+    VkSampleCountFlagBits                           samples
+    VkAttachmentLoadOp                              loadOp
+    VkAttachmentStoreOp                             storeOp
+    VkAttachmentLoadOp                              stencilLoadOp
+    VkAttachmentStoreOp                             stencilStoreOp
+    VkImageLayout                                   initialLayout
+    VkImageLayout                                   finalLayout
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+class VkAttachmentReference2KHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    u32                                             attachment
+    VkImageLayout                                   layout
+    VkImageAspectFlags                              aspectMask
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+class VkSubpassDescription2KHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkSubpassDescriptionFlags                       flags
+    VkPipelineBindPoint                             pipelineBindPoint
+    u32                                             viewMask
+    u32                                             inputAttachmentCount
+    const VkAttachmentReference2KHR*                pInputAttachments
+    u32                                             colorAttachmentCount
+    const VkAttachmentReference2KHR*                pColorAttachments
+    const VkAttachmentReference2KHR*                pResolveAttachments
+    const VkAttachmentReference2KHR*                pDepthStencilAttachment
+    u32                                             preserveAttachmentCount
+    const u32*                                      pPreserveAttachments
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+class VkSubpassDependency2KHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    u32                                             srcSubpass
+    u32                                             dstSubpass
+    VkPipelineStageFlags                            srcStageMask
+    VkPipelineStageFlags                            dstStageMask
+    VkAccessFlags                                   srcAccessMask
+    VkAccessFlags                                   dstAccessMask
+    VkDependencyFlags                               dependencyFlags
+    s32                                             viewOffset
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+class VkRenderPassCreateInfo2KHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkRenderPassCreateFlags                         flags
+    u32                                             attachmentCount
+    const VkAttachmentDescription2KHR*              pAttachments
+    u32                                             subpassCount
+    const VkSubpassDescription2KHR*                 pSubpasses
+    u32                                             dependencyCount
+    const VkSubpassDependency2KHR*                  pDependencies
+    u32                                             correlatedViewMaskCount
+    const u32*                                      pCorrelatedViewMasks
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+class VkSubpassBeginInfoKHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkSubpassContents                               contents
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+class VkSubpassEndInfoKHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+}
+
 @extension("VK_KHR_shared_presentable_image") // 112
 class VkSharedPresentSurfaceCapabilitiesKHR {
     VkStructureType                                 sType
@@ -5951,6 +6198,42 @@
     VkBool32                                        variablePointers
 }
 
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayProperties2KHR {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkDisplayPropertiesKHR                          displayProperties
+}
+
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayPlaneProperties2KHR {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkDisplayPlanePropertiesKHR                     displayPlaneProperties
+}
+
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayModeProperties2KHR {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkDisplayModePropertiesKHR                      displayModeProperties
+}
+
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayPlaneInfo2KHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkDisplayModeKHR                                mode
+    u32                                             planeIndex
+}
+
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayPlaneCapabilities2KHR {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkDisplayPlaneCapabilitiesKHR                   capabilities
+}
+
 @extension("VK_MVK_ios_surface") // 123
 class VkIOSSurfaceCreateInfoMVK {
     VkStructureType                                 sType
@@ -5991,7 +6274,7 @@
     u64                                             objectHandle
     const char*                                     pObjectName
 }
- 
+
 @extension("VK_EXT_debug_utils") // 129
 class VkDebugUtilsObjectTagInfoEXT {
     VkStructureType                                 sType
@@ -6002,7 +6285,7 @@
     platform.size_t                                 tagSize
     const void*                                     pTag
 }
- 
+
 @extension("VK_EXT_debug_utils") // 129
 class VkDebugUtilsLabelEXT {
     VkStructureType                                 sType
@@ -6341,6 +6624,84 @@
     VkValidationCacheEXT                            validationCache
 }
 
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkDescriptorSetLayoutBindingFlagsCreateInfoEXT {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    u32                                             bindingCount
+    const VkDescriptorBindingFlagsEXT*              pBindingFlags
+}
+
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkPhysicalDeviceDescriptorIndexingFeaturesEXT {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        shaderInputAttachmentArrayDynamicIndexing
+    VkBool32                                        shaderUniformTexelBufferArrayDynamicIndexing
+    VkBool32                                        shaderStorageTexelBufferArrayDynamicIndexing
+    VkBool32                                        shaderUniformBufferArrayNonUniformIndexing
+    VkBool32                                        shaderSampledImageArrayNonUniformIndexing
+    VkBool32                                        shaderStorageBufferArrayNonUniformIndexing
+    VkBool32                                        shaderStorageImageArrayNonUniformIndexing
+    VkBool32                                        shaderInputAttachmentArrayNonUniformIndexing
+    VkBool32                                        shaderUniformTexelBufferArrayNonUniformIndexing
+    VkBool32                                        shaderStorageTexelBufferArrayNonUniformIndexing
+    VkBool32                                        descriptorBindingUniformBufferUpdateAfterBind
+    VkBool32                                        descriptorBindingSampledImageUpdateAfterBind
+    VkBool32                                        descriptorBindingStorageImageUpdateAfterBind
+    VkBool32                                        descriptorBindingStorageBufferUpdateAfterBind
+    VkBool32                                        descriptorBindingUniformTexelBufferUpdateAfterBind
+    VkBool32                                        descriptorBindingStorageTexelBufferUpdateAfterBind
+    VkBool32                                        descriptorBindingUpdateUnusedWhilePending
+    VkBool32                                        descriptorBindingPartiallyBound
+    VkBool32                                        descriptorBindingVariableDescriptorCount
+    VkBool32                                        runtimeDescriptorArray
+}
+
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkPhysicalDeviceDescriptorIndexingPropertiesEXT {
+    VkStructureType                                 sType
+    void*                                           pNext
+    u32                                             maxUpdateAfterBindDescriptorsInAllPools
+    VkBool32                                        shaderUniformBufferArrayNonUniformIndexingNative
+    VkBool32                                        shaderSampledImageArrayNonUniformIndexingNative
+    VkBool32                                        shaderStorageBufferArrayNonUniformIndexingNative
+    VkBool32                                        shaderStorageImageArrayNonUniformIndexingNative
+    VkBool32                                        shaderInputAttachmentArrayNonUniformIndexingNative
+    VkBool32                                        robustBufferAccessUpdateAfterBind
+    VkBool32                                        quadDivergentImplicitLod
+    u32                                             maxPerStageDescriptorUpdateAfterBindSamplers
+    u32                                             maxPerStageDescriptorUpdateAfterBindUniformBuffers
+    u32                                             maxPerStageDescriptorUpdateAfterBindStorageBuffers
+    u32                                             maxPerStageDescriptorUpdateAfterBindSampledImages
+    u32                                             maxPerStageDescriptorUpdateAfterBindStorageImages
+    u32                                             maxPerStageDescriptorUpdateAfterBindInputAttachments
+    u32                                             maxPerStageUpdateAfterBindResources
+    u32                                             maxDescriptorSetUpdateAfterBindSamplers
+    u32                                             maxDescriptorSetUpdateAfterBindUniformBuffers
+    u32                                             maxDescriptorSetUpdateAfterBindUniformBuffersDynamic
+    u32                                             maxDescriptorSetUpdateAfterBindStorageBuffers
+    u32                                             maxDescriptorSetUpdateAfterBindStorageBuffersDynamic
+    u32                                             maxDescriptorSetUpdateAfterBindSampledImages
+    u32                                             maxDescriptorSetUpdateAfterBindStorageImages
+    u32                                             maxDescriptorSetUpdateAfterBindInputAttachments
+}
+
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkDescriptorSetVariableDescriptorCountAllocateInfoEXT {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    u32                                             descriptorSetCount
+    const u32*                                      pDescriptorCounts
+}
+
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkDescriptorSetVariableDescriptorCountLayoutSupportEXT {
+    VkStructureType                                 sType
+    void*                                           pNext
+    u32                                             maxVariableDescriptorCount
+}
+
 @extension("VK_KHR_maintenance3") // 169
 class VkPhysicalDeviceMaintenance3PropertiesKHR {
     VkStructureType                                 sType
@@ -6363,6 +6724,15 @@
     VkQueueGlobalPriorityEXT                        globalPriority
 }
 
+@extension("VK_KHR_8bit_storage") // 178
+class VkPhysicalDevice8BitStorageFeaturesKHR {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkBool32                                        storageBuffer8BitAccess
+    VkBool32                                        uniformAndStorageBuffer8BitAccess
+    VkBool32                                        storagePushConstant8
+}
+
 @extension("VK_EXT_external_memory_host") // 179
 class VkImportMemoryHostPointerInfoEXT {
     VkStructureType                                 sType
@@ -6385,6 +6755,62 @@
     VkDeviceSize                                    minImportedHostPointerAlignment
 }
 
+@extension("VK_AMD_shader_core_properties") // 186
+class VkPhysicalDeviceShaderCorePropertiesAMD {
+    VkStructureType                                 sType
+    void*                                           pNext
+    u32                                             shaderEngineCount
+    u32                                             shaderArraysPerEngineCount
+    u32                                             computeUnitsPerShaderArray
+    u32                                             simdPerComputeUnit
+    u32                                             wavefrontsPerSimd
+    u32                                             wavefrontSize
+    u32                                             sgprsPerSimd
+    u32                                             minSgprAllocation
+    u32                                             maxSgprAllocation
+    u32                                             sgprAllocationGranularity
+    u32                                             vgprsPerSimd
+    u32                                             minVgprAllocation
+    u32                                             maxVgprAllocation
+    u32                                             vgprAllocationGranularity
+}
+
+@extension("VK_EXT_vertex_attribute_divisor") // 191
+class VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT {
+    VkStructureType                                 sType
+    void*                                           pNext
+    u32                                             maxVertexAttribDivisor
+}
+
+@extension("VK_EXT_vertex_attribute_divisor") // 191
+class VkVertexInputBindingDivisorDescriptionEXT {
+    u32                                             binding
+    u32                                             divisor
+}
+
+@extension("VK_EXT_vertex_attribute_divisor") // 191
+class VkPipelineVertexInputDivisorStateCreateInfoEXT {
+    VkStructureType                                     sType
+    const void*                                         pNext
+    u32                                                 vertexBindingDivisorCount
+    const VkVertexInputBindingDivisorDescriptionEXT*    pVertexBindingDivisors
+}
+
+@extension("VK_NV_device_diagnostic_checkpoints") // 207
+class VkQueueFamilyCheckpointPropertiesNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkPipelineStageFlags                            checkpointExecutionStageMask
+}
+
+@extension("VK_NV_device_diagnostic_checkpoints") // 207
+class VkCheckpointDataNV {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkPipelineStageFlagBits                         stage
+    void*                                           pCheckpointMarker
+}
+
 
 ////////////////
 //  Commands  //
@@ -9563,6 +9989,17 @@
         const VkWriteDescriptorSet*                 pDescriptorWrites) {
 }
 
+@extension("VK_EXT_conditional_rendering") // 82
+cmd void vkCmdBeginConditionalRenderingEXT(
+        VkCommandBuffer                             commandBuffer,
+        const VkConditionalRenderingBeginInfoEXT*   pConditionalRenderingBegin) {
+}
+
+@extension("VK_EXT_conditional_rendering") // 82
+cmd void vkCmdEndConditionalRenderingEXT(
+        VkCommandBuffer                             commandBuffer) {
+}
+
 @extension("VK_KHR_descriptor_update_template") // 86
 cmd VkResult vkCreateDescriptorUpdateTemplateKHR(
         VkDevice                                    device,
@@ -9782,6 +10219,35 @@
         const VkHdrMetadataEXT*                     pMetadata) {
 }
 
+@extension("VK_KHR_create_renderpass2") // 110
+cmd VkResult vkCreateRenderPass2KHR(
+        VkDevice                                    device,
+        const VkRenderPassCreateInfo2KHR*           pCreateInfo,
+        const VkAllocationCallbacks*                pAllocator,
+        VkRenderPass*                               pRenderPass) {
+    return ?
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+cmd void vkCmdBeginRenderPass2KHR(
+        VkCommandBuffer                             commandBuffer,
+        const VkRenderPassBeginInfo*                pRenderPassBegin,
+        const VkSubpassBeginInfoKHR*                pSubpassBeginInfo) {
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+cmd void vkCmdNextSubpass2KHR(
+        VkCommandBuffer                             commandBuffer,
+        const VkSubpassBeginInfoKHR*                pSubpassBeginInfo,
+        const VkSubpassEndInfoKHR*                  pSubpassEndInfo) {
+}
+
+@extension("VK_KHR_create_renderpass2") // 110
+cmd void vkCmdEndRenderPass2KHR(
+        VkCommandBuffer                             commandBuffer,
+        const VkSubpassEndInfoKHR*                  pSubpassEndInfo) {
+}
+
 @extension("VK_KHR_shared_presentable_image") // 112
 cmd VkResult vkGetSwapchainStatusKHR(
         VkDevice                                    device,
@@ -9843,6 +10309,39 @@
     return ?
 }
 
+@extension("VK_KHR_display_properties2") // 122
+cmd VkResult vkGetPhysicalDeviceDisplayProperties2KHR(
+        VkPhysicalDevice                            physicalDevice,
+        u32*                                        pPropertyCount,
+        VkDisplayProperties2KHR*                    pProperties) {
+    return ?
+}
+
+@extension("VK_KHR_display_properties2") // 122
+cmd VkResult vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
+        VkPhysicalDevice                            physicalDevice,
+        u32*                                        pPropertyCount,
+        VkDisplayPlaneProperties2KHR*               pProperties) {
+    return ?
+}
+
+@extension("VK_KHR_display_properties2") // 122
+cmd VkResult vkGetDisplayModeProperties2KHR(
+        VkPhysicalDevice                            physicalDevice,
+        VkDisplayKHR                                display,
+        u32*                                        pPropertyCount,
+        VkDisplayModeProperties2KHR*                pProperties) {
+    return ?
+}
+
+@extension("VK_KHR_display_properties2") // 122
+cmd VkResult vkGetDisplayPlaneCapabilities2KHR(
+        VkPhysicalDevice                            physicalDevice,
+        const VkDisplayPlaneInfo2KHR*               pDisplayPlaneInfo,
+        VkDisplayPlaneCapabilities2KHR*             pCapabilities) {
+    return ?
+}
+
 @extension("VK_MVK_ios_surface") // 123
 cmd VkResult vkCreateIOSSurfaceMVK(
         VkInstance                                  instance,
@@ -9878,36 +10377,36 @@
         const VkDebugUtilsObjectNameInfoEXT*        pNameInfo) {
     return ?
 }
- 
+
 @extension("VK_EXT_debug_utils") // 129
 cmd VkResult vkSetDebugUtilsObjectTagEXT(
         VkDevice                                    device,
         const VkDebugUtilsObjectTagInfoEXT*         pTagInfo) {
     return ?
 }
- 
+
 @extension("VK_EXT_debug_utils") // 129
 cmd void vkQueueBeginDebugUtilsLabelEXT(
         VkQueue                                     queue,
         const VkDebugUtilsLabelEXT*                 pLabelInfo) {
 }
- 
+
 @extension("VK_EXT_debug_utils") // 129
 cmd void vkQueueEndDebugUtilsLabelEXT(VkQueue       queue) {
 }
- 
+
 @extension("VK_EXT_debug_utils") // 129
 cmd void vkQueueInsertDebugUtilsLabelEXT(
         VkQueue                                     queue,
         const VkDebugUtilsLabelEXT*                 pLabelInfo) {
 }
- 
+
 @extension("VK_EXT_debug_utils") // 129
 cmd void vkCmdBeginDebugUtilsLabelEXT(
         VkCommandBuffer                             commandBuffer,
         const VkDebugUtilsLabelEXT*                 pLabelInfo) {
 }
- 
+
 @extension("VK_EXT_debug_utils") // 129
 cmd void vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
 }
@@ -10068,6 +10567,28 @@
         VkDescriptorSetLayoutSupportKHR*            pSupport) {
 }
 
+@extension("VK_KHR_draw_indirect_count") // 170
+cmd void vkCmdDrawIndirectCountKHR(
+        VkCommandBuffer                             commandBuffer,
+        VkBuffer                                    buffer,
+        VkDeviceSize                                offset,
+        VkBuffer                                    countBuffer,
+        VkDeviceSize                                countBufferOffset,
+        u32                                         maxDrawCount,
+        u32                                         stride) {
+}
+
+@extension("VK_KHR_draw_indirect_count") // 170
+cmd void vkCmdDrawIndexedIndirectCountKHR(
+        VkCommandBuffer                             commandBuffer,
+        VkBuffer                                    buffer,
+        VkDeviceSize                                offset,
+        VkBuffer                                    countBuffer,
+        VkDeviceSize                                countBufferOffset,
+        u32                                         maxDrawCount,
+        u32                                         stride) {
+}
+
 @extension("VK_EXT_external_memory_host") // 179
 cmd VkResult vkGetMemoryHostPointerPropertiesEXT(
         VkDevice                                    device,
@@ -10077,6 +10598,29 @@
     return ?
 }
 
+@extension("VK_AMD_buffer_marker") // 180
+cmd void vkCmdWriteBufferMarkerAMD(
+        VkCommandBuffer                             commandBuffer,
+        VkPipelineStageFlagBits                     pipelineStage,
+        VkBuffer                                    dstBuffer,
+        VkDeviceSize                                dstOffset,
+        u32                                         marker) {
+}
+
+@extension("VK_NV_device_diagnostic_checkpoints") // 207
+cmd void vkCmdSetCheckpointNV(
+        VkCommandBuffer                             commandBuffer,
+        const void*                                 pCheckpointMarker) {
+}
+
+@extension("VK_NV_device_diagnostic_checkpoints") // 207
+cmd void vkGetQueueCheckpointDataNV(
+        VkQueue                                     queue,
+        u32*                                        pCheckpointDataCount,
+        VkCheckpointDataNV*                         pCheckpointData) {
+}
+
+
 ////////////////
 // Validation //
 ////////////////
diff --git a/vulkan/doc/README b/vulkan/doc/README
new file mode 100644
index 0000000..d1dc2e1
--- /dev/null
+++ b/vulkan/doc/README
@@ -0,0 +1,2 @@
+The former contents of implementors_guide/ are now at
+https://source.android.com/devices/graphics/implement-vulkan
diff --git a/vulkan/doc/implementors_guide/implementors_guide-docinfo.adoc b/vulkan/doc/implementors_guide/implementors_guide-docinfo.adoc
deleted file mode 100644
index 69b8c61..0000000
--- a/vulkan/doc/implementors_guide/implementors_guide-docinfo.adoc
+++ /dev/null
@@ -1,23 +0,0 @@
-<style type="text/css">
-
-code,div.listingblock {
-	max-width: 68em;
-}
-
-p {
-    max-width: 50em;
-}
-
-table {
-    max-width: 50em;
-}
-
-table.tableblock {
-  border-width: 1px;
-}
-
-h2 {
-    max-width: 35em;
-}
-
-</style>
diff --git a/vulkan/doc/implementors_guide/implementors_guide.adoc b/vulkan/doc/implementors_guide/implementors_guide.adoc
deleted file mode 100644
index 24af950..0000000
--- a/vulkan/doc/implementors_guide/implementors_guide.adoc
+++ /dev/null
@@ -1,209 +0,0 @@
-// asciidoc -b html5 -d book -f implementors_guide.conf implementors_guide.adoc
-= Vulkan on Android Implementor's Guide =
-:toc: right
-:numbered:
-:revnumber: 5
-
-This document is intended for GPU IHVs writing Vulkan drivers for Android, and OEMs integrating them for specific devices. It describes how a Vulkan driver interacts with the system, how GPU-specific tools should be installed, and Android-specific requirements.
-
-== Architecture ==
-
-The primary interface between Vulkan applications and a device's Vulkan driver is the loader, which is part of AOSP and installed at +/system/lib[64]/libvulkan.so+. The loader provides the core Vulkan API entry points, as well as entry points of a few extensions that are required on Android and always present. In particular, the window system integration (WSI) extensions are exported by the loader and primarily implemented in it rather than the driver. The loader also supports enumerating and loading layers which can expose additional extensions and/or intercept core API calls on their way to the driver.
-
-The NDK will include a stub +libvulkan.so+ exporting the same symbols as the loader. Calling the Vulkan functions exported from +libvulkan.so+ will enter trampoline functions in the loader which will dispatch to the appropriate layer or driver based on their first argument. The +vkGet*ProcAddr+ calls will return the function pointers that the trampolines would dispatch to, so calling through these function pointers rather than the exported symbols will be slightly more efficient since it skips the trampoline and dispatch.
-
-=== Driver Enumeration and Loading ===
-
-Android expects the GPUs available to the system to be known when the system image is built, so its driver enumeration process isn't as elaborate as on other platforms. The loader will use the existing HAL mechanism for discovering and loading the driver. As of this writing, the preferred paths for 32-bit and 64-bit Vulkan drivers are:
-
-    /vendor/lib/hw/vulkan.<ro.product.platform>.so
-    /vendor/lib64/hw/vulkan.<ro.product.platform>.so
-
-where +<ro.product.platform>+ is replaced by the value of the system property of that name. See https://android.googlesource.com/platform/hardware/libhardware/+/master/hardware.c[libhardware/hardware.c] for details and supported alternative locations.
-
-The Vulkan +hw_module_t+ derivative is currently trivial. If support for multiple drivers is ever added, the HAL module will export a list of strings that can be passed to the module +open+ call. For the time being, only one driver is supported, and the constant string +HWVULKAN_DEVICE_0+ is passed to +open+.
-
-The Vulkan +hw_device_t+ derivative corresponds to a single driver, though that driver can support multiple Vulkan physical devices. The +hw_device_t+ structure contains a function pointer for the +vkGetInstanceProcAddr+ function. The loader finds all other driver Vulkan functions by calling that +vkGetInstanceProcAddr+ function.
-
-=== Layer Discovery and Loading ===
-
-Android's security model and policies differ significantly from other platforms. In particular, Android does not allow loading external code into a non-debuggable process on production (non-rooted) devices, nor does it allow external code to inspect or control the process's memory/state/etc. This includes a prohibition on saving core dumps, API traces, etc. to disk for later inspection. So only layers delivered as part of the application will be enabled on production devices, and drivers must also not provide functionality that violates these policies.
-
-There are three major use cases for layers:
-
-1. Development-time layers: validation layers, shims for tracing/profiling/debugging tools, etc. These shouldn't be installed on the system image of production devices: they would be a waste of space for most users, and they should be updateable without requiring a system update. A developer wishing to use one of these during development has the ability to modify their application package (e.g. adding a file to their native libraries directory). IHV and OEM engineers who are trying to diagnose failures in shipping, unmodifiable apps are assumed to have access to non-production (rooted) builds of the system image.
-
-2. Utility layers, such as a layer that implements a heap for device memory. These layers will almost always expose extensions. Developers choose which layers, and which versions of those layers, to use in their application; different applications that use the same layer may still use different versions. Developers will choose which of these layers to ship in their application package.
-
-3. Injected layers, like framerate, social network, or game launcher overlays, which are provided by the user or some other application without the application's knowledge or consent. These violate Android's security policies and will not be supported.
-
-In the normal state the loader will only search in the application's normal library search path (as defined by the system ClassLoader) for layers. It will attempt to load any shared library named +libVkLayer_*.so+ as a layer library. Android does not use manifests to describe layers: because layers must have been deliberately included in the application by the developer, the motivation for manifests on other platforms don't apply.
-
-On debuggable devices (+ro.debuggable+ property exists and is non-zero, generally rooted or engineering builds) the loader will also search the directory +/data/local/debug/vulkan+ and attempt to load layer libraries it finds there. This directory doesn't exist by default. On Android N and later, because this location is writable by adb, SELinux policies prevent mapping code located here as executable. So to use layers from here, SELinux enforcement must be disabled: +adb shell setenforce 0+. This mechanism is not intended for application developers, only for IHV and OEM engineers working on test devices that don't have private or sensitive data.
-
-Our goal is to allow layers to be ported with only build-environment changes between Android and other platforms. For this to work, layers must properly implement things like +vkGetInstanceLayerProperties+ and +vkGetInstanceExtensionProperties+, even though the LunarG loader doesn't use them (it gets the information from manifests instead).
-
-== Window System Integration ==
-
-The +vk_wsi_swapchin+ and +vk_wsi_device_swapchain+ extensions are primarily be implemented by the platform and live in +libvulkan.so+. The +VkSwapchain+ object and all interaction with +ANativeWindow+ will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver's +vkGetDeviceProcAddr+ functions, after passing through any enabled layers.
-
-Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on +format+ and +imageUsage+, but also on the intended usage of the swapchain. The swapchain usage bits are defined as
-[source,c]
-----
-typedef enum VkSwapchainImageUsageFlagBitsANDROID {
-    VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID = 0x00000001,
-    VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
-} VkSwapchainImageUsageFlagBitsANDROID;
-typedef VkFlags VkSwapchainImageUsageFlagsANDROID;
-----
-
-Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling
-[source,c]
-----
-VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
-    VkDevice            device,
-    VkFormat            format,
-    VkImageUsageFlags   imageUsage,
-    VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
-    uint64_t*           grallocConsumerUsage,
-    uint64_t*           grallocProducerUsage,
-);
-----
-The +format+ and +imageUsage+ parameters are taken from the +VkSwapchainCreateInfoKHR+ structure. The driver should fill +*grallocConsumerUsage+ and +*grallocProducerUsage+ with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.
-
-An older version of this function is deprecated but still supported for backwards compatibility; it will be used if +vkGetSwapchainGrallocUsage2ANDROID+ is not supported:
-[source,c]
-----
-VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
-    VkDevice            device,
-    VkFormat            format,
-    VkImageUsageFlags   imageUsage,
-    int*                grallocUsage
-);
-----
-
-+VkNativeBufferANDROID+ is a +vkCreateImage+ extension structure for creating an image backed by a gralloc buffer. This structure is provided to +vkCreateImage+ in the +VkImageCreateInfo+ structure chain. Calls to +vkCreateImage+ with this structure will happen during the first call to +vkGetSwapChainInfoWSI(.. VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)+. The WSI implementation will allocate the number of native buffers requested for the swapchain, then create a +VkImage+ for each one.
-
-[source,c]
-----
-typedef struct {
-    VkStructureType             sType; // must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID
-    const void*                 pNext;
-
-    // Buffer handle and stride returned from gralloc alloc()
-    buffer_handle_t             handle;
-    int                         stride;
-
-    // Gralloc format and usage requested when the buffer was allocated.
-    int                         format;
-    int                         usage; // deprecated
-    struct {
-        uint64_t                consumer;
-        uint64_t                producer;
-    } usage2;
-} VkNativeBufferANDROID;
-----
-
-When creating a gralloc-backed image, the +VkImageCreateInfo+ will have:
-[source,txt]
-----
-  .imageType           = VK_IMAGE_TYPE_2D
-  .format              = a VkFormat matching the format requested for the gralloc buffer
-  .extent              = the 2D dimensions requested for the gralloc buffer
-  .mipLevels           = 1
-  .arraySize           = 1
-  .samples             = 1
-  .tiling              = VK_IMAGE_TILING_OPTIMAL
-  .usage               = VkSwapChainCreateInfoWSI::imageUsageFlags
-  .flags               = 0
-  .sharingMode         = VkSwapChainCreateInfoWSI::sharingMode
-  .queueFamilyCount    = VkSwapChainCreateInfoWSI::queueFamilyCount
-  .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices
-----
-
-Additionally, when any swapchain image usage flags are required for the swapchain, the platform will provide a +VkSwapchainImageCreateInfoANDROID+ extension structure in the +VkImageCreateInfo+ chain provided to +vkCreateImage+, containing the swapchain image usage flags:
-[source,c]
-----
-typedef struct {
-    VkStructureType                        sType; // must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID
-    const void*                            pNext;
-
-    VkSwapchainImageUsageFlagsANDROID      usage;
-} VkSwapchainImageCreateInfoANDROID;
-----
-
-+vkAcquireImageANDROID+ acquires ownership of a swapchain image and imports an
-externally-signalled native fence into both an existing VkSemaphore object
-and an existing VkFence object:
-
-[source,c]
-----
-VkResult VKAPI vkAcquireImageANDROID(
-    VkDevice            device,
-    VkImage             image,
-    int                 nativeFenceFd,
-    VkSemaphore         semaphore,
-    VkFence             fence
-);
-----
-
-This function is called during +vkAcquireNextImageWSI+ to import a native
-fence into the +VkSemaphore+ and +VkFence+ objects provided by the
-application. Both semaphore and fence objects are optional in this call. The
-driver may also use this opportunity to recognize and handle any external
-changes to the gralloc buffer state; many drivers won't need to do anything
-here. This call puts the +VkSemaphore+ and +VkFence+ into the same "pending"
-state as +vkQueueSignalSemaphore+ and +vkQueueSubmit+ respectively, so queues
-can wait on the semaphore and the application can wait on the fence. Both
-objects become signalled when the underlying native fence signals; if the
-native fence has already signalled, then the semaphore will be in the signalled
-state when this function returns. The driver takes ownership of the fence fd
-and is responsible for closing it when no longer needed. It must do so even if
-neither a semaphore or fence object is provided, or even if
-+vkAcquireImageANDROID+ fails and returns an error. If +fenceFd+ is -1, it
-is as if the native fence was already signalled.
-
-+vkQueueSignalReleaseImageANDROID+ prepares a swapchain image for external use, and creates a native fence and schedules it to be signalled when prior work on the queue has completed.
-
-[source,c]
-----
-VkResult VKAPI vkQueueSignalReleaseImageANDROID(
-    VkQueue             queue,
-    uint32_t            waitSemaphoreCount,
-    const VkSemaphore*  pWaitSemaphores,
-    VkImage             image,
-    int*                pNativeFenceFd
-);
-----
-
-This will be called during +vkQueuePresentWSI+ on the provided queue. Effects are similar to +vkQueueSignalSemaphore+, except with a native fence instead of a semaphore. The native fence must: not signal until the +waitSemaphoreCount+ semaphores in +pWaitSemaphores+ have signaled. Unlike +vkQueueSignalSemaphore+, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set +*pNativeFenceFd+ to -1. The file descriptor returned in +*pNativeFenceFd+ is owned and will be closed by the caller. Many drivers will be able to ignore the +image+ parameter, but some may need to prepare CPU-side data structures associated with a gralloc buffer for use by external image consumers. Preparing buffer contents for use by external consumers should have been done asynchronously as part of transitioning the image to +VK_IMAGE_LAYOUT_PRESENT_SRC_KHR+.
-
-If +image+ was created with +VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID+, then the driver must tolerate +vkQueueSignalReleaseImageANDROID+ being called repeatedly without intervening calls to +vkAcquireImageANDROID+.
-
-== History ==
-
-. *2015-07-08* Initial version
-. *2015-08-16*
-   * Renamed to Implementor's Guide
-   * Wording and formatting changes
-   * Updated based on resolution of Khronos bug 14265
-   * Deferred support for multiple drivers
-. *2015-11-04*
-   * Added vkGetSwapchainGrallocUsageANDROID
-   * Replaced vkImportNativeFenceANDROID and vkQueueSignalNativeFenceANDROID
-     with vkAcquireImageANDROID and vkQueueSignalReleaseImageANDROID, to allow
-     drivers to known the ownership state of swapchain images.
-. *2015-12-03*
-   * Added a VkFence parameter to vkAcquireImageANDROID corresponding to the
-     parameter added to vkAcquireNextImageKHR.
-. *2016-01-08*
-   * Added waitSemaphoreCount and pWaitSemaphores parameters to vkQueueSignalReleaseImageANDROID.
-. *2016-06-17*
-   * Updates to reflect final behavior, closed some TBDs now that they've BDed.
-. *2017-01-06*
-   * Extension version 6
-   * Added VkSwapchainImageUsageFlagBitsANDROID
-   * Added vkGetSwapchainGrallocUsage2ANDROID
-   * Added VkSwapchainImageCreateInfoANDROID
-. *2017-02-09*
-   * Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
\ No newline at end of file
diff --git a/vulkan/doc/implementors_guide/implementors_guide.conf b/vulkan/doc/implementors_guide/implementors_guide.conf
deleted file mode 100644
index 572a4d9..0000000
--- a/vulkan/doc/implementors_guide/implementors_guide.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-[attributes]
-newline=\n
-
-[replacements]
-\+\/-=&plusmn;
diff --git a/vulkan/doc/implementors_guide/implementors_guide.html b/vulkan/doc/implementors_guide/implementors_guide.html
deleted file mode 100644
index 9fecce5..0000000
--- a/vulkan/doc/implementors_guide/implementors_guide.html
+++ /dev/null
@@ -1,1076 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta name="generator" content="AsciiDoc 8.6.9">
-<title>Vulkan on Android Implementor&#8217;s Guide</title>
-<style type="text/css">
-/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
-
-/* Default font. */
-body {
-  font-family: Georgia,serif;
-}
-
-/* Title font. */
-h1, h2, h3, h4, h5, h6,
-div.title, caption.title,
-thead, p.table.header,
-#toctitle,
-#author, #revnumber, #revdate, #revremark,
-#footer {
-  font-family: Arial,Helvetica,sans-serif;
-}
-
-body {
-  margin: 1em 5% 1em 5%;
-}
-
-a {
-  color: blue;
-  text-decoration: underline;
-}
-a:visited {
-  color: fuchsia;
-}
-
-em {
-  font-style: italic;
-  color: navy;
-}
-
-strong {
-  font-weight: bold;
-  color: #083194;
-}
-
-h1, h2, h3, h4, h5, h6 {
-  color: #527bbd;
-  margin-top: 1.2em;
-  margin-bottom: 0.5em;
-  line-height: 1.3;
-}
-
-h1, h2, h3 {
-  border-bottom: 2px solid silver;
-}
-h2 {
-  padding-top: 0.5em;
-}
-h3 {
-  float: left;
-}
-h3 + * {
-  clear: left;
-}
-h5 {
-  font-size: 1.0em;
-}
-
-div.sectionbody {
-  margin-left: 0;
-}
-
-hr {
-  border: 1px solid silver;
-}
-
-p {
-  margin-top: 0.5em;
-  margin-bottom: 0.5em;
-}
-
-ul, ol, li > p {
-  margin-top: 0;
-}
-ul > li     { color: #aaa; }
-ul > li > * { color: black; }
-
-.monospaced, code, pre {
-  font-family: "Courier New", Courier, monospace;
-  font-size: inherit;
-  color: navy;
-  padding: 0;
-  margin: 0;
-}
-pre {
-  white-space: pre-wrap;
-}
-
-#author {
-  color: #527bbd;
-  font-weight: bold;
-  font-size: 1.1em;
-}
-#email {
-}
-#revnumber, #revdate, #revremark {
-}
-
-#footer {
-  font-size: small;
-  border-top: 2px solid silver;
-  padding-top: 0.5em;
-  margin-top: 4.0em;
-}
-#footer-text {
-  float: left;
-  padding-bottom: 0.5em;
-}
-#footer-badges {
-  float: right;
-  padding-bottom: 0.5em;
-}
-
-#preamble {
-  margin-top: 1.5em;
-  margin-bottom: 1.5em;
-}
-div.imageblock, div.exampleblock, div.verseblock,
-div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
-div.admonitionblock {
-  margin-top: 1.0em;
-  margin-bottom: 1.5em;
-}
-div.admonitionblock {
-  margin-top: 2.0em;
-  margin-bottom: 2.0em;
-  margin-right: 10%;
-  color: #606060;
-}
-
-div.content { /* Block element content. */
-  padding: 0;
-}
-
-/* Block element titles. */
-div.title, caption.title {
-  color: #527bbd;
-  font-weight: bold;
-  text-align: left;
-  margin-top: 1.0em;
-  margin-bottom: 0.5em;
-}
-div.title + * {
-  margin-top: 0;
-}
-
-td div.title:first-child {
-  margin-top: 0.0em;
-}
-div.content div.title:first-child {
-  margin-top: 0.0em;
-}
-div.content + div.title {
-  margin-top: 0.0em;
-}
-
-div.sidebarblock > div.content {
-  background: #ffffee;
-  border: 1px solid #dddddd;
-  border-left: 4px solid #f0f0f0;
-  padding: 0.5em;
-}
-
-div.listingblock > div.content {
-  border: 1px solid #dddddd;
-  border-left: 5px solid #f0f0f0;
-  background: #f8f8f8;
-  padding: 0.5em;
-}
-
-div.quoteblock, div.verseblock {
-  padding-left: 1.0em;
-  margin-left: 1.0em;
-  margin-right: 10%;
-  border-left: 5px solid #f0f0f0;
-  color: #888;
-}
-
-div.quoteblock > div.attribution {
-  padding-top: 0.5em;
-  text-align: right;
-}
-
-div.verseblock > pre.content {
-  font-family: inherit;
-  font-size: inherit;
-}
-div.verseblock > div.attribution {
-  padding-top: 0.75em;
-  text-align: left;
-}
-/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
-div.verseblock + div.attribution {
-  text-align: left;
-}
-
-div.admonitionblock .icon {
-  vertical-align: top;
-  font-size: 1.1em;
-  font-weight: bold;
-  text-decoration: underline;
-  color: #527bbd;
-  padding-right: 0.5em;
-}
-div.admonitionblock td.content {
-  padding-left: 0.5em;
-  border-left: 3px solid #dddddd;
-}
-
-div.exampleblock > div.content {
-  border-left: 3px solid #dddddd;
-  padding-left: 0.5em;
-}
-
-div.imageblock div.content { padding-left: 0; }
-span.image img { border-style: none; vertical-align: text-bottom; }
-a.image:visited { color: white; }
-
-dl {
-  margin-top: 0.8em;
-  margin-bottom: 0.8em;
-}
-dt {
-  margin-top: 0.5em;
-  margin-bottom: 0;
-  font-style: normal;
-  color: navy;
-}
-dd > *:first-child {
-  margin-top: 0.1em;
-}
-
-ul, ol {
-    list-style-position: outside;
-}
-ol.arabic {
-  list-style-type: decimal;
-}
-ol.loweralpha {
-  list-style-type: lower-alpha;
-}
-ol.upperalpha {
-  list-style-type: upper-alpha;
-}
-ol.lowerroman {
-  list-style-type: lower-roman;
-}
-ol.upperroman {
-  list-style-type: upper-roman;
-}
-
-div.compact ul, div.compact ol,
-div.compact p, div.compact p,
-div.compact div, div.compact div {
-  margin-top: 0.1em;
-  margin-bottom: 0.1em;
-}
-
-tfoot {
-  font-weight: bold;
-}
-td > div.verse {
-  white-space: pre;
-}
-
-div.hdlist {
-  margin-top: 0.8em;
-  margin-bottom: 0.8em;
-}
-div.hdlist tr {
-  padding-bottom: 15px;
-}
-dt.hdlist1.strong, td.hdlist1.strong {
-  font-weight: bold;
-}
-td.hdlist1 {
-  vertical-align: top;
-  font-style: normal;
-  padding-right: 0.8em;
-  color: navy;
-}
-td.hdlist2 {
-  vertical-align: top;
-}
-div.hdlist.compact tr {
-  margin: 0;
-  padding-bottom: 0;
-}
-
-.comment {
-  background: yellow;
-}
-
-.footnote, .footnoteref {
-  font-size: 0.8em;
-}
-
-span.footnote, span.footnoteref {
-  vertical-align: super;
-}
-
-#footnotes {
-  margin: 20px 0 20px 0;
-  padding: 7px 0 0 0;
-}
-
-#footnotes div.footnote {
-  margin: 0 0 5px 0;
-}
-
-#footnotes hr {
-  border: none;
-  border-top: 1px solid silver;
-  height: 1px;
-  text-align: left;
-  margin-left: 0;
-  width: 20%;
-  min-width: 100px;
-}
-
-div.colist td {
-  padding-right: 0.5em;
-  padding-bottom: 0.3em;
-  vertical-align: top;
-}
-div.colist td img {
-  margin-top: 0.3em;
-}
-
-@media print {
-  #footer-badges { display: none; }
-}
-
-#toc {
-  margin-bottom: 2.5em;
-}
-
-#toctitle {
-  color: #527bbd;
-  font-size: 1.1em;
-  font-weight: bold;
-  margin-top: 1.0em;
-  margin-bottom: 0.1em;
-}
-
-div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
-  margin-top: 0;
-  margin-bottom: 0;
-}
-div.toclevel2 {
-  margin-left: 2em;
-  font-size: 0.9em;
-}
-div.toclevel3 {
-  margin-left: 4em;
-  font-size: 0.9em;
-}
-div.toclevel4 {
-  margin-left: 6em;
-  font-size: 0.9em;
-}
-
-span.aqua { color: aqua; }
-span.black { color: black; }
-span.blue { color: blue; }
-span.fuchsia { color: fuchsia; }
-span.gray { color: gray; }
-span.green { color: green; }
-span.lime { color: lime; }
-span.maroon { color: maroon; }
-span.navy { color: navy; }
-span.olive { color: olive; }
-span.purple { color: purple; }
-span.red { color: red; }
-span.silver { color: silver; }
-span.teal { color: teal; }
-span.white { color: white; }
-span.yellow { color: yellow; }
-
-span.aqua-background { background: aqua; }
-span.black-background { background: black; }
-span.blue-background { background: blue; }
-span.fuchsia-background { background: fuchsia; }
-span.gray-background { background: gray; }
-span.green-background { background: green; }
-span.lime-background { background: lime; }
-span.maroon-background { background: maroon; }
-span.navy-background { background: navy; }
-span.olive-background { background: olive; }
-span.purple-background { background: purple; }
-span.red-background { background: red; }
-span.silver-background { background: silver; }
-span.teal-background { background: teal; }
-span.white-background { background: white; }
-span.yellow-background { background: yellow; }
-
-span.big { font-size: 2em; }
-span.small { font-size: 0.6em; }
-
-span.underline { text-decoration: underline; }
-span.overline { text-decoration: overline; }
-span.line-through { text-decoration: line-through; }
-
-div.unbreakable { page-break-inside: avoid; }
-
-
-/*
- * xhtml11 specific
- *
- * */
-
-div.tableblock {
-  margin-top: 1.0em;
-  margin-bottom: 1.5em;
-}
-div.tableblock > table {
-  border: 3px solid #527bbd;
-}
-thead, p.table.header {
-  font-weight: bold;
-  color: #527bbd;
-}
-p.table {
-  margin-top: 0;
-}
-/* Because the table frame attribute is overriden by CSS in most browsers. */
-div.tableblock > table[frame="void"] {
-  border-style: none;
-}
-div.tableblock > table[frame="hsides"] {
-  border-left-style: none;
-  border-right-style: none;
-}
-div.tableblock > table[frame="vsides"] {
-  border-top-style: none;
-  border-bottom-style: none;
-}
-
-
-/*
- * html5 specific
- *
- * */
-
-table.tableblock {
-  margin-top: 1.0em;
-  margin-bottom: 1.5em;
-}
-thead, p.tableblock.header {
-  font-weight: bold;
-  color: #527bbd;
-}
-p.tableblock {
-  margin-top: 0;
-}
-table.tableblock {
-  border-width: 3px;
-  border-spacing: 0px;
-  border-style: solid;
-  border-color: #527bbd;
-  border-collapse: collapse;
-}
-th.tableblock, td.tableblock {
-  border-width: 1px;
-  padding: 4px;
-  border-style: solid;
-  border-color: #527bbd;
-}
-
-table.tableblock.frame-topbot {
-  border-left-style: hidden;
-  border-right-style: hidden;
-}
-table.tableblock.frame-sides {
-  border-top-style: hidden;
-  border-bottom-style: hidden;
-}
-table.tableblock.frame-none {
-  border-style: hidden;
-}
-
-th.tableblock.halign-left, td.tableblock.halign-left {
-  text-align: left;
-}
-th.tableblock.halign-center, td.tableblock.halign-center {
-  text-align: center;
-}
-th.tableblock.halign-right, td.tableblock.halign-right {
-  text-align: right;
-}
-
-th.tableblock.valign-top, td.tableblock.valign-top {
-  vertical-align: top;
-}
-th.tableblock.valign-middle, td.tableblock.valign-middle {
-  vertical-align: middle;
-}
-th.tableblock.valign-bottom, td.tableblock.valign-bottom {
-  vertical-align: bottom;
-}
-
-
-/*
- * manpage specific
- *
- * */
-
-body.manpage h1 {
-  padding-top: 0.5em;
-  padding-bottom: 0.5em;
-  border-top: 2px solid silver;
-  border-bottom: 2px solid silver;
-}
-body.manpage h2 {
-  border-style: none;
-}
-body.manpage div.sectionbody {
-  margin-left: 3em;
-}
-
-@media print {
-  body.manpage div#toc { display: none; }
-}
-
-
-</style>
-<script type="text/javascript">
-/*<![CDATA[*/
-var asciidoc = {  // Namespace.
-
-/////////////////////////////////////////////////////////////////////
-// Table Of Contents generator
-/////////////////////////////////////////////////////////////////////
-
-/* Author: Mihai Bazon, September 2002
- * http://students.infoiasi.ro/~mishoo
- *
- * Table Of Content generator
- * Version: 0.4
- *
- * Feel free to use this script under the terms of the GNU General Public
- * License, as long as you do not remove or alter this notice.
- */
-
- /* modified by Troy D. Hanson, September 2006. License: GPL */
- /* modified by Stuart Rackham, 2006, 2009. License: GPL */
-
-// toclevels = 1..4.
-toc: function (toclevels) {
-
-  function getText(el) {
-    var text = "";
-    for (var i = el.firstChild; i != null; i = i.nextSibling) {
-      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
-        text += i.data;
-      else if (i.firstChild != null)
-        text += getText(i);
-    }
-    return text;
-  }
-
-  function TocEntry(el, text, toclevel) {
-    this.element = el;
-    this.text = text;
-    this.toclevel = toclevel;
-  }
-
-  function tocEntries(el, toclevels) {
-    var result = new Array;
-    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
-    // Function that scans the DOM tree for header elements (the DOM2
-    // nodeIterator API would be a better technique but not supported by all
-    // browsers).
-    var iterate = function (el) {
-      for (var i = el.firstChild; i != null; i = i.nextSibling) {
-        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
-          var mo = re.exec(i.tagName);
-          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
-            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
-          }
-          iterate(i);
-        }
-      }
-    }
-    iterate(el);
-    return result;
-  }
-
-  var toc = document.getElementById("toc");
-  if (!toc) {
-    return;
-  }
-
-  // Delete existing TOC entries in case we're reloading the TOC.
-  var tocEntriesToRemove = [];
-  var i;
-  for (i = 0; i < toc.childNodes.length; i++) {
-    var entry = toc.childNodes[i];
-    if (entry.nodeName.toLowerCase() == 'div'
-     && entry.getAttribute("class")
-     && entry.getAttribute("class").match(/^toclevel/))
-      tocEntriesToRemove.push(entry);
-  }
-  for (i = 0; i < tocEntriesToRemove.length; i++) {
-    toc.removeChild(tocEntriesToRemove[i]);
-  }
-
-  // Rebuild TOC entries.
-  var entries = tocEntries(document.getElementById("content"), toclevels);
-  for (var i = 0; i < entries.length; ++i) {
-    var entry = entries[i];
-    if (entry.element.id == "")
-      entry.element.id = "_toc_" + i;
-    var a = document.createElement("a");
-    a.href = "#" + entry.element.id;
-    a.appendChild(document.createTextNode(entry.text));
-    var div = document.createElement("div");
-    div.appendChild(a);
-    div.className = "toclevel" + entry.toclevel;
-    toc.appendChild(div);
-  }
-  if (entries.length == 0)
-    toc.parentNode.removeChild(toc);
-},
-
-
-/////////////////////////////////////////////////////////////////////
-// Footnotes generator
-/////////////////////////////////////////////////////////////////////
-
-/* Based on footnote generation code from:
- * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
- */
-
-footnotes: function () {
-  // Delete existing footnote entries in case we're reloading the footnodes.
-  var i;
-  var noteholder = document.getElementById("footnotes");
-  if (!noteholder) {
-    return;
-  }
-  var entriesToRemove = [];
-  for (i = 0; i < noteholder.childNodes.length; i++) {
-    var entry = noteholder.childNodes[i];
-    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
-      entriesToRemove.push(entry);
-  }
-  for (i = 0; i < entriesToRemove.length; i++) {
-    noteholder.removeChild(entriesToRemove[i]);
-  }
-
-  // Rebuild footnote entries.
-  var cont = document.getElementById("content");
-  var spans = cont.getElementsByTagName("span");
-  var refs = {};
-  var n = 0;
-  for (i=0; i<spans.length; i++) {
-    if (spans[i].className == "footnote") {
-      n++;
-      var note = spans[i].getAttribute("data-note");
-      if (!note) {
-        // Use [\s\S] in place of . so multi-line matches work.
-        // Because JavaScript has no s (dotall) regex flag.
-        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
-        spans[i].innerHTML =
-          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
-          "' title='View footnote' class='footnote'>" + n + "</a>]";
-        spans[i].setAttribute("data-note", note);
-      }
-      noteholder.innerHTML +=
-        "<div class='footnote' id='_footnote_" + n + "'>" +
-        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
-        n + "</a>. " + note + "</div>";
-      var id =spans[i].getAttribute("id");
-      if (id != null) refs["#"+id] = n;
-    }
-  }
-  if (n == 0)
-    noteholder.parentNode.removeChild(noteholder);
-  else {
-    // Process footnoterefs.
-    for (i=0; i<spans.length; i++) {
-      if (spans[i].className == "footnoteref") {
-        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
-        href = href.match(/#.*/)[0];  // Because IE return full URL.
-        n = refs[href];
-        spans[i].innerHTML =
-          "[<a href='#_footnote_" + n +
-          "' title='View footnote' class='footnote'>" + n + "</a>]";
-      }
-    }
-  }
-},
-
-install: function(toclevels) {
-  var timerId;
-
-  function reinstall() {
-    asciidoc.footnotes();
-    if (toclevels) {
-      asciidoc.toc(toclevels);
-    }
-  }
-
-  function reinstallAndRemoveTimer() {
-    clearInterval(timerId);
-    reinstall();
-  }
-
-  timerId = setInterval(reinstall, 500);
-  if (document.addEventListener)
-    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
-  else
-    window.onload = reinstallAndRemoveTimer;
-}
-
-}
-asciidoc.install(2);
-/*]]>*/
-</script>
-</head>
-<body class="book">
-<div id="header">
-<h1>Vulkan on Android Implementor&#8217;s Guide</h1>
-<span id="revnumber">version 5</span>
-<div id="toc">
-  <div id="toctitle">Table of Contents</div>
-  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
-</div>
-</div>
-<div id="content">
-<div id="preamble">
-<div class="sectionbody">
-<div class="paragraph"><p>This document is intended for GPU IHVs writing Vulkan drivers for Android, and OEMs integrating them for specific devices. It describes how a Vulkan driver interacts with the system, how GPU-specific tools should be installed, and Android-specific requirements.</p></div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_architecture">1. Architecture</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>The primary interface between Vulkan applications and a device&#8217;s Vulkan driver is the loader, which is part of AOSP and installed at <span class="monospaced">/system/lib[64]/libvulkan.so</span>. The loader provides the core Vulkan API entry points, as well as entry points of a few extensions that are required on Android and always present. In particular, the window system integration (WSI) extensions are exported by the loader and primarily implemented in it rather than the driver. The loader also supports enumerating and loading layers which can expose additional extensions and/or intercept core API calls on their way to the driver.</p></div>
-<div class="paragraph"><p>The NDK will include a stub <span class="monospaced">libvulkan.so</span> exporting the same symbols as the loader. Calling the Vulkan functions exported from <span class="monospaced">libvulkan.so</span> will enter trampoline functions in the loader which will dispatch to the appropriate layer or driver based on their first argument. The <span class="monospaced">vkGet*ProcAddr</span> calls will return the function pointers that the trampolines would dispatch to, so calling through these function pointers rather than the exported symbols will be slightly more efficient since it skips the trampoline and dispatch.</p></div>
-<div class="sect2">
-<h3 id="_driver_enumeration_and_loading">1.1. Driver Enumeration and Loading</h3>
-<div class="paragraph"><p>Android expects the GPUs available to the system to be known when the system image is built, so its driver enumeration process isn&#8217;t as elaborate as on other platforms. The loader will use the existing HAL mechanism for discovering and loading the driver. As of this writing, the preferred paths for 32-bit and 64-bit Vulkan drivers are:</p></div>
-<div class="literalblock">
-<div class="content monospaced">
-<pre>/vendor/lib/hw/vulkan.&lt;ro.product.platform&gt;.so
-/vendor/lib64/hw/vulkan.&lt;ro.product.platform&gt;.so</pre>
-</div></div>
-<div class="paragraph"><p>where <span class="monospaced">&lt;ro.product.platform&gt;</span> is replaced by the value of the system property of that name. See <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/hardware.c">libhardware/hardware.c</a> for details and supported alternative locations.</p></div>
-<div class="paragraph"><p>The Vulkan <span class="monospaced">hw_module_t</span> derivative is currently trivial. If support for multiple drivers is ever added, the HAL module will export a list of strings that can be passed to the module <span class="monospaced">open</span> call. For the time being, only one driver is supported, and the constant string <span class="monospaced">HWVULKAN_DEVICE_0</span> is passed to <span class="monospaced">open</span>.</p></div>
-<div class="paragraph"><p>The Vulkan <span class="monospaced">hw_device_t</span> derivative corresponds to a single driver, though that driver can support multiple Vulkan physical devices. The <span class="monospaced">hw_device_t</span> structure contains a function pointer for the <span class="monospaced">vkGetInstanceProcAddr</span> function. The loader finds all other driver Vulkan functions by calling that <span class="monospaced">vkGetInstanceProcAddr</span> function.</p></div>
-</div>
-<div class="sect2">
-<h3 id="_layer_discovery_and_loading">1.2. Layer Discovery and Loading</h3>
-<div class="paragraph"><p>Android&#8217;s security model and policies differ significantly from other platforms. In particular, Android does not allow loading external code into a non-debuggable process on production (non-rooted) devices, nor does it allow external code to inspect or control the process&#8217;s memory/state/etc. This includes a prohibition on saving core dumps, API traces, etc. to disk for later inspection. So only layers delivered as part of the application will be enabled on production devices, and drivers must also not provide functionality that violates these policies.</p></div>
-<div class="paragraph"><p>There are three major use cases for layers:</p></div>
-<div class="olist arabic"><ol class="arabic">
-<li>
-<p>
-Development-time layers: validation layers, shims for tracing/profiling/debugging tools, etc. These shouldn&#8217;t be installed on the system image of production devices: they would be a waste of space for most users, and they should be updateable without requiring a system update. A developer wishing to use one of these during development has the ability to modify their application package (e.g. adding a file to their native libraries directory). IHV and OEM engineers who are trying to diagnose failures in shipping, unmodifiable apps are assumed to have access to non-production (rooted) builds of the system image.
-</p>
-</li>
-<li>
-<p>
-Utility layers, such as a layer that implements a heap for device memory. These layers will almost always expose extensions. Developers choose which layers, and which versions of those layers, to use in their application; different applications that use the same layer may still use different versions. Developers will choose which of these layers to ship in their application package.
-</p>
-</li>
-<li>
-<p>
-Injected layers, like framerate, social network, or game launcher overlays, which are provided by the user or some other application without the application&#8217;s knowledge or consent. These violate Android&#8217;s security policies and will not be supported.
-</p>
-</li>
-</ol></div>
-<div class="paragraph"><p>In the normal state the loader will only search in the application&#8217;s normal library search path (as defined by the system ClassLoader) for layers. It will attempt to load any shared library named <span class="monospaced">libVkLayer_*.so</span> as a layer library. Android does not use manifests to describe layers: because layers must have been deliberately included in the application by the developer, the motivation for manifests on other platforms don&#8217;t apply.</p></div>
-<div class="paragraph"><p>On debuggable devices (<span class="monospaced">ro.debuggable</span> property exists and is non-zero, generally rooted or engineering builds) the loader will also search the directory <span class="monospaced">/data/local/debug/vulkan</span> and attempt to load layer libraries it finds there. This directory doesn&#8217;t exist by default. On Android N and later, because this location is writable by adb, SELinux policies prevent mapping code located here as executable. So to use layers from here, SELinux enforcement must be disabled: <span class="monospaced">adb shell setenforce 0</span>. This mechanism is not intended for application developers, only for IHV and OEM engineers working on test devices that don&#8217;t have private or sensitive data.</p></div>
-<div class="paragraph"><p>Our goal is to allow layers to be ported with only build-environment changes between Android and other platforms. For this to work, layers must properly implement things like <span class="monospaced">vkGetInstanceLayerProperties</span> and <span class="monospaced">vkGetInstanceExtensionProperties</span>, even though the LunarG loader doesn&#8217;t use them (it gets the information from manifests instead).</p></div>
-</div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_window_system_integration">2. Window System Integration</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>The <span class="monospaced">vk_wsi_swapchin</span> and <span class="monospaced">vk_wsi_device_swapchain</span> extensions are primarily be implemented by the platform and live in <span class="monospaced">libvulkan.so</span>. The <span class="monospaced">VkSwapchain</span> object and all interaction with <span class="monospaced">ANativeWindow</span> will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver&#8217;s <span class="monospaced">vkGetDeviceProcAddr</span> functions, after passing through any enabled layers.</p></div>
-<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The swapchain usage bits are defined as</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">enum</span></span> VkSwapchainImageUsageFlagBitsANDROID <span style="color: #FF0000">{</span>
-    VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID <span style="color: #990000">=</span> <span style="color: #993399">0x00000001</span><span style="color: #990000">,</span>
-    VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM <span style="color: #990000">=</span> <span style="color: #993399">0x7FFFFFFF</span>
-<span style="color: #FF0000">}</span> VkSwapchainImageUsageFlagBitsANDROID<span style="color: #990000">;</span>
-<span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="color: #008080">VkFlags</span> VkSwapchainImageUsageFlagsANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VKAPI_ATTR <span style="color: #008080">VkResult</span> <span style="color: #008080">VKAPI_CALL</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsage2ANDROID</span></span><span style="color: #990000">(</span>
-    <span style="color: #008080">VkDevice</span>            device<span style="color: #990000">,</span>
-    <span style="color: #008080">VkFormat</span>            format<span style="color: #990000">,</span>
-    <span style="color: #008080">VkImageUsageFlags</span>   imageUsage<span style="color: #990000">,</span>
-    <span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span> swapchainImageUsage<span style="color: #990000">,</span>
-    uint64_t<span style="color: #990000">*</span>           grallocConsumerUsage<span style="color: #990000">,</span>
-    uint64_t<span style="color: #990000">*</span>           grallocProducerUsage<span style="color: #990000">,</span>
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocConsumerUsage</span> and <span class="monospaced">*grallocProducerUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div>
-<div class="paragraph"><p>An older version of this function is deprecated but still supported for backwards compatibility; it will be used if <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> is not supported:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span>
-    <span style="color: #008080">VkDevice</span>            device<span style="color: #990000">,</span>
-    <span style="color: #008080">VkFormat</span>            format<span style="color: #990000">,</span>
-    <span style="color: #008080">VkImageUsageFlags</span>   imageUsage<span style="color: #990000">,</span>
-    <span style="color: #009900">int</span><span style="color: #990000">*</span>                grallocUsage
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p><span class="monospaced">VkNativeBufferANDROID</span> is a <span class="monospaced">vkCreateImage</span> extension structure for creating an image backed by a gralloc buffer. This structure is provided to <span class="monospaced">vkCreateImage</span> in the <span class="monospaced">VkImageCreateInfo</span> structure chain. Calls to <span class="monospaced">vkCreateImage</span> with this structure will happen during the first call to <span class="monospaced">vkGetSwapChainInfoWSI(.. VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</span>. The WSI implementation will allocate the number of native buffers requested for the swapchain, then create a <span class="monospaced">VkImage</span> for each one.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
-    <span style="color: #008080">VkStructureType</span>             sType<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID</span></span>
-    <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> <span style="color: #009900">void</span><span style="color: #990000">*</span>                 pNext<span style="color: #990000">;</span>
-
-    <span style="font-style: italic"><span style="color: #9A1900">// Buffer handle and stride returned from gralloc alloc()</span></span>
-    <span style="color: #008080">buffer_handle_t</span>             handle<span style="color: #990000">;</span>
-    <span style="color: #009900">int</span>                         stride<span style="color: #990000">;</span>
-
-    <span style="font-style: italic"><span style="color: #9A1900">// Gralloc format and usage requested when the buffer was allocated.</span></span>
-    <span style="color: #009900">int</span>                         format<span style="color: #990000">;</span>
-    <span style="color: #009900">int</span>                         usage<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// deprecated</span></span>
-    <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
-        <span style="color: #008080">uint64_t</span>                consumer<span style="color: #990000">;</span>
-        <span style="color: #008080">uint64_t</span>                producer<span style="color: #990000">;</span>
-    <span style="color: #FF0000">}</span> usage2<span style="color: #990000">;</span>
-<span style="color: #FF0000">}</span> VkNativeBufferANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p>When creating a gralloc-backed image, the <span class="monospaced">VkImageCreateInfo</span> will have:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>  .imageType           = VK_IMAGE_TYPE_2D
-  .format              = a VkFormat matching the format requested for the gralloc buffer
-  .extent              = the 2D dimensions requested for the gralloc buffer
-  .mipLevels           = 1
-  .arraySize           = 1
-  .samples             = 1
-  .tiling              = VK_IMAGE_TILING_OPTIMAL
-  .usage               = VkSwapChainCreateInfoWSI::imageUsageFlags
-  .flags               = 0
-  .sharingMode         = VkSwapChainCreateInfoWSI::sharingMode
-  .queueFamilyCount    = VkSwapChainCreateInfoWSI::queueFamilyCount
-  .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices</tt></pre></div></div>
-<div class="paragraph"><p>Additionally, when any swapchain image usage flags are required for the swapchain, the platform will provide a <span class="monospaced">VkSwapchainImageCreateInfoANDROID</span> extension structure in the <span class="monospaced">VkImageCreateInfo</span> chain provided to <span class="monospaced">vkCreateImage</span>, containing the swapchain image usage flags:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
-    <span style="color: #008080">VkStructureType</span>                        sType<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID</span></span>
-    <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> <span style="color: #009900">void</span><span style="color: #990000">*</span>                            pNext<span style="color: #990000">;</span>
-
-    <span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span>      usage<span style="color: #990000">;</span>
-<span style="color: #FF0000">}</span> VkSwapchainImageCreateInfoANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p><span class="monospaced">vkAcquireImageANDROID</span> acquires ownership of a swapchain image and imports an
-externally-signalled native fence into both an existing VkSemaphore object
-and an existing VkFence object:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkAcquireImageANDROID</span></span><span style="color: #990000">(</span>
-    <span style="color: #008080">VkDevice</span>            device<span style="color: #990000">,</span>
-    <span style="color: #008080">VkImage</span>             image<span style="color: #990000">,</span>
-    <span style="color: #009900">int</span>                 nativeFenceFd<span style="color: #990000">,</span>
-    <span style="color: #008080">VkSemaphore</span>         semaphore<span style="color: #990000">,</span>
-    VkFence             fence
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>This function is called during <span class="monospaced">vkAcquireNextImageWSI</span> to import a native
-fence into the <span class="monospaced">VkSemaphore</span> and <span class="monospaced">VkFence</span> objects provided by the
-application. Both semaphore and fence objects are optional in this call. The
-driver may also use this opportunity to recognize and handle any external
-changes to the gralloc buffer state; many drivers won&#8217;t need to do anything
-here. This call puts the <span class="monospaced">VkSemaphore</span> and <span class="monospaced">VkFence</span> into the same "pending"
-state as <span class="monospaced">vkQueueSignalSemaphore</span> and <span class="monospaced">vkQueueSubmit</span> respectively, so queues
-can wait on the semaphore and the application can wait on the fence. Both
-objects become signalled when the underlying native fence signals; if the
-native fence has already signalled, then the semaphore will be in the signalled
-state when this function returns. The driver takes ownership of the fence fd
-and is responsible for closing it when no longer needed. It must do so even if
-neither a semaphore or fence object is provided, or even if
-<span class="monospaced">vkAcquireImageANDROID</span> fails and returns an error. If <span class="monospaced">fenceFd</span> is -1, it
-is as if the native fence was already signalled.</p></div>
-<div class="paragraph"><p><span class="monospaced">vkQueueSignalReleaseImageANDROID</span> prepares a swapchain image for external use, and creates a native fence and schedules it to be signalled when prior work on the queue has completed.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkQueueSignalReleaseImageANDROID</span></span><span style="color: #990000">(</span>
-    <span style="color: #008080">VkQueue</span>             queue<span style="color: #990000">,</span>
-    <span style="color: #008080">uint32_t</span>            waitSemaphoreCount<span style="color: #990000">,</span>
-    <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> VkSemaphore<span style="color: #990000">*</span>  pWaitSemaphores<span style="color: #990000">,</span>
-    <span style="color: #008080">VkImage</span>             image<span style="color: #990000">,</span>
-    <span style="color: #009900">int</span><span style="color: #990000">*</span>                pNativeFenceFd
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>This will be called during <span class="monospaced">vkQueuePresentWSI</span> on the provided queue. Effects are similar to <span class="monospaced">vkQueueSignalSemaphore</span>, except with a native fence instead of a semaphore. The native fence must: not signal until the <span class="monospaced">waitSemaphoreCount</span> semaphores in <span class="monospaced">pWaitSemaphores</span> have signaled. Unlike <span class="monospaced">vkQueueSignalSemaphore</span>, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set <span class="monospaced">*pNativeFenceFd</span> to -1. The file descriptor returned in <span class="monospaced">*pNativeFenceFd</span> is owned and will be closed by the caller. Many drivers will be able to ignore the <span class="monospaced">image</span> parameter, but some may need to prepare CPU-side data structures associated with a gralloc buffer for use by external image consumers. Preparing buffer contents for use by external consumers should have been done asynchronously as part of transitioning the image to <span class="monospaced">VK_IMAGE_LAYOUT_PRESENT_SRC_KHR</span>.</p></div>
-<div class="paragraph"><p>If <span class="monospaced">image</span> was created with <span class="monospaced">VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID</span>, then the driver must tolerate <span class="monospaced">vkQueueSignalReleaseImageANDROID</span> being called repeatedly without intervening calls to <span class="monospaced">vkAcquireImageANDROID</span>.</p></div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_history">3. History</h2>
-<div class="sectionbody">
-<div class="olist arabic"><ol class="arabic">
-<li>
-<p>
-<strong>2015-07-08</strong> Initial version
-</p>
-</li>
-<li>
-<p>
-<strong>2015-08-16</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Renamed to Implementor&#8217;s Guide
-</p>
-</li>
-<li>
-<p>
-Wording and formatting changes
-</p>
-</li>
-<li>
-<p>
-Updated based on resolution of Khronos bug 14265
-</p>
-</li>
-<li>
-<p>
-Deferred support for multiple drivers
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2015-11-04</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Added vkGetSwapchainGrallocUsageANDROID
-</p>
-</li>
-<li>
-<p>
-Replaced vkImportNativeFenceANDROID and vkQueueSignalNativeFenceANDROID
-     with vkAcquireImageANDROID and vkQueueSignalReleaseImageANDROID, to allow
-     drivers to known the ownership state of swapchain images.
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2015-12-03</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Added a VkFence parameter to vkAcquireImageANDROID corresponding to the
-     parameter added to vkAcquireNextImageKHR.
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2016-01-08</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Added waitSemaphoreCount and pWaitSemaphores parameters to vkQueueSignalReleaseImageANDROID.
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2016-06-17</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Updates to reflect final behavior, closed some TBDs now that they&#8217;ve BDed.
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2017-01-06</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Extension version 6
-</p>
-</li>
-<li>
-<p>
-Added VkSwapchainImageUsageFlagBitsANDROID
-</p>
-</li>
-<li>
-<p>
-Added vkGetSwapchainGrallocUsage2ANDROID
-</p>
-</li>
-<li>
-<p>
-Added VkSwapchainImageCreateInfoANDROID
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2017-02-09</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
-</p>
-</li>
-</ul></div>
-</li>
-</ol></div>
-</div>
-</div>
-</div>
-<div id="footnotes"><hr></div>
-<div id="footer">
-<div id="footer-text">
-Version 5<br>
-Last updated 2017-02-09 22:40:30 PST
-</div>
-</div>
-</body>
-</html>
diff --git a/vulkan/include/vulkan/vulkan_android.h b/vulkan/include/vulkan/vulkan_android.h
index 42521d9..07aaeda 100644
--- a/vulkan/include/vulkan/vulkan_android.h
+++ b/vulkan/include/vulkan/vulkan_android.h
@@ -56,7 +56,7 @@
 #define VK_ANDROID_external_memory_android_hardware_buffer 1
 struct AHardwareBuffer;
 
-#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 2
+#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 3
 #define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer"
 
 typedef struct VkAndroidHardwareBufferUsageANDROID {
diff --git a/vulkan/include/vulkan/vulkan_core.h b/vulkan/include/vulkan/vulkan_core.h
index 6e5ea80..d511015 100644
--- a/vulkan/include/vulkan/vulkan_core.h
+++ b/vulkan/include/vulkan/vulkan_core.h
@@ -43,7 +43,7 @@
 #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
 #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
 // Version of this file
-#define VK_HEADER_VERSION 68
+#define VK_HEADER_VERSION 82
 
 
 #define VK_NULL_HANDLE 0
@@ -147,6 +147,7 @@
     VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
     VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
     VK_ERROR_INVALID_SHADER_NV = -1000012000,
+    VK_ERROR_FRAGMENTATION_EXT = -1000161000,
     VK_ERROR_NOT_PERMITTED_EXT = -1000174001,
     VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY,
     VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE,
@@ -319,6 +320,9 @@
     VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000,
     VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000,
+    VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001,
+    VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002,
     VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
     VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000,
     VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001,
@@ -340,6 +344,13 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000,
     VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001,
     VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000,
+    VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002,
+    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = 1000109003,
+    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = 1000109004,
+    VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = 1000109005,
+    VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = 1000109006,
     VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
     VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000,
     VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001,
@@ -349,6 +360,11 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
     VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
     VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
+    VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000,
+    VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001,
+    VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002,
+    VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003,
+    VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004,
     VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
     VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
     VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000,
@@ -377,10 +393,21 @@
     VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000,
     VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
     VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004,
     VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000,
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
     VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
+    VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
+    VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
+    VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
     VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,
@@ -1200,6 +1227,16 @@
     VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
 } VkObjectType;
 
+typedef enum VkVendorId {
+    VK_VENDOR_ID_VIV = 0x10001,
+    VK_VENDOR_ID_VSI = 0x10002,
+    VK_VENDOR_ID_KAZAN = 0x10003,
+    VK_VENDOR_ID_BEGIN_RANGE = VK_VENDOR_ID_VIV,
+    VK_VENDOR_ID_END_RANGE = VK_VENDOR_ID_KAZAN,
+    VK_VENDOR_ID_RANGE_SIZE = (VK_VENDOR_ID_KAZAN - VK_VENDOR_ID_VIV + 1),
+    VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF
+} VkVendorId;
+
 typedef VkFlags VkInstanceCreateFlags;
 
 typedef enum VkFormatFeatureFlagBits {
@@ -1343,6 +1380,7 @@
     VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
     VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
     VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
+    VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000,
     VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000,
     VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkPipelineStageFlagBits;
@@ -1431,6 +1469,7 @@
     VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040,
     VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
     VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
+    VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200,
     VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkBufferUsageFlagBits;
 typedef VkFlags VkBufferUsageFlags;
@@ -1496,12 +1535,14 @@
 
 typedef enum VkDescriptorSetLayoutCreateFlagBits {
     VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001,
+    VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002,
     VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkDescriptorSetLayoutCreateFlagBits;
 typedef VkFlags VkDescriptorSetLayoutCreateFlags;
 
 typedef enum VkDescriptorPoolCreateFlagBits {
     VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001,
+    VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002,
     VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkDescriptorPoolCreateFlagBits;
 typedef VkFlags VkDescriptorPoolCreateFlags;
@@ -1540,6 +1581,7 @@
     VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
     VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
     VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000,
+    VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000,
     VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000,
     VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000,
     VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000,
@@ -2704,6 +2746,16 @@
     uint32_t    firstInstance;
 } VkDrawIndirectCommand;
 
+typedef struct VkBaseOutStructure {
+    VkStructureType               sType;
+    struct VkBaseOutStructure*    pNext;
+} VkBaseOutStructure;
+
+typedef struct VkBaseInStructure {
+    VkStructureType                    sType;
+    const struct VkBaseInStructure*    pNext;
+} VkBaseInStructure;
+
 
 typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
 typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator);
@@ -3736,6 +3788,7 @@
     VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020,
     VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040,
     VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080,
+    VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100,
     VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkSubgroupFeatureFlagBits;
 typedef VkFlags VkSubgroupFeatureFlags;
@@ -5095,7 +5148,7 @@
 
 
 #define VK_KHR_maintenance1 1
-#define VK_KHR_MAINTENANCE1_SPEC_VERSION  1
+#define VK_KHR_MAINTENANCE1_SPEC_VERSION  2
 #define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1"
 
 typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR;
@@ -5398,6 +5451,114 @@
     const void*                                 pData);
 #endif
 
+#define VK_KHR_create_renderpass2 1
+#define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1
+#define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2"
+
+typedef struct VkAttachmentDescription2KHR {
+    VkStructureType                 sType;
+    const void*                     pNext;
+    VkAttachmentDescriptionFlags    flags;
+    VkFormat                        format;
+    VkSampleCountFlagBits           samples;
+    VkAttachmentLoadOp              loadOp;
+    VkAttachmentStoreOp             storeOp;
+    VkAttachmentLoadOp              stencilLoadOp;
+    VkAttachmentStoreOp             stencilStoreOp;
+    VkImageLayout                   initialLayout;
+    VkImageLayout                   finalLayout;
+} VkAttachmentDescription2KHR;
+
+typedef struct VkAttachmentReference2KHR {
+    VkStructureType       sType;
+    const void*           pNext;
+    uint32_t              attachment;
+    VkImageLayout         layout;
+    VkImageAspectFlags    aspectMask;
+} VkAttachmentReference2KHR;
+
+typedef struct VkSubpassDescription2KHR {
+    VkStructureType                     sType;
+    const void*                         pNext;
+    VkSubpassDescriptionFlags           flags;
+    VkPipelineBindPoint                 pipelineBindPoint;
+    uint32_t                            viewMask;
+    uint32_t                            inputAttachmentCount;
+    const VkAttachmentReference2KHR*    pInputAttachments;
+    uint32_t                            colorAttachmentCount;
+    const VkAttachmentReference2KHR*    pColorAttachments;
+    const VkAttachmentReference2KHR*    pResolveAttachments;
+    const VkAttachmentReference2KHR*    pDepthStencilAttachment;
+    uint32_t                            preserveAttachmentCount;
+    const uint32_t*                     pPreserveAttachments;
+} VkSubpassDescription2KHR;
+
+typedef struct VkSubpassDependency2KHR {
+    VkStructureType         sType;
+    const void*             pNext;
+    uint32_t                srcSubpass;
+    uint32_t                dstSubpass;
+    VkPipelineStageFlags    srcStageMask;
+    VkPipelineStageFlags    dstStageMask;
+    VkAccessFlags           srcAccessMask;
+    VkAccessFlags           dstAccessMask;
+    VkDependencyFlags       dependencyFlags;
+    int32_t                 viewOffset;
+} VkSubpassDependency2KHR;
+
+typedef struct VkRenderPassCreateInfo2KHR {
+    VkStructureType                       sType;
+    const void*                           pNext;
+    VkRenderPassCreateFlags               flags;
+    uint32_t                              attachmentCount;
+    const VkAttachmentDescription2KHR*    pAttachments;
+    uint32_t                              subpassCount;
+    const VkSubpassDescription2KHR*       pSubpasses;
+    uint32_t                              dependencyCount;
+    const VkSubpassDependency2KHR*        pDependencies;
+    uint32_t                              correlatedViewMaskCount;
+    const uint32_t*                       pCorrelatedViewMasks;
+} VkRenderPassCreateInfo2KHR;
+
+typedef struct VkSubpassBeginInfoKHR {
+    VkStructureType      sType;
+    const void*          pNext;
+    VkSubpassContents    contents;
+} VkSubpassBeginInfoKHR;
+
+typedef struct VkSubpassEndInfoKHR {
+    VkStructureType    sType;
+    const void*        pNext;
+} VkSubpassEndInfoKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo*      pRenderPassBegin, const VkSubpassBeginInfoKHR*      pSubpassBeginInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR*      pSubpassBeginInfo, const VkSubpassEndInfoKHR*        pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR*        pSubpassEndInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR(
+    VkDevice                                    device,
+    const VkRenderPassCreateInfo2KHR*           pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkRenderPass*                               pRenderPass);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBegin,
+    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo,
+    const VkSubpassEndInfoKHR*                  pSubpassEndInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassEndInfoKHR*                  pSubpassEndInfo);
+#endif
+
 #define VK_KHR_shared_presentable_image 1
 #define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
 #define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
@@ -5560,6 +5721,70 @@
 
 
 
+#define VK_KHR_get_display_properties2 1
+#define VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION 1
+#define VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_display_properties2"
+
+typedef struct VkDisplayProperties2KHR {
+    VkStructureType           sType;
+    void*                     pNext;
+    VkDisplayPropertiesKHR    displayProperties;
+} VkDisplayProperties2KHR;
+
+typedef struct VkDisplayPlaneProperties2KHR {
+    VkStructureType                sType;
+    void*                          pNext;
+    VkDisplayPlanePropertiesKHR    displayPlaneProperties;
+} VkDisplayPlaneProperties2KHR;
+
+typedef struct VkDisplayModeProperties2KHR {
+    VkStructureType               sType;
+    void*                         pNext;
+    VkDisplayModePropertiesKHR    displayModeProperties;
+} VkDisplayModeProperties2KHR;
+
+typedef struct VkDisplayPlaneInfo2KHR {
+    VkStructureType     sType;
+    const void*         pNext;
+    VkDisplayModeKHR    mode;
+    uint32_t            planeIndex;
+} VkDisplayPlaneInfo2KHR;
+
+typedef struct VkDisplayPlaneCapabilities2KHR {
+    VkStructureType                  sType;
+    void*                            pNext;
+    VkDisplayPlaneCapabilitiesKHR    capabilities;
+} VkDisplayPlaneCapabilities2KHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlaneProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModeProperties2KHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModeProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR* pCapabilities);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pPropertyCount,
+    VkDisplayProperties2KHR*                    pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pPropertyCount,
+    VkDisplayPlaneProperties2KHR*               pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR(
+    VkPhysicalDevice                            physicalDevice,
+    VkDisplayKHR                                display,
+    uint32_t*                                   pPropertyCount,
+    VkDisplayModeProperties2KHR*                pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR(
+    VkPhysicalDevice                            physicalDevice,
+    const VkDisplayPlaneInfo2KHR*               pDisplayPlaneInfo,
+    VkDisplayPlaneCapabilities2KHR*             pCapabilities);
+#endif
+
 #define VK_KHR_dedicated_allocation 1
 #define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3
 #define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation"
@@ -5715,6 +5940,47 @@
     VkDescriptorSetLayoutSupport*               pSupport);
 #endif
 
+#define VK_KHR_draw_indirect_count 1
+#define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
+#define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count"
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountKHR(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    VkBuffer                                    countBuffer,
+    VkDeviceSize                                countBufferOffset,
+    uint32_t                                    maxDrawCount,
+    uint32_t                                    stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    VkBuffer                                    countBuffer,
+    VkDeviceSize                                countBufferOffset,
+    uint32_t                                    maxDrawCount,
+    uint32_t                                    stride);
+#endif
+
+#define VK_KHR_8bit_storage 1
+#define VK_KHR_8BIT_STORAGE_SPEC_VERSION  1
+#define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage"
+
+typedef struct VkPhysicalDevice8BitStorageFeaturesKHR {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           storageBuffer8BitAccess;
+    VkBool32           uniformAndStorageBuffer8BitAccess;
+    VkBool32           storagePushConstant8;
+} VkPhysicalDevice8BitStorageFeaturesKHR;
+
+
+
 #define VK_EXT_debug_report 1
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
 
@@ -6147,10 +6413,10 @@
 } VkValidationCheckEXT;
 
 typedef struct VkValidationFlagsEXT {
-    VkStructureType          sType;
-    const void*              pNext;
-    uint32_t                 disabledValidationCheckCount;
-    VkValidationCheckEXT*    pDisabledValidationChecks;
+    VkStructureType                sType;
+    const void*                    pNext;
+    uint32_t                       disabledValidationCheckCount;
+    const VkValidationCheckEXT*    pDisabledValidationChecks;
 } VkValidationFlagsEXT;
 
 
@@ -6165,6 +6431,51 @@
 #define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote"
 
 
+#define VK_EXT_conditional_rendering 1
+#define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 1
+#define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering"
+
+
+typedef enum VkConditionalRenderingFlagBitsEXT {
+    VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT = 0x00000001,
+    VK_CONDITIONAL_RENDERING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkConditionalRenderingFlagBitsEXT;
+typedef VkFlags VkConditionalRenderingFlagsEXT;
+
+typedef struct VkConditionalRenderingBeginInfoEXT {
+    VkStructureType                   sType;
+    const void*                       pNext;
+    VkBuffer                          buffer;
+    VkDeviceSize                      offset;
+    VkConditionalRenderingFlagsEXT    flags;
+} VkConditionalRenderingBeginInfoEXT;
+
+typedef struct VkPhysicalDeviceConditionalRenderingFeaturesEXT {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           conditionalRendering;
+    VkBool32           inheritedConditionalRendering;
+} VkPhysicalDeviceConditionalRenderingFeaturesEXT;
+
+typedef struct VkCommandBufferInheritanceConditionalRenderingInfoEXT {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkBool32           conditionalRenderingEnable;
+} VkCommandBufferInheritanceConditionalRenderingInfoEXT;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdBeginConditionalRenderingEXT)(VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin);
+typedef void (VKAPI_PTR *PFN_vkCmdEndConditionalRenderingEXT)(VkCommandBuffer commandBuffer);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginConditionalRenderingEXT(
+    VkCommandBuffer                             commandBuffer,
+    const VkConditionalRenderingBeginInfoEXT*   pConditionalRenderingBegin);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndConditionalRenderingEXT(
+    VkCommandBuffer                             commandBuffer);
+#endif
+
 #define VK_NVX_device_generated_commands 1
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkObjectTableNVX)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX)
@@ -7230,6 +7541,95 @@
     void*                                       pData);
 #endif
 
+#define VK_EXT_descriptor_indexing 1
+#define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2
+#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
+
+
+typedef enum VkDescriptorBindingFlagBitsEXT {
+    VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = 0x00000001,
+    VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = 0x00000002,
+    VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = 0x00000004,
+    VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008,
+    VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDescriptorBindingFlagBitsEXT;
+typedef VkFlags VkDescriptorBindingFlagsEXT;
+
+typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT {
+    VkStructureType                       sType;
+    const void*                           pNext;
+    uint32_t                              bindingCount;
+    const VkDescriptorBindingFlagsEXT*    pBindingFlags;
+} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderInputAttachmentArrayDynamicIndexing;
+    VkBool32           shaderUniformTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderStorageTexelBufferArrayDynamicIndexing;
+    VkBool32           shaderUniformBufferArrayNonUniformIndexing;
+    VkBool32           shaderSampledImageArrayNonUniformIndexing;
+    VkBool32           shaderStorageBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageImageArrayNonUniformIndexing;
+    VkBool32           shaderInputAttachmentArrayNonUniformIndexing;
+    VkBool32           shaderUniformTexelBufferArrayNonUniformIndexing;
+    VkBool32           shaderStorageTexelBufferArrayNonUniformIndexing;
+    VkBool32           descriptorBindingUniformBufferUpdateAfterBind;
+    VkBool32           descriptorBindingSampledImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageImageUpdateAfterBind;
+    VkBool32           descriptorBindingStorageBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUniformTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingStorageTexelBufferUpdateAfterBind;
+    VkBool32           descriptorBindingUpdateUnusedWhilePending;
+    VkBool32           descriptorBindingPartiallyBound;
+    VkBool32           descriptorBindingVariableDescriptorCount;
+    VkBool32           runtimeDescriptorArray;
+} VkPhysicalDeviceDescriptorIndexingFeaturesEXT;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           maxUpdateAfterBindDescriptorsInAllPools;
+    VkBool32           shaderUniformBufferArrayNonUniformIndexingNative;
+    VkBool32           shaderSampledImageArrayNonUniformIndexingNative;
+    VkBool32           shaderStorageBufferArrayNonUniformIndexingNative;
+    VkBool32           shaderStorageImageArrayNonUniformIndexingNative;
+    VkBool32           shaderInputAttachmentArrayNonUniformIndexingNative;
+    VkBool32           robustBufferAccessUpdateAfterBind;
+    VkBool32           quadDivergentImplicitLod;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindSamplers;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindSampledImages;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindStorageImages;
+    uint32_t           maxPerStageDescriptorUpdateAfterBindInputAttachments;
+    uint32_t           maxPerStageUpdateAfterBindResources;
+    uint32_t           maxDescriptorSetUpdateAfterBindSamplers;
+    uint32_t           maxDescriptorSetUpdateAfterBindUniformBuffers;
+    uint32_t           maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+    uint32_t           maxDescriptorSetUpdateAfterBindStorageBuffers;
+    uint32_t           maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+    uint32_t           maxDescriptorSetUpdateAfterBindSampledImages;
+    uint32_t           maxDescriptorSetUpdateAfterBindStorageImages;
+    uint32_t           maxDescriptorSetUpdateAfterBindInputAttachments;
+} VkPhysicalDeviceDescriptorIndexingPropertiesEXT;
+
+typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint32_t           descriptorSetCount;
+    const uint32_t*    pDescriptorCounts;
+} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
+
+typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           maxVariableDescriptorCount;
+} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
+
+
+
 #define VK_EXT_shader_viewport_index_layer 1
 #define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1
 #define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
@@ -7293,6 +7693,107 @@
     VkMemoryHostPointerPropertiesEXT*           pMemoryHostPointerProperties);
 #endif
 
+#define VK_AMD_buffer_marker 1
+#define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1
+#define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker"
+
+typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarkerAMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD(
+    VkCommandBuffer                             commandBuffer,
+    VkPipelineStageFlagBits                     pipelineStage,
+    VkBuffer                                    dstBuffer,
+    VkDeviceSize                                dstOffset,
+    uint32_t                                    marker);
+#endif
+
+#define VK_AMD_shader_core_properties 1
+#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1
+#define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties"
+
+typedef struct VkPhysicalDeviceShaderCorePropertiesAMD {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           shaderEngineCount;
+    uint32_t           shaderArraysPerEngineCount;
+    uint32_t           computeUnitsPerShaderArray;
+    uint32_t           simdPerComputeUnit;
+    uint32_t           wavefrontsPerSimd;
+    uint32_t           wavefrontSize;
+    uint32_t           sgprsPerSimd;
+    uint32_t           minSgprAllocation;
+    uint32_t           maxSgprAllocation;
+    uint32_t           sgprAllocationGranularity;
+    uint32_t           vgprsPerSimd;
+    uint32_t           minVgprAllocation;
+    uint32_t           maxVgprAllocation;
+    uint32_t           vgprAllocationGranularity;
+} VkPhysicalDeviceShaderCorePropertiesAMD;
+
+
+
+#define VK_EXT_vertex_attribute_divisor 1
+#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 2
+#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor"
+
+typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT {
+    VkStructureType    sType;
+    void*              pNext;
+    uint32_t           maxVertexAttribDivisor;
+} VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT;
+
+typedef struct VkVertexInputBindingDivisorDescriptionEXT {
+    uint32_t    binding;
+    uint32_t    divisor;
+} VkVertexInputBindingDivisorDescriptionEXT;
+
+typedef struct VkPipelineVertexInputDivisorStateCreateInfoEXT {
+    VkStructureType                                     sType;
+    const void*                                         pNext;
+    uint32_t                                            vertexBindingDivisorCount;
+    const VkVertexInputBindingDivisorDescriptionEXT*    pVertexBindingDivisors;
+} VkPipelineVertexInputDivisorStateCreateInfoEXT;
+
+
+
+#define VK_NV_shader_subgroup_partitioned 1
+#define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1
+#define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned"
+
+
+#define VK_NV_device_diagnostic_checkpoints 1
+#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2
+#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints"
+
+typedef struct VkQueueFamilyCheckpointPropertiesNV {
+    VkStructureType         sType;
+    void*                   pNext;
+    VkPipelineStageFlags    checkpointExecutionStageMask;
+} VkQueueFamilyCheckpointPropertiesNV;
+
+typedef struct VkCheckpointDataNV {
+    VkStructureType            sType;
+    void*                      pNext;
+    VkPipelineStageFlagBits    stage;
+    void*                      pCheckpointMarker;
+} VkCheckpointDataNV;
+
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetCheckpointNV)(VkCommandBuffer commandBuffer, const void* pCheckpointMarker);
+typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointDataNV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointDataNV* pCheckpointData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCheckpointNV(
+    VkCommandBuffer                             commandBuffer,
+    const void*                                 pCheckpointMarker);
+
+VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointDataNV(
+    VkQueue                                     queue,
+    uint32_t*                                   pCheckpointDataCount,
+    VkCheckpointDataNV*                         pCheckpointData);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 7f4f2c4..cbba5f4 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -43,7 +43,6 @@
     ],
 
     cppflags: [
-        "-std=c++14",
         "-Wno-c99-extensions",
         "-Wno-c++98-compat-pedantic",
         "-Wno-exit-time-destructors",
diff --git a/vulkan/libvulkan/api_gen.cpp b/vulkan/libvulkan/api_gen.cpp
index 7650e0c..629ebb1 100644
--- a/vulkan/libvulkan/api_gen.cpp
+++ b/vulkan/libvulkan/api_gen.cpp
@@ -553,7 +553,11 @@
         "vkEnumeratePhysicalDeviceGroups",
         "vkEnumeratePhysicalDeviceGroupsKHR",
         "vkEnumeratePhysicalDevices",
+        "vkGetDisplayModeProperties2KHR",
+        "vkGetDisplayPlaneCapabilities2KHR",
         "vkGetInstanceProcAddr",
+        "vkGetPhysicalDeviceDisplayPlaneProperties2KHR",
+        "vkGetPhysicalDeviceDisplayProperties2KHR",
         "vkGetPhysicalDeviceExternalBufferProperties",
         "vkGetPhysicalDeviceExternalBufferPropertiesKHR",
         "vkGetPhysicalDeviceExternalFenceProperties",
diff --git a/vulkan/nulldrv/Android.bp b/vulkan/nulldrv/Android.bp
index 3329609..7be9c66 100644
--- a/vulkan/nulldrv/Android.bp
+++ b/vulkan/nulldrv/Android.bp
@@ -32,7 +32,6 @@
         "-DLOG_NDEBUG=0",
     ],
     cppflags: [
-        "-std=c++1y",
         "-Wno-c++98-compat-pedantic",
         "-Wno-c99-extensions",
     ],
diff --git a/vulkan/tools/Android.bp b/vulkan/tools/Android.bp
index d81d9ec..2514094 100644
--- a/vulkan/tools/Android.bp
+++ b/vulkan/tools/Android.bp
@@ -29,7 +29,6 @@
         "-Wno-switch-enum",
     ],
     cppflags: [
-        "-std=c++1y",
         "-Wno-c++98-compat-pedantic",
         "-Wno-c99-extensions",
         "-Wno-old-style-cast",