Merge "Add adbd tls APIs to adbd_auth library."
diff --git a/cmds/installd/CacheTracker.cpp b/cmds/installd/CacheTracker.cpp
index 8b868fb..a61f6bf 100644
--- a/cmds/installd/CacheTracker.cpp
+++ b/cmds/installd/CacheTracker.cpp
@@ -75,8 +75,7 @@
bool CacheTracker::loadQuotaStats() {
int cacheGid = multiuser_get_cache_gid(mUserId, mAppId);
- int extCacheGid = multiuser_get_ext_cache_gid(mUserId, mAppId);
- if (IsQuotaSupported(mUuid) && cacheGid != -1 && extCacheGid != -1) {
+ if (IsQuotaSupported(mUuid) && cacheGid != -1) {
int64_t space;
if ((space = GetOccupiedSpaceForGid(mUuid, cacheGid)) != -1) {
cacheUsed += space;
@@ -84,7 +83,7 @@
return false;
}
- if ((space = GetOccupiedSpaceForGid(mUuid, extCacheGid)) != -1) {
+ if ((space = get_occupied_app_cache_space_external(mUuid, mUserId, mAppId)) != -1) {
cacheUsed += space;
} else {
return false;
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 0fde31a..b3e6792 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -53,6 +53,7 @@
#include <log/log.h> // TODO: Move everything to base/logging.
#include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h>
+#include <private/android_projectid_config.h>
#include <selinux/android.h>
#include <system/thread_defs.h>
#include <utils/Trace.h>
@@ -689,11 +690,13 @@
if (delete_dir_contents_and_dir(path) != 0) {
res = error("Failed to delete " + path);
}
- destroy_app_current_profiles(packageName, userId);
- // TODO(calin): If the package is still installed by other users it's probably
- // beneficial to keep the reference profile around.
- // Verify if it's ok to do that.
- destroy_app_reference_profile(packageName);
+ if ((flags & FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
+ destroy_app_current_profiles(packageName, userId);
+ // TODO(calin): If the package is still installed by other users it's probably
+ // beneficial to keep the reference profile around.
+ // Verify if it's ok to do that.
+ destroy_app_reference_profile(packageName);
+ }
}
if (flags & FLAG_STORAGE_EXTERNAL) {
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
@@ -1475,8 +1478,8 @@
static void collectQuotaStats(const std::string& uuid, int32_t userId,
int32_t appId, struct stats* stats, struct stats* extStats) {
int64_t space;
+ uid_t uid = multiuser_get_uid(userId, appId);
if (stats != nullptr) {
- uid_t uid = multiuser_get_uid(userId, appId);
if ((space = GetOccupiedSpaceForUid(uuid, uid)) != -1) {
stats->dataSize += space;
}
@@ -1497,20 +1500,44 @@
}
if (extStats != nullptr) {
- int extGid = multiuser_get_ext_gid(userId, appId);
- if (extGid != -1) {
- if ((space = GetOccupiedSpaceForGid(uuid, extGid)) != -1) {
- extStats->dataSize += space;
+ static const bool supportsSdCardFs = supports_sdcardfs();
+ space = get_occupied_app_space_external(uuid, userId, appId);
+
+ if (space != -1) {
+ extStats->dataSize += space;
+ if (!supportsSdCardFs && stats != nullptr) {
+ // On devices without sdcardfs, if internal and external are on
+ // the same volume, a uid such as u0_a123 is used for
+ // application dirs on both internal and external storage;
+ // therefore, substract that amount from internal to make sure
+ // we don't count it double.
+ stats->dataSize -= space;
}
}
- int extCacheGid = multiuser_get_ext_cache_gid(userId, appId);
- if (extCacheGid != -1) {
- if ((space = GetOccupiedSpaceForGid(uuid, extCacheGid)) != -1) {
- extStats->dataSize += space;
- extStats->cacheSize += space;
+ space = get_occupied_app_cache_space_external(uuid, userId, appId);
+ if (space != -1) {
+ extStats->dataSize += space; // cache counts for "data"
+ extStats->cacheSize += space;
+ if (!supportsSdCardFs && stats != nullptr) {
+ // On devices without sdcardfs, if internal and external are on
+ // the same volume, a uid such as u0_a123 is used for both
+ // internal and external storage; therefore, substract that
+ // amount from internal to make sure we don't count it double.
+ stats->dataSize -= space;
}
}
+
+ if (!supportsSdCardFs && stats != nullptr) {
+ // On devices without sdcardfs, the UID of OBBs on external storage
+ // matches the regular app UID (eg u0_a123); therefore, to avoid
+ // OBBs being include in stats->dataSize, compute the OBB size for
+ // this app, and substract it from the size reported on internal
+ // storage
+ long obbProjectId = uid - AID_APP_START + PROJECT_ID_EXT_OBB_START;
+ int64_t appObbSize = GetOccupiedSpaceForProjectId(uuid, obbProjectId);
+ stats->dataSize -= appObbSize;
+ }
}
}
@@ -1759,6 +1786,106 @@
return ok();
}
+struct external_sizes {
+ int64_t audioSize;
+ int64_t videoSize;
+ int64_t imageSize;
+ int64_t totalSize; // excludes OBBs (Android/obb), but includes app data + cache
+ int64_t obbSize;
+};
+
+#define PER_USER_RANGE 100000
+
+static long getProjectIdForUser(int userId, long projectId) {
+ return userId * PER_USER_RANGE + projectId;
+}
+
+static external_sizes getExternalSizesForUserWithQuota(const std::string& uuid, int32_t userId, const std::vector<int32_t>& appIds) {
+ struct external_sizes sizes = {};
+ int64_t space;
+
+ if (supports_sdcardfs()) {
+ uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
+ if ((space = GetOccupiedSpaceForUid(uuid, uid)) != -1) {
+ sizes.totalSize = space;
+ }
+
+ gid_t audioGid = multiuser_get_uid(userId, AID_MEDIA_AUDIO);
+ if ((space = GetOccupiedSpaceForGid(uuid, audioGid)) != -1) {
+ sizes.audioSize = space;
+ }
+
+ gid_t videoGid = multiuser_get_uid(userId, AID_MEDIA_VIDEO);
+ if ((space = GetOccupiedSpaceForGid(uuid, videoGid)) != -1) {
+ sizes.videoSize = space;
+ }
+
+ gid_t imageGid = multiuser_get_uid(userId, AID_MEDIA_IMAGE);
+ if ((space = GetOccupiedSpaceForGid(uuid, imageGid)) != -1) {
+ sizes.imageSize = space;
+ }
+
+ if ((space = GetOccupiedSpaceForGid(uuid, AID_MEDIA_OBB)) != -1) {
+ sizes.obbSize = space;
+ }
+ } else {
+ int64_t totalSize = 0;
+ long defaultProjectId = getProjectIdForUser(userId, PROJECT_ID_EXT_DEFAULT);
+ if ((space = GetOccupiedSpaceForProjectId(uuid, defaultProjectId)) != -1) {
+ // This is all files that are not audio/video/images, excluding
+ // OBBs and app-private data
+ totalSize += space;
+ }
+
+ long audioProjectId = getProjectIdForUser(userId, PROJECT_ID_EXT_MEDIA_AUDIO);
+ if ((space = GetOccupiedSpaceForProjectId(uuid, audioProjectId)) != -1) {
+ sizes.audioSize = space;
+ totalSize += space;
+ }
+
+ long videoProjectId = getProjectIdForUser(userId, PROJECT_ID_EXT_MEDIA_VIDEO);
+ if ((space = GetOccupiedSpaceForProjectId(uuid, videoProjectId)) != -1) {
+ sizes.videoSize = space;
+ totalSize += space;
+ }
+
+ long imageProjectId = getProjectIdForUser(userId, PROJECT_ID_EXT_MEDIA_IMAGE);
+ if ((space = GetOccupiedSpaceForProjectId(uuid, imageProjectId)) != -1) {
+ sizes.imageSize = space;
+ totalSize += space;
+ }
+
+ int64_t totalAppDataSize = 0;
+ int64_t totalAppCacheSize = 0;
+ int64_t totalAppObbSize = 0;
+ for (auto appId : appIds) {
+ if (appId >= AID_APP_START) {
+ // App data
+ uid_t uid = multiuser_get_uid(userId, appId);
+ long projectId = uid - AID_APP_START + PROJECT_ID_EXT_DATA_START;
+ totalAppDataSize += GetOccupiedSpaceForProjectId(uuid, projectId);
+
+ // App cache
+ long cacheProjectId = uid - AID_APP_START + PROJECT_ID_EXT_CACHE_START;
+ totalAppCacheSize += GetOccupiedSpaceForProjectId(uuid, cacheProjectId);
+
+ // App OBBs
+ long obbProjectId = uid - AID_APP_START + PROJECT_ID_EXT_OBB_START;
+ totalAppObbSize += GetOccupiedSpaceForProjectId(uuid, obbProjectId);
+ }
+ }
+ // Total size should include app data + cache
+ totalSize += totalAppDataSize;
+ totalSize += totalAppCacheSize;
+ sizes.totalSize = totalSize;
+
+ // Only OBB is separate
+ sizes.obbSize = totalAppObbSize;
+ }
+
+ return sizes;
+}
+
binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::string>& uuid,
int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
std::vector<int64_t>* _aidl_return) {
@@ -1787,14 +1914,6 @@
}
if (flags & FLAG_USE_QUOTA) {
- int64_t space;
-
- ATRACE_BEGIN("obb");
- if ((space = GetOccupiedSpaceForGid(uuidString, AID_MEDIA_OBB)) != -1) {
- extStats.codeSize += space;
- }
- ATRACE_END();
-
ATRACE_BEGIN("code");
calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize, -1, -1, true);
ATRACE_END();
@@ -1816,10 +1935,9 @@
}
ATRACE_BEGIN("external");
- uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
- if ((space = GetOccupiedSpaceForUid(uuidString, uid)) != -1) {
- extStats.dataSize += space;
- }
+ auto sizes = getExternalSizesForUserWithQuota(uuidString, userId, appIds);
+ extStats.dataSize += sizes.totalSize;
+ extStats.codeSize += sizes.obbSize;
ATRACE_END();
if (!uuid) {
@@ -1830,13 +1948,11 @@
-1, -1, true);
ATRACE_END();
}
-
ATRACE_BEGIN("quota");
int64_t dataSize = extStats.dataSize;
for (auto appId : appIds) {
if (appId >= AID_APP_START) {
collectQuotaStats(uuidString, userId, appId, &stats, &extStats);
-
#if MEASURE_DEBUG
// Sleep to make sure we don't lose logs
usleep(1);
@@ -1932,29 +2048,13 @@
}
if (flags & FLAG_USE_QUOTA) {
- int64_t space;
-
ATRACE_BEGIN("quota");
- uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
- if ((space = GetOccupiedSpaceForUid(uuidString, uid)) != -1) {
- totalSize = space;
- }
-
- gid_t audioGid = multiuser_get_uid(userId, AID_MEDIA_AUDIO);
- if ((space = GetOccupiedSpaceForGid(uuidString, audioGid)) != -1) {
- audioSize = space;
- }
- gid_t videoGid = multiuser_get_uid(userId, AID_MEDIA_VIDEO);
- if ((space = GetOccupiedSpaceForGid(uuidString, videoGid)) != -1) {
- videoSize = space;
- }
- gid_t imageGid = multiuser_get_uid(userId, AID_MEDIA_IMAGE);
- if ((space = GetOccupiedSpaceForGid(uuidString, imageGid)) != -1) {
- imageSize = space;
- }
- if ((space = GetOccupiedSpaceForGid(uuidString, AID_MEDIA_OBB)) != -1) {
- obbSize = space;
- }
+ auto sizes = getExternalSizesForUserWithQuota(uuidString, userId, appIds);
+ totalSize = sizes.totalSize;
+ audioSize = sizes.audioSize;
+ videoSize = sizes.videoSize;
+ imageSize = sizes.imageSize;
+ obbSize = sizes.obbSize;
ATRACE_END();
ATRACE_BEGIN("apps");
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 2f79552..f82afa8 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -26,6 +26,7 @@
#include <sys/xattr.h>
#include <sys/statvfs.h>
+#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
@@ -34,9 +35,11 @@
#include <cutils/properties.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>
+#include <private/android_projectid_config.h>
#include "dexopt_return_codes.h"
#include "globals.h" // extern variables.
+#include "QuotaUtils.h"
#ifndef LOG_TAG
#define LOG_TAG "installd"
@@ -1060,6 +1063,51 @@
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.
diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h
index 6a42026..2503168 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -150,6 +150,10 @@
int prepare_app_cache_dir(const std::string& parent, const char* name, mode_t target_mode,
uid_t uid, gid_t gid);
+bool supports_sdcardfs();
+int64_t get_occupied_app_space_external(const std::string& uuid, int32_t userId, int32_t appId);
+int64_t get_occupied_app_cache_space_external(const std::string& uuid, int32_t userId, int32_t appId);
+
// Collect all non empty profiles from the global profile directory and
// put 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.
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index f064bd7..71d8130 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -64,8 +64,7 @@
bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name,
bool allowIsolated, int dumpFlags) {
- auto manager = interface_cast<AidlServiceManager>(
- ProcessState::self()->getContextObject(nullptr));
+ auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager()));
bool reRegister = mRegisteredServices.count(name) > 0;
std::string regStr = (reRegister) ? "Re-registering" : "Registering";
@@ -114,9 +113,7 @@
void ClientCounterCallback::tryShutdown() {
ALOGI("Trying to shut down the service. No clients in use for any service in process.");
- // This makes the same assumption as IServiceManager.cpp. Could dedupe if used in more places.
- auto manager = interface_cast<AidlServiceManager>(
- ProcessState::self()->getContextObject(nullptr));
+ auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager()));
auto unRegisterIt = mRegisteredServices.begin();
for (; unRegisterIt != mRegisteredServices.end(); ++unRegisterIt) {
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 822247f..f1077ae 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -558,6 +558,13 @@
bool Parcel::enforceInterface(const String16& interface,
IPCThreadState* threadState) const
{
+ return enforceInterface(interface.string(), interface.size(), threadState);
+}
+
+bool Parcel::enforceInterface(const char16_t* interface,
+ size_t len,
+ IPCThreadState* threadState) const
+{
// StrictModePolicy.
int32_t strictPolicy = readInt32();
if (threadState == nullptr) {
@@ -584,12 +591,15 @@
return false;
}
// Interface descriptor.
- const String16 str(readString16());
- if (str == interface) {
+ size_t parcel_interface_len;
+ const char16_t* parcel_interface = readString16Inplace(&parcel_interface_len);
+ if (len == parcel_interface_len &&
+ (!len || !memcmp(parcel_interface, interface, len * sizeof (char16_t)))) {
return true;
} else {
ALOGW("**** enforceInterface() expected '%s' but read '%s'",
- String8(interface).string(), String8(str).string());
+ String8(interface, len).string(),
+ String8(parcel_interface, parcel_interface_len).string());
return false;
}
}
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index c0f5e31..631e8c5 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -112,6 +112,10 @@
{
sp<IBinder> context = getStrongProxyForHandle(0);
+ if (context == nullptr) {
+ ALOGW("Not able to get context object on %s.", mDriverName.c_str());
+ }
+
// The root object is special since we get it directly from the driver, it is never
// written by Parcell::writeStrongBinder.
internal::Stability::tryMarkCompilationUnit(context.get());
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index d4bb85b..4b1a758 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -96,6 +96,9 @@
// passed in.
bool enforceInterface(const String16& interface,
IPCThreadState* threadState = nullptr) const;
+ bool enforceInterface(const char16_t* interface,
+ size_t len,
+ IPCThreadState* threadState = nullptr) const;
bool checkInterface(IBinder*) const;
void freeData();
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 703ceae..c33c44f 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -247,15 +247,12 @@
if (fd != -1) {
return STATUS_UNKNOWN_ERROR;
}
- return parcel->get()->writeInt32(0); // null
+ return PruneStatusT(parcel->get()->writeInt32(0)); // null
}
+ status_t status = parcel->get()->writeInt32(1); // not-null
+ if (status != STATUS_OK) return PruneStatusT(status);
- ParcelFileDescriptor parcelFd = ParcelFileDescriptor(unique_fd(fd));
- status_t status = parcel->get()->writeParcelable(parcelFd);
-
- // ownership is retained by caller
- (void)parcelFd.release().release();
-
+ status = parcel->get()->writeDupParcelFileDescriptor(fd);
return PruneStatusT(status);
}
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 5e0574a..8cb06e1 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -30,6 +30,7 @@
#include <private/binder/binder_module.h>
#include <sys/epoll.h>
+#include <sys/prctl.h>
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
@@ -106,6 +107,7 @@
if (pid == -1)
return pid;
if (pid == 0) {
+ prctl(PR_SET_PDEATHSIG, SIGHUP);
close(pipefd[0]);
execv(binderservername, childargv);
status = -errno;
diff --git a/libs/cputimeinstate/cputimeinstate.cpp b/libs/cputimeinstate/cputimeinstate.cpp
index a03775b..58126dc 100644
--- a/libs/cputimeinstate/cputimeinstate.cpp
+++ b/libs/cputimeinstate/cputimeinstate.cpp
@@ -161,6 +161,17 @@
return bpf_attach_tracepoint(prog_fd, eventType.c_str(), eventName.c_str()) >= 0;
}
+static std::optional<uint32_t> getPolicyFreqIdx(uint32_t policy) {
+ auto path = StringPrintf("/sys/devices/system/cpu/cpufreq/policy%u/scaling_cur_freq",
+ gPolicyCpus[policy][0]);
+ auto freqVec = readNumbersFromFile(path);
+ if (!freqVec.has_value() || freqVec->size() != 1) return {};
+ for (uint32_t idx = 0; idx < gPolicyFreqs[policy].size(); ++idx) {
+ if ((*freqVec)[0] == gPolicyFreqs[policy][idx]) return idx + 1;
+ }
+ return {};
+}
+
// Start tracking and aggregating data to be reported by getUidCpuFreqTimes and getUidsCpuFreqTimes.
// Returns true on success, false otherwise.
// Tracking is active only once a live process has successfully called this function; if the calling
@@ -215,7 +226,9 @@
unique_fd policyFreqIdxFd(bpf_obj_get_wronly(BPF_FS_PATH "map_time_in_state_policy_freq_idx_map"));
if (policyFreqIdxFd < 0) return false;
for (uint32_t i = 0; i < gNPolicies; ++i) {
- if (writeToMapEntry(policyFreqIdxFd, &i, &zero, BPF_ANY)) return false;
+ auto freqIdx = getPolicyFreqIdx(i);
+ if (!freqIdx.has_value()) return false;
+ if (writeToMapEntry(policyFreqIdxFd, &i, &(*freqIdx), BPF_ANY)) return false;
}
gTracking = attachTracepointProgram("sched", "sched_switch") &&