Loading cmds/installd/InstalldNativeService.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -1986,7 +1986,18 @@ static void collectManualExternalStatsForUser(const std::string& path, struct st } fts_close(fts); } static bool ownsExternalStorage(int32_t appId) { // Fetch external storage owner appid and check if it is the same as the // current appId whose size is calculated struct stat s; auto _picDir = StringPrintf("%s/Pictures", create_data_media_path(nullptr, 0).c_str()); // check if the stat are present if (stat(_picDir.c_str(), &s) == 0) { // fetch the appId from the uid of the media app return ((int32_t)multiuser_get_app_id(s.st_uid) == appId); } return false; } binder::Status InstalldNativeService::getAppSize(const std::optional<std::string>& uuid, const std::vector<std::string>& packageNames, int32_t userId, int32_t flags, int32_t appId, const std::vector<int64_t>& ceDataInodes, Loading Loading @@ -2041,8 +2052,10 @@ binder::Status InstalldNativeService::getAppSize(const std::optional<std::string calculate_tree_size(obbCodePath, &extStats.codeSize); } ATRACE_END(); if (flags & FLAG_USE_QUOTA && appId >= AID_APP_START) { // Calculating the app size of the external storage owning app in a manual way, since // calculating it through quota apis also includes external media storage in the app storage // numbers if (flags & FLAG_USE_QUOTA && appId >= AID_APP_START && !ownsExternalStorage(appId)) { ATRACE_BEGIN("code"); for (const auto& codePath : codePaths) { calculate_tree_size(codePath, &stats.codeSize, -1, Loading cmds/installd/tests/Android.bp +22 −6 Original line number Diff line number Diff line Loading @@ -13,7 +13,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_utils_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libutils", Loading @@ -33,7 +36,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_cache_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libbinder", Loading Loading @@ -75,7 +81,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_service_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libbinder", Loading @@ -84,6 +93,7 @@ cc_test { "libprocessgroup", "libselinux", "libutils", "packagemanager_aidl-cpp", "server_configurable_flags", ], static_libs: [ Loading Loading @@ -117,7 +127,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_dexopt_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libbinder", Loading Loading @@ -160,7 +173,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_otapreopt_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libcutils", Loading @@ -169,6 +185,6 @@ cc_test { ], static_libs: [ "liblog", "libotapreoptparameters" "libotapreoptparameters", ], } cmds/installd/tests/installd_service_test.cpp +77 −3 Original line number Diff line number Diff line Loading @@ -18,10 +18,11 @@ #include <string> #include <fcntl.h> #include <pwd.h> #include <stdlib.h> #include <string.h> #include <sys/statvfs.h> #include <sys/stat.h> #include <sys/statvfs.h> #include <sys/xattr.h> #include <android-base/file.h> Loading @@ -32,8 +33,10 @@ #include <cutils/properties.h> #include <gtest/gtest.h> #include "binder_test_utils.h" #include <android/content/pm/IPackageManagerNative.h> #include <binder/IServiceManager.h> #include "InstalldNativeService.h" #include "binder_test_utils.h" #include "dexopt.h" #include "globals.h" #include "utils.h" Loading @@ -41,6 +44,34 @@ using android::base::StringPrintf; namespace android { std::string get_package_name(uid_t uid) { sp<IServiceManager> sm = defaultServiceManager(); sp<content::pm::IPackageManagerNative> package_mgr; if (sm.get() == nullptr) { LOG(INFO) << "Cannot find service manager"; } else { sp<IBinder> binder = sm->getService(String16("package_native")); if (binder.get() == nullptr) { LOG(INFO) << "Cannot find package_native"; } else { package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder); } } // find package name std::string pkg; if (package_mgr != nullptr) { std::vector<std::string> names; binder::Status status = package_mgr->getNamesForUids({(int)uid}, &names); if (!status.isOk()) { LOG(INFO) << "getNamesForUids failed: %s", status.exceptionMessage().c_str(); } else { if (!names[0].empty()) { pkg = names[0].c_str(); } } } return pkg; } namespace installd { constexpr const char* kTestUuid = "TEST"; Loading Loading @@ -248,7 +279,50 @@ TEST_F(ServiceTest, CalculateCache) { 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) { 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, externalStorageSizeAfterAddingExternalFile; 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(); // 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 externalFileLocation = StringPrintf("%s/Pictures/%s", getenv("EXTERNAL_STORAGE"), "External.jpg"); std::string externalFileContentCommand = StringPrintf("dd if=/dev/zero of=%s bs=1M count=20", externalFileLocation.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, &externalStorageSizeAfterAddingExternalFile); // check that the size before adding the file and after should be the same, as the app size // is not changed. for (size_t i = 0; i < externalStorageSize.size(); i++) { ASSERT_TRUE(externalStorageSize[i] == externalStorageSizeAfterAddingExternalFile[i]); } // remove the external file std::string removeCommand = StringPrintf("rm -f %s", externalFileLocation.c_str()); system(removeCommand.c_str()); } } static bool mkdirs(const std::string& path, mode_t mode) { struct stat sb; if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) { Loading Loading
cmds/installd/InstalldNativeService.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -1986,7 +1986,18 @@ static void collectManualExternalStatsForUser(const std::string& path, struct st } fts_close(fts); } static bool ownsExternalStorage(int32_t appId) { // Fetch external storage owner appid and check if it is the same as the // current appId whose size is calculated struct stat s; auto _picDir = StringPrintf("%s/Pictures", create_data_media_path(nullptr, 0).c_str()); // check if the stat are present if (stat(_picDir.c_str(), &s) == 0) { // fetch the appId from the uid of the media app return ((int32_t)multiuser_get_app_id(s.st_uid) == appId); } return false; } binder::Status InstalldNativeService::getAppSize(const std::optional<std::string>& uuid, const std::vector<std::string>& packageNames, int32_t userId, int32_t flags, int32_t appId, const std::vector<int64_t>& ceDataInodes, Loading Loading @@ -2041,8 +2052,10 @@ binder::Status InstalldNativeService::getAppSize(const std::optional<std::string calculate_tree_size(obbCodePath, &extStats.codeSize); } ATRACE_END(); if (flags & FLAG_USE_QUOTA && appId >= AID_APP_START) { // Calculating the app size of the external storage owning app in a manual way, since // calculating it through quota apis also includes external media storage in the app storage // numbers if (flags & FLAG_USE_QUOTA && appId >= AID_APP_START && !ownsExternalStorage(appId)) { ATRACE_BEGIN("code"); for (const auto& codePath : codePaths) { calculate_tree_size(codePath, &stats.codeSize, -1, Loading
cmds/installd/tests/Android.bp +22 −6 Original line number Diff line number Diff line Loading @@ -13,7 +13,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_utils_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libutils", Loading @@ -33,7 +36,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_cache_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libbinder", Loading Loading @@ -75,7 +81,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_service_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libbinder", Loading @@ -84,6 +93,7 @@ cc_test { "libprocessgroup", "libselinux", "libutils", "packagemanager_aidl-cpp", "server_configurable_flags", ], static_libs: [ Loading Loading @@ -117,7 +127,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_dexopt_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libbinder", Loading Loading @@ -160,7 +173,10 @@ cc_test { test_suites: ["device-tests"], clang: true, srcs: ["installd_otapreopt_test.cpp"], cflags: ["-Wall", "-Werror"], cflags: [ "-Wall", "-Werror", ], shared_libs: [ "libbase", "libcutils", Loading @@ -169,6 +185,6 @@ cc_test { ], static_libs: [ "liblog", "libotapreoptparameters" "libotapreoptparameters", ], }
cmds/installd/tests/installd_service_test.cpp +77 −3 Original line number Diff line number Diff line Loading @@ -18,10 +18,11 @@ #include <string> #include <fcntl.h> #include <pwd.h> #include <stdlib.h> #include <string.h> #include <sys/statvfs.h> #include <sys/stat.h> #include <sys/statvfs.h> #include <sys/xattr.h> #include <android-base/file.h> Loading @@ -32,8 +33,10 @@ #include <cutils/properties.h> #include <gtest/gtest.h> #include "binder_test_utils.h" #include <android/content/pm/IPackageManagerNative.h> #include <binder/IServiceManager.h> #include "InstalldNativeService.h" #include "binder_test_utils.h" #include "dexopt.h" #include "globals.h" #include "utils.h" Loading @@ -41,6 +44,34 @@ using android::base::StringPrintf; namespace android { std::string get_package_name(uid_t uid) { sp<IServiceManager> sm = defaultServiceManager(); sp<content::pm::IPackageManagerNative> package_mgr; if (sm.get() == nullptr) { LOG(INFO) << "Cannot find service manager"; } else { sp<IBinder> binder = sm->getService(String16("package_native")); if (binder.get() == nullptr) { LOG(INFO) << "Cannot find package_native"; } else { package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder); } } // find package name std::string pkg; if (package_mgr != nullptr) { std::vector<std::string> names; binder::Status status = package_mgr->getNamesForUids({(int)uid}, &names); if (!status.isOk()) { LOG(INFO) << "getNamesForUids failed: %s", status.exceptionMessage().c_str(); } else { if (!names[0].empty()) { pkg = names[0].c_str(); } } } return pkg; } namespace installd { constexpr const char* kTestUuid = "TEST"; Loading Loading @@ -248,7 +279,50 @@ TEST_F(ServiceTest, CalculateCache) { 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) { 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, externalStorageSizeAfterAddingExternalFile; 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(); // 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 externalFileLocation = StringPrintf("%s/Pictures/%s", getenv("EXTERNAL_STORAGE"), "External.jpg"); std::string externalFileContentCommand = StringPrintf("dd if=/dev/zero of=%s bs=1M count=20", externalFileLocation.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, &externalStorageSizeAfterAddingExternalFile); // check that the size before adding the file and after should be the same, as the app size // is not changed. for (size_t i = 0; i < externalStorageSize.size(); i++) { ASSERT_TRUE(externalStorageSize[i] == externalStorageSizeAfterAddingExternalFile[i]); } // remove the external file std::string removeCommand = StringPrintf("rm -f %s", externalFileLocation.c_str()); system(removeCommand.c_str()); } } static bool mkdirs(const std::string& path, mode_t mode) { struct stat sb; if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) { Loading