Merge "libbinder: vendor_available"
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index f7e8d13..0d89da4 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -184,9 +184,20 @@
   return count;
 }
 
+static const char* get_location_from_path(const char* path) {
+    static constexpr char kLocationSeparator = '/';
+    const char *location = strrchr(path, kLocationSeparator);
+    if (location == NULL) {
+        return path;
+    } else {
+        // Skip the separator character.
+        return location + 1;
+    }
+}
+
 static void run_dex2oat(int zip_fd, int oat_fd, int input_vdex_fd, int output_vdex_fd, int image_fd,
         const char* input_file_name, const char* output_file_name, int swap_fd,
-        const char *instruction_set, const char* compiler_filter, bool vm_safe_mode,
+        const char* instruction_set, const char* compiler_filter, bool vm_safe_mode,
         bool debuggable, bool post_bootcomplete, int profile_fd, const char* shared_libraries) {
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
 
@@ -196,6 +207,9 @@
         return;
     }
 
+    // Get the relative path to the input file.
+    const char* relative_input_file_name = get_location_from_path(input_file_name);
+
     char dex2oat_Xms_flag[kPropertyValueMax];
     bool have_dex2oat_Xms_flag = get_property("dalvik.vm.dex2oat-Xms", dex2oat_Xms_flag, NULL) > 0;
 
@@ -286,7 +300,7 @@
     char dex2oat_image_fd[arraysize("--app-image-fd=") + MAX_INT_LEN];
 
     sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
-    sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
+    sprintf(zip_location_arg, "--zip-location=%s", relative_input_file_name);
     sprintf(input_vdex_fd_arg, "--input-vdex-fd=%d", input_vdex_fd);
     sprintf(output_vdex_fd_arg, "--output-vdex-fd=%d", output_vdex_fd);
     sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
@@ -348,8 +362,18 @@
         sprintf(profile_arg, "--profile-file-fd=%d", profile_fd);
     }
 
+    // Get the directory of the apk to pass as a base classpath directory.
+    char base_dir[arraysize("--classpath-dir=") + PKG_PATH_MAX];
+    std::string apk_dir(input_file_name);
+    unsigned long dir_index = apk_dir.rfind('/');
+    bool has_base_dir = dir_index != std::string::npos;
+    if (has_base_dir) {
+        apk_dir = apk_dir.substr(0, dir_index);
+        sprintf(base_dir, "--classpath-dir=%s", apk_dir.c_str());
+    }
 
-    ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
+
+    ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, relative_input_file_name, output_file_name);
 
     const char* argv[9  // program name, mandatory arguments and the final NULL
                      + (have_dex2oat_isa_variant ? 1 : 0)
@@ -367,6 +391,7 @@
                      + dex2oat_flags_count
                      + (profile_fd == -1 ? 0 : 1)
                      + (shared_libraries != nullptr ? 4 : 0)
+                     + (has_base_dir ? 1 : 0)
                      + (have_dex2oat_large_app_threshold ? 1 : 0)];
     int i = 0;
     argv[i++] = DEX2OAT_BIN;
@@ -431,6 +456,9 @@
         argv[i++] = RUNTIME_ARG;
         argv[i++] = shared_libraries;
     }
+    if (has_base_dir) {
+        argv[i++] = base_dir;
+    }
     // Do not add after dex2oat_flags, they should override others for debugging.
     argv[i] = NULL;
 
@@ -768,17 +796,6 @@
     exit(68);   /* only get here on exec failure */
 }
 
-static const char* get_location_from_path(const char* path) {
-    static constexpr char kLocationSeparator = '/';
-    const char *location = strrchr(path, kLocationSeparator);
-    if (location == NULL) {
-        return path;
-    } else {
-        // Skip the separator character.
-        return location + 1;
-    }
-}
-
 bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_paths) {
     std::vector<unique_fd> profile_fds;
     unique_fd reference_profile_fd;
@@ -1540,14 +1557,12 @@
             _exit(67);
         }
 
