Allow public profile compilation for primary apks

It is ok to perform a "public" compilation with
profiles comming from dex metdata files.

The PackageManager is responsible to set the is_public flag for
primary apks; so we no longer check it in installd.

(cherry picked from commit 0b386e03f83d9a308aecaebb6c7c1d6f36b79e27)

Test: installd_dexopt_test
Bug: 30934496
Merged-In: I72519c6a05aa318985396c6f93176624fe76c4be
Change-Id: I72519c6a05aa318985396c6f93176624fe76c4be
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 1139ebc..2a7ad61 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1327,9 +1327,21 @@
 Dex2oatFileWrapper maybe_open_reference_profile(const std::string& pkgname,
         const std::string& dex_path, const char* profile_name, bool profile_guided,
         bool is_public, int uid, bool is_secondary_dex) {
-    // Public apps should not be compiled with profile information ever. Same goes for the special
-    // package '*' used for the system server.
-    if (!profile_guided || is_public || (pkgname[0] == '*')) {
+    // If we are not profile guided compilation, or we are compiling system server
+    // do not bother to open the profiles; we won't be using them.
+    if (!profile_guided || (pkgname[0] == '*')) {
+        return Dex2oatFileWrapper();
+    }
+
+    // If this is a secondary dex path which is public do not open the profile.
+    // We cannot compile public secondary dex paths with profiles. That's because
+    // it will expose how the dex files are used by their owner.
+    //
+    // Note that the PackageManager is responsible to set the is_public flag for
+    // primary apks and we do not check it here. In some cases, e.g. when
+    // compiling with a public profile from the .dm file the PackageManager will
+    // set is_public toghether with the profile guided compilation.
+    if (is_secondary_dex && is_public) {
         return Dex2oatFileWrapper();
     }
 
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index ea52c0e..e176871 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -405,15 +405,14 @@
         std::string vdex = GetPrimaryDexArtifact(oat_dir, apk_path_, "vdex");
         std::string art = GetPrimaryDexArtifact(oat_dir, apk_path_, "art");
 
-        mode_t mode = S_IFREG | (compiler_filter == "speed-profile" ? 0640 : 0644);
+        bool is_public = (dex_flags & DEXOPT_PUBLIC) != 0;
+        mode_t mode = S_IFREG | (is_public ? 0644 : 0640);
         CheckFileAccess(odex, kSystemUid, uid, mode);
         CheckFileAccess(vdex, kSystemUid, uid, mode);
-        CheckFileAccess(odex, kSystemUid, uid, mode);
 
-        // empty profiles do not generate an image.
-        // todo: add tests with non-empty profiles.
-        struct stat st;
-        ASSERT_EQ(-1, stat(art.c_str(), &st));
+        if (compiler_filter == "speed-profile") {
+            CheckFileAccess(art, kSystemUid, uid, mode);
+        }
     }
 
     std::string GetPrimaryDexArtifact(const char* oat_dir,
@@ -490,10 +489,19 @@
                         DEX2OAT_FROM_SCRATCH);
 }
 
+TEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
+    LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
+    CompilePrimaryDexFail("awesome-filter",
+                          DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
+                          app_oat_dir_.c_str(),
+                          kTestAppGid,
+                          DEX2OAT_FROM_SCRATCH);
+}
+
 TEST_F(DexoptTest, DexoptPrimaryProfileNonPublic) {
     LOG(INFO) << "DexoptPrimaryProfileNonPublic";
     CompilePrimaryDexOk("speed-profile",
-                        DEXOPT_BOOTCOMPLETE,
+                        DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED,
                         app_oat_dir_.c_str(),
                         kTestAppGid,
                         DEX2OAT_FROM_SCRATCH);
@@ -501,8 +509,8 @@
 
 TEST_F(DexoptTest, DexoptPrimaryProfilePublic) {
     LOG(INFO) << "DexoptPrimaryProfilePublic";
-    CompilePrimaryDexOk("verify",
-                        DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
+    CompilePrimaryDexOk("speed-profile",
+                        DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_PUBLIC,
                         app_oat_dir_.c_str(),
                         kTestAppGid,
                         DEX2OAT_FROM_SCRATCH);
@@ -511,21 +519,12 @@
 TEST_F(DexoptTest, DexoptPrimaryBackgroundOk) {
     LOG(INFO) << "DexoptPrimaryBackgroundOk";
     CompilePrimaryDexOk("speed-profile",
-                        DEXOPT_IDLE_BACKGROUND_JOB,
+                        DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED,
                         app_oat_dir_.c_str(),
                         kTestAppGid,
                         DEX2OAT_FROM_SCRATCH);
 }
 
-TEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
-    LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
-    CompilePrimaryDexFail("awesome-filter",
-                          DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
-                          app_oat_dir_.c_str(),
-                          kTestAppGid,
-                          DEX2OAT_FROM_SCRATCH);
-}
-
 class PrimaryDexReCompilationTest : public DexoptTest {
   public:
     virtual void SetUp() {