Merge "binder_rust: add async variants of get_interface and wait_for_interface"
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 157d259..39ef0b5 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -422,9 +422,131 @@
return true;
}
+static bool chown_app_dir(const std::string& path, uid_t uid, uid_t previousUid, gid_t cacheGid) {
+ FTS* fts;
+ char *argv[] = { (char*) path.c_str(), nullptr };
+ if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
+ return false;
+ }
+ for (FTSENT* p; (p = fts_read(fts)) != nullptr;) {
+ if (p->fts_info == FTS_D && p->fts_level == 1
+ && (strcmp(p->fts_name, "cache") == 0
+ || strcmp(p->fts_name, "code_cache") == 0)) {
+ // Mark cache dirs
+ p->fts_number = 1;
+ } else {
+ // Inherit parent's number
+ p->fts_number = p->fts_parent->fts_number;
+ }
+
+ switch (p->fts_info) {
+ case FTS_D:
+ case FTS_F:
+ case FTS_SL:
+ case FTS_SLNONE:
+ if (p->fts_statp->st_uid == previousUid) {
+ if (lchown(p->fts_path, uid, p->fts_number ? cacheGid : uid) != 0) {
+ PLOG(WARNING) << "Failed to lchown " << p->fts_path;
+ }
+ } else {
+ LOG(WARNING) << "Ignoring " << p->fts_path << " with unexpected UID "
+ << p->fts_statp->st_uid << " instead of " << previousUid;
+ }
+ break;
+ }
+ }
+ fts_close(fts);
+ return true;
+}
+
+static void chown_app_profile_dir(const std::string &packageName, int32_t appId, int32_t userId) {
+ uid_t uid = multiuser_get_uid(userId, appId);
+ gid_t sharedGid = multiuser_get_shared_gid(userId, appId);
+
+ const std::string profile_dir =
+ create_primary_current_profile_package_dir_path(userId, packageName);
+ char *argv[] = { (char*) profile_dir.c_str(), nullptr };
+ if (FTS* fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr)) {
+ for (FTSENT* p; (p = fts_read(fts)) != nullptr;) {
+ switch (p->fts_info) {
+ case FTS_D:
+ case FTS_F:
+ case FTS_SL:
+ case FTS_SLNONE:
+ if (lchown(p->fts_path, uid, uid) != 0) {
+ PLOG(WARNING) << "Failed to lchown " << p->fts_path;
+ }
+ break;
+ }
+ }
+ fts_close(fts);
+ }
+
+ const std::string ref_profile_path =
+ create_primary_reference_profile_package_dir_path(packageName);
+ argv[0] = (char *) ref_profile_path.c_str();
+ if (FTS* fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr)) {
+ for (FTSENT* p; (p = fts_read(fts)) != nullptr;) {
+ if (p->fts_info == FTS_D && p->fts_level == 0) {
+ if (chown(p->fts_path, AID_SYSTEM, sharedGid) != 0) {
+ PLOG(WARNING) << "Failed to chown " << p->fts_path;
+ }
+ continue;
+ }
+ switch (p->fts_info) {
+ case FTS_D:
+ case FTS_F:
+ case FTS_SL:
+ case FTS_SLNONE:
+ if (lchown(p->fts_path, sharedGid, sharedGid) != 0) {
+ PLOG(WARNING) << "Failed to lchown " << p->fts_path;
+ }
+ break;
+ }
+ }
+ fts_close(fts);
+ }
+}
+
+static binder::Status createAppDataDirs(const std::string& path,
+ int32_t uid, int32_t* previousUid, int32_t cacheGid,
+ const std::string& seInfo, mode_t targetMode) {
+ struct stat st{};
+ bool existing = (stat(path.c_str(), &st) == 0);
+ if (existing) {
+ if (*previousUid < 0) {
+ // If previousAppId is -1 in CreateAppDataArgs, we will assume the current owner
+ // of the directory as previousUid. This is required because it is not always possible
+ // to chown app data during app upgrade (e.g. secondary users' CE storage not unlocked)
+ *previousUid = st.st_uid;
+ }
+ if (*previousUid != uid) {
+ if (!chown_app_dir(path, uid, *previousUid, cacheGid)) {
+ return error("Failed to chown " + path);
+ }
+ }
+ }
+
+ if (prepare_app_dir(path, targetMode, uid) ||
+ prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
+ prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
+ return error("Failed to prepare " + path);
+ }
+
+ // Consider restorecon over contents if label changed
+ if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
+ restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
+ restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
+ return error("Failed to restorecon " + path);
+ }
+
+ return ok();
+}
+
binder::Status InstalldNativeService::createAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
- const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) {
+ int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion,
+ int64_t* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
@@ -437,6 +559,14 @@
if (_aidl_return != nullptr) *_aidl_return = -1;
int32_t uid = multiuser_get_uid(userId, appId);
+
+ // If previousAppId < 0, we will use the existing app data owner as previousAppUid
+ // If previousAppId == 0, we use uid as previousUid (no data migration will happen)
+ // if previousAppId > 0, an app is upgrading and changing its app ID
+ int32_t previousUid = previousAppId > 0
+ ? (int32_t) multiuser_get_uid(userId, previousAppId)
+ : (previousAppId == 0 ? uid : -1);
+
int32_t cacheGid = multiuser_get_cache_gid(userId, appId);
mode_t targetMode = targetSdkVersion >= MIN_RESTRICTED_HOME_SDK_VERSION ? 0700 : 0751;
@@ -447,19 +577,13 @@
if (flags & FLAG_STORAGE_CE) {
auto path = create_data_user_ce_package_path(uuid_, userId, pkgname);
- bool existing = (access(path.c_str(), F_OK) == 0);
- if (prepare_app_dir(path, targetMode, uid) ||
- prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
- prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
- return error("Failed to prepare " + path);
+ auto status = createAppDataDirs(path, uid, &previousUid, cacheGid, seInfo, targetMode);
+ if (!status.isOk()) {
+ return status;
}
-
- // Consider restorecon over contents if label changed
- if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
- restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
- restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
- return error("Failed to restorecon " + path);
+ if (previousUid != uid) {
+ chown_app_profile_dir(packageName, appId, userId);
}
// Remember inode numbers of cache directories so that we can clear
@@ -481,19 +605,10 @@
}
if (flags & FLAG_STORAGE_DE) {
auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
- bool existing = (access(path.c_str(), F_OK) == 0);
- if (prepare_app_dir(path, targetMode, uid) ||
- prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
- prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
- return error("Failed to prepare " + path);
- }
-
- // Consider restorecon over contents if label changed
- if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
- restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
- restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
- return error("Failed to restorecon " + path);
+ auto status = createAppDataDirs(path, uid, &previousUid, cacheGid, seInfo, targetMode);
+ if (!status.isOk()) {
+ return status;
}
if (!prepare_app_profile_dir(packageName, appId, userId)) {
@@ -503,7 +618,6 @@
return ok();
}
-
binder::Status InstalldNativeService::createAppData(
const android::os::CreateAppDataArgs& args,
android::os::CreateAppDataResult* _aidl_return) {
@@ -512,7 +626,7 @@
int64_t ceDataInode = -1;
auto status = createAppData(args.uuid, args.packageName, args.userId, args.flags, args.appId,
- args.seInfo, args.targetSdkVersion, &ceDataInode);
+ args.previousAppId, args.seInfo, args.targetSdkVersion, &ceDataInode);
_aidl_return->ceDataInode = ceDataInode;
_aidl_return->exceptionCode = status.exceptionCode();
_aidl_return->exceptionMessage = status.exceptionMessage();
@@ -526,7 +640,7 @@
std::lock_guard<std::recursive_mutex> lock(mLock);
std::vector<android::os::CreateAppDataResult> results;
- for (auto arg : args) {
+ for (const auto &arg : args) {
android::os::CreateAppDataResult result;
createAppData(arg, &result);
results.push_back(result);
@@ -624,14 +738,11 @@
}
}
if (flags & FLAG_STORAGE_DE) {
- std::string suffix = "";
- bool only_cache = false;
+ std::string suffix;
if (flags & FLAG_CLEAR_CACHE_ONLY) {
suffix = CACHE_DIR_POSTFIX;
- only_cache = true;
} else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
suffix = CODE_CACHE_DIR_POSTFIX;
- only_cache = true;
}
auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix;
@@ -1226,7 +1337,7 @@
}
if (!createAppData(toUuid, packageName, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE, appId,
- seInfo, targetSdkVersion, nullptr).isOk()) {
+ /* previousAppId */ -1, seInfo, targetSdkVersion, nullptr).isOk()) {
res = error("Failed to create package target");
goto fail;
}
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index ae257df..8cfda01 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -47,7 +47,8 @@
binder::Status createAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
- const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return);
+ int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion,
+ int64_t* _aidl_return);
binder::Status createAppData(
const android::os::CreateAppDataArgs& args,
diff --git a/cmds/installd/binder/android/os/CreateAppDataArgs.aidl b/cmds/installd/binder/android/os/CreateAppDataArgs.aidl
index 96d7faa..d5e8ee5 100644
--- a/cmds/installd/binder/android/os/CreateAppDataArgs.aidl
+++ b/cmds/installd/binder/android/os/CreateAppDataArgs.aidl
@@ -23,6 +23,7 @@
int userId;
int flags;
int appId;
+ int previousAppId;
@utf8InCpp String seInfo;
int targetSdkVersion;
}
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index ea26955..a937436 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -287,6 +287,7 @@
kTestUserId,
kAppDataFlags,
kTestAppUid,
+ 0 /* previousAppId */,
se_info_,
kOSdkVersion,
&ce_data_inode_);
@@ -1257,6 +1258,7 @@
kTestUserId,
kAppDataFlags,
kTestAppUid,
+ 0 /* previousAppId */,
se_info_,
kOSdkVersion,
&ce_data_inode_));
@@ -1320,6 +1322,7 @@
kTestUserId,
kAppDataFlags,
kTestAppUid,
+ 0 /* previousAppId */,
se_info_,
kOSdkVersion,
&ce_data_inode));
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index dc153c9..8270ae5 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -149,6 +149,11 @@
"UtilsHost.cpp",
],
},
+ recovery: {
+ exclude_header_libs: [
+ "libandroid_runtime_vm_headers",
+ ],
+ },
},
aidl: {
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 53c9b78..a5a2bb1 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -29,13 +29,11 @@
#include <android-base/hex.h>
#include <android-base/macros.h>
#include <android-base/scopeguard.h>
-#include <android_runtime/vm.h>
#include <binder/BpBinder.h>
#include <binder/Parcel.h>
#include <binder/RpcServer.h>
#include <binder/RpcTransportRaw.h>
#include <binder/Stability.h>
-#include <jni.h>
#include <utils/String8.h>
#include "FdTrigger.h"
@@ -48,6 +46,11 @@
extern "C" pid_t gettid();
#endif
+#ifndef __ANDROID_RECOVERY__
+#include <android_runtime/vm.h>
+#include <jni.h>
+#endif
+
namespace android {
using base::unique_fd;
@@ -315,6 +318,9 @@
}
namespace {
+#ifdef __ANDROID_RECOVERY__
+class JavaThreadAttacher {};
+#else
// RAII object for attaching / detaching current thread to JVM if Android Runtime exists. If
// Android Runtime doesn't exist, no-op.
class JavaThreadAttacher {
@@ -367,6 +373,7 @@
return fn();
}
};
+#endif
} // namespace
void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult) {
@@ -374,7 +381,7 @@
if (setupResult.status == OK) {
LOG_ALWAYS_FATAL_IF(!connection, "must have connection if setup succeeded");
- JavaThreadAttacher javaThreadAttacher;
+ [[maybe_unused]] JavaThreadAttacher javaThreadAttacher;
while (true) {
status_t status = session->state()->getAndExecuteCommand(connection, session,
RpcState::CommandType::ANY);
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 30d19e3..b3647d6 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -301,7 +301,7 @@
// continues to use it.
sp<GraphicBuffer> buffer = new GraphicBuffer(
kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
- GraphicBuffer::USAGE_SW_WRITE_RARELY,
+ DEFAULT_USAGE_FLAGS | GraphicBuffer::USAGE_SW_WRITE_RARELY,
"[GLConsumer debug texture]");
uint32_t* bits;
buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
diff --git a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
index 2f31888..6882ea3 100644
--- a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
+++ b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
@@ -191,7 +191,7 @@
// continues to use it.
sp<GraphicBuffer> buffer =
new GraphicBuffer(kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
- GraphicBuffer::USAGE_SW_WRITE_RARELY,
+ DEFAULT_USAGE_FLAGS | GraphicBuffer::USAGE_SW_WRITE_RARELY,
"[EGLConsumer debug texture]");
uint32_t* bits;
buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));