installd: Skip profile preparation if primary.prof does not exist

If the primary.prof does not exist in .dm file, the profman here will
create an empty reference profile, which will slow down the dex2oat.

And, the profman process is expensive (about hundreds of
milliseconds), we should avoid it if the primary.prof does not exist.

Bug: 204415663

Change-Id: I8ed16b2090659b2541c71b748f7e1a1552fa1a5e
Signed-off-by: Yang Tianping <yangtianping@oppo.com>
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index f3ec63f..b7c0e66 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -52,6 +52,7 @@
 #include <server_configurable_flags/get_flags.h>
 #include <system/thread_defs.h>
 #include <utils/Mutex.h>
+#include <ziparchive/zip_archive.h>
 
 #include "dexopt.h"
 #include "dexopt_return_codes.h"
@@ -2738,6 +2739,20 @@
     }
 }
 
+static bool check_profile_exists_in_dexmetadata(const std::string& dex_metadata) {
+    ZipArchiveHandle zip = nullptr;
+    if (OpenArchive(dex_metadata.c_str(), &zip) != 0) {
+        PLOG(ERROR) << "Failed to open dm '" << dex_metadata << "'";
+        return false;
+    }
+
+    ZipEntry64 entry;
+    int result = FindEntry(zip, "primary.prof", &entry);
+    CloseArchive(zip);
+
+    return result != 0 ? false : true;
+}
+
 bool prepare_app_profile(const std::string& package_name,
                          userid_t user_id,
                          appid_t app_id,
@@ -2754,7 +2769,7 @@
     }
 
     // Check if we need to install the profile from the dex metadata.
-    if (!dex_metadata) {
+    if (!dex_metadata || !check_profile_exists_in_dexmetadata(dex_metadata->c_str())) {
         return true;
     }