Loading media/audioserver/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ LOCAL_SHARED_LIBRARIES := \ libhwbinder \ libmedia \ libmedialogservice \ libmediautils \ libnbaio \ libnblog \ libsoundtriggerservice \ Loading media/utils/ServiceUtilities.cpp +84 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ #include <binder/PermissionCache.h> #include "mediautils/ServiceUtilities.h" #include <iterator> #include <algorithm> /* When performing permission checks we do not use permission cache for * runtime permissions (protection level dangerous) as they may change at * runtime. All other permissions (protection level normal and dangerous) Loading Loading @@ -220,4 +223,85 @@ status_t checkIMemory(const sp<IMemory>& iMemory) return NO_ERROR; } sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() { const sp<IServiceManager> sm = defaultServiceManager(); if (sm == nullptr) { ALOGW("%s: failed to retrieve defaultServiceManager", __func__); return nullptr; } sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName)); if (packageManager == nullptr) { ALOGW("%s: failed to retrieve native package manager", __func__); return nullptr; } return interface_cast<content::pm::IPackageManagerNative>(packageManager); } std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) { if (mPackageManager == nullptr) { /** Can not fetch package manager at construction it may not yet be registered. */ mPackageManager = retreivePackageManager(); if (mPackageManager == nullptr) { ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__); return std::nullopt; } } std::vector<std::string> packageNames; auto status = mPackageManager->getNamesForUids({(int32_t)uid}, &packageNames); if (!status.isOk()) { ALOGW("%s: Playback capture is denied for uid %u as the package names could not be " "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str()); return std::nullopt; } if (packageNames.empty()) { ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved " "from the package manager: %s", __func__, uid, status.toString8().c_str()); return std::nullopt; } std::vector<bool> isAllowed; status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed); if (!status.isOk()) { ALOGW("%s: Playback capture is denied for uid %u as the manifest property could not be " "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str()); return std::nullopt; } if (packageNames.size() != isAllowed.size()) { ALOGW("%s: Playback capture is denied for uid %u as the package manager returned incoherent" " response size: %zu != %zu", __func__, uid, packageNames.size(), isAllowed.size()); return std::nullopt; } // Zip together packageNames and isAllowed for debug logs Packages& packages = mDebugLog[uid]; packages.resize(packageNames.size()); // Reuse all objects std::transform(begin(packageNames), end(packageNames), begin(isAllowed), begin(packages), [] (auto& name, bool isAllowed) -> Package { return {std::move(name), isAllowed}; }); // Only allow playback record if all packages in this UID allow it bool playbackCaptureAllowed = std::all_of(begin(isAllowed), end(isAllowed), [](bool b) { return b; }); return playbackCaptureAllowed; } void MediaPackageManager::dump(int fd, int spaces) const { dprintf(fd, "%*sAllow playback capture log:\n", spaces, ""); if (mPackageManager == nullptr) { dprintf(fd, "%*sNo package manager\n", spaces + 2, ""); } dprintf(fd, "%*sPackage manager errors: %u\n", spaces + 2, "", mPackageManagerErrors); for (const auto& uidCache : mDebugLog) { for (const auto& package : std::get<Packages>(uidCache)) { dprintf(fd, "%*s- uid=%5u, allowPlaybackCapture=%s, packageName=%s\n", spaces + 2, "", std::get<const uid_t>(uidCache), package.playbackCaptureAllowed ? "true " : "false", package.name.c_str()); } } } } // namespace android media/utils/include/mediautils/ServiceUtilities.h +36 −0 Original line number Diff line number Diff line Loading @@ -14,13 +14,22 @@ * limitations under the License. */ #ifndef ANDROID_MEDIAUTILS_SERVICEUTILITIES_H #define ANDROID_MEDIAUTILS_SERVICEUTILITIES_H #include <unistd.h> #include <android/content/pm/IPackageManagerNative.h> #include <binder/IMemory.h> #include <binder/PermissionController.h> #include <cutils/multiuser.h> #include <private/android_filesystem_config.h> #include <map> #include <optional> #include <string> #include <vector> namespace android { // Audio permission utilities Loading Loading @@ -72,4 +81,31 @@ bool modifyDefaultAudioEffectsAllowed(); bool dumpAllowed(); bool modifyPhoneStateAllowed(pid_t pid, uid_t uid); status_t checkIMemory(const sp<IMemory>& iMemory); class MediaPackageManager { public: /** Query the PackageManager to check if all apps of an UID allow playback capture. */ bool allowPlaybackCapture(uid_t uid) { auto result = doIsAllowed(uid); if (!result) { mPackageManagerErrors++; } return result.value_or(false); } void dump(int fd, int spaces = 0) const; private: static constexpr const char* nativePackageManagerName = "package_native"; std::optional<bool> doIsAllowed(uid_t uid); sp<content::pm::IPackageManagerNative> retreivePackageManager(); sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest uint_t mPackageManagerErrors = 0; struct Package { std::string name; bool playbackCaptureAllowed = false; }; using Packages = std::vector<Package>; std::map<uid_t, Packages> mDebugLog; }; } #endif // ANDROID_MEDIAUTILS_SERVICEUTILITIES_H services/audiopolicy/Android.mk +1 −1 Original line number Diff line number Diff line Loading @@ -90,7 +90,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES += libmedia_helper LOCAL_SHARED_LIBRARIES += libmediametrics LOCAL_SHARED_LIBRARIES += libhidlbase libxml2 LOCAL_SHARED_LIBRARIES += libbinder libhidlbase libxml2 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1) LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF Loading services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +8 −5 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ #include "AudioPolicyService.h" #include "TypeConverter.h" #include <media/MediaAnalyticsItem.h> #include <mediautils/ServiceUtilities.h> #include <media/AudioPolicy.h> #include <utils/Log.h> Loading Loading @@ -167,7 +166,7 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream) return mAudioPolicyManager->getOutput(stream); } status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *originalAttr, audio_io_handle_t *output, audio_session_t session, audio_stream_type_t *stream, Loading @@ -191,9 +190,13 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid); uid = callingUid; } audio_attributes_t attr = *originalAttr; if (!mPackageManager.allowPlaybackCapture(uid)) { attr.flags |= AUDIO_FLAG_NO_CAPTURE; } audio_output_flags_t originalFlags = flags; AutoCallerClear acc; status_t result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, status_t result = mAudioPolicyManager->getOutputForAttr(&attr, output, session, stream, uid, config, &flags, selectedDeviceId, portId, secondaryOutputs); Loading @@ -209,14 +212,14 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, *selectedDeviceId = AUDIO_PORT_HANDLE_NONE; *portId = AUDIO_PORT_HANDLE_NONE; secondaryOutputs->clear(); result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, config, result = mAudioPolicyManager->getOutputForAttr(&attr, output, session, stream, uid, config, &flags, selectedDeviceId, portId, secondaryOutputs); } if (result == NO_ERROR) { sp <AudioPlaybackClient> client = new AudioPlaybackClient(*attr, *output, uid, pid, session, *selectedDeviceId, *stream); new AudioPlaybackClient(attr, *output, uid, pid, session, *selectedDeviceId, *stream); mAudioPlaybackClients.add(*portId, client); } return result; Loading Loading
media/audioserver/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ LOCAL_SHARED_LIBRARIES := \ libhwbinder \ libmedia \ libmedialogservice \ libmediautils \ libnbaio \ libnblog \ libsoundtriggerservice \ Loading
media/utils/ServiceUtilities.cpp +84 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,9 @@ #include <binder/PermissionCache.h> #include "mediautils/ServiceUtilities.h" #include <iterator> #include <algorithm> /* When performing permission checks we do not use permission cache for * runtime permissions (protection level dangerous) as they may change at * runtime. All other permissions (protection level normal and dangerous) Loading Loading @@ -220,4 +223,85 @@ status_t checkIMemory(const sp<IMemory>& iMemory) return NO_ERROR; } sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() { const sp<IServiceManager> sm = defaultServiceManager(); if (sm == nullptr) { ALOGW("%s: failed to retrieve defaultServiceManager", __func__); return nullptr; } sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName)); if (packageManager == nullptr) { ALOGW("%s: failed to retrieve native package manager", __func__); return nullptr; } return interface_cast<content::pm::IPackageManagerNative>(packageManager); } std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) { if (mPackageManager == nullptr) { /** Can not fetch package manager at construction it may not yet be registered. */ mPackageManager = retreivePackageManager(); if (mPackageManager == nullptr) { ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__); return std::nullopt; } } std::vector<std::string> packageNames; auto status = mPackageManager->getNamesForUids({(int32_t)uid}, &packageNames); if (!status.isOk()) { ALOGW("%s: Playback capture is denied for uid %u as the package names could not be " "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str()); return std::nullopt; } if (packageNames.empty()) { ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved " "from the package manager: %s", __func__, uid, status.toString8().c_str()); return std::nullopt; } std::vector<bool> isAllowed; status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed); if (!status.isOk()) { ALOGW("%s: Playback capture is denied for uid %u as the manifest property could not be " "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str()); return std::nullopt; } if (packageNames.size() != isAllowed.size()) { ALOGW("%s: Playback capture is denied for uid %u as the package manager returned incoherent" " response size: %zu != %zu", __func__, uid, packageNames.size(), isAllowed.size()); return std::nullopt; } // Zip together packageNames and isAllowed for debug logs Packages& packages = mDebugLog[uid]; packages.resize(packageNames.size()); // Reuse all objects std::transform(begin(packageNames), end(packageNames), begin(isAllowed), begin(packages), [] (auto& name, bool isAllowed) -> Package { return {std::move(name), isAllowed}; }); // Only allow playback record if all packages in this UID allow it bool playbackCaptureAllowed = std::all_of(begin(isAllowed), end(isAllowed), [](bool b) { return b; }); return playbackCaptureAllowed; } void MediaPackageManager::dump(int fd, int spaces) const { dprintf(fd, "%*sAllow playback capture log:\n", spaces, ""); if (mPackageManager == nullptr) { dprintf(fd, "%*sNo package manager\n", spaces + 2, ""); } dprintf(fd, "%*sPackage manager errors: %u\n", spaces + 2, "", mPackageManagerErrors); for (const auto& uidCache : mDebugLog) { for (const auto& package : std::get<Packages>(uidCache)) { dprintf(fd, "%*s- uid=%5u, allowPlaybackCapture=%s, packageName=%s\n", spaces + 2, "", std::get<const uid_t>(uidCache), package.playbackCaptureAllowed ? "true " : "false", package.name.c_str()); } } } } // namespace android
media/utils/include/mediautils/ServiceUtilities.h +36 −0 Original line number Diff line number Diff line Loading @@ -14,13 +14,22 @@ * limitations under the License. */ #ifndef ANDROID_MEDIAUTILS_SERVICEUTILITIES_H #define ANDROID_MEDIAUTILS_SERVICEUTILITIES_H #include <unistd.h> #include <android/content/pm/IPackageManagerNative.h> #include <binder/IMemory.h> #include <binder/PermissionController.h> #include <cutils/multiuser.h> #include <private/android_filesystem_config.h> #include <map> #include <optional> #include <string> #include <vector> namespace android { // Audio permission utilities Loading Loading @@ -72,4 +81,31 @@ bool modifyDefaultAudioEffectsAllowed(); bool dumpAllowed(); bool modifyPhoneStateAllowed(pid_t pid, uid_t uid); status_t checkIMemory(const sp<IMemory>& iMemory); class MediaPackageManager { public: /** Query the PackageManager to check if all apps of an UID allow playback capture. */ bool allowPlaybackCapture(uid_t uid) { auto result = doIsAllowed(uid); if (!result) { mPackageManagerErrors++; } return result.value_or(false); } void dump(int fd, int spaces = 0) const; private: static constexpr const char* nativePackageManagerName = "package_native"; std::optional<bool> doIsAllowed(uid_t uid); sp<content::pm::IPackageManagerNative> retreivePackageManager(); sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest uint_t mPackageManagerErrors = 0; struct Package { std::string name; bool playbackCaptureAllowed = false; }; using Packages = std::vector<Package>; std::map<uid_t, Packages> mDebugLog; }; } #endif // ANDROID_MEDIAUTILS_SERVICEUTILITIES_H
services/audiopolicy/Android.mk +1 −1 Original line number Diff line number Diff line Loading @@ -90,7 +90,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_SHARED_LIBRARIES += libmedia_helper LOCAL_SHARED_LIBRARIES += libmediametrics LOCAL_SHARED_LIBRARIES += libhidlbase libxml2 LOCAL_SHARED_LIBRARIES += libbinder libhidlbase libxml2 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1) LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF Loading
services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +8 −5 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ #include "AudioPolicyService.h" #include "TypeConverter.h" #include <media/MediaAnalyticsItem.h> #include <mediautils/ServiceUtilities.h> #include <media/AudioPolicy.h> #include <utils/Log.h> Loading Loading @@ -167,7 +166,7 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream) return mAudioPolicyManager->getOutput(stream); } status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *originalAttr, audio_io_handle_t *output, audio_session_t session, audio_stream_type_t *stream, Loading @@ -191,9 +190,13 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid); uid = callingUid; } audio_attributes_t attr = *originalAttr; if (!mPackageManager.allowPlaybackCapture(uid)) { attr.flags |= AUDIO_FLAG_NO_CAPTURE; } audio_output_flags_t originalFlags = flags; AutoCallerClear acc; status_t result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, status_t result = mAudioPolicyManager->getOutputForAttr(&attr, output, session, stream, uid, config, &flags, selectedDeviceId, portId, secondaryOutputs); Loading @@ -209,14 +212,14 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, *selectedDeviceId = AUDIO_PORT_HANDLE_NONE; *portId = AUDIO_PORT_HANDLE_NONE; secondaryOutputs->clear(); result = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, config, result = mAudioPolicyManager->getOutputForAttr(&attr, output, session, stream, uid, config, &flags, selectedDeviceId, portId, secondaryOutputs); } if (result == NO_ERROR) { sp <AudioPlaybackClient> client = new AudioPlaybackClient(*attr, *output, uid, pid, session, *selectedDeviceId, *stream); new AudioPlaybackClient(attr, *output, uid, pid, session, *selectedDeviceId, *stream); mAudioPlaybackClients.add(*portId, client); } return result; Loading