From 771cc344c65894405b05da1a22ffd57ae915d819 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Wed, 19 Feb 2020 23:26:56 +0100 Subject: Implement quota calculation for project ID based quota. Devices launching with R will no longer have the sdcardfs filesystem; instead, quota tracking on external storage is implemented by project IDs. Switch over the existing quota calculation to use project IDs when sdcardfs is not available. Bug: 146419093 Test: atest StorageHostTest (on devices with and without sdcardfs) Change-Id: I17925c811b08c7c85fff02ee6e279e4d7586e3ff --- cmds/installd/utils.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'cmds/installd/utils.cpp') diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp index 4eb1df0b2e..64eefe6f74 100644 --- a/cmds/installd/utils.cpp +++ b/cmds/installd/utils.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -34,9 +35,11 @@ #include #include #include +#include #include "dexopt_return_codes.h" #include "globals.h" // extern variables. +#include "QuotaUtils.h" #ifndef LOG_TAG #define LOG_TAG "installd" @@ -1060,6 +1063,51 @@ int prepare_app_cache_dir(const std::string& parent, const char* name, mode_t ta return 0; } +static const char* kProcFilesystems = "/proc/filesystems"; +bool supports_sdcardfs() { + std::string supported; + if (!android::base::ReadFileToString(kProcFilesystems, &supported)) { + PLOG(ERROR) << "Failed to read supported filesystems"; + return false; + } + return supported.find("sdcardfs\n") != std::string::npos; +} + +int64_t get_occupied_app_space_external(const std::string& uuid, int32_t userId, int32_t appId) { + static const bool supportsSdcardFs = supports_sdcardfs(); + + if (supportsSdcardFs) { + int extGid = multiuser_get_ext_gid(userId, appId); + + if (extGid == -1) { + return -1; + } + + return GetOccupiedSpaceForGid(uuid, extGid); + } else { + uid_t uid = multiuser_get_uid(userId, appId); + long projectId = uid - AID_APP_START + PROJECT_ID_EXT_DATA_START; + return GetOccupiedSpaceForProjectId(uuid, projectId); + } +} +int64_t get_occupied_app_cache_space_external(const std::string& uuid, int32_t userId, int32_t appId) { + static const bool supportsSdcardFs = supports_sdcardfs(); + + if (supportsSdcardFs) { + int extCacheGid = multiuser_get_ext_cache_gid(userId, appId); + + if (extCacheGid == -1) { + return -1; + } + + return GetOccupiedSpaceForGid(uuid, extCacheGid); + } else { + uid_t uid = multiuser_get_uid(userId, appId); + long projectId = uid - AID_APP_START + PROJECT_ID_EXT_CACHE_START; + return GetOccupiedSpaceForProjectId(uuid, projectId); + } +} + // Collect all non empty profiles from the given directory and puts then into profile_paths. // The profiles are identified based on PROFILE_EXT extension. // If a subdirectory or profile file cannot be opened the method logs a warning and moves on. -- cgit v1.2.3-59-g8ed1b