Loading api/current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -24191,8 +24191,10 @@ package android.media { public final class AudioPlaybackCaptureConfiguration { method @NonNull public int[] getExcludeUids(); method @NonNull public int[] getExcludeUsages(); method @NonNull public int[] getExcludeUserIds(); method @NonNull public int[] getMatchingUids(); method @NonNull public int[] getMatchingUsages(); method @NonNull public int[] getMatchingUserIds(); method @NonNull public android.media.projection.MediaProjection getMediaProjection(); } Loading @@ -24200,9 +24202,11 @@ package android.media { ctor public AudioPlaybackCaptureConfiguration.Builder(@NonNull android.media.projection.MediaProjection); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUid(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUsage(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUserId(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration build(); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUid(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUsage(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUserId(int); } public final class AudioPlaybackConfiguration implements android.os.Parcelable { api/system-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -4367,6 +4367,7 @@ package android.media.audiopolicy { field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2 field public static final int RULE_MATCH_ATTRIBUTE_USAGE = 1; // 0x1 field public static final int RULE_MATCH_UID = 4; // 0x4 field public static final int RULE_MATCH_USERID = 8; // 0x8 } public static class AudioMixingRule.Builder { Loading @@ -4387,9 +4388,11 @@ package android.media.audiopolicy { method public int getFocusDuckingBehavior(); method public int getStatus(); method public boolean removeUidDeviceAffinity(int); method public boolean removeUserIdDeviceAffinity(int); method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; method public void setRegistration(String); method public boolean setUidDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public boolean setUserIdDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public String toLogFriendlyString(); field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0 field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0 Loading api/test-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -1397,6 +1397,7 @@ package android.media.audiopolicy { field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2 field public static final int RULE_MATCH_ATTRIBUTE_USAGE = 1; // 0x1 field public static final int RULE_MATCH_UID = 4; // 0x4 field public static final int RULE_MATCH_USERID = 8; // 0x8 } public static class AudioMixingRule.Builder { Loading @@ -1417,9 +1418,11 @@ package android.media.audiopolicy { method public int getFocusDuckingBehavior(); method public int getStatus(); method public boolean removeUidDeviceAffinity(int); method public boolean removeUserIdDeviceAffinity(int); method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; method public void setRegistration(String); method public boolean setUidDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public boolean setUserIdDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public String toLogFriendlyString(); field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0 field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0 Loading core/jni/android_media_AudioSystem.cpp +64 −32 Original line number Diff line number Diff line Loading @@ -307,6 +307,43 @@ static int _check_AudioSystem_Command(const char* caller, status_t status) return kAudioStatusError; } static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes, jobjectArray deviceAddresses, Vector<AudioDeviceTypeAddr> &audioDeviceTypeAddrVector) { if (deviceTypes == nullptr || deviceAddresses == nullptr) { return (jint)AUDIO_JAVA_BAD_VALUE; } jsize deviceCount = env->GetArrayLength(deviceTypes); if (deviceCount == 0 || deviceCount != env->GetArrayLength(deviceAddresses)) { return (jint)AUDIO_JAVA_BAD_VALUE; } // retrieve all device types std::vector<audio_devices_t> deviceTypesVector; jint *typesPtr = nullptr; typesPtr = env->GetIntArrayElements(deviceTypes, 0); if (typesPtr == nullptr) { return (jint)AUDIO_JAVA_BAD_VALUE; } for (jint i = 0; i < deviceCount; i++) { deviceTypesVector.push_back((audio_devices_t)typesPtr[i]); } // check each address is a string and add device type/address to list jclass stringClass = FindClassOrDie(env, "java/lang/String"); for (jint i = 0; i < deviceCount; i++) { jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i); if (!env->IsInstanceOf(addrJobj, stringClass)) { return (jint)AUDIO_JAVA_BAD_VALUE; } const char *address = env->GetStringUTFChars((jstring)addrJobj, NULL); AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address); audioDeviceTypeAddrVector.add(dev); env->ReleaseStringUTFChars((jstring)addrJobj, address); } env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0); return (jint)NO_ERROR; } static jint android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on) { Loading Loading @@ -1905,6 +1942,10 @@ static jint convertAudioMixToNative(JNIEnv *env, nCriterion.mValue.mUid = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); break; case RULE_MATCH_USERID: nCriterion.mValue.mUserId = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); break; case RULE_MATCH_ATTRIBUTE_USAGE: case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: { jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr); Loading Loading @@ -1990,39 +2031,11 @@ exit: static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz, jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) { if (deviceTypes == nullptr || deviceAddresses == nullptr) { return (jint) AUDIO_JAVA_BAD_VALUE; } jsize nb = env->GetArrayLength(deviceTypes); if (nb == 0 || nb != env->GetArrayLength(deviceAddresses)) { return (jint) AUDIO_JAVA_BAD_VALUE; } // retrieve all device types std::vector<audio_devices_t> deviceTypesVector; jint* typesPtr = nullptr; typesPtr = env->GetIntArrayElements(deviceTypes, 0); if (typesPtr == nullptr) { return (jint) AUDIO_JAVA_BAD_VALUE; } for (jint i = 0; i < nb; i++) { deviceTypesVector.push_back((audio_devices_t) typesPtr[i]); } // check each address is a string and add device type/address to list for device affinity Vector<AudioDeviceTypeAddr> deviceVector; jclass stringClass = FindClassOrDie(env, "java/lang/String"); for (jint i = 0; i < nb; i++) { jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i); if (!env->IsInstanceOf(addrJobj, stringClass)) { return (jint) AUDIO_JAVA_BAD_VALUE; } const char* address = env->GetStringUTFChars((jstring) addrJobj, NULL); AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address); deviceVector.add(dev); env->ReleaseStringUTFChars((jstring) addrJobj, address); jint results = getVectorOfAudioDeviceTypeAddr(env, deviceTypes, deviceAddresses, deviceVector); if (results != NO_ERROR) { return results; } env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0); status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector); return (jint) nativeToJavaStatus(status); } Loading @@ -2033,6 +2046,23 @@ static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, job return (jint) nativeToJavaStatus(status); } static jint android_media_AudioSystem_setUserIdDeviceAffinities(JNIEnv *env, jobject clazz, jint userId, jintArray deviceTypes, jobjectArray deviceAddresses) { Vector<AudioDeviceTypeAddr> deviceVector; jint results = getVectorOfAudioDeviceTypeAddr(env, deviceTypes, deviceAddresses, deviceVector); if (results != NO_ERROR) { return results; } status_t status = AudioSystem::setUserIdDeviceAffinities((int)userId, deviceVector); return (jint)nativeToJavaStatus(status); } static jint android_media_AudioSystem_removeUserIdDeviceAffinities(JNIEnv *env, jobject clazz, jint userId) { status_t status = AudioSystem::removeUserIdDeviceAffinities((int)userId); return (jint)nativeToJavaStatus(status); } static jint android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz) Loading Loading @@ -2463,7 +2493,9 @@ static const JNINativeMethod gMethods[] = { {"setPreferredDeviceForStrategy", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setPreferredDeviceForStrategy}, {"removePreferredDeviceForStrategy", "(I)I", (void *)android_media_AudioSystem_removePreferredDeviceForStrategy}, {"getPreferredDeviceForStrategy", "(I[Landroid/media/AudioDeviceAddress;)I", (void *)android_media_AudioSystem_getPreferredDeviceForStrategy}, {"getDevicesForAttributes", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAddress;)I", (void *)android_media_AudioSystem_getDevicesForAttributes} {"getDevicesForAttributes", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAddress;)I", (void *)android_media_AudioSystem_getDevicesForAttributes}, {"setUserIdDeviceAffinities", "(I[I[Ljava/lang/String;)I", (void *)android_media_AudioSystem_setUserIdDeviceAffinities}, {"removeUserIdDeviceAffinities", "(I)I", (void *)android_media_AudioSystem_removeUserIdDeviceAffinities} }; static const JNINativeMethod gEventHandlerMethods[] = { Loading media/java/android/media/AudioPlaybackCaptureConfiguration.java +48 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,12 @@ public final class AudioPlaybackCaptureConfiguration { criterion -> criterion.getIntProp()); } /** @return the userId's passed to {@link Builder#addMatchingUserId(int)}. */ public @NonNull int[] getMatchingUserIds() { return getIntPredicates(AudioMixingRule.RULE_MATCH_USERID, criterion -> criterion.getIntProp()); } /** @return the usages passed to {@link Builder#excludeUsage(int)}. */ @AttributeUsage public @NonNull int[] getExcludeUsages() { Loading @@ -115,6 +121,12 @@ public final class AudioPlaybackCaptureConfiguration { criterion -> criterion.getIntProp()); } /** @return the userId's passed to {@link Builder#excludeUserId(int)}. */ public @NonNull int[] getExcludeUserIds() { return getIntPredicates(AudioMixingRule.RULE_EXCLUDE_USERID, criterion -> criterion.getIntProp()); } private int[] getIntPredicates(int rule, ToIntFunction<AudioMixMatchCriterion> getPredicate) { return mAudioMixingRule.getCriteria().stream() Loading Loading @@ -153,6 +165,7 @@ public final class AudioPlaybackCaptureConfiguration { private final MediaProjection mProjection; private int mUsageMatchType = MATCH_TYPE_UNSPECIFIED; private int mUidMatchType = MATCH_TYPE_UNSPECIFIED; private int mUserIdMatchType = MATCH_TYPE_UNSPECIFIED; /** @param projection A MediaProjection that supports audio projection. */ public Builder(@NonNull MediaProjection projection) { Loading Loading @@ -201,6 +214,23 @@ public final class AudioPlaybackCaptureConfiguration { return this; } /** * Only capture audio output by app with the matching {@code userId}. * * <p>If called multiple times, will capture audio output by apps whose userId is any of the * given userId's. * * @throws IllegalStateException if called in conjunction with {@link #excludeUserId(int)}. */ public @NonNull Builder addMatchingUserId(int userId) { Preconditions.checkState( mUserIdMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_USERID, userId); mUserIdMatchType = MATCH_TYPE_INCLUSIVE; return this; } /** * Only capture audio output that does not match the given {@link AudioAttributes}. * Loading Loading @@ -237,6 +267,24 @@ public final class AudioPlaybackCaptureConfiguration { return this; } /** * Only capture audio output by apps that do not have the matching {@code userId}. * * <p>If called multiple times, will capture audio output by apps whose userId is not any of * the given userId's. * * @throws IllegalStateException if called in conjunction with * {@link #addMatchingUserId(int)}. */ public @NonNull Builder excludeUserId(int userId) { Preconditions.checkState( mUserIdMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.excludeMixRule(AudioMixingRule.RULE_MATCH_USERID, userId); mUserIdMatchType = MATCH_TYPE_EXCLUSIVE; return this; } /** * Builds the configuration instance. * Loading Loading
api/current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -24191,8 +24191,10 @@ package android.media { public final class AudioPlaybackCaptureConfiguration { method @NonNull public int[] getExcludeUids(); method @NonNull public int[] getExcludeUsages(); method @NonNull public int[] getExcludeUserIds(); method @NonNull public int[] getMatchingUids(); method @NonNull public int[] getMatchingUsages(); method @NonNull public int[] getMatchingUserIds(); method @NonNull public android.media.projection.MediaProjection getMediaProjection(); } Loading @@ -24200,9 +24202,11 @@ package android.media { ctor public AudioPlaybackCaptureConfiguration.Builder(@NonNull android.media.projection.MediaProjection); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUid(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUsage(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUserId(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration build(); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUid(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUsage(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUserId(int); } public final class AudioPlaybackConfiguration implements android.os.Parcelable {
api/system-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -4367,6 +4367,7 @@ package android.media.audiopolicy { field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2 field public static final int RULE_MATCH_ATTRIBUTE_USAGE = 1; // 0x1 field public static final int RULE_MATCH_UID = 4; // 0x4 field public static final int RULE_MATCH_USERID = 8; // 0x8 } public static class AudioMixingRule.Builder { Loading @@ -4387,9 +4388,11 @@ package android.media.audiopolicy { method public int getFocusDuckingBehavior(); method public int getStatus(); method public boolean removeUidDeviceAffinity(int); method public boolean removeUserIdDeviceAffinity(int); method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; method public void setRegistration(String); method public boolean setUidDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public boolean setUserIdDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public String toLogFriendlyString(); field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0 field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0 Loading
api/test-current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -1397,6 +1397,7 @@ package android.media.audiopolicy { field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2 field public static final int RULE_MATCH_ATTRIBUTE_USAGE = 1; // 0x1 field public static final int RULE_MATCH_UID = 4; // 0x4 field public static final int RULE_MATCH_USERID = 8; // 0x8 } public static class AudioMixingRule.Builder { Loading @@ -1417,9 +1418,11 @@ package android.media.audiopolicy { method public int getFocusDuckingBehavior(); method public int getStatus(); method public boolean removeUidDeviceAffinity(int); method public boolean removeUserIdDeviceAffinity(int); method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; method public void setRegistration(String); method public boolean setUidDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public boolean setUserIdDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public String toLogFriendlyString(); field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0 field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0 Loading
core/jni/android_media_AudioSystem.cpp +64 −32 Original line number Diff line number Diff line Loading @@ -307,6 +307,43 @@ static int _check_AudioSystem_Command(const char* caller, status_t status) return kAudioStatusError; } static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes, jobjectArray deviceAddresses, Vector<AudioDeviceTypeAddr> &audioDeviceTypeAddrVector) { if (deviceTypes == nullptr || deviceAddresses == nullptr) { return (jint)AUDIO_JAVA_BAD_VALUE; } jsize deviceCount = env->GetArrayLength(deviceTypes); if (deviceCount == 0 || deviceCount != env->GetArrayLength(deviceAddresses)) { return (jint)AUDIO_JAVA_BAD_VALUE; } // retrieve all device types std::vector<audio_devices_t> deviceTypesVector; jint *typesPtr = nullptr; typesPtr = env->GetIntArrayElements(deviceTypes, 0); if (typesPtr == nullptr) { return (jint)AUDIO_JAVA_BAD_VALUE; } for (jint i = 0; i < deviceCount; i++) { deviceTypesVector.push_back((audio_devices_t)typesPtr[i]); } // check each address is a string and add device type/address to list jclass stringClass = FindClassOrDie(env, "java/lang/String"); for (jint i = 0; i < deviceCount; i++) { jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i); if (!env->IsInstanceOf(addrJobj, stringClass)) { return (jint)AUDIO_JAVA_BAD_VALUE; } const char *address = env->GetStringUTFChars((jstring)addrJobj, NULL); AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address); audioDeviceTypeAddrVector.add(dev); env->ReleaseStringUTFChars((jstring)addrJobj, address); } env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0); return (jint)NO_ERROR; } static jint android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on) { Loading Loading @@ -1905,6 +1942,10 @@ static jint convertAudioMixToNative(JNIEnv *env, nCriterion.mValue.mUid = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); break; case RULE_MATCH_USERID: nCriterion.mValue.mUserId = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); break; case RULE_MATCH_ATTRIBUTE_USAGE: case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: { jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr); Loading Loading @@ -1990,39 +2031,11 @@ exit: static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz, jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) { if (deviceTypes == nullptr || deviceAddresses == nullptr) { return (jint) AUDIO_JAVA_BAD_VALUE; } jsize nb = env->GetArrayLength(deviceTypes); if (nb == 0 || nb != env->GetArrayLength(deviceAddresses)) { return (jint) AUDIO_JAVA_BAD_VALUE; } // retrieve all device types std::vector<audio_devices_t> deviceTypesVector; jint* typesPtr = nullptr; typesPtr = env->GetIntArrayElements(deviceTypes, 0); if (typesPtr == nullptr) { return (jint) AUDIO_JAVA_BAD_VALUE; } for (jint i = 0; i < nb; i++) { deviceTypesVector.push_back((audio_devices_t) typesPtr[i]); } // check each address is a string and add device type/address to list for device affinity Vector<AudioDeviceTypeAddr> deviceVector; jclass stringClass = FindClassOrDie(env, "java/lang/String"); for (jint i = 0; i < nb; i++) { jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i); if (!env->IsInstanceOf(addrJobj, stringClass)) { return (jint) AUDIO_JAVA_BAD_VALUE; } const char* address = env->GetStringUTFChars((jstring) addrJobj, NULL); AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address); deviceVector.add(dev); env->ReleaseStringUTFChars((jstring) addrJobj, address); jint results = getVectorOfAudioDeviceTypeAddr(env, deviceTypes, deviceAddresses, deviceVector); if (results != NO_ERROR) { return results; } env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0); status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector); return (jint) nativeToJavaStatus(status); } Loading @@ -2033,6 +2046,23 @@ static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, job return (jint) nativeToJavaStatus(status); } static jint android_media_AudioSystem_setUserIdDeviceAffinities(JNIEnv *env, jobject clazz, jint userId, jintArray deviceTypes, jobjectArray deviceAddresses) { Vector<AudioDeviceTypeAddr> deviceVector; jint results = getVectorOfAudioDeviceTypeAddr(env, deviceTypes, deviceAddresses, deviceVector); if (results != NO_ERROR) { return results; } status_t status = AudioSystem::setUserIdDeviceAffinities((int)userId, deviceVector); return (jint)nativeToJavaStatus(status); } static jint android_media_AudioSystem_removeUserIdDeviceAffinities(JNIEnv *env, jobject clazz, jint userId) { status_t status = AudioSystem::removeUserIdDeviceAffinities((int)userId); return (jint)nativeToJavaStatus(status); } static jint android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz) Loading Loading @@ -2463,7 +2493,9 @@ static const JNINativeMethod gMethods[] = { {"setPreferredDeviceForStrategy", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setPreferredDeviceForStrategy}, {"removePreferredDeviceForStrategy", "(I)I", (void *)android_media_AudioSystem_removePreferredDeviceForStrategy}, {"getPreferredDeviceForStrategy", "(I[Landroid/media/AudioDeviceAddress;)I", (void *)android_media_AudioSystem_getPreferredDeviceForStrategy}, {"getDevicesForAttributes", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAddress;)I", (void *)android_media_AudioSystem_getDevicesForAttributes} {"getDevicesForAttributes", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAddress;)I", (void *)android_media_AudioSystem_getDevicesForAttributes}, {"setUserIdDeviceAffinities", "(I[I[Ljava/lang/String;)I", (void *)android_media_AudioSystem_setUserIdDeviceAffinities}, {"removeUserIdDeviceAffinities", "(I)I", (void *)android_media_AudioSystem_removeUserIdDeviceAffinities} }; static const JNINativeMethod gEventHandlerMethods[] = { Loading
media/java/android/media/AudioPlaybackCaptureConfiguration.java +48 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,12 @@ public final class AudioPlaybackCaptureConfiguration { criterion -> criterion.getIntProp()); } /** @return the userId's passed to {@link Builder#addMatchingUserId(int)}. */ public @NonNull int[] getMatchingUserIds() { return getIntPredicates(AudioMixingRule.RULE_MATCH_USERID, criterion -> criterion.getIntProp()); } /** @return the usages passed to {@link Builder#excludeUsage(int)}. */ @AttributeUsage public @NonNull int[] getExcludeUsages() { Loading @@ -115,6 +121,12 @@ public final class AudioPlaybackCaptureConfiguration { criterion -> criterion.getIntProp()); } /** @return the userId's passed to {@link Builder#excludeUserId(int)}. */ public @NonNull int[] getExcludeUserIds() { return getIntPredicates(AudioMixingRule.RULE_EXCLUDE_USERID, criterion -> criterion.getIntProp()); } private int[] getIntPredicates(int rule, ToIntFunction<AudioMixMatchCriterion> getPredicate) { return mAudioMixingRule.getCriteria().stream() Loading Loading @@ -153,6 +165,7 @@ public final class AudioPlaybackCaptureConfiguration { private final MediaProjection mProjection; private int mUsageMatchType = MATCH_TYPE_UNSPECIFIED; private int mUidMatchType = MATCH_TYPE_UNSPECIFIED; private int mUserIdMatchType = MATCH_TYPE_UNSPECIFIED; /** @param projection A MediaProjection that supports audio projection. */ public Builder(@NonNull MediaProjection projection) { Loading Loading @@ -201,6 +214,23 @@ public final class AudioPlaybackCaptureConfiguration { return this; } /** * Only capture audio output by app with the matching {@code userId}. * * <p>If called multiple times, will capture audio output by apps whose userId is any of the * given userId's. * * @throws IllegalStateException if called in conjunction with {@link #excludeUserId(int)}. */ public @NonNull Builder addMatchingUserId(int userId) { Preconditions.checkState( mUserIdMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_USERID, userId); mUserIdMatchType = MATCH_TYPE_INCLUSIVE; return this; } /** * Only capture audio output that does not match the given {@link AudioAttributes}. * Loading Loading @@ -237,6 +267,24 @@ public final class AudioPlaybackCaptureConfiguration { return this; } /** * Only capture audio output by apps that do not have the matching {@code userId}. * * <p>If called multiple times, will capture audio output by apps whose userId is not any of * the given userId's. * * @throws IllegalStateException if called in conjunction with * {@link #addMatchingUserId(int)}. */ public @NonNull Builder excludeUserId(int userId) { Preconditions.checkState( mUserIdMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES); mAudioMixingRuleBuilder.excludeMixRule(AudioMixingRule.RULE_MATCH_USERID, userId); mUserIdMatchType = MATCH_TYPE_EXCLUSIVE; return this; } /** * Builds the configuration instance. * Loading