diff options
51 files changed, 844 insertions, 470 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index f494f6e661..16ebf6f107 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -5,6 +5,7 @@ clang_format = true # Only turn on clang-format check for the following subfolders. clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp cmds/idlcli/ + cmds/servicemanager/ include/input/ libs/binder/fuzzer/ libs/binder/ diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp index c04b558e2d..3a87776162 100644 --- a/cmds/installd/otapreopt_chroot.cpp +++ b/cmds/installd/otapreopt_chroot.cpp @@ -27,6 +27,7 @@ #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/macros.h> +#include <android-base/scopeguard.h> #include <android-base/stringprintf.h> #include <android-base/unique_fd.h> #include <libdm/dm.h> @@ -72,6 +73,15 @@ static void ActivateApexPackages() { } } +static void DeactivateApexPackages() { + std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--unmount-all"}; + std::string apexd_error_msg; + bool exec_result = Exec(apexd_cmd, &apexd_error_msg); + if (!exec_result) { + PLOG(ERROR) << "Running /system/bin/apexd --unmount-all failed: " << apexd_error_msg; + } +} + static void TryExtraMount(const char* name, const char* slot, const char* target) { std::string partition_name = StringPrintf("%s%s", name, slot); @@ -231,10 +241,30 @@ static int otapreopt_chroot(const int argc, char **arg) { exit(205); } + // Call apexd --unmount-all to free up loop and dm block devices, so that we can re-use + // them during the next invocation. Since otapreopt_chroot calls exit in case something goes + // wrong we need to register our own atexit handler. + // We want to register this handler before actually activating apex packages. This is mostly + // due to the fact that if fail to unmount apexes, then on the next run of otapreopt_chroot + // we will ask for new loop devices instead of re-using existing ones, and we really don't want + // to do that. :) + if (atexit(DeactivateApexPackages) != 0) { + LOG(ERROR) << "Failed to register atexit hander"; + exit(206); + } + // Try to mount APEX packages in "/apex" in the chroot dir. We need at least // the ART APEX, as it is required by otapreopt to run dex2oat. ActivateApexPackages(); + auto cleanup = android::base::make_scope_guard([](){ + std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--unmount-all"}; + std::string apexd_error_msg; + bool exec_result = Exec(apexd_cmd, &apexd_error_msg); + if (!exec_result) { + PLOG(ERROR) << "Running /system/bin/apexd --unmount-all failed: " << apexd_error_msg; + } + }); // Check that an ART APEX has been activated; clean up and exit // early otherwise. static constexpr const std::string_view kRequiredApexs[] = { diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp index c47df52984..c4ecd070c1 100644 --- a/cmds/installd/utils.cpp +++ b/cmds/installd/utils.cpp @@ -1062,6 +1062,8 @@ int prepare_app_cache_dir(const std::string& parent, const char* name, mode_t ta static const char* kProcFilesystems = "/proc/filesystems"; bool supports_sdcardfs() { + if (!property_get_bool("external_storage.sdcardfs.enabled", true)) + return false; std::string supported; if (!android::base::ReadFileToString(kProcFilesystems, &supported)) { PLOG(ERROR) << "Failed to read supported filesystems"; diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp index b6ff28d416..7c1ca91528 100644 --- a/cmds/lshal/test.cpp +++ b/cmds/lshal/test.cpp @@ -508,10 +508,10 @@ TEST_F(ListTest, DumpVintf) { EXPECT_THAT(output, HasSubstr("a.h.foo6@6.0::IFoo/6")); EXPECT_EQ("", err.str()); + std::string error; vintf::HalManifest m; - EXPECT_EQ(true, vintf::gHalManifestConverter(&m, out.str())) - << "--init-vintf does not emit valid HAL manifest: " - << vintf::gHalManifestConverter.lastError(); + EXPECT_EQ(true, vintf::gHalManifestConverter(&m, out.str(), &error)) + << "--init-vintf does not emit valid HAL manifest: " << error; } // test default columns diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp index 9de344a820..3ebdeee7aa 100644 --- a/cmds/servicemanager/Android.bp +++ b/cmds/servicemanager/Android.bp @@ -14,6 +14,7 @@ cc_defaults { "-Wall", "-Wextra", "-Werror", + "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION", ], srcs: [ diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp index 0dbab4e055..2f5524940e 100644 --- a/cmds/servicemanager/ServiceManager.cpp +++ b/cmds/servicemanager/ServiceManager.cpp @@ -239,7 +239,8 @@ Status ServiceManager::addService(const std::string& name, const sp<IBinder>& bi #endif // !VENDORSERVICEMANAGER // implicitly unlinked when the binder is removed - if (binder->remoteBinder() != nullptr && binder->linkToDeath(this) != OK) { + if (binder->remoteBinder() != nullptr && + binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) { LOG(ERROR) << "Could not linkToDeath when adding " << name; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } @@ -307,7 +308,9 @@ Status ServiceManager::registerForNotifications( return Status::fromExceptionCode(Status::EX_NULL_POINTER); } - if (OK != IInterface::asBinder(callback)->linkToDeath(this)) { + if (OK != + IInterface::asBinder(callback)->linkToDeath( + sp<ServiceManager>::fromExisting(this))) { LOG(ERROR) << "Could not linkToDeath when adding " << name; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } @@ -461,7 +464,8 @@ Status ServiceManager::registerClientCallback(const std::string& name, const sp< return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT); } - if (OK != IInterface::asBinder(cb)->linkToDeath(this)) { + if (OK != + IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) { LOG(ERROR) << "Could not linkToDeath when adding client callback for " << name; return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE); } @@ -491,7 +495,7 @@ void ServiceManager::removeClientCallback(const wp<IBinder>& who, } ssize_t ServiceManager::Service::getNodeStrongRefCount() { - sp<BpBinder> bpBinder = binder->remoteBinder(); + sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder()); if (bpBinder == nullptr) return -1; return ProcessState::self()->getStrongRefCountForNode(bpBinder); diff --git a/cmds/servicemanager/main.cpp b/cmds/servicemanager/main.cpp index 627dfe6382..8c1beaca20 100644 --- a/cmds/servicemanager/main.cpp +++ b/cmds/servicemanager/main.cpp @@ -39,7 +39,7 @@ using ::android::sp; class BinderCallback : public LooperCallback { public: static sp<BinderCallback> setupTo(const sp<Looper>& looper) { - sp<BinderCallback> cb = new BinderCallback; + sp<BinderCallback> cb = sp<BinderCallback>::make(); int binder_fd = -1; IPCThreadState::self()->setupPolling(&binder_fd); @@ -65,7 +65,7 @@ public: class ClientCallbackCallback : public LooperCallback { public: static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) { - sp<ClientCallbackCallback> cb = new ClientCallbackCallback(manager); + sp<ClientCallbackCallback> cb = sp<ClientCallbackCallback>::make(manager); int fdTimer = timerfd_create(CLOCK_MONOTONIC, 0 /*flags*/); LOG_ALWAYS_FATAL_IF(fdTimer < 0, "Failed to timerfd_create: fd: %d err: %d", fdTimer, errno); @@ -105,6 +105,7 @@ public: return 1; // Continue receiving callbacks. } private: + friend sp<ClientCallbackCallback>; ClientCallbackCallback(const sp<ServiceManager>& manager) : mManager(manager) {} sp<ServiceManager> mManager; }; @@ -120,7 +121,7 @@ int main(int argc, char** argv) { ps->setThreadPoolMaxThreadCount(0); ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY); - sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>()); + sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>()); if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) { LOG(ERROR) << "Could not self register servicemanager"; } diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp index fb9f9df856..5d5a75e174 100644 --- a/cmds/servicemanager/test_sm.cpp +++ b/cmds/servicemanager/test_sm.cpp @@ -46,7 +46,7 @@ static sp<IBinder> getBinder() { } }; - return new LinkableBinder; + return sp<LinkableBinder>::make(); } class MockAccess : public Access { @@ -71,7 +71,7 @@ static sp<ServiceManager> getPermissiveServiceManager() { ON_CALL(*access, canFind(_, _)).WillByDefault(Return(true)); ON_CALL(*access, canList(_)).WillByDefault(Return(true)); - sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access)); + sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access)); return sm; } @@ -119,7 +119,7 @@ TEST(AddService, AddDisallowedFromApp) { .uid = uid, })); EXPECT_CALL(*access, canAdd(_, _)).Times(0); - sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access)); + sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access)); EXPECT_FALSE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); @@ -161,7 +161,7 @@ TEST(AddService, NoPermissions) { EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{})); EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(false)); - sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access)); + sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access)); EXPECT_FALSE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); @@ -194,7 +194,7 @@ TEST(GetService, NoPermissionsForGettingService) { EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true)); EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(false)); - sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access)); + sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access)); EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); @@ -218,7 +218,7 @@ TEST(GetService, AllowedFromIsolated) { EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true)); EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true)); - sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access)); + sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access)); sp<IBinder> service = getBinder(); EXPECT_TRUE(sm->addService("foo", service, true /*allowIsolated*/, @@ -244,7 +244,7 @@ TEST(GetService, NotAllowedFromIsolated) { // TODO(b/136023468): when security check is first, this should be called first // EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true)); - sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access)); + sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access)); EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); @@ -261,7 +261,7 @@ TEST(ListServices, NoPermissions) { EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{})); EXPECT_CALL(*access, canList(_)).WillOnce(Return(false)); - sp<ServiceManager> sm = new NiceMock<MockServiceManager>(std::move(access)); + sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access)); std::vector<std::string> out; EXPECT_FALSE(sm->listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL, &out).isOk()); @@ -329,9 +329,9 @@ TEST(ServiceNotifications, NoPermissionsRegister) { EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{})); EXPECT_CALL(*access, canFind(_,_)).WillOnce(Return(false)); - sp<ServiceManager> sm = new ServiceManager(std::move(access)); + sp<ServiceManager> sm = sp<ServiceManager>::make(std::move(access)); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_EQ(sm->registerForNotifications("foofoo", cb).exceptionCode(), Status::EX_SECURITY); @@ -343,9 +343,9 @@ TEST(ServiceNotifications, NoPermissionsUnregister) { EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{})); EXPECT_CALL(*access, canFind(_,_)).WillOnce(Return(false)); - sp<ServiceManager> sm = new ServiceManager(std::move(access)); + sp<ServiceManager> sm = sp<ServiceManager>::make(std::move(access)); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); // should always hit security error first EXPECT_EQ(sm->unregisterForNotifications("foofoo", cb).exceptionCode(), @@ -355,7 +355,7 @@ TEST(ServiceNotifications, NoPermissionsUnregister) { TEST(ServiceNotifications, InvalidName) { auto sm = getPermissiveServiceManager(); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_EQ(sm->registerForNotifications("foo@foo", cb).exceptionCode(), Status::EX_ILLEGAL_ARGUMENT); @@ -371,7 +371,7 @@ TEST(ServiceNotifications, NullCallback) { TEST(ServiceNotifications, Unregister) { auto sm = getPermissiveServiceManager(); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_TRUE(sm->registerForNotifications("foofoo", cb).isOk()); EXPECT_EQ(sm->unregisterForNotifications("foofoo", cb).exceptionCode(), 0); @@ -380,7 +380,7 @@ TEST(ServiceNotifications, Unregister) { TEST(ServiceNotifications, UnregisterWhenNoRegistrationExists) { auto sm = getPermissiveServiceManager(); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_EQ(sm->unregisterForNotifications("foofoo", cb).exceptionCode(), Status::EX_ILLEGAL_STATE); @@ -389,7 +389,7 @@ TEST(ServiceNotifications, UnregisterWhenNoRegistrationExists) { TEST(ServiceNotifications, NoNotification) { auto sm = getPermissiveServiceManager(); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); EXPECT_TRUE(sm->registerForNotifications("foofoo", cb).isOk()); EXPECT_TRUE(sm->addService("otherservice", getBinder(), @@ -402,7 +402,7 @@ TEST(ServiceNotifications, NoNotification) { TEST(ServiceNotifications, GetNotification) { auto sm = getPermissiveServiceManager(); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); sp<IBinder> service = getBinder(); @@ -417,7 +417,7 @@ TEST(ServiceNotifications, GetNotification) { TEST(ServiceNotifications, GetNotificationForAlreadyRegisteredService) { auto sm = getPermissiveServiceManager(); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); sp<IBinder> service = getBinder(); @@ -433,7 +433,7 @@ TEST(ServiceNotifications, GetNotificationForAlreadyRegisteredService) { TEST(ServiceNotifications, GetMultipleNotification) { auto sm = getPermissiveServiceManager(); - sp<CallbackHistorian> cb = new CallbackHistorian; + sp<CallbackHistorian> cb = sp<CallbackHistorian>::make(); sp<IBinder> binder1 = getBinder(); sp<IBinder> binder2 = getBinder(); diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index 49cb098084..f85c4dce79 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -58,21 +58,15 @@ cc_library_headers { // transport itself and should be moved to AIDL or in domain-specific libs. // // Currently, these are only on system android (not vendor, not host) +// TODO(b/183654927) - move these into separate libraries libbinder_device_interface_sources = [ - "ActivityManager.cpp", "AppOpsManager.cpp", - "IActivityManager.cpp", "IAppOpsCallback.cpp", "IAppOpsService.cpp", - "IBatteryStats.cpp", - "IMediaResourceMonitor.cpp", + "IPermissionController.cpp", - "IProcessInfoService.cpp", - "IUidObserver.cpp", "PermissionCache.cpp", "PermissionController.cpp", - "ProcessInfoService.cpp", - "IpPrefix.cpp", ] cc_library { @@ -265,3 +259,56 @@ aidl_interface { }, }, } + +// libbinder historically contained additional interfaces that provided specific +// functionality in the platform but have nothing to do with binder itself. These +// are moved out of libbinder in order to avoid the overhead of their vtables. +// If you are working on or own one of these interfaces, the responsible things +// to would be: +// - give them a new home +// - convert them to AIDL instead of having manually written parceling code + +cc_library { + name: "libbatterystats_aidl", + srcs: [ + "IBatteryStats.cpp", + ], + export_include_dirs: ["include_batterystats"], + shared_libs: [ + "libbinder", + "libutils", + ], +} + +cc_library { + name: "libprocessinfoservice_aidl", + srcs: [ + "IProcessInfoService.cpp", + "ProcessInfoService.cpp", + ], + export_include_dirs: ["include_processinfo"], + shared_libs: [ + "libbinder", + "libutils", + "liblog", + ], +} + +cc_library { + name: "libactivitymanager_aidl", + srcs: [ + "ActivityManager.cpp", + "IActivityManager.cpp", + "IUidObserver.cpp", + ":activity_manager_procstate_aidl", + ], + export_include_dirs: ["include_activitymanager"], + shared_libs: [ + "libbinder", + "libutils", + "liblog", + ], + aidl: { + export_aidl_headers: true, + }, +} diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp index 825a821cc4..53b36fffdc 100644 --- a/libs/binder/BpBinder.cpp +++ b/libs/binder/BpBinder.cpp @@ -194,10 +194,13 @@ bool BpBinder::isDescriptorCached() const { const String16& BpBinder::getInterfaceDescriptor() const { if (isDescriptorCached() == false) { - Parcel send, reply; + sp<BpBinder> thiz = const_cast<BpBinder*>(this); + + Parcel data; + data.markForBinder(thiz); + Parcel reply; // do the IPC without a lock held. - status_t err = const_cast<BpBinder*>(this)->transact( - INTERFACE_TRANSACTION, send, &reply); + status_t err = thiz->transact(INTERFACE_TRANSACTION, data, &reply); if (err == NO_ERROR) { String16 res(reply.readString16()); Mutex::Autolock _l(mLock); diff --git a/libs/binder/IBatteryStats.cpp b/libs/binder/IBatteryStats.cpp index d0085dfa45..0de804c3c2 100644 --- a/libs/binder/IBatteryStats.cpp +++ b/libs/binder/IBatteryStats.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <binder/IBatteryStats.h> +#include <batterystats/IBatteryStats.h> #include <utils/Log.h> #include <binder/Parcel.h> diff --git a/libs/binder/IMediaResourceMonitor.cpp b/libs/binder/IMediaResourceMonitor.cpp deleted file mode 100644 index f5fa817b5e..0000000000 --- a/libs/binder/IMediaResourceMonitor.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <binder/IMediaResourceMonitor.h> -#include <binder/Parcel.h> -#include <utils/Errors.h> -#include <sys/types.h> - -namespace android { - -// ---------------------------------------------------------------------- - -class BpMediaResourceMonitor : public BpInterface<IMediaResourceMonitor> { -public: - explicit BpMediaResourceMonitor(const sp<IBinder>& impl) - : BpInterface<IMediaResourceMonitor>(impl) {} - - virtual void notifyResourceGranted(/*in*/ int32_t pid, /*in*/ const int32_t type) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaResourceMonitor::getInterfaceDescriptor()); - data.writeInt32(pid); - data.writeInt32(type); - remote()->transact(NOTIFY_RESOURCE_GRANTED, data, &reply, IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(MediaResourceMonitor, "android.media.IMediaResourceMonitor") - -// ---------------------------------------------------------------------- - -// NOLINTNEXTLINE(google-default-arguments) -status_t BnMediaResourceMonitor::onTransact( uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags) { - switch(code) { - case NOTIFY_RESOURCE_GRANTED: { - CHECK_INTERFACE(IMediaResourceMonitor, data, reply); - int32_t pid = data.readInt32(); - const int32_t type = data.readInt32(); - notifyResourceGranted(/*in*/ pid, /*in*/ type); - return NO_ERROR; - } break; - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - -// ---------------------------------------------------------------------- - -} // namespace android diff --git a/libs/binder/IProcessInfoService.cpp b/libs/binder/IProcessInfoService.cpp index 570edb9eb7..d26754e96c 100644 --- a/libs/binder/IProcessInfoService.cpp +++ b/libs/binder/IProcessInfoService.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <binder/IProcessInfoService.h> +#include <processinfo/IProcessInfoService.h> #include <binder/Parcel.h> #include <utils/Errors.h> #include <sys/types.h> diff --git a/libs/binder/IpPrefix.cpp b/libs/binder/IpPrefix.cpp deleted file mode 100644 index 4edc493f11..0000000000 --- a/libs/binder/IpPrefix.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "IpPrefix" - -#include <binder/IpPrefix.h> -#include <vector> - -#include <binder/IBinder.h> -#include <binder/Parcel.h> -#include <log/log.h> -#include <utils/Errors.h> - -using android::BAD_VALUE; -using android::NO_ERROR; -using android::Parcel; -using android::status_t; - -namespace android { - -namespace net { - -#define RETURN_IF_FAILED(calledOnce) \ - { \ - status_t returnStatus = calledOnce; \ - if (returnStatus) { \ - ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \ - return returnStatus; \ - } \ - } - -status_t IpPrefix::writeToParcel(Parcel* parcel) const { - /* - * Keep implementation in sync with writeToParcel() in - * frameworks/base/core/java/android/net/IpPrefix.java. - */ - std::vector<uint8_t> byte_vector; - - if (mIsIpv6) { - const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mIn6Addr); - byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr)); - } else { - const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&mUnion.mInAddr); - byte_vector.insert(byte_vector.end(), bytes, bytes+sizeof(mUnion.mIn6Addr)); - } - - RETURN_IF_FAILED(parcel->writeByteVector(byte_vector)); - RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(mPrefixLength))); - - return NO_ERROR; -} - -status_t IpPrefix::readFromParcel(const Parcel* parcel) { - /* - * Keep implementation in sync with readFromParcel() in - * frameworks/base/core/java/android/net/IpPrefix.java. - */ - std::vector<uint8_t> byte_vector; - - RETURN_IF_FAILED(parcel->readByteVector(&byte_vector)); - RETURN_IF_FAILED(parcel->readInt32(&mPrefixLength)); - - if (byte_vector.size() == 16) { - mIsIpv6 = true; - memcpy((void*)&mUnion.mIn6Addr, &byte_vector[0], sizeof(mUnion.mIn6Addr)); - - } else if (byte_vector.size() == 4) { - mIsIpv6 = false; - memcpy((void*)&mUnion.mInAddr, &byte_vector[0], sizeof(mUnion.mInAddr)); - - } else { - ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \ - return BAD_VALUE; - } - - return NO_ERROR; -} - -const struct in6_addr& IpPrefix::getAddressAsIn6Addr() const -{ - return mUnion.mIn6Addr; -} - -const struct in_addr& IpPrefix::getAddressAsInAddr() const -{ - return mUnion.mInAddr; -} - -bool IpPrefix::getAddressAsIn6Addr(struct in6_addr* addr) const -{ - if (isIpv6()) { - *addr = mUnion.mIn6Addr; - return true; - } - return false; -} - -bool IpPrefix::getAddressAsInAddr(struct in_addr* addr) const -{ - if (isIpv4()) { - *addr = mUnion.mInAddr; - return true; - } - return false; -} - -bool IpPrefix::isIpv6() const -{ - return mIsIpv6; -} - -bool IpPrefix::isIpv4() const -{ - return !mIsIpv6; -} - -int32_t IpPrefix::getPrefixLength() const -{ - return mPrefixLength; -} - -void IpPrefix::setAddress(const struct in6_addr& addr) -{ - mUnion.mIn6Addr = addr; - mIsIpv6 = true; -} - -void IpPrefix::setAddress(const struct in_addr& addr) -{ - mUnion.mInAddr = addr; - mIsIpv6 = false; -} - -void IpPrefix::setPrefixLength(int32_t prefix) -{ - mPrefixLength = prefix; -} - -bool operator==(const IpPrefix& lhs, const IpPrefix& rhs) -{ - if (lhs.mIsIpv6 != rhs.mIsIpv6) { - return false; - } - - if (lhs.mPrefixLength != rhs.mPrefixLength) { - return false; - } - - if (lhs.mIsIpv6) { - return 0 == memcmp(lhs.mUnion.mIn6Addr.s6_addr, rhs.mUnion.mIn6Addr.s6_addr, sizeof(struct in6_addr)); - } - - return 0 == memcmp(&lhs.mUnion.mInAddr, &rhs.mUnion.mInAddr, sizeof(struct in_addr)); -} - -} // namespace net - -} // namespace android diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 34a474b252..b1dddd14ec 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -418,6 +418,11 @@ status_t Parcel::setData(const uint8_t* buffer, size_t len) status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len) { + if (parcel->isForRpc() != isForRpc()) { + ALOGE("Cannot append Parcel of one format to another."); + return BAD_TYPE; + } + status_t err; const uint8_t *data = parcel->mData; const binder_size_t *objects = parcel->mObjects; @@ -555,12 +560,17 @@ void Parcel::markSensitive() const } void Parcel::markForBinder(const sp<IBinder>& binder) { + LOG_ALWAYS_FATAL_IF(mData != nullptr, "format must be set before data is written"); + if (binder && binder->remoteBinder() && binder->remoteBinder()->isRpcBinder()) { markForRpc(binder->remoteBinder()->getPrivateAccessorForId().rpcConnection()); } } void Parcel::markForRpc(const sp<RpcConnection>& connection) { + LOG_ALWAYS_FATAL_IF(mData != nullptr && mOwner == nullptr, + "format must be set before data is written OR on IPC data"); + LOG_ALWAYS_FATAL_IF(connection == nullptr, "markForRpc requires connection"); mConnection = connection; } @@ -2100,6 +2110,9 @@ size_t Parcel::ipcObjectsCount() const void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, const binder_size_t* objects, size_t objectsCount, release_func relFunc) { + // this code uses 'mOwner == nullptr' to understand whether it owns memory + LOG_ALWAYS_FATAL_IF(relFunc == nullptr, "must provide cleanup function"); + freeData(); mData = const_cast<uint8_t*>(data); diff --git a/libs/binder/ProcessInfoService.cpp b/libs/binder/ProcessInfoService.cpp index f75141e5da..0fb954a450 100644 --- a/libs/binder/ProcessInfoService.cpp +++ b/libs/binder/ProcessInfoService.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <binder/ProcessInfoService.h> +#include <processinfo/ProcessInfoService.h> #include <binder/IServiceManager.h> #include <utils/Log.h> diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index 64e842e927..755ff35781 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -192,7 +192,7 @@ bool RpcState::rpcSend(const base::unique_fd& fd, const char* what, const void* return false; } - ssize_t sent = TEMP_FAILURE_RETRY(send(fd.get(), data, size, 0)); + ssize_t sent = TEMP_FAILURE_RETRY(send(fd.get(), data, size, MSG_NOSIGNAL)); if (sent < 0 || sent != static_cast<ssize_t>(size)) { ALOGE("Failed to send %s (sent %zd of %zu bytes) on fd %d, error: %s", what, sent, size, @@ -212,7 +212,7 @@ bool RpcState::rpcRec(const base::unique_fd& fd, const char* what, void* data, s return false; } - ssize_t recd = TEMP_FAILURE_RETRY(recv(fd.get(), data, size, MSG_WAITALL)); + ssize_t recd = TEMP_FAILURE_RETRY(recv(fd.get(), data, size, MSG_WAITALL | MSG_NOSIGNAL)); if (recd < 0 || recd != static_cast<ssize_t>(size)) { terminate(); @@ -312,8 +312,8 @@ status_t RpcState::transact(const base::unique_fd& fd, const RpcAddress& address return waitForReply(fd, connection, reply); } -static void cleanup_data(Parcel* p, const uint8_t* data, size_t dataSize, - const binder_size_t* objects, size_t objectsCount) { +static void cleanup_reply_data(Parcel* p, const uint8_t* data, size_t dataSize, + const binder_size_t* objects, size_t objectsCount) { (void)p; delete[] const_cast<uint8_t*>(data - offsetof(RpcWireReply, data)); (void)dataSize; @@ -351,7 +351,7 @@ status_t RpcState::waitForReply(const base::unique_fd& fd, const sp<RpcConnectio if (rpcReply->status != OK) return rpcReply->status; reply->ipcSetDataReference(rpcReply->data, command.bodySize - offsetof(RpcWireReply, data), - nullptr, 0, cleanup_data); + nullptr, 0, cleanup_reply_data); reply->markForRpc(connection); @@ -427,6 +427,15 @@ status_t RpcState::processTransact(const base::unique_fd& fd, const sp<RpcConnec return processTransactInternal(fd, connection, std::move(transactionData)); } +static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t dataSize, + const binder_size_t* objects, size_t objectsCount) { + (void)p; + (void)data; + (void)dataSize; + (void)objects; + (void)objectsCount; +} + status_t RpcState::processTransactInternal(const base::unique_fd& fd, const sp<RpcConnection>& connection, std::vector<uint8_t>&& transactionData) { @@ -490,7 +499,12 @@ status_t RpcState::processTransactInternal(const base::unique_fd& fd, } Parcel data; - data.setData(transaction->data, transactionData.size() - offsetof(RpcWireTransaction, data)); + // transaction->data is owned by this function. Parcel borrows this data and + // only holds onto it for the duration of this function call. Parcel will be + // deleted before the 'transactionData' object. + data.ipcSetDataReference(transaction->data, + transactionData.size() - offsetof(RpcWireTransaction, data), + nullptr /*object*/, 0 /*objectCount*/, do_nothing_to_transact_data); data.markForRpc(connection); Parcel reply; diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp index 06830c027b..709cf67127 100644 --- a/libs/binder/Stability.cpp +++ b/libs/binder/Stability.cpp @@ -38,18 +38,30 @@ Stability::Category Stability::Category::currentFromLevel(Level level) { }; } -void Stability::forceDowngradeCompilationUnit(const sp<IBinder>& binder) { +void Stability::forceDowngradeToStability(const sp<IBinder>& binder, Level level) { // Downgrading a remote binder would require also copying the version from // the binder sent here. In practice though, we don't need to downgrade the // stability of a remote binder, since this would as an effect only restrict // what we can do to it. LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder"); - auto stability = Category::currentFromLevel(getLocalLevel()); + auto stability = Category::currentFromLevel(level); status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } +void Stability::forceDowngradeToLocalStability(const sp<IBinder>& binder) { + forceDowngradeToStability(binder, getLocalLevel()); +} + +void Stability::forceDowngradeToSystemStability(const sp<IBinder>& binder) { + forceDowngradeToStability(binder, Level::SYSTEM); +} + +void Stability::forceDowngradeToVendorStability(const sp<IBinder>& binder) { + forceDowngradeToStability(binder, Level::VENDOR); +} + std::string Stability::Category::debugString() { return levelString(level) + " wire protocol version " + std::to_string(version); diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h index f4a21ddd86..ea917539b7 100644 --- a/libs/binder/include/binder/IInterface.h +++ b/libs/binder/include/binder/IInterface.h @@ -186,7 +186,7 @@ template<typename INTERFACE> inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface( const String16& _descriptor) { - if (_descriptor == INTERFACE::descriptor) return this; + if (_descriptor == INTERFACE::descriptor) return sp<IInterface>::fromExisting(this); return nullptr; } diff --git a/libs/binder/include/binder/IMediaResourceMonitor.h b/libs/binder/include/binder/IMediaResourceMonitor.h deleted file mode 100644 index f92d557932..0000000000 --- a/libs/binder/include/binder/IMediaResourceMonitor.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#ifndef __ANDROID_VNDK__ - -#include <binder/IInterface.h> - -namespace android { - -// ---------------------------------------------------------------------- - -class IMediaResourceMonitor : public IInterface { -public: - DECLARE_META_INTERFACE(MediaResourceMonitor) - - // Values should be in sync with Intent.EXTRA_MEDIA_RESOURCE_TYPE_XXX. - enum { - TYPE_VIDEO_CODEC = 0, - TYPE_AUDIO_CODEC = 1, - }; - - virtual void notifyResourceGranted(/*in*/ int32_t pid, /*in*/ const int32_t type) = 0; - - enum { - NOTIFY_RESOURCE_GRANTED = IBinder::FIRST_CALL_TRANSACTION, - }; -}; - -// ---------------------------------------------------------------------- - -class BnMediaResourceMonitor : public BnInterface<IMediaResourceMonitor> { -public: - // NOLINTNEXTLINE(google-default-arguments) - virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags = 0); -}; - -// ---------------------------------------------------------------------- - -} // namespace android - -#else // __ANDROID_VNDK__ -#error "This header is not visible to vendors" -#endif // __ANDROID_VNDK__ diff --git a/libs/binder/include/binder/IpPrefix.h b/libs/binder/include/binder/IpPrefix.h deleted file mode 100644 index a8faa3fded..0000000000 --- a/libs/binder/include/binder/IpPrefix.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#ifndef __ANDROID_VNDK__ - -#include <netinet/in.h> - -#include <binder/Parcelable.h> -#include <utils/String16.h> -#include <utils/StrongPointer.h> - -namespace android { - -namespace net { - -/* - * C++ implementation of the Java class android.net.IpPrefix - */ -class IpPrefix : public Parcelable { -public: - IpPrefix() = default; - virtual ~IpPrefix() = default; - IpPrefix(const IpPrefix& prefix) = default; - - IpPrefix(const struct in6_addr& addr, int32_t plen): - mUnion(addr), mPrefixLength(plen), mIsIpv6(true) { } - - IpPrefix(const struct in_addr& addr, int32_t plen): - mUnion(addr), mPrefixLength(plen), mIsIpv6(false) { } - - bool getAddressAsIn6Addr(struct in6_addr* addr) const; - bool getAddressAsInAddr(struct in_addr* addr) const; - - const struct in6_addr& getAddressAsIn6Addr() const; - const struct in_addr& getAddressAsInAddr() const; - - bool isIpv6() const; - bool isIpv4() const; - - int32_t getPrefixLength() const; - - void setAddress(const struct in6_addr& addr); - void setAddress(const struct in_addr& addr); - - void setPrefixLength(int32_t prefix); - - friend bool operator==(const IpPrefix& lhs, const IpPrefix& rhs); - - friend bool operator!=(const IpPrefix& lhs, const IpPrefix& rhs) { - return !(lhs == rhs); - } - -public: - // Overrides - status_t writeToParcel(Parcel* parcel) const override; - status_t readFromParcel(const Parcel* parcel) override; - -private: - union InternalUnion { - InternalUnion() = default; - explicit InternalUnion(const struct in6_addr &addr):mIn6Addr(addr) { } - explicit InternalUnion(const struct in_addr &addr):mInAddr(addr) { } - struct in6_addr mIn6Addr; - struct in_addr mInAddr; - } mUnion; - int32_t mPrefixLength; - bool mIsIpv6; -}; - -} // namespace net - -} // namespace android - -#else // __ANDROID_VNDK__ -#error "This header is not visible to vendors" -#endif // __ANDROID_VNDK__ diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 957837233b..211790d14c 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -101,10 +101,6 @@ public: // is for an RPC transaction). void markForBinder(const sp<IBinder>& binder); - // Whenever possible, markForBinder should be preferred. This method is - // called automatically on reply Parcels for RPC transactions. - void markForRpc(const sp<RpcConnection>& connection); - // Whether this Parcel is written for RPC transactions (after calls to // markForBinder or markForRpc). bool isForRpc() const; @@ -540,6 +536,10 @@ private: const binder_size_t* objects, size_t objectsCount, release_func relFunc); + // Whenever possible, markForBinder should be preferred. This method is + // called automatically on reply Parcels for RPC transactions. + void markForRpc(const sp<RpcConnection>& connection); + status_t finishWrite(size_t len); void releaseObjects(); void acquireObjects(); diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h index 2405ab6b9e..ca29440e7c 100644 --- a/libs/binder/include/binder/ProcessState.h +++ b/libs/binder/include/binder/ProcessState.h @@ -124,7 +124,6 @@ private: Vector<handle_entry>mHandleToObject; - String8 mRootDir; bool mThreadPoolStarted; volatile int32_t mThreadPoolSeq; diff --git a/libs/binder/include/binder/RpcConnection.h b/libs/binder/include/binder/RpcConnection.h index a300575454..efa922dbda 100644 --- a/libs/binder/include/binder/RpcConnection.h +++ b/libs/binder/include/binder/RpcConnection.h @@ -106,6 +106,7 @@ public: }; private: + friend sp<RpcConnection>; RpcConnection(); bool addServer(const SocketAddress& address); diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h index a09e587f04..f4bfac890a 100644 --- a/libs/binder/include/binder/Stability.h +++ b/libs/binder/include/binder/Stability.h @@ -54,12 +54,37 @@ public: // Given a binder interface at a certain stability, there may be some // requirements associated with that higher stability level. For instance, a // VINTF stability binder is required to be in the VINTF manifest. This API - // can be called to use that same interface within a partition. - static void forceDowngradeCompilationUnit(const sp<IBinder>& binder); + // can be called to use that same interface within the local partition. + static void forceDowngradeToLocalStability(const sp<IBinder>& binder); // WARNING: Below APIs are only ever expected to be called by auto-generated code. // Instead of calling them, you should set the stability of a .aidl interface + // WARNING: The only client of + // - forceDowngradeToSystemStability() and; + // - korceDowngradeToVendorStability() + // should be AIBinder_forceDowngradeToLocalStability(). + // + // getLocalLevel() in libbinder returns Level::SYSTEM when called + // from libbinder_ndk (even on vendor partition). So we explicitly provide + // these methods for use by the NDK API: + // AIBinder_forceDowngradeToLocalStability(). + // + // This allows correctly downgrading the binder's stability to either system/vendor, + // depending on the partition. + + // Given a binder interface at a certain stability, there may be some + // requirements associated with that higher stability level. For instance, a + // VINTF stability binder is required to be in the VINTF manifest. This API + // can be called to use that same interface within the vendor partition. + static void forceDowngradeToVendorStability(const sp<IBinder>& binder); + + // Given a binder interface at a certain stability, there may be some + // requirements associated with that higher stability level. For instance, a + // VINTF stability binder is required to be in the VINTF manifest. This API + // can be called to use that same interface within the system partition. + static void forceDowngradeToSystemStability(const sp<IBinder>& binder); + // WARNING: This is only ever expected to be called by auto-generated code. You likely want to // change or modify the stability class of the interface you are using. // This must be called as soon as the binder in question is constructed. No thread safety @@ -146,6 +171,9 @@ private: // returns the stability according to how this was built static Level getLocalLevel(); + // Downgrades binder stability to the specified level. + static void forceDowngradeToStability(const sp<IBinder>& binder, Level level); + enum { REPR_NONE = 0, REPR_LOG = 1, diff --git a/libs/binder/include/binder/ActivityManager.h b/libs/binder/include_activitymanager/binder/ActivityManager.h index b90dc862ce..b90dc862ce 100644 --- a/libs/binder/include/binder/ActivityManager.h +++ b/libs/binder/include_activitymanager/binder/ActivityManager.h diff --git a/libs/binder/include/binder/IActivityManager.h b/libs/binder/include_activitymanager/binder/IActivityManager.h index fde56a01a4..e3b5e43760 100644 --- a/libs/binder/include/binder/IActivityManager.h +++ b/libs/binder/include_activitymanager/binder/IActivityManager.h @@ -18,8 +18,8 @@ #ifndef __ANDROID_VNDK__ -#include <binder/IInterface.h> #include <binder/IUidObserver.h> +#include <binder/IInterface.h> namespace android { diff --git a/libs/binder/include/binder/IUidObserver.h b/libs/binder/include_activitymanager/binder/IUidObserver.h index 9291c0b45f..9291c0b45f 100644 --- a/libs/binder/include/binder/IUidObserver.h +++ b/libs/binder/include_activitymanager/binder/IUidObserver.h diff --git a/libs/binder/include/binder/IBatteryStats.h b/libs/binder/include_batterystats/batterystats/IBatteryStats.h index 6defc7fb0b..6defc7fb0b 100644 --- a/libs/binder/include/binder/IBatteryStats.h +++ b/libs/binder/include_batterystats/batterystats/IBatteryStats.h diff --git a/libs/binder/include/binder/IProcessInfoService.h b/libs/binder/include_processinfo/processinfo/IProcessInfoService.h index 622f23162f..622f23162f 100644 --- a/libs/binder/include/binder/IProcessInfoService.h +++ b/libs/binder/include_processinfo/processinfo/IProcessInfoService.h diff --git a/libs/binder/include/binder/ProcessInfoService.h b/libs/binder/include_processinfo/processinfo/ProcessInfoService.h index 6b3b5ce4df..978856dc6a 100644 --- a/libs/binder/include/binder/ProcessInfoService.h +++ b/libs/binder/include_processinfo/processinfo/ProcessInfoService.h @@ -18,7 +18,7 @@ #ifndef __ANDROID_VNDK__ -#include <binder/IProcessInfoService.h> +#include <processinfo/IProcessInfoService.h> #include <utils/Errors.h> #include <utils/Singleton.h> #include <sys/types.h> diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index 0f59de4309..883403ac59 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -363,7 +363,8 @@ const char* AIBinder_Class_getDescriptor(const AIBinder_Class* clazz) { } void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) { - CHECK(who == mWho); + CHECK(who == mWho) << who.unsafe_get() << "(" << who.get_refs() << ") vs " << mWho.unsafe_get() + << " (" << mWho.get_refs() << ")"; mOnDied(mCookie); @@ -598,6 +599,8 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) { } *in = new AParcel(binder); + (*in)->get()->markForBinder(binder->getBinder()); + status_t status = (*in)->get()->writeInterfaceToken(clazz->getInterfaceDescriptor()); binder_status_t ret = PruneStatusT(status); diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h index 8941e4996c..b9adc9a025 100644 --- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h +++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h @@ -36,6 +36,9 @@ __BEGIN_DECLS +/** + * Flags for AIBinder_transact. + */ typedef uint32_t binder_flags_t; enum { /** @@ -47,7 +50,10 @@ enum { FLAG_ONEWAY = 0x01, }; -// Also see IBinder.h in libbinder +/** + * Codes for AIBinder_transact. This defines the range of codes available for + * usage. Other codes are used or reserved by the Android system. + */ typedef uint32_t transaction_code_t; enum { /** @@ -202,7 +208,8 @@ typedef binder_status_t (*AIBinder_onDump)(AIBinder* binder, int fd, const char* * * Available since API level 29. * - * \param dump function to call when an instance of this binder class is being dumped. + * \param clazz class which should use this dump function + * \param onDump function to call when an instance of this binder class is being dumped. */ void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) __INTRODUCED_IN(29); diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h index b4dc08a49b..6f1fdfcd20 100644 --- a/libs/binder/ndk/include_ndk/android/binder_status.h +++ b/libs/binder/ndk/include_ndk/android/binder_status.h @@ -189,7 +189,7 @@ __attribute__((warn_unused_result)) AStatus* AStatus_fromServiceSpecificErrorWit * * Available since API level 29. * - * \param a low-level error to associate with this status object. + * \param status a low-level error to associate with this status object. * * \return a newly constructed status object that the caller owns. */ diff --git a/libs/binder/ndk/include_platform/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h index ce7255e174..f113ba8f21 100644 --- a/libs/binder/ndk/include_platform/android/binder_stability.h +++ b/libs/binder/ndk/include_platform/android/binder_stability.h @@ -45,6 +45,18 @@ static inline void AIBinder_markCompilationUnitStability(AIBinder* binder) { AIBinder_markVendorStability(binder); } +/** + * Given a binder interface at a certain stability, there may be some + * requirements associated with that higher stability level. For instance, a + * VINTF stability binder is required to be in the VINTF manifest. This API + * can be called to use that same interface within the vendor partition. + */ +void AIBinder_forceDowngradeToVendorStability(AIBinder* binder); + +static inline void AIBinder_forceDowngradeToLocalStability(AIBinder* binder) { + AIBinder_forceDowngradeToVendorStability(binder); +} + #else // defined(__ANDROID_VENDOR__) enum { @@ -62,9 +74,27 @@ static inline void AIBinder_markCompilationUnitStability(AIBinder* binder) { AIBinder_markSystemStability(binder); } +/** + * Given a binder interface at a certain stability, there may be some + * requirements associated with that higher stability level. For instance, a + * VINTF stability binder is required to be in the VINTF manifest. This API + * can be called to use that same interface within the system partition. + */ +void AIBinder_forceDowngradeToSystemStability(AIBinder* binder); + +static inline void AIBinder_forceDowngradeToLocalStability(AIBinder* binder) { + AIBinder_forceDowngradeToSystemStability(binder); +} + #endif // defined(__ANDROID_VENDOR__) /** + * WARNING: this is not expected to be used manually. When the build system has + * versioned checks in place for an interface that prevent it being changed year + * over year (specifically like those for @VintfStability stable AIDL + * interfaces), this could be called. Calling this without this or equivalent + * infrastructure will lead to de facto frozen APIs or GSI test failures. + * * This interface has system<->vendor stability */ void AIBinder_markVintfStability(AIBinder* binder); diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt index f1db653e07..67c85b66d4 100644 --- a/libs/binder/ndk/libbinder_ndk.map.txt +++ b/libs/binder/ndk/libbinder_ndk.map.txt @@ -127,6 +127,9 @@ LIBBINDER_NDK31 { # introduced=31 AServiceManager_tryUnregister; # llndk AServiceManager_reRegister; # llndk + AIBinder_forceDowngradeToSystemStability; # apex + AIBinder_forceDowngradeToVendorStability; # llndk + AIBinder_Class_getDescriptor; AIBinder_Weak_clone; AIBinder_Weak_lt; diff --git a/libs/binder/ndk/parcel_internal.h b/libs/binder/ndk/parcel_internal.h index 6b7295e4b9..b4f6358841 100644 --- a/libs/binder/ndk/parcel_internal.h +++ b/libs/binder/ndk/parcel_internal.h @@ -27,9 +27,8 @@ struct AParcel { const ::android::Parcel* get() const { return mParcel; } ::android::Parcel* get() { return mParcel; } - explicit AParcel(const AIBinder* binder) - : AParcel(binder, new ::android::Parcel, true /*owns*/) {} - AParcel(const AIBinder* binder, ::android::Parcel* parcel, bool owns) + explicit AParcel(AIBinder* binder) : AParcel(binder, new ::android::Parcel, true /*owns*/) {} + AParcel(AIBinder* binder, ::android::Parcel* parcel, bool owns) : mBinder(binder), mParcel(parcel), mOwns(owns) {} ~AParcel() { @@ -38,7 +37,7 @@ struct AParcel { } } - static const AParcel readOnly(const AIBinder* binder, const ::android::Parcel* parcel) { + static const AParcel readOnly(AIBinder* binder, const ::android::Parcel* parcel) { return AParcel(binder, const_cast<::android::Parcel*>(parcel), false); } diff --git a/libs/binder/ndk/stability.cpp b/libs/binder/ndk/stability.cpp index a5b3ecea4a..7eafb9c025 100644 --- a/libs/binder/ndk/stability.cpp +++ b/libs/binder/ndk/stability.cpp @@ -31,7 +31,7 @@ using ::android::internal::Stability; #error libbinder_ndk should only be built in a system context #endif -// explicit extern because symbol is only declared in header when __ANDROID_VNDK__ +// explicit extern because symbol is only declared in header when __ANDROID_VENDOR__ extern "C" void AIBinder_markVendorStability(AIBinder* binder) { Stability::markVndk(binder->getBinder().get()); } @@ -43,3 +43,12 @@ void AIBinder_markSystemStability(AIBinder* binder) { void AIBinder_markVintfStability(AIBinder* binder) { Stability::markVintf(binder->getBinder().get()); } + +// explicit extern because symbol is only declared in header when __ANDROID_VENDOR__ +extern "C" void AIBinder_forceDowngradeToVendorStability(AIBinder* binder) { + Stability::forceDowngradeToVendorStability(binder->getBinder()); +} + +void AIBinder_forceDowngradeToSystemStability(AIBinder* binder) { + Stability::forceDowngradeToSystemStability(binder->getBinder()); +} diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp index 2a3658e2f5..afc4b1b72c 100644 --- a/libs/binder/tests/Android.bp +++ b/libs/binder/tests/Android.bp @@ -104,25 +104,51 @@ cc_test { require_root: true, } +aidl_interface { + name: "binderRpcTestIface", + host_supported: true, + unstable: true, + srcs: [ + "IBinderRpcSession.aidl", + "IBinderRpcTest.aidl", + ], + backend: { + java: { + enabled: false, + }, + }, +} + cc_test { name: "binderRpcTest", - defaults: ["binder_test_defaults"], + host_supported: true, + target: { + darwin: { + enabled: false, + }, + }, + defaults: [ + "binder_test_defaults", + "libbinder_ndk_host_user", + ], srcs: [ - "IBinderRpcSession.aidl", - "IBinderRpcTest.aidl", "binderRpcTest.cpp", ], shared_libs: [ "libbinder", + "libbinder_ndk", "libbase", "libutils", "libcutils", "liblog", ], + static_libs: [ + "binderRpcTestIface-cpp", + "binderRpcTestIface-ndk_platform", + ], test_suites: ["general-tests"], require_root: true, - host_supported: true, } cc_test { @@ -211,6 +237,11 @@ aidl_interface { srcs: [ "IBinderStabilityTest.aidl", ], + backend: { + java: { + enabled: false, + }, + }, } cc_test { diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp index 936ee5e91a..a51c98774e 100644 --- a/libs/binder/tests/binderRpcTest.cpp +++ b/libs/binder/tests/binderRpcTest.cpp @@ -16,7 +16,10 @@ #include <BnBinderRpcSession.h> #include <BnBinderRpcTest.h> +#include <aidl/IBinderRpcTest.h> #include <android-base/logging.h> +#include <android/binder_auto_utils.h> +#include <android/binder_libbinder.h> #include <binder/Binder.h> #include <binder/BpBinder.h> #include <binder/IServiceManager.h> @@ -41,6 +44,13 @@ namespace android { +TEST(BinderRpcParcel, EntireParcelFormatted) { + Parcel p; + p.writeInt32(3); + + EXPECT_DEATH(p.markForBinder(sp<BBinder>::make()), ""); +} + using android::binder::Status; #define EXPECT_OK(status) \ @@ -383,6 +393,12 @@ TEST_P(BinderRpc, Ping) { EXPECT_EQ(OK, proc.rootBinder->pingBinder()); } +TEST_P(BinderRpc, GetInterfaceDescriptor) { + auto proc = createRpcTestSocketServerProcess(1); + ASSERT_NE(proc.rootBinder, nullptr); + EXPECT_EQ(IBinderRpcTest::descriptor, proc.rootBinder->getInterfaceDescriptor()); +} + TEST_P(BinderRpc, TransactionsMustBeMarkedRpc) { auto proc = createRpcTestSocketServerProcess(1); Parcel data; @@ -390,6 +406,19 @@ TEST_P(BinderRpc, TransactionsMustBeMarkedRpc) { EXPECT_EQ(BAD_TYPE, proc.rootBinder->transact(IBinder::PING_TRANSACTION, data, &reply, 0)); } +TEST_P(BinderRpc, AppendSeparateFormats) { + auto proc = createRpcTestSocketServerProcess(1); + + Parcel p1; + p1.markForBinder(proc.rootBinder); + p1.writeInt32(3); + + Parcel p2; + + EXPECT_EQ(BAD_TYPE, p1.appendFrom(&p2, 0, p2.dataSize())); + EXPECT_EQ(BAD_TYPE, p2.appendFrom(&p1, 0, p1.dataSize())); +} + TEST_P(BinderRpc, UnknownTransaction) { auto proc = createRpcTestSocketServerProcess(1); Parcel data; @@ -765,9 +794,6 @@ TEST_P(BinderRpc, OnewayCallQueueing) { } TEST_P(BinderRpc, Die) { - // TODO(b/183141167): handle this in library - signal(SIGPIPE, SIG_IGN); - for (bool doDeathCleanup : {true, false}) { auto proc = createRpcTestSocketServerProcess(1); @@ -786,6 +812,30 @@ TEST_P(BinderRpc, Die) { } } +TEST_P(BinderRpc, WorksWithLibbinderNdkPing) { + auto proc = createRpcTestSocketServerProcess(1); + + ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(proc.rootBinder)); + ASSERT_NE(binder, nullptr); + + ASSERT_EQ(STATUS_OK, AIBinder_ping(binder.get())); +} + +TEST_P(BinderRpc, WorksWithLibbinderNdkUserTransaction) { + auto proc = createRpcTestSocketServerProcess(1); + + ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(proc.rootBinder)); + ASSERT_NE(binder, nullptr); + + auto ndkBinder = aidl::IBinderRpcTest::fromBinder(binder); + ASSERT_NE(ndkBinder, nullptr); + + std::string out; + ndk::ScopedAStatus status = ndkBinder->doubleString("aoeu", &out); + ASSERT_TRUE(status.isOk()) << status.getDescription(); + ASSERT_EQ("aoeuaoeu", out); +} + ssize_t countFds() { DIR* dir = opendir("/proc/self/fd/"); if (dir == nullptr) return -1; diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp index 42705401da..cb309bdd81 100644 --- a/libs/binder/tests/binderStabilityTest.cpp +++ b/libs/binder/tests/binderStabilityTest.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <android/binder_libbinder.h> #include <android/binder_manager.h> #include <android/binder_stability.h> #include <binder/Binder.h> @@ -131,17 +132,55 @@ TEST(BinderStability, OnlyVintfStabilityBinderNeedsVintfDeclaration) { EXPECT_TRUE(Stability::requiresVintfDeclaration(BadStableBinder::vintf())); } -TEST(BinderStability, ForceDowngradeStability) { +TEST(BinderStability, ForceDowngradeToLocalStability) { sp<IBinder> someBinder = BadStableBinder::vintf(); EXPECT_TRUE(Stability::requiresVintfDeclaration(someBinder)); // silly to do this after already using the binder, but it's for the test - Stability::forceDowngradeCompilationUnit(someBinder); + Stability::forceDowngradeToLocalStability(someBinder); EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder)); } +TEST(BinderStability, NdkForceDowngradeToLocalStability) { + sp<IBinder> someBinder = BadStableBinder::vintf(); + + EXPECT_TRUE(Stability::requiresVintfDeclaration(someBinder)); + + // silly to do this after already using the binder, but it's for the test + AIBinder_forceDowngradeToLocalStability(AIBinder_fromPlatformBinder(someBinder)); + + EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder)); +} + +TEST(BinderStability, ForceDowngradeToVendorStability) { + sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer); + auto server = interface_cast<IBinderStabilityTest>(serverBinder); + + ASSERT_NE(nullptr, server.get()); + ASSERT_NE(nullptr, IInterface::asBinder(server)->remoteBinder()); + + { + sp<BadStableBinder> binder = BadStableBinder::vintf(); + + EXPECT_TRUE(Stability::requiresVintfDeclaration(binder)); + EXPECT_TRUE(server->sendAndCallBinder(binder).isOk()); + EXPECT_TRUE(binder->gotUserTransaction); + } + { + sp<BadStableBinder> binder = BadStableBinder::vintf(); + + // This method should never be called directly. This is done only for the test. + Stability::forceDowngradeToVendorStability(binder); + + // Binder downgraded to vendor stability, cannot be called from system context + EXPECT_FALSE(Stability::requiresVintfDeclaration(binder)); + EXPECT_EQ(BAD_TYPE, server->sendAndCallBinder(binder).exceptionCode()); + EXPECT_FALSE(binder->gotUserTransaction); + } +} + TEST(BinderStability, VintfStabilityServerMustBeDeclaredInManifest) { sp<IBinder> vintfServer = BadStableBinder::vintf(); diff --git a/services/memtrackproxy/Android.bp b/services/memtrackproxy/Android.bp new file mode 100644 index 0000000000..7d78f3b2cf --- /dev/null +++ b/services/memtrackproxy/Android.bp @@ -0,0 +1,50 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_native_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_native_license"], +} + +cc_library_shared { + name: "libmemtrackproxy", + shared_libs: [ + "libbase", + "libbinder_ndk", + "libbinder", + "libhidlbase", + "liblog", + "libcutils", + "libutils", + "android.hardware.memtrack@1.0", + "android.hardware.memtrack-V1-ndk_platform", + ], + srcs: [ + "MemtrackProxy.cpp", + ], + export_include_dirs: [ + "include", + ], + local_include_dirs: [ + "include/memtrackproxy", + ], + export_shared_lib_headers: [ + "android.hardware.memtrack@1.0", + "android.hardware.memtrack-V1-ndk_platform", + ], +} diff --git a/services/memtrackproxy/MemtrackProxy.cpp b/services/memtrackproxy/MemtrackProxy.cpp new file mode 100644 index 0000000000..467616724a --- /dev/null +++ b/services/memtrackproxy/MemtrackProxy.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MemtrackProxy.h" + +#include <android-base/logging.h> +#include <android/binder_manager.h> +#include <private/android_filesystem_config.h> + +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; + +namespace aidl { +namespace android { +namespace hardware { +namespace memtrack { + +// Check Memtrack Flags +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SMAPS_ACCOUNTED) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SMAPS_ACCOUNTED)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SMAPS_UNACCOUNTED) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SMAPS_UNACCOUNTED)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SHARED) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SHARED)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SHARED_PSS) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SHARED_PSS)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::PRIVATE) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_PRIVATE)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SYSTEM) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SYSTEM)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::DEDICATED) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_DEDICATED)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::NONSECURE) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_NONSECURE)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SECURE) == + static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SECURE)); + +// Check Memtrack Types +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::OTHER) == + static_cast<uint32_t>(V1_aidl::MemtrackType::OTHER)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::GL) == + static_cast<uint32_t>(V1_aidl::MemtrackType::GL)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::GRAPHICS) == + static_cast<uint32_t>(V1_aidl::MemtrackType::GRAPHICS)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::MULTIMEDIA) == + static_cast<uint32_t>(V1_aidl::MemtrackType::MULTIMEDIA)); +static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::CAMERA) == + static_cast<uint32_t>(V1_aidl::MemtrackType::CAMERA)); + +__attribute__((warn_unused_result)) bool translate(const V1_0_hidl::MemtrackRecord& in, + V1_aidl::MemtrackRecord* out) { + // Convert uint64_t to int64_t (long in AIDL). AIDL doesn't support unsigned types. + if (in.sizeInBytes > std::numeric_limits<int64_t>::max() || in.sizeInBytes < 0) { + return false; + } + out->sizeInBytes = static_cast<int64_t>(in.sizeInBytes); + + // It's ok to just assign directly, since this is a bitmap. + out->flags = in.flags; + return true; +} + +sp<V1_0_hidl::IMemtrack> MemtrackProxy::MemtrackHidlInstance() { + return V1_0_hidl::IMemtrack::getService(); +} + +std::shared_ptr<V1_aidl::IMemtrack> MemtrackProxy::MemtrackAidlInstance() { + const auto instance = std::string() + V1_aidl::IMemtrack::descriptor + "/default"; + bool declared = AServiceManager_isDeclared(instance.c_str()); + if (!declared) { + return nullptr; + } + ndk::SpAIBinder memtrack_binder = + ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str())); + return V1_aidl::IMemtrack::fromBinder(memtrack_binder); +} + +bool MemtrackProxy::CheckUid(uid_t calling_uid) { + // Allow AID_SHELL for adb shell dumpsys meminfo + return calling_uid == AID_SYSTEM || calling_uid == AID_ROOT || calling_uid == AID_SHELL; +} + +bool MemtrackProxy::CheckPid(pid_t calling_pid, pid_t request_pid) { + return calling_pid == request_pid; +} + +MemtrackProxy::MemtrackProxy() + : memtrack_hidl_instance_(MemtrackProxy::MemtrackHidlInstance()), + memtrack_aidl_instance_(MemtrackProxy::MemtrackAidlInstance()) {} + +ndk::ScopedAStatus MemtrackProxy::getMemory(int pid, MemtrackType type, + std::vector<MemtrackRecord>* _aidl_return) { + if (pid < 0) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + if (!MemtrackProxy::CheckPid(AIBinder_getCallingPid(), pid) && + !MemtrackProxy::CheckUid(AIBinder_getCallingUid())) { + return ndk::ScopedAStatus::fromExceptionCodeWithMessage( + EX_SECURITY, + "Only AID_ROOT, AID_SYSTEM and AID_SHELL can request getMemory() for PIDs other " + "than the calling PID"); + } + + if (type != MemtrackType::OTHER && type != MemtrackType::GL && type != MemtrackType::GRAPHICS && + type != MemtrackType::MULTIMEDIA && type != MemtrackType::CAMERA) { + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + } + + _aidl_return->clear(); + + if (memtrack_aidl_instance_) { + return memtrack_aidl_instance_->getMemory(pid, type, _aidl_return); + } else if (memtrack_hidl_instance_) { + ndk::ScopedAStatus aidl_status; + + Return<void> ret = memtrack_hidl_instance_->getMemory( + pid, static_cast<V1_0_hidl::MemtrackType>(type), + [&_aidl_return, &aidl_status](V1_0_hidl::MemtrackStatus status, + hidl_vec<V1_0_hidl::MemtrackRecord> records) { + switch (status) { + case V1_0_hidl::MemtrackStatus::SUCCESS: + aidl_status = ndk::ScopedAStatus::ok(); + break; + case V1_0_hidl::MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED: + [[fallthrough]]; + case V1_0_hidl::MemtrackStatus::TYPE_NOT_SUPPORTED: + [[fallthrough]]; + default: + aidl_status = + ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + return; + } + + _aidl_return->resize(records.size()); + for (size_t i = 0; i < records.size(); i++) { + if (!translate(records[i], &(*_aidl_return)[i])) { + aidl_status = ndk::ScopedAStatus::fromExceptionCodeWithMessage( + EX_SERVICE_SPECIFIC, + "Failed to convert HIDL MemtrackRecord to AIDL"); + return; + } + } + }); + + // Check HIDL return + if (!ret.isOk()) { + const char* err_msg = "HIDL Memtrack::getMemory() failed"; + aidl_status = + ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC, err_msg); + LOG(ERROR) << err_msg << ": " << ret.description(); + } + + return aidl_status; + } + + return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER, + "Memtrack HAL service not available"); +} + +ndk::ScopedAStatus MemtrackProxy::getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) { + if (!MemtrackProxy::CheckUid(AIBinder_getCallingUid())) { + return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SECURITY, + "Only AID_ROOT, AID_SYSTEM and AID_SHELL can request getGpuDeviceInfo()"); + } + + _aidl_return->clear(); + + if (memtrack_aidl_instance_ || + (memtrack_aidl_instance_ = MemtrackProxy::MemtrackAidlInstance())) { + return memtrack_aidl_instance_->getGpuDeviceInfo(_aidl_return); + } + + return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER, + "Memtrack HAL service not available"); +} + +} // namespace memtrack +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/services/memtrackproxy/include/memtrackproxy/MemtrackProxy.h b/services/memtrackproxy/include/memtrackproxy/MemtrackProxy.h new file mode 100644 index 0000000000..5ac1fbf417 --- /dev/null +++ b/services/memtrackproxy/include/memtrackproxy/MemtrackProxy.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/memtrack/BnMemtrack.h> +#include <aidl/android/hardware/memtrack/DeviceInfo.h> +#include <aidl/android/hardware/memtrack/IMemtrack.h> +#include <aidl/android/hardware/memtrack/MemtrackRecord.h> +#include <aidl/android/hardware/memtrack/MemtrackType.h> +#include <android/hardware/memtrack/1.0/IMemtrack.h> + +using ::android::sp; + +namespace V1_0_hidl = ::android::hardware::memtrack::V1_0; +namespace V1_aidl = ::aidl::android::hardware::memtrack; + +namespace aidl { +namespace android { +namespace hardware { +namespace memtrack { + +__attribute__((warn_unused_result)) bool translate(const V1_0_hidl::MemtrackRecord& in, + V1_aidl::MemtrackRecord* out); + +class MemtrackProxy : public BnMemtrack { +public: + MemtrackProxy(); + ndk::ScopedAStatus getMemory(int pid, MemtrackType type, + std::vector<MemtrackRecord>* _aidl_return) override; + ndk::ScopedAStatus getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) override; + +private: + static sp<V1_0_hidl::IMemtrack> MemtrackHidlInstance(); + static std::shared_ptr<V1_aidl::IMemtrack> MemtrackAidlInstance(); + static bool CheckUid(uid_t calling_uid); + static bool CheckPid(pid_t calling_pid, pid_t request_pid); + + sp<V1_0_hidl::IMemtrack> memtrack_hidl_instance_; + std::shared_ptr<V1_aidl::IMemtrack> memtrack_aidl_instance_; +}; + +} // namespace memtrack +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/services/memtrackproxy/test/Android.bp b/services/memtrackproxy/test/Android.bp new file mode 100644 index 0000000000..f943761ee8 --- /dev/null +++ b/services/memtrackproxy/test/Android.bp @@ -0,0 +1,36 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_native_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_native_license"], +} + +cc_test { + name: "memtrackproxy_test", + srcs: [ + "MemtrackProxyTest.cpp", + ], + shared_libs: [ + "libbinder_ndk", + "libmemtrackproxy", + "android.hardware.memtrack-V1-ndk_platform", + ], + test_suites: ["general-tests"], + require_root: true, +} diff --git a/services/memtrackproxy/test/MemtrackProxyTest.cpp b/services/memtrackproxy/test/MemtrackProxyTest.cpp new file mode 100644 index 0000000000..16dfba025d --- /dev/null +++ b/services/memtrackproxy/test/MemtrackProxyTest.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <aidl/android/hardware/memtrack/DeviceInfo.h> +#include <aidl/android/hardware/memtrack/IMemtrack.h> +#include <aidl/android/hardware/memtrack/MemtrackRecord.h> +#include <aidl/android/hardware/memtrack/MemtrackType.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> +#include <gtest/gtest.h> +#include <unistd.h> + +using aidl::android::hardware::memtrack::DeviceInfo; +using aidl::android::hardware::memtrack::IMemtrack; +using aidl::android::hardware::memtrack::MemtrackRecord; +using aidl::android::hardware::memtrack::MemtrackType; + +class MemtrackProxyTest : public ::testing::Test { +public: + virtual void SetUp() override { + const char* kMemtrackProxyService = "memtrack.proxy"; + auto memtrackProxyBinder = + ndk::SpAIBinder(AServiceManager_waitForService(kMemtrackProxyService)); + memtrack_proxy_ = IMemtrack::fromBinder(memtrackProxyBinder); + ASSERT_NE(memtrack_proxy_, nullptr); + } + + std::shared_ptr<IMemtrack> memtrack_proxy_; +}; + +TEST_F(MemtrackProxyTest, GetMemoryForInvalidPid) { + int pid = -1; + + for (MemtrackType type : ndk::enum_range<MemtrackType>()) { + std::vector<MemtrackRecord> records; + + auto status = memtrack_proxy_->getMemory(pid, type, &records); + + EXPECT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT); + } +} + +TEST_F(MemtrackProxyTest, GetMemoryForCallingPid) { + int pid = getpid(); + + for (MemtrackType type : ndk::enum_range<MemtrackType>()) { + std::vector<MemtrackRecord> records; + + auto status = memtrack_proxy_->getMemory(pid, type, &records); + + EXPECT_TRUE(status.isOk()); + } +} + +TEST_F(MemtrackProxyTest, GetMemoryForOtherPid) { + int pid = 1; + + for (MemtrackType type : ndk::enum_range<MemtrackType>()) { + std::vector<MemtrackRecord> records; + + auto status = memtrack_proxy_->getMemory(pid, type, &records); + + // Test is run as root + EXPECT_TRUE(status.isOk()); + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp index ca9ff7c8c3..9aecaff409 100644 --- a/services/sensorservice/Android.bp +++ b/services/sensorservice/Android.bp @@ -7,9 +7,6 @@ package { default_applicable_licenses: ["frameworks_native_license"], } -subdirs = [ - "hidl" -] cc_library_shared { name: "libsensorservice", @@ -52,6 +49,8 @@ cc_library_shared { "libhardware_legacy", "libutils", "liblog", + "libactivitymanager_aidl", + "libbatterystats_aidl", "libbinder", "libsensor", "libsensorprivacy", @@ -71,8 +70,11 @@ cc_library_shared { generated_headers: ["framework-cppstream-protos"], - // our public headers depend on libsensor and libsensorprivacy - export_shared_lib_headers: ["libsensor", "libsensorprivacy"], + export_shared_lib_headers: [ + "libactivitymanager_aidl", + "libsensor", + "libsensorprivacy", + ], } cc_binary { diff --git a/services/sensorservice/BatteryService.h b/services/sensorservice/BatteryService.h index 43a750c6c2..09eb2c1d10 100644 --- a/services/sensorservice/BatteryService.h +++ b/services/sensorservice/BatteryService.h @@ -17,7 +17,7 @@ #include <stdint.h> #include <sys/types.h> -#include <binder/IBatteryStats.h> +#include <batterystats/IBatteryStats.h> #include <utils/Singleton.h> namespace android { diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp index 866007e188..eb24a22719 100644 --- a/services/vr/hardware_composer/Android.bp +++ b/services/vr/hardware_composer/Android.bp @@ -108,6 +108,7 @@ cc_library_static { cc_binary { name: "vr_hwc", + enabled: false, system_ext_specific: true, vintf_fragments: ["manifest_vr_hwc.xml"], srcs: [ diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 4b69bec743..2913850ab3 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -1088,7 +1088,8 @@ VkResult CreateSwapchainKHR(VkDevice device, ALOGW_IF(err != android::OK, "native_window_api_connect failed: %s (%d)", strerror(-err), err); - err = window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, -1); + err = + window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, nsecs_t{-1}); if (err != android::OK) { ALOGE("window->perform(SET_DEQUEUE_TIMEOUT) failed: %s (%d)", strerror(-err), err); diff --git a/vulkan/vkjson/vkjson_instance.cc b/vulkan/vkjson/vkjson_instance.cc index 73586d42f8..c3f49632b9 100644 --- a/vulkan/vkjson/vkjson_instance.cc +++ b/vulkan/vkjson/vkjson_instance.cc @@ -433,6 +433,10 @@ VkJsonInstance VkJsonGetInstance() { VkJsonDeviceGroup device_group; std::vector<VkPhysicalDeviceGroupProperties> group_properties; group_properties.resize(count); + for (auto& properties : group_properties) { + properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES; + properties.pNext = nullptr; + } result = (*vkpEnumeratePhysicalDeviceGroups)(vkinstance, &count, group_properties.data()); if (result != VK_SUCCESS) { |