Check for IOCTL feature changed to not set inheritence

Inheritence flags should only be set on directories and not files,
setting inheritence flags on files fails and leads to not using project
ids.
Also refined the tests to make sure that project ids are indeed used.

Bug: b/215154615
Test: atest installd/StorageHostTest
Test: atest installd/installd_service_test.cpp
Ignore-AOSP-First: It will be picked up in AOSP manually, needs to be in
master first to resolve merge conflicts.
Change-Id: Iac38ba6f77c14141d8b06b63f52bf75fe0c54c66

Change-Id: Ia5baf127af5a078592d8b2db4b2f3d8c048a8692
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 4e12579..1c5aa4f 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -3429,7 +3429,7 @@
     auto temp_path = StringPrintf("%smisc/installd/ioctl_check", android_data_dir.c_str());
     if (access(temp_path.c_str(), F_OK) != 0) {
         int fd = open(temp_path.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0644);
-        result = set_quota_project_id(temp_path, 0, true) == 0;
+        result = set_quota_project_id(temp_path, 0, false) == 0;
         close(fd);
         // delete the temp file
         remove(temp_path.c_str());
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index 38cb370..162e668 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -465,7 +465,7 @@
     EXPECT_TRUE(create_cache_path(buf, "/path/to/file.apk", "isa"));
     EXPECT_EQ("/data/dalvik-cache/isa/path@to@file.apk@classes.dex", std::string(buf));
 }
-TEST_F(ServiceTest, GetAppSize) {
+TEST_F(ServiceTest, GetAppSizeManualForMedia) {
     struct stat s;
 
     std::string externalPicDir =
@@ -509,6 +509,97 @@
         system(removeCommand.c_str());
     }
 }
+TEST_F(ServiceTest, GetAppSizeProjectID_UID) {
+    struct stat s;
+    std::string externalPicDir =
+            StringPrintf("%s/Pictures", create_data_media_path(nullptr, 0).c_str());
+    if (stat(externalPicDir.c_str(), &s) == 0) {
+        // fetch the appId from the uid of the external storage owning app
+        int32_t externalStorageAppId = multiuser_get_app_id(s.st_uid);
+        // Fetch Package Name for the external storage owning app uid
+        std::string pkg = get_package_name(s.st_uid);
+
+        std::vector<int64_t> externalStorageSize, externalStorageSizeAfterAddingCacheFile;
+        std::vector<int64_t> ceDataInodes;
+
+        std::vector<std::string> codePaths;
+        std::vector<std::string> packageNames;
+        // set up parameters
+        packageNames.push_back(pkg);
+        ceDataInodes.push_back(0);
+        // initialise the mounts
+        service->invalidateMounts();
+        auto using_project_ids =
+                StringPrintf("%smisc/installd/using_project_ids", android_data_dir.c_str());
+        bool usingProjectIds = access(using_project_ids.c_str(), F_OK) == 0;
+        if (!usingProjectIds) {
+            service->setFirstBoot();
+        }
+
+        if (access(using_project_ids.c_str(), F_OK) != 0) {
+            // projectids is not used, so check that ioctl features should be absent
+            auto temp_path = StringPrintf("%smisc/installd/ioctl_check", android_data_dir.c_str());
+
+            if (access(temp_path.c_str(), F_OK) != 0) {
+                open(temp_path.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0644);
+                bool result = set_quota_project_id(temp_path, 0, false) == 0;
+                // delete the temp file
+                // remove the external file
+                remove(temp_path.c_str());
+                // since using_project_ids file is not present, so ioctl settings should be absent
+                //  that is denoted by the result of setting project id flag as false
+                ASSERT_FALSE(result);
+            }
+        }
+        // call the getAppSize to get the current size of the external storage owning app
+        service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
+                            externalStorageAppId, ceDataInodes, codePaths, &externalStorageSize);
+        // add a file with 20MB size to the external storage
+        std::string externalStorageCacheDir =
+                StringPrintf("%s/%s/cache", create_data_user_ce_path(nullptr, 0).c_str(),
+                             pkg.c_str());
+        std::string cacheFileLocation =
+                StringPrintf("%s/%s", externalStorageCacheDir.c_str(), "External.jpg");
+        std::string externalFileContentCommand =
+                StringPrintf("dd if=/dev/zero of=%s bs=1M count=20", cacheFileLocation.c_str());
+        system(externalFileContentCommand.c_str());
+        // call the getAppSize again to get the new size of the external storage owning app
+        service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
+                            externalStorageAppId, ceDataInodes, codePaths,
+                            &externalStorageSizeAfterAddingCacheFile);
+        // check that the size of cache and data increases when cache file is added
+        int64_t sizeDiffData = externalStorageSizeAfterAddingCacheFile[1] - externalStorageSize[1];
+        int64_t sizeDiffCache = externalStorageSizeAfterAddingCacheFile[2] - externalStorageSize[2];
+        ASSERT_TRUE(sizeDiffData == sizeDiffCache);
+        // remove the external file
+        std::string removeCommand = StringPrintf("rm -f %s", cacheFileLocation.c_str());
+        system(removeCommand.c_str());
+        // remove the setFirstBoot setting
+        std::string removeCommand2 = "rm -f /data/misc/installd/using_project_ids";
+        system(removeCommand2.c_str());
+        // Do now without project id
+        std::vector<int64_t> sizeWithUID, sizeWithUIDAfterAddingCacheFile;
+        // call the getAppSize to get the current size of the external storage owning app
+        service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
+                            externalStorageAppId, ceDataInodes, codePaths, &sizeWithUID);
+        // add a file with 20MB size to the external storage
+        system(externalFileContentCommand.c_str());
+        // call the getAppSize again to get the new size of the external storage owning app
+        service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
+                            externalStorageAppId, ceDataInodes, codePaths,
+                            &sizeWithUIDAfterAddingCacheFile);
+        // check that the size of cache and data increases when cache file is added
+        sizeDiffData = sizeWithUIDAfterAddingCacheFile[1] - sizeWithUID[1];
+        sizeDiffCache = sizeWithUIDAfterAddingCacheFile[2] - sizeWithUID[2];
+        ASSERT_TRUE(sizeDiffData == sizeDiffCache);
+        // remove the external file
+        system(removeCommand.c_str());
+        // reset the using_project_id if it was initially set
+        if (usingProjectIds) {
+            service->setFirstBoot();
+        }
+    }
+}
 TEST_F(ServiceTest, GetAppSizeWrongSizes) {
     int32_t externalStorageAppId = -1;
     std::vector<int64_t> externalStorageSize;