Add package name when initializing SoundPool.
The package name is useful for permission validation. Currently, package
name is required when starting external vibration so that the vibrator
service can verify if the app has the permission to start vibration.
Bug: 175595599
Test: SoundPool tests in cts
Test: play audio-coupled-haptic file using SoundPool.
Change-Id: Ibfe414063a303118a5bb393d65ea5dc2323bf722
Merged-In: Ibfe414063a303118a5bb393d65ea5dc2323bf722
(cherry picked from commit de9005bab1)
This commit is contained in:
@@ -149,7 +149,8 @@ public class SoundPool extends PlayerBase {
|
|||||||
super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL);
|
super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL);
|
||||||
|
|
||||||
// do native setup
|
// do native setup
|
||||||
if (native_setup(new WeakReference<SoundPool>(this), maxStreams, attributes) != 0) {
|
if (native_setup(new WeakReference<SoundPool>(this),
|
||||||
|
maxStreams, attributes, getCurrentOpPackageName()) != 0) {
|
||||||
throw new RuntimeException("Native setup failed");
|
throw new RuntimeException("Native setup failed");
|
||||||
}
|
}
|
||||||
mAttributes = attributes;
|
mAttributes = attributes;
|
||||||
@@ -501,7 +502,7 @@ public class SoundPool extends PlayerBase {
|
|||||||
private native final int _load(FileDescriptor fd, long offset, long length, int priority);
|
private native final int _load(FileDescriptor fd, long offset, long length, int priority);
|
||||||
|
|
||||||
private native final int native_setup(Object weakRef, int maxStreams,
|
private native final int native_setup(Object weakRef, int maxStreams,
|
||||||
Object/*AudioAttributes*/ attributes);
|
@NonNull Object/*AudioAttributes*/ attributes, @NonNull String opPackageName);
|
||||||
|
|
||||||
private native final int _play(int soundID, float leftVolume, float rightVolume,
|
private native final int _play(int soundID, float leftVolume, float rightVolume,
|
||||||
int priority, int loop, float rate);
|
int priority, int loop, float rate);
|
||||||
|
|||||||
@@ -84,8 +84,9 @@ bool checkLoop(int32_t *loop)
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
SoundPool::SoundPool(int32_t maxStreams, const audio_attributes_t* attributes)
|
SoundPool::SoundPool(
|
||||||
: mStreamManager(maxStreams, kStreamManagerThreads, attributes)
|
int32_t maxStreams, const audio_attributes_t* attributes, const std::string& opPackageName)
|
||||||
|
: mStreamManager(maxStreams, kStreamManagerThreads, attributes, opPackageName)
|
||||||
{
|
{
|
||||||
ALOGV("%s(maxStreams=%d, attr={ content_type=%d, usage=%d, flags=0x%x, tags=%s })",
|
ALOGV("%s(maxStreams=%d, attr={ content_type=%d, usage=%d, flags=0x%x, tags=%s })",
|
||||||
__func__, maxStreams,
|
__func__, maxStreams,
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
#include "SoundManager.h"
|
#include "SoundManager.h"
|
||||||
#include "StreamManager.h"
|
#include "StreamManager.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +31,8 @@ namespace android {
|
|||||||
*/
|
*/
|
||||||
class SoundPool {
|
class SoundPool {
|
||||||
public:
|
public:
|
||||||
SoundPool(int32_t maxStreams, const audio_attributes_t* attributes);
|
SoundPool(int32_t maxStreams, const audio_attributes_t* attributes,
|
||||||
|
const std::string& opPackageName = {});
|
||||||
~SoundPool();
|
~SoundPool();
|
||||||
|
|
||||||
// SoundPool Java API support
|
// SoundPool Java API support
|
||||||
|
|||||||
@@ -332,7 +332,9 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID,
|
|||||||
0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
|
0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
|
||||||
AudioTrack::TRANSFER_DEFAULT,
|
AudioTrack::TRANSFER_DEFAULT,
|
||||||
nullptr /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/,
|
nullptr /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/,
|
||||||
mStreamManager->getAttributes());
|
mStreamManager->getAttributes(),
|
||||||
|
false /*doNotReconnect*/, 1.0f /*maxRequiredSpeed*/,
|
||||||
|
mStreamManager->getOpPackageName());
|
||||||
// Set caller name so it can be logged in destructor.
|
// Set caller name so it can be logged in destructor.
|
||||||
// MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_SOUNDPOOL
|
// MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_SOUNDPOOL
|
||||||
newTrack->setCallerName("soundpool");
|
newTrack->setCallerName("soundpool");
|
||||||
|
|||||||
@@ -98,9 +98,11 @@ int32_t StreamMap::getNextIdForStream(Stream* stream) const {
|
|||||||
#pragma clang diagnostic ignored "-Wthread-safety-analysis"
|
#pragma clang diagnostic ignored "-Wthread-safety-analysis"
|
||||||
|
|
||||||
StreamManager::StreamManager(
|
StreamManager::StreamManager(
|
||||||
int32_t streams, size_t threads, const audio_attributes_t* attributes)
|
int32_t streams, size_t threads, const audio_attributes_t* attributes,
|
||||||
|
std::string opPackageName)
|
||||||
: StreamMap(streams)
|
: StreamMap(streams)
|
||||||
, mAttributes(*attributes)
|
, mAttributes(*attributes)
|
||||||
|
, mOpPackageName(std::move(opPackageName))
|
||||||
{
|
{
|
||||||
ALOGV("%s(%d, %zu, ...)", __func__, streams, threads);
|
ALOGV("%s(%d, %zu, ...)", __func__, streams, threads);
|
||||||
forEach([this](Stream *stream) {
|
forEach([this](Stream *stream) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -386,7 +387,8 @@ class StreamManager : public StreamMap {
|
|||||||
public:
|
public:
|
||||||
// Note: the SoundPool pointer is only used for stream initialization.
|
// Note: the SoundPool pointer is only used for stream initialization.
|
||||||
// It is not stored in StreamManager.
|
// It is not stored in StreamManager.
|
||||||
StreamManager(int32_t streams, size_t threads, const audio_attributes_t* attributes);
|
StreamManager(int32_t streams, size_t threads, const audio_attributes_t* attributes,
|
||||||
|
std::string opPackageName);
|
||||||
~StreamManager();
|
~StreamManager();
|
||||||
|
|
||||||
// Returns positive streamID on success, 0 on failure. This is locked.
|
// Returns positive streamID on success, 0 on failure. This is locked.
|
||||||
@@ -400,6 +402,8 @@ public:
|
|||||||
|
|
||||||
const audio_attributes_t* getAttributes() const { return &mAttributes; }
|
const audio_attributes_t* getAttributes() const { return &mAttributes; }
|
||||||
|
|
||||||
|
const std::string& getOpPackageName() const { return mOpPackageName; }
|
||||||
|
|
||||||
// Moves the stream to the restart queue (called upon BUFFER_END of the static track)
|
// Moves the stream to the restart queue (called upon BUFFER_END of the static track)
|
||||||
// this is locked internally.
|
// this is locked internally.
|
||||||
// If activeStreamIDToMatch is nonzero, it will only move to the restart queue
|
// If activeStreamIDToMatch is nonzero, it will only move to the restart queue
|
||||||
@@ -473,6 +477,8 @@ private:
|
|||||||
// The paired stream may be active or restarting.
|
// The paired stream may be active or restarting.
|
||||||
// No particular order.
|
// No particular order.
|
||||||
std::unordered_set<Stream*> mProcessingStreams GUARDED_BY(mStreamManagerLock);
|
std::unordered_set<Stream*> mProcessingStreams GUARDED_BY(mStreamManagerLock);
|
||||||
|
|
||||||
|
const std::string mOpPackageName;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace android::soundpool
|
} // namespace android::soundpool
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <nativehelper/JNIPlatformHelp.h>
|
#include <nativehelper/JNIPlatformHelp.h>
|
||||||
|
#include <nativehelper/ScopedUtfChars.h>
|
||||||
#include <android_runtime/AndroidRuntime.h>
|
#include <android_runtime/AndroidRuntime.h>
|
||||||
#include "SoundPool.h"
|
#include "SoundPool.h"
|
||||||
|
|
||||||
@@ -181,7 +182,7 @@ static void android_media_callback(SoundPoolEvent event, SoundPool* soundPool, v
|
|||||||
|
|
||||||
static jint
|
static jint
|
||||||
android_media_SoundPool_native_setup(JNIEnv *env, jobject thiz, jobject weakRef,
|
android_media_SoundPool_native_setup(JNIEnv *env, jobject thiz, jobject weakRef,
|
||||||
jint maxChannels, jobject jaa)
|
jint maxChannels, jobject jaa, jstring opPackageName)
|
||||||
{
|
{
|
||||||
if (jaa == nullptr) {
|
if (jaa == nullptr) {
|
||||||
ALOGE("Error creating SoundPool: invalid audio attributes");
|
ALOGE("Error creating SoundPool: invalid audio attributes");
|
||||||
@@ -203,7 +204,8 @@ android_media_SoundPool_native_setup(JNIEnv *env, jobject thiz, jobject weakRef,
|
|||||||
paa->flags = (audio_flags_mask_t) env->GetIntField(jaa, javaAudioAttrFields.fieldFlags);
|
paa->flags = (audio_flags_mask_t) env->GetIntField(jaa, javaAudioAttrFields.fieldFlags);
|
||||||
|
|
||||||
ALOGV("android_media_SoundPool_native_setup");
|
ALOGV("android_media_SoundPool_native_setup");
|
||||||
auto *ap = new SoundPool(maxChannels, paa);
|
ScopedUtfChars opPackageNameStr(env, opPackageName);
|
||||||
|
auto *ap = new SoundPool(maxChannels, paa, opPackageNameStr.c_str());
|
||||||
if (ap == nullptr) {
|
if (ap == nullptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -298,7 +300,7 @@ static JNINativeMethod gMethods[] = {
|
|||||||
(void *)android_media_SoundPool_setRate
|
(void *)android_media_SoundPool_setRate
|
||||||
},
|
},
|
||||||
{ "native_setup",
|
{ "native_setup",
|
||||||
"(Ljava/lang/Object;ILjava/lang/Object;)I",
|
"(Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I",
|
||||||
(void*)android_media_SoundPool_native_setup
|
(void*)android_media_SoundPool_native_setup
|
||||||
},
|
},
|
||||||
{ "native_release",
|
{ "native_release",
|
||||||
|
|||||||
Reference in New Issue
Block a user