Add NativePermissionController for audio perms
Audioserver currently sync calls upwards to system_server to check
permission related information.
Add the implementation of NativePermissionController which receives
package/uid updates from system server, and caches the info to provide
and validate package info for audioserver.
Bug: 338089555
Flag: com.android.media.audio.audioserver_permissions
Test: atest audiopermissioncontroller_test
Change-Id: I44f335e32f38ea474e88b3d9970d62a1e886c543
diff --git a/aidl/com/android/media/permission/UidPackageState.aidl b/aidl/com/android/media/permission/UidPackageState.aidl
index 41b8c65..747a7ef 100644
--- a/aidl/com/android/media/permission/UidPackageState.aidl
+++ b/aidl/com/android/media/permission/UidPackageState.aidl
@@ -20,6 +20,7 @@
* Entity representing the package names associated with a particular uid/app-id
* {@hide}
*/
+@JavaDerive(equals = true, toString = true)
parcelable UidPackageState {
int uid;
@utf8InCpp List<String> packageNames;
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index fc8ad77..ba231c1 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -48,6 +48,7 @@
"aaudio-aidl-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
+ "audio-permission-aidl-cpp",
"audiopolicy-aidl-cpp",
"audiopolicy-types-aidl-cpp",
"av-types-aidl-cpp",
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 04a8a45..9ccabe9 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -457,6 +457,7 @@
"latest_android_media_audio_common_types_import_interface",
],
imports: [
+ "audio-permission-aidl",
"audioclient-types-aidl",
"audiopolicy-types-aidl",
"capture_state_listener-aidl",
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 633493c..7894699 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -58,6 +58,8 @@
import android.media.audio.common.AudioUuid;
import android.media.audio.common.Int;
+import com.android.media.permission.INativePermissionController;
+
/**
* IAudioPolicyService interface (see AudioPolicyInterface for method descriptions).
*
@@ -471,6 +473,11 @@
int /* uid_t */ uid);
+ /**
+ * Get the native permission controller for audioserver, to push package and permission info
+ * required to control audio access.
+ */
+ INativePermissionController getPermissionController();
// When adding a new method, please review and update
// AudioPolicyService.cpp AudioPolicyService::onTransact()
// AudioPolicyService.cpp IAUDIOPOLICYSERVICE_BINDER_METHOD_MACRO_LIST
diff --git a/media/libaudioclient/aidl/fuzzer/Android.bp b/media/libaudioclient/aidl/fuzzer/Android.bp
index 6cfccd6..f58be0b 100644
--- a/media/libaudioclient/aidl/fuzzer/Android.bp
+++ b/media/libaudioclient/aidl/fuzzer/Android.bp
@@ -22,6 +22,7 @@
name: "libaudioclient_aidl_fuzzer_defaults",
static_libs: [
"android.hardware.audio.common@7.0-enums",
+ "audiopermissioncontroller",
"libaudiomockhal",
"libcgrouprc",
"libcgrouprc_format",
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index 055da5b..9c3ad44 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -122,6 +122,7 @@
],
static_libs: [
"android.hardware.audio.common@7.0-enums",
+ "audio-permission-aidl-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-aidl-cpp",
diff --git a/services/audiopolicy/fuzzer/aidl/Android.bp b/services/audiopolicy/fuzzer/aidl/Android.bp
index 2c85955..a91ecd7 100644
--- a/services/audiopolicy/fuzzer/aidl/Android.bp
+++ b/services/audiopolicy/fuzzer/aidl/Android.bp
@@ -44,6 +44,7 @@
"packagemanager_aidl-cpp",
],
static_libs: [
+ "audiopermissioncontroller",
"libaudiomockhal",
"libfakeservicemanager",
"libmediaplayerservice",
diff --git a/services/audiopolicy/permission/Android.bp b/services/audiopolicy/permission/Android.bp
new file mode 100644
index 0000000..1aa29e0
--- /dev/null
+++ b/services/audiopolicy/permission/Android.bp
@@ -0,0 +1,102 @@
+package {
+ default_team: "trendy_team_android_media_audio_framework",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+ name: "audiopermissioncontroller",
+
+ srcs: [
+ "NativePermissionController.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+
+ header_libs: [
+ "libcutils_headers",
+ "liberror_headers",
+ ],
+ export_header_lib_headers: [
+ "liberror_headers",
+ ],
+ static_libs: [
+ "audio-permission-aidl-cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "libutils",
+ "liblog",
+ ],
+
+ host_supported: true,
+ sanitize: {
+ integer_overflow: true,
+ },
+ cflags: [
+ "-Wall",
+ "-Wdeprecated",
+ "-Wextra",
+ "-Werror=format",
+ "-Wextra-semi",
+ "-Wthread-safety",
+ "-Wconditional-uninitialized",
+ "-Wimplicit-fallthrough",
+ "-Wreorder-init-list",
+ "-Werror=reorder-init-list",
+ "-Wshadow-all",
+ "-Wunreachable-code-aggressive",
+ "-Werror",
+ "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
+ "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+ ],
+ tidy: true,
+ tidy_checks: [
+ "android-*",
+ "bugprone-*",
+ "cert-*",
+ "clang-analyzer-security*",
+ "google-*",
+ "misc-*",
+ "modernize-*",
+ "performance-*",
+ ],
+ tidy_checks_as_errors: [
+ "android-*",
+ "bugprone-*",
+ "cert-*",
+ "clang-analyzer-security*",
+ "google-*",
+ "misc-*",
+ "modernize-*",
+ "performance-*",
+ ],
+}
+
+cc_test {
+ name: "audiopermissioncontroller_test",
+ host_supported: true,
+ defaults: [
+ "libmediautils_tests_config",
+ ],
+ static_libs: [
+ "audio-permission-aidl-cpp",
+ "audiopermissioncontroller",
+ "framework-permission-aidl-cpp",
+ "libgmock",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+ srcs: [
+ "tests/NativePermissionControllerTest.cpp",
+ ],
+ test_options: {
+ unit_test: true,
+ },
+ test_suites: ["general-tests"],
+}
diff --git a/services/audiopolicy/permission/NativePermissionController.cpp b/services/audiopolicy/permission/NativePermissionController.cpp
new file mode 100644
index 0000000..d88c69f
--- /dev/null
+++ b/services/audiopolicy/permission/NativePermissionController.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2024 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 <media/NativePermissionController.h>
+
+#include <algorithm>
+#include <optional>
+#include <utility>
+
+#include <android-base/expected.h>
+#include <cutils/android_filesystem_config.h>
+#include <utils/Errors.h>
+
+using ::android::base::unexpected;
+using ::android::binder::Status;
+using ::android::error::Result;
+
+namespace com::android::media::permission {
+static std::optional<std::string> getFixedPackageName(uid_t uid) {
+ // These values are in sync with AppOpsService
+ switch (uid % AID_USER_OFFSET) {
+ case AID_ROOT:
+ return "root";
+ case AID_SYSTEM:
+ return "system";
+ case AID_SHELL:
+ return "shell";
+ case AID_MEDIA:
+ return "media";
+ case AID_AUDIOSERVER:
+ return "audioserver";
+ case AID_CAMERASERVER:
+ return "cameraserver";
+ // These packages are not handled by AppOps, but labeling may be useful for us
+ case AID_RADIO:
+ return "telephony";
+ case AID_BLUETOOTH:
+ return "bluetooth";
+ default:
+ return std::nullopt;
+ }
+}
+
+// -- Begin Binder methods
+Status NativePermissionController::populatePackagesForUids(
+ const std::vector<UidPackageState>& initialPackageStates) {
+ std::lock_guard l{m_};
+ if (!is_package_populated_) is_package_populated_ = true;
+ package_map_.clear();
+ std::transform(initialPackageStates.begin(), initialPackageStates.end(),
+ std::inserter(package_map_, package_map_.end()),
+ [](const auto& x) -> std::pair<uid_t, std::vector<std::string>> {
+ return {x.uid, x.packageNames};
+ });
+ std::erase_if(package_map_, [](const auto& x) { return x.second.empty(); });
+ return Status::ok();
+}
+
+Status NativePermissionController::updatePackagesForUid(const UidPackageState& newPackageState) {
+ std::lock_guard l{m_};
+ package_map_.insert_or_assign(newPackageState.uid, newPackageState.packageNames);
+ const auto& cursor = package_map_.find(newPackageState.uid);
+
+ if (newPackageState.packageNames.empty()) {
+ if (cursor != package_map_.end()) {
+ package_map_.erase(cursor);
+ }
+ } else {
+ if (cursor != package_map_.end()) {
+ cursor->second = newPackageState.packageNames;
+ } else {
+ package_map_.insert({newPackageState.uid, newPackageState.packageNames});
+ }
+ }
+ return Status::ok();
+}
+
+// -- End Binder methods
+
+Result<std::vector<std::string>> NativePermissionController::getPackagesForUid(uid_t uid) const {
+ uid = uid % AID_USER_OFFSET;
+ const auto fixed_package_opt = getFixedPackageName(uid);
+ if (fixed_package_opt.has_value()) {
+ return Result<std::vector<std::string>>{std::in_place_t{}, {fixed_package_opt.value()}};
+ }
+ std::lock_guard l{m_};
+ if (!is_package_populated_) return unexpected{::android::NO_INIT};
+ const auto cursor = package_map_.find(uid);
+ if (cursor != package_map_.end()) {
+ return cursor->second;
+ } else {
+ return unexpected{::android::BAD_VALUE};
+ }
+}
+
+Result<bool> NativePermissionController::validateUidPackagePair(
+ uid_t uid, const std::string& packageName) const {
+ uid = uid % AID_USER_OFFSET;
+ const auto fixed_package_opt = getFixedPackageName(uid);
+ if (fixed_package_opt.has_value()) {
+ return packageName == fixed_package_opt.value();
+ }
+ std::lock_guard l{m_};
+ if (!is_package_populated_) return unexpected{::android::NO_INIT};
+ const auto cursor = package_map_.find(uid);
+ return (cursor != package_map_.end()) &&
+ (std::find(cursor->second.begin(), cursor->second.end(), packageName) !=
+ cursor->second.end());
+}
+} // namespace com::android::media::permission
diff --git a/services/audiopolicy/permission/include/media/IPermissionProvider.h b/services/audiopolicy/permission/include/media/IPermissionProvider.h
new file mode 100644
index 0000000..9184ffb
--- /dev/null
+++ b/services/audiopolicy/permission/include/media/IPermissionProvider.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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 <sys/types.h>
+
+#include <optional>
+#include <vector>
+
+#include <error/Result.h>
+
+namespace com::android::media::permission {
+
+class IPermissionProvider {
+ public:
+ // Get all package names which run under a certain app-id. Returns non-empty.
+ // Not user specific, since packages are across users. Special app-ids (system,
+ // shell, etc.) are handled. Fails if the provider does not know about the
+ // app-id.
+ virtual ::android::error::Result<std::vector<std::string>> getPackagesForUid(
+ uid_t uid) const = 0;
+ // True iff the provided package name runs under the app-id of uid.
+ // Special app-ids (system, shell, etc.) are handled.
+ // Fails if the provider does not know about the app-id.
+ virtual ::android::error::Result<bool> validateUidPackagePair(
+ uid_t uid, const std::string& packageName) const = 0;
+ virtual ~IPermissionProvider() = default;
+};
+} // namespace com::android::media::permission
diff --git a/services/audiopolicy/permission/include/media/NativePermissionController.h b/services/audiopolicy/permission/include/media/NativePermissionController.h
new file mode 100644
index 0000000..c0e717c
--- /dev/null
+++ b/services/audiopolicy/permission/include/media/NativePermissionController.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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 <mutex>
+#include <optional>
+#include <unordered_map>
+
+#include "IPermissionProvider.h"
+
+#include <android-base/thread_annotations.h>
+#include <com/android/media/permission/BnNativePermissionController.h>
+
+namespace com::android::media::permission {
+
+class NativePermissionController : public BnNativePermissionController, public IPermissionProvider {
+ using Status = ::android::binder::Status;
+
+ public:
+ Status populatePackagesForUids(const std::vector<UidPackageState>& initialPackageStates) final;
+ Status updatePackagesForUid(const UidPackageState& newPackageState) final;
+ // end binder methods
+
+ ::android::error::Result<std::vector<std::string>> getPackagesForUid(uid_t uid) const final;
+ ::android::error::Result<bool> validateUidPackagePair(
+ uid_t uid, const std::string& packageName) const final;
+
+ private:
+ mutable std::mutex m_;
+ // map of app_ids to the set of packages names which could run in them (should be 1)
+ std::unordered_map<uid_t, std::vector<std::string>> package_map_ GUARDED_BY(m_);
+ bool is_package_populated_ GUARDED_BY(m_);
+};
+} // namespace com::android::media::permission
diff --git a/services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp b/services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp
new file mode 100644
index 0000000..f23a8b3
--- /dev/null
+++ b/services/audiopolicy/permission/tests/NativePermissionControllerTest.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2024 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 <media/NativePermissionController.h>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <android-base/expected.h>
+
+using ::android::base::unexpected;
+using ::android::binder::Status;
+using com::android::media::permission::NativePermissionController;
+using com::android::media::permission::UidPackageState;
+
+class NativePermissionControllerTest : public ::testing::Test {
+ protected:
+ android::sp<NativePermissionController> holder_ =
+ android::sp<NativePermissionController>::make();
+ NativePermissionController& controller_ = *holder_;
+};
+static UidPackageState createState(uid_t uid, std::vector<std::string> packagesNames) {
+ UidPackageState out{};
+ out.uid = uid;
+ out.packageNames = std::move(packagesNames);
+ return out;
+}
+
+static std::vector<std::string> makeVector(const char* one) {
+ return {one};
+}
+
+static std::vector<std::string> makeVector(const char* one, const char* two) {
+ return {one, two};
+}
+
+#define UNWRAP_EQ(expr, desired_expr) \
+ do { \
+ auto tmp_ = (expr); \
+ EXPECT_TRUE(tmp_.has_value()); \
+ if (tmp_.has_value()) EXPECT_EQ(*tmp_, desired_expr); \
+ } while (0)
+
+// --- Tests for non-populated ----
+TEST_F(NativePermissionControllerTest, getPackagesForUid_NotPopulated) {
+ // Verify errors are returned
+ EXPECT_EQ(controller_.getPackagesForUid(10000), unexpected{android::NO_INIT});
+ EXPECT_EQ(controller_.getPackagesForUid(10001), unexpected{android::NO_INIT});
+
+ // fixed uids should work
+ UNWRAP_EQ(controller_.getPackagesForUid(1000), makeVector("system"));
+}
+
+TEST_F(NativePermissionControllerTest, validateUidPackagePair_NotPopulated) {
+ // Verify errors are returned
+ EXPECT_EQ(controller_.validateUidPackagePair(10000, "com.package"),
+ unexpected{android::NO_INIT});
+
+ // fixed uids should work
+ UNWRAP_EQ(controller_.validateUidPackagePair(1000, "system"), true);
+}
+// --- Tests for populatePackagesForUids ----
+TEST_F(NativePermissionControllerTest, populatePackages_EmptyInput) {
+ std::vector<UidPackageState> input;
+
+ // succeeds
+ EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+
+ // Verify unknown uid behavior
+ const auto res1 = controller_.getPackagesForUid(10000);
+ ASSERT_FALSE(res1.has_value());
+ EXPECT_EQ(res1.error(), ::android::BAD_VALUE);
+}
+
+TEST_F(NativePermissionControllerTest, populatePackages_ValidInput) {
+ std::vector<UidPackageState> input{
+ createState(10000, {"com.example.app1", "com.example.app2"}),
+ createState(10001, {"com.example2.app1"}),
+ };
+
+ EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+
+ UNWRAP_EQ(controller_.getPackagesForUid(10000),
+ makeVector("com.example.app1", "com.example.app2"));
+ UNWRAP_EQ(controller_.getPackagesForUid(10001), makeVector("com.example2.app1"));
+}
+
+// --- Tests for updatePackagesForUid ---
+TEST_F(NativePermissionControllerTest, updatePackages_NewUid) {
+ std::vector<UidPackageState> input{
+ createState(10000, {"com.example.app1", "com.example.app2"}),
+ createState(10001, {"com.example2.app1"}),
+ };
+ UidPackageState newState = createState(12000, {"com.example.other"});
+
+ EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+ EXPECT_TRUE(controller_.updatePackagesForUid(newState).isOk());
+
+ // Verify the results: only the updated package should be changed
+ UNWRAP_EQ(controller_.getPackagesForUid(10000),
+ makeVector("com.example.app1", "com.example.app2"));
+ UNWRAP_EQ(controller_.getPackagesForUid(10001), makeVector("com.example2.app1"));
+ UNWRAP_EQ(controller_.getPackagesForUid(12000), makeVector("com.example.other"));
+}
+
+TEST_F(NativePermissionControllerTest, updatePackages_ExistingUid) {
+ std::vector<UidPackageState> input{
+ createState(10000, {"com.example.app1", "com.example.app2", "com.example.app3"}),
+ createState(10001, {"com.example2.app1"}),
+ };
+
+ EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+ // Update packages for existing uid
+ UidPackageState newState = createState(10000, {"com.example.other", "com.example.new"});
+ EXPECT_TRUE(controller_.updatePackagesForUid(newState).isOk());
+
+ // Verify update
+ UNWRAP_EQ(controller_.getPackagesForUid(10000),
+ makeVector("com.example.other", "com.example.new"));
+}
+
+TEST_F(NativePermissionControllerTest, updatePackages_EmptyRemovesEntry) {
+ std::vector<UidPackageState> input{
+ createState(10000, {"com.example.app1"}),
+ };
+
+ EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+
+ UidPackageState newState{}; // Empty package list
+ newState.uid = 10000;
+ EXPECT_TRUE(controller_.updatePackagesForUid(newState).isOk());
+ // getPackages for unknown UID should error out
+ const auto res = controller_.getPackagesForUid(10000);
+ ASSERT_FALSE(res.has_value());
+ EXPECT_EQ(res.error(), ::android::BAD_VALUE);
+}
+
+TEST_F(NativePermissionControllerTest, validateUidPackagePair_ValidPair) {
+ std::vector<UidPackageState> input{
+ createState(10000, {"com.example.app1", "com.example.app2"}),
+ };
+
+ EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+
+ UNWRAP_EQ(controller_.validateUidPackagePair(10000, "com.example.app1"), true);
+}
+
+TEST_F(NativePermissionControllerTest, validateUidPackagePair_InvalidPackage) {
+ std::vector<UidPackageState> input{
+ createState(10000, {"com.example.app1", "com.example.app2"}),
+ };
+
+ EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+
+ UNWRAP_EQ(controller_.validateUidPackagePair(10000, "com.example.other"), false);
+}
+
+TEST_F(NativePermissionControllerTest, validateUidPackagePair_UnknownUid) {
+ std::vector<UidPackageState> input{
+ createState(10000, {"com.example.app1", "com.example.app2"}),
+ };
+
+ EXPECT_TRUE(controller_.populatePackagesForUids(input).isOk());
+
+ UNWRAP_EQ(controller_.validateUidPackagePair(12000, "any.package"), false);
+}
diff --git a/services/audiopolicy/service/Android.bp b/services/audiopolicy/service/Android.bp
index 9b7a470..f23ec94 100644
--- a/services/audiopolicy/service/Android.bp
+++ b/services/audiopolicy/service/Android.bp
@@ -52,6 +52,8 @@
],
static_libs: [
+ "audio-permission-aidl-cpp",
+ "audiopermissioncontroller",
"libaudiopolicycomponents",
"libeffectsconfig",
],
@@ -81,7 +83,7 @@
],
static_libs: [
- "framework-permission-aidl-cpp",
+ "framework-permission-aidl-cpp", // TODO remove when unnnecessary
],
header_libs: [
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index a862037..106fbf6 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -14,12 +14,14 @@
* limitations under the License.
*/
-#define LOG_TAG "AudioPolicyIntefaceImpl"
+#define LOG_TAG "AudioPolicyInterfaceImpl"
//#define LOG_NDEBUG 0
#include "AudioPolicyService.h"
#include "AudioRecordClient.h"
#include "TypeConverter.h"
+
+#include <android/content/AttributionSourceState.h>
#include <android_media_audiopolicy.h>
#include <media/AidlConversion.h>
#include <media/AudioPolicy.h>
@@ -27,7 +29,6 @@
#include <media/MediaMetricsItem.h>
#include <media/PolicyAidlConversion.h>
#include <utils/Log.h>
-#include <android/content/AttributionSourceState.h>
#define VALUE_OR_RETURN_BINDER_STATUS(x) \
({ auto _tmp = (x); \
@@ -49,6 +50,7 @@
namespace audiopolicy_flags = android::media::audiopolicy;
using binder::Status;
using aidl_utils::binderStatusFromStatusT;
+using com::android::media::permission::NativePermissionController;
using content::AttributionSourceState;
using media::audio::common::AudioConfig;
using media::audio::common::AudioConfigBase;
@@ -2643,4 +2645,9 @@
mAudioPolicyManager->clearPreferredMixerAttributes(&attr, portId, uid));
}
+Status AudioPolicyService::getPermissionController(sp<INativePermissionController>* out) {
+ *out = mPermissionController;
+ return Status::ok();
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 3e1245b..cd010ab 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -164,6 +164,7 @@
BINDER_METHOD_ENTRY(getPreferredMixerAttributes) \
BINDER_METHOD_ENTRY(clearPreferredMixerAttributes) \
BINDER_METHOD_ENTRY(getRegisteredPolicyMixes) \
+BINDER_METHOD_ENTRY(getPermissionController) \
\
// singleton for Binder Method Statistics for IAudioPolicyService
static auto& getIAudioPolicyServiceStatistics() {
@@ -226,7 +227,9 @@
mCaptureStateNotifier(false),
mCreateAudioPolicyManager(createAudioPolicyManager),
mDestroyAudioPolicyManager(destroyAudioPolicyManager),
- mUsecaseValidator(media::createUsecaseValidator()) {
+ mUsecaseValidator(media::createUsecaseValidator()),
+ mPermissionController(sp<NativePermissionController>::make())
+{
setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
setInheritRt(true);
}
@@ -1368,6 +1371,17 @@
break;
}
+ switch (code) {
+ case TRANSACTION_getPermissionController: {
+ if (!isAudioServerOrSystemServerUid(IPCThreadState::self()->getCallingUid())) {
+ ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
+ __func__, code, IPCThreadState::self()->getCallingPid(),
+ IPCThreadState::self()->getCallingUid());
+ return INVALID_OPERATION;
+ }
+ }
+ }
+
const std::string methodName = getIAudioPolicyServiceStatistics().getMethodForCode(code);
mediautils::TimeCheck check(
std::string("IAudioPolicyService::").append(methodName),
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 5297e47..abc1dca 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -21,6 +21,7 @@
#include <android/media/GetSpatializerResponse.h>
#include <android-base/thread_annotations.h>
#include <audio_utils/mutex.h>
+#include <com/android/media/permission/INativePermissionController.h>
#include <cutils/misc.h>
#include <cutils/config_utils.h>
#include <cutils/compiler.h>
@@ -35,6 +36,7 @@
#include <media/ToneGenerator.h>
#include <media/AudioEffect.h>
#include <media/AudioPolicy.h>
+#include <media/NativePermissionController.h>
#include <media/UsecaseValidator.h>
#include <mediautils/ServiceUtilities.h>
#include "AudioPolicyEffects.h"
@@ -68,6 +70,8 @@
}
using ::android::media::audiopolicy::AudioRecordClient;
+using ::com::android::media::permission::INativePermissionController;
+using ::com::android::media::permission::NativePermissionController;
class AudioPolicyService :
public BinderService<AudioPolicyService>,
@@ -314,6 +318,9 @@
binder::Status getRegisteredPolicyMixes(
std::vector <::android::media::AudioMix>* mixes) override;
+ // Should only be called by AudioService to push permission data down to audioserver
+ binder::Status getPermissionController(sp<INativePermissionController>* out) override;
+
status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override;
// IBinder::DeathRecipient
@@ -1045,6 +1052,7 @@
CreateAudioPolicyManagerInstance mCreateAudioPolicyManager;
DestroyAudioPolicyManagerInstance mDestroyAudioPolicyManager;
std::unique_ptr<media::UsecaseValidator> mUsecaseValidator;
+ const sp<NativePermissionController> mPermissionController;
};
} // namespace android