Add attributionTag to audio-recordings
... by switching from packageName/uid/pid to the Identity class.
This allows up to track which parts of the app trigger audio-recordings.
Test: atest CtsAppOpsTestCases
CtsNativeMediaAAudioTestCases
Fixes: 160150145
Change-Id: I0913a336a862e4a1cb38b9d967cfbdc490513ab0
This commit is contained in:
committed by
Nate Myren
parent
50f0175f3e
commit
fece2436d4
@@ -20565,6 +20565,7 @@ package android.media {
|
||||
method @NonNull public android.media.AudioRecord.Builder setAudioPlaybackCaptureConfig(@NonNull android.media.AudioPlaybackCaptureConfiguration);
|
||||
method public android.media.AudioRecord.Builder setAudioSource(int) throws java.lang.IllegalArgumentException;
|
||||
method public android.media.AudioRecord.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
|
||||
method @NonNull public android.media.AudioRecord.Builder setContext(@NonNull android.content.Context);
|
||||
method @NonNull public android.media.AudioRecord.Builder setPrivacySensitive(boolean);
|
||||
}
|
||||
|
||||
@@ -22739,7 +22740,8 @@ package android.media {
|
||||
}
|
||||
|
||||
public class MediaRecorder implements android.media.AudioRecordingMonitor android.media.AudioRouting android.media.MicrophoneDirection {
|
||||
ctor public MediaRecorder();
|
||||
ctor @Deprecated public MediaRecorder();
|
||||
ctor public MediaRecorder(@NonNull android.content.Context);
|
||||
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
|
||||
method protected void finalize();
|
||||
method public java.util.List<android.media.MicrophoneInfo> getActiveMicrophones() throws java.io.IOException;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["frameworks_base_core_jni_license"],
|
||||
}
|
||||
@@ -218,6 +217,7 @@ cc_library_shared {
|
||||
"fd_utils.cpp",
|
||||
"android_hardware_input_InputWindowHandle.cpp",
|
||||
"android_hardware_input_InputApplicationHandle.cpp",
|
||||
"permission_utils.cpp",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
@@ -236,6 +236,7 @@ cc_library_shared {
|
||||
"audioflinger-aidl-cpp",
|
||||
"av-types-aidl-cpp",
|
||||
"android.hardware.camera.device@3.2",
|
||||
"media_permission-aidl-cpp",
|
||||
"libandroidicu",
|
||||
"libbpf_android",
|
||||
"libnetdbpf",
|
||||
|
||||
@@ -97,6 +97,7 @@ extern int register_android_media_AudioVolumeGroupChangeHandler(JNIEnv *env);
|
||||
extern int register_android_media_MicrophoneInfo(JNIEnv *env);
|
||||
extern int register_android_media_ToneGenerator(JNIEnv *env);
|
||||
extern int register_android_media_midi(JNIEnv *env);
|
||||
extern int register_android_media_permission_Identity(JNIEnv* env);
|
||||
|
||||
namespace android {
|
||||
|
||||
@@ -1562,6 +1563,7 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_media_RemoteDisplay),
|
||||
REG_JNI(register_android_media_ToneGenerator),
|
||||
REG_JNI(register_android_media_midi),
|
||||
REG_JNI(register_android_media_permission_Identity),
|
||||
|
||||
REG_JNI(register_android_opengl_classes),
|
||||
REG_JNI(register_android_server_NetworkManagementSocketTagger),
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <jni.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include "core_jni_helpers.h"
|
||||
#include "permission_utils.h"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <media/AudioRecord.h>
|
||||
@@ -39,6 +40,9 @@
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using android::media::permission::convertIdentity;
|
||||
using android::media::permission::Identity;
|
||||
|
||||
using namespace android;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -181,12 +185,11 @@ static sp<AudioRecord> setAudioRecord(JNIEnv* env, jobject thiz, const sp<AudioR
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static jint
|
||||
android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||
jobject jaa, jintArray jSampleRate, jint channelMask, jint channelIndexMask,
|
||||
jint audioFormat, jint buffSizeInBytes, jintArray jSession, jstring opPackageName,
|
||||
jlong nativeRecordInJavaObj)
|
||||
{
|
||||
static jint android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||
jobject jaa, jintArray jSampleRate, jint channelMask,
|
||||
jint channelIndexMask, jint audioFormat,
|
||||
jint buffSizeInBytes, jintArray jSession,
|
||||
jobject jIdentity, jlong nativeRecordInJavaObj) {
|
||||
//ALOGV(">> Entering android_media_AudioRecord_setup");
|
||||
//ALOGV("sampleRate=%d, audioFormat=%d, channel mask=%x, buffSizeInBytes=%d "
|
||||
// "nativeRecordInJavaObj=0x%llX",
|
||||
@@ -262,10 +265,8 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||
size_t frameSize = channelCount * bytesPerSample;
|
||||
size_t frameCount = buffSizeInBytes / frameSize;
|
||||
|
||||
ScopedUtfChars opPackageNameStr(env, opPackageName);
|
||||
|
||||
// create an uninitialized AudioRecord object
|
||||
lpRecorder = new AudioRecord(String16(opPackageNameStr.c_str()));
|
||||
lpRecorder = new AudioRecord(convertIdentity(env, jIdentity));
|
||||
|
||||
// read the AudioAttributes values
|
||||
auto paa = JNIAudioAttributeHelper::makeUnique();
|
||||
@@ -373,8 +374,6 @@ native_init_failure:
|
||||
return (jint) AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static jint
|
||||
android_media_AudioRecord_start(JNIEnv *env, jobject thiz, jint event, jint triggerSession)
|
||||
@@ -893,9 +892,11 @@ static jint android_media_AudioRecord_get_port_id(JNIEnv *env, jobject thiz) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
// name, signature, funcPtr
|
||||
{"native_start", "(II)I", (void *)android_media_AudioRecord_start},
|
||||
{"native_stop", "()V", (void *)android_media_AudioRecord_stop},
|
||||
{"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILjava/lang/String;J)I",
|
||||
{"native_setup",
|
||||
"(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILandroid/media/permission/Identity;J)I",
|
||||
(void *)android_media_AudioRecord_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_AudioRecord_finalize},
|
||||
{"native_release", "()V", (void *)android_media_AudioRecord_release},
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
using namespace android;
|
||||
|
||||
using ::android::media::VolumeShaper;
|
||||
using ::android::media::permission::Identity;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static const char* const kClassPathName = "android/media/AudioTrack";
|
||||
@@ -328,7 +329,10 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we
|
||||
|
||||
// create the native AudioTrack object
|
||||
ScopedUtfChars opPackageNameStr(env, opPackageName);
|
||||
lpTrack = new AudioTrack(opPackageNameStr.c_str());
|
||||
// TODO b/182469354: make consistent with AudioRecord
|
||||
Identity identity = Identity();
|
||||
identity.packageName = std::string(opPackageNameStr.c_str());
|
||||
lpTrack = new AudioTrack(identity);
|
||||
|
||||
// read the AudioAttributes values
|
||||
auto paa = JNIAudioAttributeHelper::makeUnique();
|
||||
@@ -390,8 +394,8 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we
|
||||
sessionId, // audio session ID
|
||||
offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK
|
||||
: AudioTrack::TRANSFER_SYNC,
|
||||
(offload || encapsulationMode) ? &offloadInfo : NULL, -1,
|
||||
-1, // default uid, pid values
|
||||
(offload || encapsulationMode) ? &offloadInfo : NULL,
|
||||
Identity(), // default uid, pid values
|
||||
paa.get());
|
||||
break;
|
||||
|
||||
@@ -416,8 +420,8 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we
|
||||
true, // thread can call Java
|
||||
sessionId, // audio session ID
|
||||
AudioTrack::TRANSFER_SHARED,
|
||||
NULL, // default offloadInfo
|
||||
-1, -1, // default uid, pid values
|
||||
NULL, // default offloadInfo
|
||||
Identity(), // default uid, pid values
|
||||
paa.get());
|
||||
break;
|
||||
|
||||
|
||||
71
core/jni/permission_utils.cpp
Normal file
71
core/jni/permission_utils.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 "permission_utils.h"
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
static struct {
|
||||
jfieldID fieldUid; // Identity.uid
|
||||
jfieldID fieldPid; // Identity.pid
|
||||
jfieldID fieldPackageName; // Identity.packageName
|
||||
jfieldID fieldAttributionTag; // Identity.attributionTag
|
||||
} javaIdentityFields;
|
||||
|
||||
static const JNINativeMethod method_table[] = {
|
||||
// no static methods, currently
|
||||
};
|
||||
|
||||
int register_android_media_permission_Identity(JNIEnv* env) {
|
||||
jclass identityClass = android::FindClassOrDie(env, "android/media/permission/Identity");
|
||||
javaIdentityFields.fieldUid = android::GetFieldIDOrDie(env, identityClass, "uid", "I");
|
||||
javaIdentityFields.fieldPid = android::GetFieldIDOrDie(env, identityClass, "pid", "I");
|
||||
javaIdentityFields.fieldPackageName =
|
||||
android::GetFieldIDOrDie(env, identityClass, "packageName", "Ljava/lang/String;");
|
||||
javaIdentityFields.fieldAttributionTag =
|
||||
android::GetFieldIDOrDie(env, identityClass, "attributionTag", "Ljava/lang/String;");
|
||||
|
||||
return android::RegisterMethodsOrDie(env, "android/media/permission/Identity", method_table,
|
||||
NELEM(method_table));
|
||||
}
|
||||
|
||||
namespace android::media::permission {
|
||||
|
||||
Identity convertIdentity(JNIEnv* env, const jobject& jIdentity) {
|
||||
Identity identity;
|
||||
|
||||
identity.uid = env->GetIntField(jIdentity, javaIdentityFields.fieldUid);
|
||||
identity.pid = env->GetIntField(jIdentity, javaIdentityFields.fieldPid);
|
||||
|
||||
jstring packageNameStr = static_cast<jstring>(
|
||||
env->GetObjectField(jIdentity, javaIdentityFields.fieldPackageName));
|
||||
if (packageNameStr == nullptr) {
|
||||
identity.packageName = std::nullopt;
|
||||
} else {
|
||||
identity.packageName = std::string(ScopedUtfChars(env, packageNameStr).c_str());
|
||||
}
|
||||
|
||||
jstring attributionTagStr = static_cast<jstring>(
|
||||
env->GetObjectField(jIdentity, javaIdentityFields.fieldAttributionTag));
|
||||
if (attributionTagStr == nullptr) {
|
||||
identity.attributionTag = std::nullopt;
|
||||
} else {
|
||||
identity.attributionTag = std::string(ScopedUtfChars(env, attributionTagStr).c_str());
|
||||
}
|
||||
|
||||
return identity;
|
||||
}
|
||||
|
||||
} // namespace android::media::permission
|
||||
27
core/jni/permission_utils.h
Normal file
27
core/jni/permission_utils.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 <android/media/permission/Identity.h>
|
||||
#include <jni.h>
|
||||
|
||||
namespace android::media::permission {
|
||||
|
||||
Identity convertIdentity(JNIEnv* env, const jobject& jIdentity);
|
||||
}
|
||||
|
||||
int register_android_media_permission_Identity(JNIEnv* env);
|
||||
@@ -27,6 +27,9 @@ aidl_interface {
|
||||
aidl_interface {
|
||||
name: "media_permission-aidl",
|
||||
unstable: true,
|
||||
host_supported: true,
|
||||
vendor_available: true,
|
||||
double_loadable: true,
|
||||
local_include_dir: "aidl",
|
||||
srcs: [
|
||||
"aidl/android/media/permission/Identity.aidl",
|
||||
|
||||
@@ -22,11 +22,11 @@ package android.media.permission;
|
||||
*/
|
||||
parcelable Identity {
|
||||
/** Linux user ID. */
|
||||
int uid;
|
||||
int uid = -1;
|
||||
/** Linux process ID. */
|
||||
int pid;
|
||||
int pid = -1;
|
||||
/** Package name. If null, the first package owned by the given uid will be assumed. */
|
||||
@nullable String packageName;
|
||||
@nullable @utf8InCpp String packageName;
|
||||
/** Attribution tag. Mostly used for diagnostic purposes. */
|
||||
@nullable String attributionTag;
|
||||
@nullable @utf8InCpp String attributionTag;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.media;
|
||||
|
||||
import static android.media.permission.PermissionUtil.myIdentity;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.IntDef;
|
||||
@@ -26,9 +28,11 @@ import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.ActivityThread;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.media.MediaRecorder.Source;
|
||||
import android.media.audiopolicy.AudioMix;
|
||||
import android.media.audiopolicy.AudioPolicy;
|
||||
import android.media.permission.Identity;
|
||||
import android.media.projection.MediaProjection;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
@@ -54,6 +58,7 @@ import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@@ -352,6 +357,32 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
@RequiresPermission(android.Manifest.permission.RECORD_AUDIO)
|
||||
public AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
|
||||
int sessionId) throws IllegalArgumentException {
|
||||
this(attributes, format, bufferSizeInBytes, sessionId, ActivityThread.currentApplication());
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
|
||||
* @param attributes a non-null {@link AudioAttributes} instance. Use
|
||||
* {@link AudioAttributes.Builder#setCapturePreset(int)} for configuring the audio
|
||||
* source for this instance.
|
||||
* @param format a non-null {@link AudioFormat} instance describing the format of the data
|
||||
* that will be recorded through this AudioRecord. See {@link AudioFormat.Builder} for
|
||||
* configuring the audio format parameters such as encoding, channel mask and sample rate.
|
||||
* @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written
|
||||
* to during the recording. New audio data can be read from this buffer in smaller chunks
|
||||
* than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum
|
||||
* required buffer size for the successful creation of an AudioRecord instance. Using values
|
||||
* smaller than getMinBufferSize() will result in an initialization failure.
|
||||
* @param sessionId ID of audio session the AudioRecord must be attached to, or
|
||||
* {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction
|
||||
* time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before
|
||||
* construction.
|
||||
* @param context An optional context to pull an attribution tag from.
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
private AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
|
||||
int sessionId, @Nullable Context context) throws IllegalArgumentException {
|
||||
mRecordingState = RECORDSTATE_STOPPED;
|
||||
|
||||
if (attributes == null) {
|
||||
@@ -414,15 +445,21 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
|
||||
audioBuffSizeCheck(bufferSizeInBytes);
|
||||
|
||||
Identity identity = myIdentity(context);
|
||||
if (identity.packageName == null) {
|
||||
// Command line utility
|
||||
identity.packageName = "uid:" + Binder.getCallingUid();
|
||||
}
|
||||
|
||||
int[] sampleRate = new int[] {mSampleRate};
|
||||
int[] session = new int[1];
|
||||
session[0] = sessionId;
|
||||
//TODO: update native initialization when information about hardware init failure
|
||||
// due to capture device already open is available.
|
||||
int initResult = native_setup( new WeakReference<AudioRecord>(this),
|
||||
int initResult = native_setup(new WeakReference<AudioRecord>(this),
|
||||
mAudioAttributes, sampleRate, mChannelMask, mChannelIndexMask,
|
||||
mAudioFormat, mNativeBufferSizeInBytes,
|
||||
session, getCurrentOpPackageName(), 0 /*nativeRecordInJavaObj*/);
|
||||
session, identity, 0 /*nativeRecordInJavaObj*/);
|
||||
if (initResult != SUCCESS) {
|
||||
loge("Error code "+initResult+" when initializing native AudioRecord object.");
|
||||
return; // with mState == STATE_UNINITIALIZED
|
||||
@@ -434,15 +471,6 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
mState = STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
private String getCurrentOpPackageName() {
|
||||
String opPackageName = ActivityThread.currentOpPackageName();
|
||||
if (opPackageName != null) {
|
||||
return opPackageName;
|
||||
}
|
||||
// Command line utility
|
||||
return "uid:" + Binder.getCallingUid();
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor which explicitly connects a Native (C++) AudioRecord. For use by
|
||||
* the AudioRecordRoutingProxy subclass.
|
||||
@@ -492,7 +520,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
0 /*mAudioFormat*/,
|
||||
0 /*mNativeBufferSizeInBytes*/,
|
||||
session,
|
||||
ActivityThread.currentOpPackageName(),
|
||||
myIdentity(null),
|
||||
nativeRecordInJavaObj);
|
||||
if (initResult != SUCCESS) {
|
||||
loge("Error code "+initResult+" when initializing native AudioRecord object.");
|
||||
@@ -548,6 +576,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
private AudioPlaybackCaptureConfiguration mAudioPlaybackCaptureConfiguration;
|
||||
private AudioAttributes mAttributes;
|
||||
private AudioFormat mFormat;
|
||||
private Context mContext;
|
||||
private int mBufferSizeInBytes;
|
||||
private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
|
||||
private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
|
||||
@@ -582,6 +611,18 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the context the record belongs to.
|
||||
* @param context a non-null {@link Context} instance
|
||||
* @return the same Builder instance.
|
||||
*/
|
||||
public @NonNull Builder setContext(@NonNull Context context) {
|
||||
Objects.requireNonNull(context);
|
||||
// keep reference, we only copy the data when building
|
||||
mContext = context;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* To be only used by system components. Allows specifying non-public capture presets
|
||||
@@ -793,7 +834,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
* mFormat.getBytesPerSample(mFormat.getEncoding());
|
||||
}
|
||||
final AudioRecord record = new AudioRecord(
|
||||
mAttributes, mFormat, mBufferSizeInBytes, mSessionId);
|
||||
mAttributes, mFormat, mBufferSizeInBytes, mSessionId, mContext);
|
||||
if (record.getState() == STATE_UNINITIALIZED) {
|
||||
// release is not necessary
|
||||
throw new UnsupportedOperationException("Cannot create AudioRecord");
|
||||
@@ -2035,15 +2076,32 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
|
||||
// Native methods called from the Java side
|
||||
//--------------------
|
||||
|
||||
@UnsupportedAppUsage
|
||||
private native final int native_setup(Object audiorecord_this,
|
||||
/**
|
||||
* @deprecated Use native_setup that takes an Identity object
|
||||
* @return
|
||||
*/
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
|
||||
publicAlternatives = "{@code AudioRecord.Builder}")
|
||||
@Deprecated
|
||||
private int native_setup(Object audiorecordThis,
|
||||
Object /*AudioAttributes*/ attributes,
|
||||
int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
|
||||
int buffSizeInBytes, int[] sessionId, String opPackageName,
|
||||
long nativeRecordInJavaObj);
|
||||
long nativeRecordInJavaObj) {
|
||||
Identity identity = myIdentity(null);
|
||||
identity.packageName = opPackageName;
|
||||
|
||||
return native_setup(audiorecordThis, attributes, sampleRate, channelMask, channelIndexMask,
|
||||
audioFormat, buffSizeInBytes, sessionId, identity, nativeRecordInJavaObj);
|
||||
}
|
||||
|
||||
private native int native_setup(Object audiorecordThis,
|
||||
Object /*AudioAttributes*/ attributes,
|
||||
int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
|
||||
int buffSizeInBytes, int[] sessionId, Identity identity, long nativeRecordInJavaObj);
|
||||
|
||||
// TODO remove: implementation calls directly into implementation of native_release()
|
||||
private native final void native_finalize();
|
||||
private native void native_finalize();
|
||||
|
||||
/**
|
||||
* @hide
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.media;
|
||||
|
||||
import static android.Manifest.permission.BIND_IMS_SERVICE;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.media.permission.PermissionUtil.myIdentity;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.IntDef;
|
||||
@@ -34,6 +35,7 @@ import android.content.res.AssetFileDescriptor;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.media.SubtitleController.Anchor;
|
||||
import android.media.SubtitleTrack.RenderingWidget;
|
||||
import android.media.permission.Identity;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@@ -53,6 +55,7 @@ import android.provider.Settings;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.system.OsConstants;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
@@ -684,11 +687,14 @@ public class MediaPlayer extends PlayerBase
|
||||
mTimeProvider = new TimeProvider(this);
|
||||
mOpenSubtitleSources = new Vector<InputStream>();
|
||||
|
||||
Identity identity = myIdentity(null);
|
||||
// set the package name to empty if it was null
|
||||
identity.packageName = TextUtils.emptyIfNull(identity.packageName);
|
||||
|
||||
/* Native setup requires a weak reference to our object.
|
||||
* It's easier to create it here than in C++.
|
||||
*/
|
||||
native_setup(new WeakReference<MediaPlayer>(this),
|
||||
getCurrentOpPackageName());
|
||||
native_setup(new WeakReference<MediaPlayer>(this), identity);
|
||||
|
||||
baseRegisterPlayer(sessionId);
|
||||
}
|
||||
@@ -2471,7 +2477,7 @@ public class MediaPlayer extends PlayerBase
|
||||
private native final int native_setMetadataFilter(Parcel request);
|
||||
|
||||
private static native final void native_init();
|
||||
private native void native_setup(Object mediaplayerThis, @NonNull String opPackageName);
|
||||
private native void native_setup(Object mediaplayerThis, @NonNull Identity identity);
|
||||
private native final void native_finalize();
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.media;
|
||||
|
||||
import static android.media.permission.PermissionUtil.myIdentity;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.IntDef;
|
||||
@@ -25,7 +27,9 @@ import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.app.ActivityThread;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.hardware.Camera;
|
||||
import android.media.permission.Identity;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -48,6 +52,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@@ -127,9 +132,21 @@ public class MediaRecorder implements AudioRouting,
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
* @deprecated Use {@link #MediaRecorder(Context)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public MediaRecorder() {
|
||||
this(ActivityThread.currentApplication());
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
* @param context Context the recorder belongs to
|
||||
*/
|
||||
public MediaRecorder(@NonNull Context context) {
|
||||
Objects.requireNonNull(context);
|
||||
Looper looper;
|
||||
if ((looper = Looper.myLooper()) != null) {
|
||||
mEventHandler = new EventHandler(this, looper);
|
||||
@@ -140,12 +157,11 @@ public class MediaRecorder implements AudioRouting,
|
||||
}
|
||||
|
||||
mChannelCount = 1;
|
||||
String packageName = ActivityThread.currentPackageName();
|
||||
/* Native setup requires a weak reference to our object.
|
||||
* It's easier to create it here than in C++.
|
||||
*/
|
||||
native_setup(new WeakReference<MediaRecorder>(this), packageName,
|
||||
ActivityThread.currentOpPackageName());
|
||||
native_setup(new WeakReference<MediaRecorder>(this),
|
||||
ActivityThread.currentPackageName(), myIdentity(context));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1740,12 +1756,22 @@ public class MediaRecorder implements AudioRouting,
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
private static native final void native_init();
|
||||
|
||||
@UnsupportedAppUsage
|
||||
private native final void native_setup(Object mediarecorder_this,
|
||||
String clientName, String opPackageName) throws IllegalStateException;
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
|
||||
publicAlternatives = "{@link MediaRecorder}")
|
||||
private void native_setup(Object mediarecorderThis,
|
||||
String clientName, String opPackageName) throws IllegalStateException {
|
||||
Identity identity = myIdentity(null);
|
||||
identity.packageName = opPackageName;
|
||||
|
||||
native_setup(mediarecorderThis, clientName, identity);
|
||||
}
|
||||
|
||||
private native void native_setup(Object mediarecorderThis,
|
||||
String clientName, Identity identity)
|
||||
throws IllegalStateException;
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
private native final void native_finalize();
|
||||
private native void native_finalize();
|
||||
|
||||
@UnsupportedAppUsage
|
||||
private native void setParameter(String nameValuePair);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.media.audiofx;
|
||||
|
||||
import static android.media.permission.PermissionUtil.myIdentity;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
@@ -23,11 +25,11 @@ import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.ActivityThread;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.media.AudioDeviceAttributes;
|
||||
import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.permission.Identity;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -515,10 +517,11 @@ public class AudioEffect {
|
||||
}
|
||||
|
||||
// native initialization
|
||||
// TODO b/182469354: Make consistent with AudioRecord
|
||||
int initResult = native_setup(new WeakReference<AudioEffect>(this),
|
||||
type.toString(), uuid.toString(), priority, audioSession,
|
||||
deviceType, deviceAddress,
|
||||
id, desc, ActivityThread.currentOpPackageName(), probe);
|
||||
id, desc, myIdentity(null), probe);
|
||||
if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
|
||||
Log.e(TAG, "Error code " + initResult
|
||||
+ " when initializing AudioEffect.");
|
||||
@@ -1385,7 +1388,7 @@ public class AudioEffect {
|
||||
private native final int native_setup(Object audioeffect_this, String type,
|
||||
String uuid, int priority, int audioSession,
|
||||
int deviceType, String deviceAddress, int[] id, Object[] desc,
|
||||
String opPackageName, boolean probe);
|
||||
Identity identity, boolean probe);
|
||||
|
||||
private native final void native_finalize();
|
||||
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package android.media.audiofx;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import static android.media.permission.PermissionUtil.myIdentity;
|
||||
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.media.permission.Identity;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
@@ -217,9 +219,11 @@ public class Visualizer {
|
||||
|
||||
synchronized (mStateLock) {
|
||||
mState = STATE_UNINITIALIZED;
|
||||
|
||||
// native initialization
|
||||
// TODO b/182469354: make consistent with AudioRecord
|
||||
int result = native_setup(new WeakReference<Visualizer>(this), audioSession, id,
|
||||
ActivityThread.currentOpPackageName());
|
||||
myIdentity(null));
|
||||
if (result != SUCCESS && result != ALREADY_EXISTS) {
|
||||
Log.e(TAG, "Error code "+result+" when initializing Visualizer.");
|
||||
switch (result) {
|
||||
@@ -686,7 +690,7 @@ public class Visualizer {
|
||||
private native final int native_setup(Object audioeffect_this,
|
||||
int audioSession,
|
||||
int[] id,
|
||||
String opPackageName);
|
||||
Identity identity);
|
||||
|
||||
@GuardedBy("mStateLock")
|
||||
private native final void native_finalize();
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
package android.media.permission;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityThread;
|
||||
import android.content.Context;
|
||||
import android.content.PermissionChecker;
|
||||
import android.os.Binder;
|
||||
import android.os.Process;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -48,6 +51,25 @@ import java.util.Objects;
|
||||
* @hide
|
||||
*/
|
||||
public class PermissionUtil {
|
||||
/**
|
||||
* Create an identity for the current process and the passed context.
|
||||
*
|
||||
* @param context The process the identity is for. If {@code null}, the process's default
|
||||
* identity is chosen.
|
||||
* @return The identity for the current process and context
|
||||
*/
|
||||
public static @NonNull Identity myIdentity(@Nullable Context context) {
|
||||
Identity identity = new Identity();
|
||||
|
||||
identity.pid = Process.myPid();
|
||||
identity.uid = Process.myUid();
|
||||
identity.packageName = context != null ? context.getOpPackageName()
|
||||
: ActivityThread.currentOpPackageName();
|
||||
identity.attributionTag = context != null ? context.getAttributionTag() : null;
|
||||
|
||||
return identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate an originator, where the binder call is coming from a middleman.
|
||||
*
|
||||
|
||||
@@ -84,6 +84,7 @@ cc_library_shared {
|
||||
"android.hardware.drm@1.4",
|
||||
"android.hidl.memory@1.0",
|
||||
"android.hidl.token@1.0-utils",
|
||||
"media_permission-aidl-cpp",
|
||||
],
|
||||
|
||||
header_libs: [
|
||||
@@ -182,7 +183,7 @@ cc_library_shared {
|
||||
"libnativehelper",
|
||||
"libutils",
|
||||
"tv_tuner_aidl_interface-ndk_platform",
|
||||
"tv_tuner_resource_manager_aidl_interface-ndk_platform"
|
||||
"tv_tuner_resource_manager_aidl_interface-ndk_platform",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
@@ -212,4 +213,3 @@ cc_library_shared {
|
||||
"-Wunreachable-code",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "MediaPlayer-JNI"
|
||||
#include "permission_utils.h"
|
||||
#include "utils/Log.h"
|
||||
|
||||
#include <media/mediaplayer.h>
|
||||
@@ -79,6 +80,8 @@ static StateExceptionFields gStateExceptionFields;
|
||||
using namespace android;
|
||||
|
||||
using media::VolumeShaper;
|
||||
using media::permission::Identity;
|
||||
using media::permission::convertIdentity;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -946,11 +949,11 @@ android_media_MediaPlayer_native_init(JNIEnv *env)
|
||||
|
||||
static void
|
||||
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||
jstring opPackageName)
|
||||
jobject jIdentity)
|
||||
{
|
||||
ALOGV("native_setup");
|
||||
ScopedUtfChars opPackageNameStr(env, opPackageName);
|
||||
sp<MediaPlayer> mp = new MediaPlayer(opPackageNameStr.c_str());
|
||||
|
||||
sp<MediaPlayer> mp = new MediaPlayer(convertIdentity(env, jIdentity));
|
||||
if (mp == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
|
||||
return;
|
||||
@@ -1406,7 +1409,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
|
||||
{"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
|
||||
{"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
|
||||
{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;)V",(void *)android_media_MediaPlayer_native_setup},
|
||||
{"native_setup", "(Ljava/lang/Object;Landroid/media/permission/Identity;)V",(void *)android_media_MediaPlayer_native_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
|
||||
{"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
|
||||
{"native_setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "MediaRecorderJNI"
|
||||
#include "permission_utils.h"
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <gui/Surface.h>
|
||||
@@ -50,6 +51,8 @@
|
||||
|
||||
using namespace android;
|
||||
|
||||
using android::media::permission::convertIdentity;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// helper function to extract a native Camera object from a Camera Java object
|
||||
@@ -617,13 +620,12 @@ android_media_MediaRecorder_native_init(JNIEnv *env)
|
||||
|
||||
static void
|
||||
android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||
jstring packageName, jstring opPackageName)
|
||||
jstring packageName, jobject jIdentity)
|
||||
{
|
||||
ALOGV("setup");
|
||||
|
||||
ScopedUtfChars opPackageNameStr(env, opPackageName);
|
||||
sp<MediaRecorder> mr = new MediaRecorder(convertIdentity(env, jIdentity));
|
||||
|
||||
sp<MediaRecorder> mr = new MediaRecorder(String16(opPackageNameStr.c_str()));
|
||||
if (mr == NULL) {
|
||||
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
|
||||
return;
|
||||
@@ -869,7 +871,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},
|
||||
{"release", "()V", (void *)android_media_MediaRecorder_release},
|
||||
{"native_init", "()V", (void *)android_media_MediaRecorder_native_init},
|
||||
{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Landroid/media/permission/Identity;)V",
|
||||
(void *)android_media_MediaRecorder_native_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
|
||||
{"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface },
|
||||
|
||||
@@ -27,6 +27,11 @@ cc_library_shared {
|
||||
"libaudioclient",
|
||||
"libaudioutils",
|
||||
"libaudiofoundation",
|
||||
"media_permission-aidl-cpp",
|
||||
],
|
||||
|
||||
export_shared_lib_headers: [
|
||||
"media_permission-aidl-cpp",
|
||||
],
|
||||
|
||||
version_script: "exports.lds",
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace android {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Visualizer::Visualizer (const String16& opPackageName)
|
||||
: AudioEffect(opPackageName)
|
||||
Visualizer::Visualizer (const Identity& identity)
|
||||
: AudioEffect(identity)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include <media/AudioEffect.h>
|
||||
#include <system/audio_effects/effect_visualizer.h>
|
||||
#include <utils/Thread.h>
|
||||
#include "android/media/permission/Identity.h"
|
||||
|
||||
using namespace android::media::permission;
|
||||
|
||||
/**
|
||||
* The Visualizer class enables application to retrieve part of the currently playing audio for
|
||||
@@ -65,7 +68,7 @@ public:
|
||||
/* Constructor.
|
||||
* See AudioEffect constructor for details on parameters.
|
||||
*/
|
||||
explicit Visualizer(const String16& opPackageName);
|
||||
explicit Visualizer(const Identity& identity);
|
||||
|
||||
~Visualizer();
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include "media/AudioEffect.h"
|
||||
#include "permission_utils.h"
|
||||
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
|
||||
@@ -34,6 +35,8 @@
|
||||
|
||||
using namespace android;
|
||||
|
||||
using media::permission::convertIdentity;
|
||||
|
||||
#define AUDIOEFFECT_SUCCESS 0
|
||||
#define AUDIOEFFECT_ERROR (-1)
|
||||
#define AUDIOEFFECT_ERROR_ALREADY_EXISTS (-2)
|
||||
@@ -270,7 +273,7 @@ static jint
|
||||
android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||
jstring type, jstring uuid, jint priority, jint sessionId,
|
||||
jint deviceType, jstring deviceAddress,
|
||||
jintArray jId, jobjectArray javadesc, jstring opPackageName, jboolean probe)
|
||||
jintArray jId, jobjectArray javadesc, jobject jIdentity, jboolean probe)
|
||||
{
|
||||
ALOGV("android_media_AudioEffect_native_setup");
|
||||
AudioEffectJniStorage* lpJniStorage = NULL;
|
||||
@@ -283,8 +286,6 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
|
||||
jobject jdesc;
|
||||
AudioDeviceTypeAddr device;
|
||||
|
||||
ScopedUtfChars opPackageNameStr(env, opPackageName);
|
||||
|
||||
setAudioEffect(env, thiz, 0);
|
||||
|
||||
if (type != NULL) {
|
||||
@@ -337,7 +338,7 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
|
||||
}
|
||||
|
||||
// create the native AudioEffect object
|
||||
lpAudioEffect = new AudioEffect(String16(opPackageNameStr.c_str()));
|
||||
lpAudioEffect = new AudioEffect(convertIdentity(env, jIdentity));
|
||||
if (lpAudioEffect == 0) {
|
||||
ALOGE("Error creating AudioEffect");
|
||||
goto setup_failure;
|
||||
@@ -773,7 +774,7 @@ android_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz _
|
||||
// Dalvik VM type signatures
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{"native_init", "()V", (void *)android_media_AudioEffect_native_init},
|
||||
{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Ljava/lang/String;Z)I",
|
||||
{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Landroid/media/permission/Identity;Z)I",
|
||||
(void *)android_media_AudioEffect_native_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_AudioEffect_native_finalize},
|
||||
{"native_release", "()V", (void *)android_media_AudioEffect_native_release},
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <utils/threads.h>
|
||||
#include "Visualizer.h"
|
||||
#include "permission_utils.h"
|
||||
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
|
||||
@@ -347,7 +348,7 @@ static void android_media_visualizer_effect_callback(int32_t event,
|
||||
|
||||
static jint
|
||||
android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
|
||||
jint sessionId, jintArray jId, jstring opPackageName)
|
||||
jint sessionId, jintArray jId, jobject jIdentity)
|
||||
{
|
||||
ALOGV("android_media_visualizer_native_setup");
|
||||
VisualizerJniStorage* lpJniStorage = NULL;
|
||||
@@ -355,8 +356,6 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
|
||||
sp<Visualizer> lpVisualizer;
|
||||
jint* nId = NULL;
|
||||
|
||||
ScopedUtfChars opPackageNameStr(env, opPackageName);
|
||||
|
||||
setVisualizer(env, thiz, 0);
|
||||
|
||||
lpJniStorage = new VisualizerJniStorage();
|
||||
@@ -382,7 +381,7 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
|
||||
}
|
||||
|
||||
// create the native Visualizer object
|
||||
lpVisualizer = new Visualizer(String16(opPackageNameStr.c_str()));
|
||||
lpVisualizer = new Visualizer(convertIdentity(env, jIdentity));
|
||||
if (lpVisualizer == 0) {
|
||||
ALOGE("Error creating Visualizer");
|
||||
goto setup_failure;
|
||||
@@ -679,7 +678,7 @@ android_media_setPeriodicCapture(JNIEnv *env, jobject thiz, jint rate, jboolean
|
||||
// Dalvik VM type signatures
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{"native_init", "()V", (void *)android_media_visualizer_native_init},
|
||||
{"native_setup", "(Ljava/lang/Object;I[ILjava/lang/String;)I",
|
||||
{"native_setup", "(Ljava/lang/Object;I[ILandroid/media/permission/Identity;)I",
|
||||
(void *)android_media_visualizer_native_setup},
|
||||
{"native_finalize", "()V", (void *)android_media_visualizer_native_finalize},
|
||||
{"native_release", "()V", (void *)android_media_visualizer_native_release},
|
||||
|
||||
@@ -63,7 +63,7 @@ tidy_errors = [
|
||||
|
||||
// Remove some pedantic stylistic requirements.
|
||||
"-google-readability-casting", // C++ casts not always necessary and may be verbose
|
||||
"-google-readability-todo", // do not require TODO(info)
|
||||
"-google-readability-todo", // do not require TODO(info)
|
||||
"-google-build-using-namespace", // Reenable and fix later.
|
||||
|
||||
"-google-explicit-constructor", // found in StreamManager.h
|
||||
@@ -100,7 +100,7 @@ cc_defaults {
|
||||
tidy_checks: tidy_errors,
|
||||
tidy_checks_as_errors: tidy_errors,
|
||||
tidy_flags: [
|
||||
"-format-style=file",
|
||||
"-format-style=file",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -135,6 +135,7 @@ cc_library_shared {
|
||||
"libaudioclient",
|
||||
"libmediandk",
|
||||
"libbinder",
|
||||
"media_permission-aidl-cpp",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "SoundPool::Stream"
|
||||
#include <utils/Log.h>
|
||||
#include<android/media/permission/Identity.h>
|
||||
|
||||
#include "Stream.h"
|
||||
|
||||
@@ -24,6 +25,8 @@
|
||||
|
||||
namespace android::soundpool {
|
||||
|
||||
using media::permission::Identity;
|
||||
|
||||
Stream::~Stream()
|
||||
{
|
||||
ALOGV("%s(%p)", __func__, this);
|
||||
@@ -326,15 +329,17 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID,
|
||||
|
||||
// do not create a new audio track if current track is compatible with sound parameters
|
||||
|
||||
Identity identity = Identity();
|
||||
identity.packageName = mStreamManager->getOpPackageName();
|
||||
// TODO b/182469354 make consistent with AudioRecord, add util for native source
|
||||
newTrack = new AudioTrack(streamType, sampleRate, sound->getFormat(),
|
||||
channelMask, sound->getIMemory(), AUDIO_OUTPUT_FLAG_FAST,
|
||||
staticCallback, userData,
|
||||
0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
|
||||
AudioTrack::TRANSFER_DEFAULT,
|
||||
nullptr /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/,
|
||||
nullptr /*offloadInfo*/, identity,
|
||||
mStreamManager->getAttributes(),
|
||||
false /*doNotReconnect*/, 1.0f /*maxRequiredSpeed*/,
|
||||
mStreamManager->getOpPackageName());
|
||||
false /*doNotReconnect*/, 1.0f /*maxRequiredSpeed*/);
|
||||
// Set caller name so it can be logged in destructor.
|
||||
// MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_SOUNDPOOL
|
||||
newTrack->setCallerName("soundpool");
|
||||
|
||||
Reference in New Issue
Block a user