summaryrefslogtreecommitdiff
path: root/media/java
diff options
context:
space:
mode:
authorBrian Orr <brianorr@google.com>2021-06-15 12:47:53 -0700
committerDaniel Norman <danielnorman@google.com>2021-06-17 13:37:54 -0700
commit71c831703ae59baf47e0afe611fecd714c481cdf (patch)
tree06731a987032723085b9e1a65951cf96abbc19cf /media/java
parent065c9e9a6e9d61d4383a91721eb56a3de253bdbe (diff)
parent81833820d54b9a6b27894f9f8dfd72222d416992 (diff)
Merge SP1A.210604.001
Change-Id: I5200ee05285ae422d5e9c1c00f45709a5d6188be
Diffstat (limited to 'media/java')
-rw-r--r--media/java/android/media/AudioManager.java9
-rw-r--r--media/java/android/media/AudioRecord.java85
-rw-r--r--media/java/android/media/MediaPlayer.java18
-rw-r--r--media/java/android/media/MediaRecorder.java24
-rw-r--r--media/java/android/media/MediaServiceManager.java16
-rw-r--r--media/java/android/media/Ringtone.java8
-rw-r--r--media/java/android/media/audiofx/AudioEffect.java18
-rw-r--r--media/java/android/media/audiofx/Visualizer.java17
-rw-r--r--media/java/android/media/permission/PermissionUtil.java18
9 files changed, 108 insertions, 105 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1cc73a6a8e1d..98f066057c9f 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -7123,7 +7123,14 @@ public class AudioManager {
}
/**
- * Set a certain surround format as enabled or not.
+ * Sets and persists a certain surround format as enabled or not.
+ * <p>
+ * This API is called by TvSettings surround sound menu when user enables or disables a
+ * surround sound format. This setting is persisted as global user setting.
+ * Applications should revert their changes to surround sound settings unless they intend to
+ * modify the global user settings across all apps. The framework does not auto-revert an
+ * application's settings after a lifecycle event. Audio focus is not required to apply these
+ * settings.
*
* @param enabled the required surround format state, true for enabled, false for disabled
* @return true if successful, otherwise false
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index de99dde471a1..2315b2d4c957 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -16,8 +16,6 @@
package android.media;
-import static android.media.permission.PermissionUtil.myIdentity;
-
import android.annotation.CallbackExecutor;
import android.annotation.FloatRange;
import android.annotation.IntDef;
@@ -29,12 +27,13 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
import android.content.Context;
import android.media.MediaRecorder.Source;
import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioPolicy;
import android.media.metrics.LogSessionId;
-import android.media.permission.Identity;
import android.media.projection.MediaProjection;
import android.os.Binder;
import android.os.Build;
@@ -42,6 +41,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.Parcel;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -381,7 +381,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
* {@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.
+ * @param context An optional context on whose behalf the recoding is performed.
+ *
* @throws IllegalArgumentException
*/
private AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
@@ -449,10 +450,11 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
audioBuffSizeCheck(bufferSizeInBytes);
- Identity identity = myIdentity(context);
- if (identity.packageName == null) {
+ AttributionSource attributionSource = (context != null)
+ ? context.getAttributionSource() : AttributionSource.myAttributionSource();
+ if (attributionSource.getPackageName() == null) {
// Command line utility
- identity.packageName = "uid:" + Binder.getCallingUid();
+ attributionSource = attributionSource.withPackageName("uid:" + Binder.getCallingUid());
}
int[] sampleRate = new int[] {mSampleRate};
@@ -461,14 +463,15 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
//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),
- mAudioAttributes, sampleRate, mChannelMask, mChannelIndexMask,
- mAudioFormat, mNativeBufferSizeInBytes,
- session, identity, 0 /*nativeRecordInJavaObj*/,
- maxSharedAudioHistoryMs);
- if (initResult != SUCCESS) {
- loge("Error code "+initResult+" when initializing native AudioRecord object.");
- return; // with mState == STATE_UNINITIALIZED
+ try (ScopedParcelState attributionSourceState = attributionSource.asScopedParcelState()) {
+ int initResult = native_setup(new WeakReference<AudioRecord>(this), mAudioAttributes,
+ sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
+ mNativeBufferSizeInBytes, session, attributionSourceState.getParcel(),
+ 0 /*nativeRecordInJavaObj*/, maxSharedAudioHistoryMs);
+ if (initResult != SUCCESS) {
+ loge("Error code " + initResult + " when initializing native AudioRecord object.");
+ return; // with mState == STATE_UNINITIALIZED
+ }
}
mSampleRate = sampleRate[0];
@@ -512,23 +515,27 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
*/
/* package */ void deferred_connect(long nativeRecordInJavaObj) {
if (mState != STATE_INITIALIZED) {
- int[] session = { 0 };
- int[] rates = { 0 };
+ int[] session = {0};
+ int[] rates = {0};
//TODO: update native initialization when information about hardware init failure
// due to capture device already open is available.
// Note that for this native_setup, we are providing an already created/initialized
// *Native* AudioRecord, so the attributes parameters to native_setup() are ignored.
- int initResult = native_setup(new WeakReference<AudioRecord>(this),
- null /*mAudioAttributes*/,
- rates /*mSampleRates*/,
- 0 /*mChannelMask*/,
- 0 /*mChannelIndexMask*/,
- 0 /*mAudioFormat*/,
- 0 /*mNativeBufferSizeInBytes*/,
- session,
- myIdentity(null),
- nativeRecordInJavaObj,
- 0);
+ final int initResult;
+ try (ScopedParcelState attributionSourceState = AttributionSource.myAttributionSource()
+ .asScopedParcelState()) {
+ initResult = native_setup(new WeakReference<>(this),
+ null /*mAudioAttributes*/,
+ rates /*mSampleRates*/,
+ 0 /*mChannelMask*/,
+ 0 /*mChannelIndexMask*/,
+ 0 /*mAudioFormat*/,
+ 0 /*mNativeBufferSizeInBytes*/,
+ session,
+ attributionSourceState.getParcel(),
+ nativeRecordInJavaObj,
+ 0);
+ }
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing native AudioRecord object.");
return; // with mState == STATE_UNINITIALIZED
@@ -620,8 +627,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
/**
* Sets the context the record belongs to. This context will be used to pull information,
- * such as attribution tags, which will be associated with the AudioRecord. However, the
- * context itself will not be retained by the AudioRecord.
+ * such as {@link android.content.AttributionSource}, which will be associated with
+ * the AudioRecord. However, the context itself will not be retained by the AudioRecord.
* @param context a non-null {@link Context} instance
* @return the same Builder instance.
*/
@@ -2227,7 +2234,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
//--------------------
/**
- * @deprecated Use native_setup that takes an Identity object
+ * @deprecated Use native_setup that takes an {@link AttributionSource} object
* @return
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
@@ -2238,18 +2245,20 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
int buffSizeInBytes, int[] sessionId, String opPackageName,
long nativeRecordInJavaObj) {
- Identity identity = myIdentity(null);
- identity.packageName = opPackageName;
-
- return native_setup(audiorecordThis, attributes, sampleRate, channelMask, channelIndexMask,
- audioFormat, buffSizeInBytes, sessionId, identity, nativeRecordInJavaObj, 0);
+ AttributionSource attributionSource = AttributionSource.myAttributionSource()
+ .withPackageName(opPackageName);
+ try (ScopedParcelState attributionSourceState = attributionSource.asScopedParcelState()) {
+ return native_setup(audiorecordThis, attributes, sampleRate, channelMask,
+ channelIndexMask, audioFormat, buffSizeInBytes, sessionId,
+ attributionSourceState.getParcel(), nativeRecordInJavaObj, 0);
+ }
}
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,
- int maxSharedAudioHistoryMs);
+ int buffSizeInBytes, int[] sessionId, @NonNull Parcel attributionSource,
+ long nativeRecordInJavaObj, int maxSharedAudioHistoryMs);
// TODO remove: implementation calls directly into implementation of native_release()
private native void native_finalize();
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 2d8babdc9f94..4f761ba0bf6a 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -18,7 +18,6 @@ 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;
@@ -28,6 +27,8 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
@@ -35,7 +36,6 @@ 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;
@@ -56,7 +56,6 @@ 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;
@@ -685,14 +684,18 @@ public class MediaPlayer extends PlayerBase
mTimeProvider = new TimeProvider(this);
mOpenSubtitleSources = new Vector<InputStream>();
- Identity identity = myIdentity(null);
+ AttributionSource attributionSource = AttributionSource.myAttributionSource();
// set the package name to empty if it was null
- identity.packageName = TextUtils.emptyIfNull(identity.packageName);
+ if (attributionSource.getPackageName() == null) {
+ attributionSource = attributionSource.withPackageName("");
+ }
/* 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), identity);
+ try (ScopedParcelState attributionSourceState = attributionSource.asScopedParcelState()) {
+ native_setup(new WeakReference<MediaPlayer>(this), attributionSourceState.getParcel());
+ }
baseRegisterPlayer(sessionId);
}
@@ -2475,7 +2478,8 @@ 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 Identity identity);
+ private native void native_setup(Object mediaplayerThis,
+ @NonNull Parcel attributionSource);
private native final void native_finalize();
/**
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index b3f622f5b01c..805340be688c 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -16,8 +16,6 @@
package android.media;
-import static android.media.permission.PermissionUtil.myIdentity;
-
import android.annotation.CallbackExecutor;
import android.annotation.FloatRange;
import android.annotation.IntDef;
@@ -27,14 +25,16 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
import android.content.Context;
import android.hardware.Camera;
import android.media.metrics.LogSessionId;
-import android.media.permission.Identity;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.Parcel;
import android.os.PersistableBundle;
import android.util.ArrayMap;
import android.util.Log;
@@ -163,8 +163,11 @@ public class MediaRecorder implements AudioRouting,
/* 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),
- ActivityThread.currentPackageName(), myIdentity(context));
+ try (ScopedParcelState attributionSourceState = context.getAttributionSource()
+ .asScopedParcelState()) {
+ native_setup(new WeakReference<>(this), ActivityThread.currentPackageName(),
+ attributionSourceState.getParcel());
+ }
}
/**
@@ -1908,14 +1911,15 @@ public class MediaRecorder implements AudioRouting,
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);
+ AttributionSource attributionSource = AttributionSource.myAttributionSource()
+ .withPackageName(opPackageName);
+ try (ScopedParcelState attributionSourceState = attributionSource.asScopedParcelState()) {
+ native_setup(mediarecorderThis, clientName, attributionSourceState.getParcel());
+ }
}
private native void native_setup(Object mediarecorderThis,
- String clientName, Identity identity)
+ String clientName, @NonNull Parcel attributionSource)
throws IllegalStateException;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
diff --git a/media/java/android/media/MediaServiceManager.java b/media/java/android/media/MediaServiceManager.java
index fd89c0c67e71..b899559d2e50 100644
--- a/media/java/android/media/MediaServiceManager.java
+++ b/media/java/android/media/MediaServiceManager.java
@@ -45,21 +45,12 @@ public class MediaServiceManager {
*/
public static final class ServiceRegisterer {
private final String mServiceName;
- private final boolean mLazyStart;
-
- /**
- * @hide
- */
- public ServiceRegisterer(String serviceName, boolean lazyStart) {
- mServiceName = serviceName;
- mLazyStart = lazyStart;
- }
/**
* @hide
*/
public ServiceRegisterer(String serviceName) {
- this(serviceName, false /*lazyStart*/);
+ mServiceName = serviceName;
}
/**
@@ -70,9 +61,6 @@ public class MediaServiceManager {
*/
@Nullable
public IBinder get() {
- if (mLazyStart) {
- return ServiceManager.waitForService(mServiceName);
- }
return ServiceManager.getService(mServiceName);
}
}
@@ -90,7 +78,7 @@ public class MediaServiceManager {
*/
@NonNull
public ServiceRegisterer getMediaTranscodingServiceRegisterer() {
- return new ServiceRegisterer(MEDIA_TRANSCODING_SERVICE, true /*lazyStart*/);
+ return new ServiceRegisterer(MEDIA_TRANSCODING_SERVICE);
}
/**
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 79d505ebbde8..f8297bc93b72 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -405,9 +405,11 @@ public class Ringtone {
*/
public void play() {
if (mLocalPlayer != null) {
- // do not play ringtones if stream volume is 0
- // (typically because ringer mode is silent).
- if (mAudioManager.getStreamVolume(
+ // Play ringtones if stream volume is over 0 or if it is a haptic-only ringtone
+ // (typically because ringer mode is vibrate).
+ boolean isHapticOnly = AudioManager.hasHapticChannels(mUri)
+ && !mAudioAttributes.areHapticChannelsMuted() && mVolume == 0;
+ if (isHapticOnly || mAudioManager.getStreamVolume(
AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) {
startLocalPlayer();
}
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index fd3c4057ad21..70bb9608f1c2 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -16,8 +16,6 @@
package android.media.audiofx;
-import static android.media.permission.PermissionUtil.myIdentity;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -26,10 +24,11 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
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;
@@ -518,10 +517,13 @@ 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, myIdentity(null), probe);
+ int initResult;
+ try (ScopedParcelState attributionSourceState = AttributionSource.myAttributionSource()
+ .asScopedParcelState()) {
+ initResult = native_setup(new WeakReference<>(this), type.toString(), uuid.toString(),
+ priority, audioSession, deviceType, deviceAddress, id, desc,
+ attributionSourceState.getParcel(), probe);
+ }
if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
Log.e(TAG, "Error code " + initResult
+ " when initializing AudioEffect.");
@@ -1388,7 +1390,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,
- Identity identity, boolean probe);
+ @NonNull Parcel attributionSource, boolean probe);
private native final void native_finalize();
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index 58c9e650bb90..3349277ede3b 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -16,12 +16,13 @@
package android.media.audiofx;
-import static android.media.permission.PermissionUtil.myIdentity;
-
+import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
-import android.media.permission.Identity;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
import android.os.Handler;
import android.os.Looper;
+import android.os.Parcel;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -222,8 +223,12 @@ public class Visualizer {
// native initialization
// TODO b/182469354: make consistent with AudioRecord
- int result = native_setup(new WeakReference<Visualizer>(this), audioSession, id,
- myIdentity(null));
+ int result;
+ try (ScopedParcelState attributionSourceState = AttributionSource.myAttributionSource()
+ .asScopedParcelState()) {
+ result = native_setup(new WeakReference<>(this), audioSession, id,
+ attributionSourceState.getParcel());
+ }
if (result != SUCCESS && result != ALREADY_EXISTS) {
Log.e(TAG, "Error code "+result+" when initializing Visualizer.");
switch (result) {
@@ -690,7 +695,7 @@ public class Visualizer {
private native final int native_setup(Object audioeffect_this,
int audioSession,
int[] id,
- Identity identity);
+ @NonNull Parcel attributionSource);
@GuardedBy("mStateLock")
private native final void native_finalize();
diff --git a/media/java/android/media/permission/PermissionUtil.java b/media/java/android/media/permission/PermissionUtil.java
index 92fe8820570c..b08d111db89c 100644
--- a/media/java/android/media/permission/PermissionUtil.java
+++ b/media/java/android/media/permission/PermissionUtil.java
@@ -51,24 +51,6 @@ 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.