-        // Pass dex2oat the relative path to the input file.
-        const char *input_file_name = get_location_from_path(dex_path);
         run_dex2oat(input_fd.get(),
                     out_oat_fd.get(),
                     in_vdex_fd.get(),
                     out_vdex_fd.get(),
                     image_fd.get(),
-                    input_file_name,
+                    dex_path,
                     out_oat_path,
                     swap_fd.get(),
                     instruction_set,
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 33bc43c..4b698c0 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -163,6 +163,7 @@
     return true;
 }
 
+// Must process hwbinder services first, then passthrough services.
 void Lshal::forEachTable(const std::function<void(Table &)> &f) {
     f(mServicesTable);
     f(mPassthroughRefTable);
@@ -243,6 +244,18 @@
 }
 
 void Lshal::dumpVintf() const {
+    mOut << "<!-- " << std::endl
+         << "    This is a skeleton device manifest. Notes: " << std::endl
+         << "    1. android.hidl.*, android.frameworks.*, android.system.* are not included." << std::endl
+         << "    2. If a HAL is supported in both hwbinder and passthrough transport, " << std::endl
+         << "       only hwbinder is shown." << std::endl
+         << "    3. It is likely that HALs in passthrough transport does not have" << std::endl
+         << "       <interface> declared; users will have to write them by hand." << std::endl
+         << "    4. sepolicy version is set to 0.0. It is recommended that the entry" << std::endl
+         << "       is removed from the manifest file and written by assemble_vintf" << std::endl
+         << "       at build time." << std::endl
+         << "-->" << std::endl;
+
     vintf::HalManifest manifest;
     forEachTable([this, &manifest] (const Table &table) {
         for (const TableEntry &entry : table) {
@@ -271,6 +284,8 @@
             std::string instanceName =
                     &table == &mImplementationsTable ? "" : splittedFqInstanceName.second;
 
+            vintf::Version version{fqName.getPackageMajorVersion(),
+                                   fqName.getPackageMinorVersion()};
             vintf::Transport transport;
             vintf::Arch arch;
             if (entry.transport == "hwbinder") {
@@ -296,34 +311,33 @@
                 continue;
             }
 
-            vintf::ManifestHal *hal = manifest.getAnyHal(fqName.package());
-            if (hal == nullptr) {
-                if (!manifest.add(vintf::ManifestHal{
+            bool done = false;
+            for (vintf::ManifestHal *hal : manifest.getHals(fqName.package())) {
+                if (hal->transport() != transport) {
+                    if (transport != vintf::Transport::PASSTHROUGH) {
+                        mErr << "Fatal: should not reach here. Generated result may be wrong."
+                             << std::endl;
+                    }
+                    done = true;
+                    break;
+                }
+                if (hal->hasVersion(version)) {
+                    hal->interfaces[interfaceName].name = interfaceName;
+                    hal->interfaces[interfaceName].instances.insert(instanceName);
+                    done = true;
+                    break;
+                }
+            }
+            if (done) {
+                continue; // to next TableEntry
+            }
+            if (!manifest.add(vintf::ManifestHal{
                     .format = vintf::HalFormat::HIDL,
                     .name = fqName.package(),
-                    .transportArch = {transport, arch}
-                })) {
-                    mErr << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
-                    continue;
-                }
-                hal = manifest.getAnyHal(fqName.package());
-            }
-            if (hal == nullptr) {
-                mErr << "Warning: cannot get hal '" << fqInstanceName
-                     << "' after adding it" << std::endl;
-                continue;
-            }
-            vintf::Version version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()};
-            if (std::find(hal->versions.begin(), hal->versions.end(), version) == hal->versions.end()) {
-                hal->versions.push_back(version);
-            }
-            if (&table != &mImplementationsTable) {
-                auto it = hal->interfaces.find(interfaceName);
-                if (it == hal->interfaces.end()) {
-                    hal->interfaces.insert({interfaceName, {interfaceName, {{instanceName}}}});
-                } else {
-                    it->second.instances.insert(instanceName);
-                }
+                    .versions = {version},
+                    .transportArch = {transport, arch},
+                    .interfaces = {{interfaceName, {interfaceName, {{instanceName}}}}}})) {
+                mErr << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
             }
         }
     });