Merge changes I2b01a0c6,I4fb7b65b into tm-dev

* changes:
  AudioService: add Spatial Audio logs
  AudioService: SA feature enabled doesn't rely on global setting
This commit is contained in:
Jean-Michel Trivi
2022-04-04 13:20:14 +00:00
committed by Android (Google) Code Review
3 changed files with 143 additions and 98 deletions

View File

@@ -16,9 +16,12 @@
package com.android.server.audio; package com.android.server.audio;
import android.annotation.IntDef;
import android.util.Log; import android.util.Log;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.LinkedList; import java.util.LinkedList;
@@ -63,6 +66,16 @@ public class AudioEventLogger {
return printLog(ALOGI, tag); return printLog(ALOGI, tag);
} }
/** @hide */
@IntDef(flag = false, value = {
ALOGI,
ALOGE,
ALOGW,
ALOGV }
)
@Retention(RetentionPolicy.SOURCE)
public @interface LogType {}
public static final int ALOGI = 0; public static final int ALOGI = 0;
public static final int ALOGE = 1; public static final int ALOGE = 1;
public static final int ALOGW = 2; public static final int ALOGW = 2;
@@ -74,7 +87,7 @@ public class AudioEventLogger {
* @param tag * @param tag
* @return * @return
*/ */
public Event printLog(int type, String tag) { public Event printLog(@LogType int type, String tag) {
switch (type) { switch (type) {
case ALOGI: case ALOGI:
Log.i(tag, eventToString()); Log.i(tag, eventToString());
@@ -135,6 +148,27 @@ public class AudioEventLogger {
mEvents.add(evt); mEvents.add(evt);
} }
/**
* Add a string-based event to the log, and print it to logcat as info.
* @param msg the message for the logs
* @param tag the logcat tag to use
*/
public synchronized void loglogi(String msg, String tag) {
final Event event = new StringEvent(msg);
log(event.printLog(tag));
}
/**
* Same as {@link #loglogi(String, String)} but specifying the logcat type
* @param msg the message for the logs
* @param logType the type of logcat entry
* @param tag the logcat tag to use
*/
public synchronized void loglog(String msg, @Event.LogType int logType, String tag) {
final Event event = new StringEvent(msg);
log(event.printLog(logType, tag));
}
public synchronized void dump(PrintWriter pw) { public synchronized void dump(PrintWriter pw) {
pw.println("Audio event log: " + mTitle); pw.println("Audio event log: " + mTitle);
for (Event evt : mEvents) { for (Event evt : mEvents) {

View File

@@ -340,7 +340,8 @@ public class AudioService extends IAudioService.Stub
private static final int MSG_DISPATCH_AUDIO_MODE = 40; private static final int MSG_DISPATCH_AUDIO_MODE = 40;
private static final int MSG_ROUTING_UPDATED = 41; private static final int MSG_ROUTING_UPDATED = 41;
private static final int MSG_INIT_HEADTRACKING_SENSORS = 42; private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
private static final int MSG_PERSIST_SPATIAL_AUDIO_ENABLED = 43; // commented out for now, will be reused for other SA persisting
//private static final int MSG_PERSIST_SPATIAL_AUDIO_ENABLED = 43;
private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44; private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44;
private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45; private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45;
private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46; private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46;
@@ -1543,9 +1544,7 @@ public class AudioService extends IAudioService.Stub
} }
} }
if (mHasSpatializerEffect) { mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
mSpatializerHelper.reset(/* featureEnabled */ isSpatialAudioEnabled());
}
onIndicateSystemReady(); onIndicateSystemReady();
// indicate the end of reconfiguration phase to audio HAL // indicate the end of reconfiguration phase to audio HAL
@@ -8114,9 +8113,7 @@ public class AudioService extends IAudioService.Stub
case MSG_INIT_SPATIALIZER: case MSG_INIT_SPATIALIZER:
mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect); mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
if (mHasSpatializerEffect) { mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
mSpatializerHelper.setFeatureEnabled(isSpatialAudioEnabled());
}
mAudioEventWakeLock.release(); mAudioEventWakeLock.release();
break; break;
@@ -8257,10 +8254,6 @@ public class AudioService extends IAudioService.Stub
onRoutingUpdatedFromAudioThread(); onRoutingUpdatedFromAudioThread();
break; break;
case MSG_PERSIST_SPATIAL_AUDIO_ENABLED:
onPersistSpatialAudioEnabled(msg.arg1 == 1);
break;
case MSG_ADD_ASSISTANT_SERVICE_UID: case MSG_ADD_ASSISTANT_SERVICE_UID:
onAddAssistantServiceUids(new int[]{msg.arg1}); onAddAssistantServiceUids(new int[]{msg.arg1});
break; break;
@@ -8864,31 +8857,6 @@ public class AudioService extends IAudioService.Stub
*/ */
private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true; private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true;
/**
* persist in user settings whether the feature is enabled.
* Can change when {@link Spatializer#setEnabled(boolean)} is called and successfully
* changes the state of the feature
* @param featureEnabled
*/
void persistSpatialAudioEnabled(boolean featureEnabled) {
sendMsg(mAudioHandler,
MSG_PERSIST_SPATIAL_AUDIO_ENABLED,
SENDMSG_REPLACE, featureEnabled ? 1 : 0, 0, null,
/*delay ms*/ 100);
}
void onPersistSpatialAudioEnabled(boolean enabled) {
mSettings.putSecureIntForUser(mContentResolver,
Settings.Secure.SPATIAL_AUDIO_ENABLED, enabled ? 1 : 0,
UserHandle.USER_CURRENT);
}
boolean isSpatialAudioEnabled() {
return mSettings.getSecureIntForUser(mContentResolver,
Settings.Secure.SPATIAL_AUDIO_ENABLED, SPATIAL_AUDIO_ENABLED_DEFAULT ? 1 : 0,
UserHandle.USER_CURRENT) == 1;
}
private void enforceModifyDefaultAudioEffectsPermission() { private void enforceModifyDefaultAudioEffectsPermission() {
if (mContext.checkCallingOrSelfPermission( if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS) android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
@@ -9748,6 +9716,7 @@ public class AudioService extends IAudioService.Stub
static final int LOG_NB_EVENTS_FORCE_USE = 20; static final int LOG_NB_EVENTS_FORCE_USE = 20;
static final int LOG_NB_EVENTS_VOLUME = 40; static final int LOG_NB_EVENTS_VOLUME = 40;
static final int LOG_NB_EVENTS_DYN_POLICY = 10; static final int LOG_NB_EVENTS_DYN_POLICY = 10;
static final int LOG_NB_EVENTS_SPATIAL = 30;
static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE, static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE,
"audio services lifecycle"); "audio services lifecycle");
@@ -9768,6 +9737,9 @@ public class AudioService extends IAudioService.Stub
static final AudioEventLogger sVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME, static final AudioEventLogger sVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME,
"volume changes (logged when command received by AudioService)"); "volume changes (logged when command received by AudioService)");
static final AudioEventLogger sSpatialLogger = new AudioEventLogger(LOG_NB_EVENTS_SPATIAL,
"spatial audio");
final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY, final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY,
"dynamic policy events (logged when command received by AudioService)"); "dynamic policy events (logged when command received by AudioService)");
@@ -9906,10 +9878,10 @@ public class AudioService extends IAudioService.Stub
pw.println("\n"); pw.println("\n");
pw.println("\nSpatial audio:"); pw.println("\nSpatial audio:");
pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect); pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)");
pw.println("isSpatializerEnabled:" + isSpatializerEnabled()); pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)");
pw.println("isSpatialAudioEnabled:" + isSpatialAudioEnabled());
mSpatializerHelper.dump(pw); mSpatializerHelper.dump(pw);
sSpatialLogger.dump(pw);
mAudioSystem.dump(pw); mAudioSystem.dump(pw);
} }

View File

@@ -177,20 +177,20 @@ public class SpatializerHelper {
} }
synchronized void init(boolean effectExpected) { synchronized void init(boolean effectExpected) {
Log.i(TAG, "Initializing"); loglogi("init effectExpected=" + effectExpected);
if (!effectExpected) { if (!effectExpected) {
Log.i(TAG, "Setting state to STATE_NOT_SUPPORTED due to effect not expected"); loglogi("init(): setting state to STATE_NOT_SUPPORTED due to effect not expected");
mState = STATE_NOT_SUPPORTED; mState = STATE_NOT_SUPPORTED;
return; return;
} }
if (mState != STATE_UNINITIALIZED) { if (mState != STATE_UNINITIALIZED) {
throw new IllegalStateException(("init() called in state:" + mState)); throw new IllegalStateException(logloge("init() called in state " + mState));
} }
// is there a spatializer? // is there a spatializer?
mSpatCallback = new SpatializerCallback(); mSpatCallback = new SpatializerCallback();
final ISpatializer spat = AudioSystem.getSpatializer(mSpatCallback); final ISpatializer spat = AudioSystem.getSpatializer(mSpatCallback);
if (spat == null) { if (spat == null) {
Log.i(TAG, "init(): No Spatializer found"); loglogi("init(): No Spatializer found");
mState = STATE_NOT_SUPPORTED; mState = STATE_NOT_SUPPORTED;
return; return;
} }
@@ -201,14 +201,14 @@ public class SpatializerHelper {
|| levels.length == 0 || levels.length == 0
|| (levels.length == 1 || (levels.length == 1
&& levels[0] == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE)) { && levels[0] == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE)) {
Log.e(TAG, "Spatializer is useless"); logloge("init(): found Spatializer is useless");
mState = STATE_NOT_SUPPORTED; mState = STATE_NOT_SUPPORTED;
return; return;
} }
for (byte level : levels) { for (byte level : levels) {
logd("found support for level: " + level); loglogi("init(): found support for level: " + level);
if (level == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL) { if (level == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL) {
logd("Setting capable level to LEVEL_MULTICHANNEL"); loglogi("init(): setting capable level to LEVEL_MULTICHANNEL");
mCapableSpatLevel = level; mCapableSpatLevel = level;
break; break;
} }
@@ -223,7 +223,7 @@ public class SpatializerHelper {
mTransauralSupported = true; mTransauralSupported = true;
break; break;
default: default:
Log.e(TAG, "Spatializer reports unknown supported mode:" + mode); logloge("init(): Spatializer reports unknown supported mode:" + mode);
break; break;
} }
} }
@@ -277,7 +277,7 @@ public class SpatializerHelper {
* @param featureEnabled * @param featureEnabled
*/ */
synchronized void reset(boolean featureEnabled) { synchronized void reset(boolean featureEnabled) {
Log.i(TAG, "Resetting"); loglogi("Resetting featureEnabled=" + featureEnabled);
releaseSpat(); releaseSpat();
mState = STATE_UNINITIALIZED; mState = STATE_UNINITIALIZED;
mSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; mSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
@@ -318,23 +318,24 @@ public class SpatializerHelper {
if (enabledAvailable.second) { if (enabledAvailable.second) {
// available for Spatial audio, check w/ effect // available for Spatial audio, check w/ effect
able = canBeSpatializedOnDevice(DEFAULT_ATTRIBUTES, DEFAULT_FORMAT, ROUTING_DEVICES); able = canBeSpatializedOnDevice(DEFAULT_ATTRIBUTES, DEFAULT_FORMAT, ROUTING_DEVICES);
Log.i(TAG, "onRoutingUpdated: can spatialize media 5.1:" + able loglogi("onRoutingUpdated: can spatialize media 5.1:" + able
+ " on device:" + ROUTING_DEVICES[0]); + " on device:" + ROUTING_DEVICES[0]);
setDispatchAvailableState(able); setDispatchAvailableState(able);
} else { } else {
Log.i(TAG, "onRoutingUpdated: device:" + ROUTING_DEVICES[0] loglogi("onRoutingUpdated: device:" + ROUTING_DEVICES[0]
+ " not available for Spatial Audio"); + " not available for Spatial Audio");
setDispatchAvailableState(false); setDispatchAvailableState(false);
} }
if (able && enabledAvailable.first) { if (able && enabledAvailable.first) {
Log.i(TAG, "Enabling Spatial Audio since enabled for media device:" loglogi("Enabling Spatial Audio since enabled for media device:"
+ ROUTING_DEVICES[0]); + ROUTING_DEVICES[0]);
} else { } else {
Log.i(TAG, "Disabling Spatial Audio since disabled for media device:" loglogi("Disabling Spatial Audio since disabled for media device:"
+ ROUTING_DEVICES[0]); + ROUTING_DEVICES[0]);
} }
setDispatchFeatureEnabledState(able && enabledAvailable.first); setDispatchFeatureEnabledState(able && enabledAvailable.first,
"onRoutingUpdated");
if (mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED if (mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED
&& mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_DISABLED) { && mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_DISABLED) {
@@ -347,7 +348,7 @@ public class SpatializerHelper {
private final class SpatializerCallback extends INativeSpatializerCallback.Stub { private final class SpatializerCallback extends INativeSpatializerCallback.Stub {
public void onLevelChanged(byte level) { public void onLevelChanged(byte level) {
logd("SpatializerCallback.onLevelChanged level:" + level); loglogi("SpatializerCallback.onLevelChanged level:" + level);
synchronized (SpatializerHelper.this) { synchronized (SpatializerHelper.this) {
mSpatLevel = spatializationLevelToSpatializerInt(level); mSpatLevel = spatializationLevelToSpatializerInt(level);
} }
@@ -358,7 +359,7 @@ public class SpatializerHelper {
} }
public void onOutputChanged(int output) { public void onOutputChanged(int output) {
logd("SpatializerCallback.onOutputChanged output:" + output); loglogi("SpatializerCallback.onOutputChanged output:" + output);
int oldOutput; int oldOutput;
synchronized (SpatializerHelper.this) { synchronized (SpatializerHelper.this) {
oldOutput = mSpatOutput; oldOutput = mSpatOutput;
@@ -375,13 +376,14 @@ public class SpatializerHelper {
private final class SpatializerHeadTrackingCallback private final class SpatializerHeadTrackingCallback
extends ISpatializerHeadTrackingCallback.Stub { extends ISpatializerHeadTrackingCallback.Stub {
public void onHeadTrackingModeChanged(byte mode) { public void onHeadTrackingModeChanged(byte mode) {
logd("SpatializerHeadTrackingCallback.onHeadTrackingModeChanged mode:" + mode);
int oldMode, newMode; int oldMode, newMode;
synchronized (this) { synchronized (this) {
oldMode = mActualHeadTrackingMode; oldMode = mActualHeadTrackingMode;
mActualHeadTrackingMode = headTrackingModeTypeToSpatializerInt(mode); mActualHeadTrackingMode = headTrackingModeTypeToSpatializerInt(mode);
newMode = mActualHeadTrackingMode; newMode = mActualHeadTrackingMode;
} }
loglogi("SpatializerHeadTrackingCallback.onHeadTrackingModeChanged mode:"
+ Spatializer.headtrackingModeToString(newMode));
if (oldMode != newMode) { if (oldMode != newMode) {
dispatchActualHeadTrackingMode(newMode); dispatchActualHeadTrackingMode(newMode);
} }
@@ -404,7 +406,8 @@ public class SpatializerHelper {
for (float val : headToStage) { for (float val : headToStage) {
t.append("[").append(String.format(Locale.ENGLISH, "%.3f", val)).append("]"); t.append("[").append(String.format(Locale.ENGLISH, "%.3f", val)).append("]");
} }
logd("SpatializerHeadTrackingCallback.onHeadToStagePoseUpdated headToStage:" + t); loglogi("SpatializerHeadTrackingCallback.onHeadToStagePoseUpdated headToStage:"
+ t);
} }
dispatchPoseUpdate(headToStage); dispatchPoseUpdate(headToStage);
} }
@@ -444,10 +447,9 @@ public class SpatializerHelper {
} }
synchronized void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { synchronized void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
// TODO add log loglogi("addCompatibleAudioDevice: dev=" + ada);
final int deviceType = ada.getType(); final int deviceType = ada.getType();
final boolean wireless = isWireless(deviceType); final boolean wireless = isWireless(deviceType);
boolean updateRouting = false;
boolean isInList = false; boolean isInList = false;
for (SADeviceState deviceState : mSADevices) { for (SADeviceState deviceState : mSADevices) {
@@ -455,8 +457,6 @@ public class SpatializerHelper {
&& (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
|| !wireless) { || !wireless) {
isInList = true; isInList = true;
// state change?
updateRouting = !deviceState.mEnabled;
deviceState.mEnabled = true; deviceState.mEnabled = true;
break; break;
} }
@@ -466,33 +466,25 @@ public class SpatializerHelper {
wireless ? ada.getAddress() : null); wireless ? ada.getAddress() : null);
dev.mEnabled = true; dev.mEnabled = true;
mSADevices.add(dev); mSADevices.add(dev);
updateRouting = true;
} }
if (updateRouting) {
onRoutingUpdated(); onRoutingUpdated();
} }
}
synchronized void removeCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { synchronized void removeCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
// TODO add log loglogi("removeCompatibleAudioDevice: dev=" + ada);
final int deviceType = ada.getType(); final int deviceType = ada.getType();
final boolean wireless = isWireless(deviceType); final boolean wireless = isWireless(deviceType);
boolean updateRouting = false;
for (SADeviceState deviceState : mSADevices) { for (SADeviceState deviceState : mSADevices) {
if (deviceType == deviceState.mDeviceType if (deviceType == deviceState.mDeviceType
&& (wireless && ada.getAddress().equals(deviceState.mDeviceAddress)) && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
|| !wireless) { || !wireless) {
// state change?
updateRouting = deviceState.mEnabled;
deviceState.mEnabled = false; deviceState.mEnabled = false;
break; break;
} }
} }
if (updateRouting) {
onRoutingUpdated(); onRoutingUpdated();
} }
}
/** /**
* Return if Spatial Audio is enabled and available for the given device * Return if Spatial Audio is enabled and available for the given device
@@ -629,6 +621,7 @@ public class SpatializerHelper {
} }
synchronized void setFeatureEnabled(boolean enabled) { synchronized void setFeatureEnabled(boolean enabled) {
loglogi("setFeatureEnabled(" + enabled + ") was featureEnabled:" + mFeatureEnabled);
if (mFeatureEnabled == enabled) { if (mFeatureEnabled == enabled) {
return; return;
} }
@@ -652,7 +645,7 @@ public class SpatializerHelper {
switch (mState) { switch (mState) {
case STATE_UNINITIALIZED: case STATE_UNINITIALIZED:
if (enabled) { if (enabled) {
throw(new IllegalStateException("Can't enable when uninitialized")); throw (new IllegalStateException("Can't enable when uninitialized"));
} }
return; return;
case STATE_NOT_SUPPORTED: case STATE_NOT_SUPPORTED:
@@ -679,7 +672,7 @@ public class SpatializerHelper {
return; return;
} }
} }
setDispatchFeatureEnabledState(enabled); setDispatchFeatureEnabledState(enabled, "setSpatializerEnabledInt");
} }
synchronized int getCapableImmersiveAudioLevel() { synchronized int getCapableImmersiveAudioLevel() {
@@ -703,7 +696,8 @@ public class SpatializerHelper {
* Update the feature state, no-op if no change * Update the feature state, no-op if no change
* @param featureEnabled * @param featureEnabled
*/ */
private synchronized void setDispatchFeatureEnabledState(boolean featureEnabled) { private synchronized void setDispatchFeatureEnabledState(boolean featureEnabled, String source)
{
if (featureEnabled) { if (featureEnabled) {
switch (mState) { switch (mState) {
case STATE_DISABLED_UNAVAILABLE: case STATE_DISABLED_UNAVAILABLE:
@@ -715,9 +709,12 @@ public class SpatializerHelper {
case STATE_ENABLED_AVAILABLE: case STATE_ENABLED_AVAILABLE:
case STATE_ENABLED_UNAVAILABLE: case STATE_ENABLED_UNAVAILABLE:
// already enabled: no-op // already enabled: no-op
loglogi("setDispatchFeatureEnabledState(" + featureEnabled
+ ") no dispatch: mState:"
+ spatStateString(mState) + " src:" + source);
return; return;
default: default:
throw(new IllegalStateException("Invalid mState:" + mState throw (new IllegalStateException("Invalid mState:" + mState
+ " for enabled true")); + " for enabled true"));
} }
} else { } else {
@@ -731,12 +728,17 @@ public class SpatializerHelper {
case STATE_DISABLED_AVAILABLE: case STATE_DISABLED_AVAILABLE:
case STATE_DISABLED_UNAVAILABLE: case STATE_DISABLED_UNAVAILABLE:
// already disabled: no-op // already disabled: no-op
loglogi("setDispatchFeatureEnabledState(" + featureEnabled
+ ") no dispatch: mState:" + spatStateString(mState)
+ " src:" + source);
return; return;
default: default:
throw (new IllegalStateException("Invalid mState:" + mState throw (new IllegalStateException("Invalid mState:" + mState
+ " for enabled false")); + " for enabled false"));
} }
} }
loglogi("setDispatchFeatureEnabledState(" + featureEnabled
+ ") mState:" + spatStateString(mState));
final int nbCallbacks = mStateCallbacks.beginBroadcast(); final int nbCallbacks = mStateCallbacks.beginBroadcast();
for (int i = 0; i < nbCallbacks; i++) { for (int i = 0; i < nbCallbacks; i++) {
try { try {
@@ -747,14 +749,13 @@ public class SpatializerHelper {
} }
} }
mStateCallbacks.finishBroadcast(); mStateCallbacks.finishBroadcast();
mAudioService.persistSpatialAudioEnabled(featureEnabled);
} }
private synchronized void setDispatchAvailableState(boolean available) { private synchronized void setDispatchAvailableState(boolean available) {
switch (mState) { switch (mState) {
case STATE_UNINITIALIZED: case STATE_UNINITIALIZED:
case STATE_NOT_SUPPORTED: case STATE_NOT_SUPPORTED:
throw(new IllegalStateException( throw (new IllegalStateException(
"Should not update available state in state:" + mState)); "Should not update available state in state:" + mState));
case STATE_DISABLED_UNAVAILABLE: case STATE_DISABLED_UNAVAILABLE:
if (available) { if (available) {
@@ -762,6 +763,8 @@ public class SpatializerHelper {
break; break;
} else { } else {
// already in unavailable state // already in unavailable state
loglogi("setDispatchAvailableState(" + available
+ ") no dispatch: mState:" + spatStateString(mState));
return; return;
} }
case STATE_ENABLED_UNAVAILABLE: case STATE_ENABLED_UNAVAILABLE:
@@ -770,11 +773,15 @@ public class SpatializerHelper {
break; break;
} else { } else {
// already in unavailable state // already in unavailable state
loglogi("setDispatchAvailableState(" + available
+ ") no dispatch: mState:" + spatStateString(mState));
return; return;
} }
case STATE_DISABLED_AVAILABLE: case STATE_DISABLED_AVAILABLE:
if (available) { if (available) {
// already in available state // already in available state
loglogi("setDispatchAvailableState(" + available
+ ") no dispatch: mState:" + spatStateString(mState));
return; return;
} else { } else {
mState = STATE_DISABLED_UNAVAILABLE; mState = STATE_DISABLED_UNAVAILABLE;
@@ -783,12 +790,15 @@ public class SpatializerHelper {
case STATE_ENABLED_AVAILABLE: case STATE_ENABLED_AVAILABLE:
if (available) { if (available) {
// already in available state // already in available state
loglogi("setDispatchAvailableState(" + available
+ ") no dispatch: mState:" + spatStateString(mState));
return; return;
} else { } else {
mState = STATE_ENABLED_UNAVAILABLE; mState = STATE_ENABLED_UNAVAILABLE;
break; break;
} }
} }
loglogi("setDispatchAvailableState(" + available + ") mState:" + spatStateString(mState));
final int nbCallbacks = mStateCallbacks.beginBroadcast(); final int nbCallbacks = mStateCallbacks.beginBroadcast();
for (int i = 0; i < nbCallbacks; i++) { for (int i = 0; i < nbCallbacks; i++) {
try { try {
@@ -851,8 +861,6 @@ public class SpatializerHelper {
// virtualization capabilities // virtualization capabilities
synchronized boolean canBeSpatialized( synchronized boolean canBeSpatialized(
@NonNull AudioAttributes attributes, @NonNull AudioFormat format) { @NonNull AudioAttributes attributes, @NonNull AudioFormat format) {
logd("canBeSpatialized usage:" + attributes.getUsage()
+ " format:" + format.toLogFriendlyString());
switch (mState) { switch (mState) {
case STATE_UNINITIALIZED: case STATE_UNINITIALIZED:
case STATE_NOT_SUPPORTED: case STATE_NOT_SUPPORTED:
@@ -879,7 +887,8 @@ public class SpatializerHelper {
mASA.getDevicesForAttributes( mASA.getDevicesForAttributes(
attributes, false /* forVolume */).toArray(devices); attributes, false /* forVolume */).toArray(devices);
final boolean able = canBeSpatializedOnDevice(attributes, format, devices); final boolean able = canBeSpatializedOnDevice(attributes, format, devices);
logd("canBeSpatialized returning " + able); logd("canBeSpatialized usage:" + attributes.getUsage()
+ " format:" + format.toLogFriendlyString() + " returning " + able);
return able; return able;
} }
@@ -1316,11 +1325,11 @@ public class SpatializerHelper {
final boolean init = mFeatureEnabled && (mSpatLevel != SpatializationLevel.NONE); final boolean init = mFeatureEnabled && (mSpatLevel != SpatializationLevel.NONE);
final String action = init ? "initializing" : "releasing"; final String action = init ? "initializing" : "releasing";
if (mSpat == null) { if (mSpat == null) {
Log.e(TAG, "not " + action + " sensors, null spatializer"); logloge("not " + action + " sensors, null spatializer");
return; return;
} }
if (!mIsHeadTrackingSupported) { if (!mIsHeadTrackingSupported) {
Log.e(TAG, "not " + action + " sensors, spatializer doesn't support headtracking"); logloge("not " + action + " sensors, spatializer doesn't support headtracking");
return; return;
} }
int headHandle = -1; int headHandle = -1;
@@ -1345,7 +1354,7 @@ public class SpatializerHelper {
// does this happen before routing is updated? // does this happen before routing is updated?
// avoid by supporting adding device here AND in onRoutingUpdated() // avoid by supporting adding device here AND in onRoutingUpdated()
headHandle = getHeadSensorHandleUpdateTracker(); headHandle = getHeadSensorHandleUpdateTracker();
Log.i(TAG, "head tracker sensor handle initialized to " + headHandle); loglogi("head tracker sensor handle initialized to " + headHandle);
screenHandle = getScreenSensorHandle(); screenHandle = getScreenSensorHandle();
Log.i(TAG, "found screen sensor handle initialized to " + screenHandle); Log.i(TAG, "found screen sensor handle initialized to " + screenHandle);
} else { } else {
@@ -1388,7 +1397,7 @@ public class SpatializerHelper {
case SpatializerHeadTrackingMode.RELATIVE_SCREEN: case SpatializerHeadTrackingMode.RELATIVE_SCREEN:
return Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE; return Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE;
default: default:
throw(new IllegalArgumentException("Unexpected head tracking mode:" + mode)); throw (new IllegalArgumentException("Unexpected head tracking mode:" + mode));
} }
} }
@@ -1403,7 +1412,7 @@ public class SpatializerHelper {
case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE: case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE:
return SpatializerHeadTrackingMode.RELATIVE_SCREEN; return SpatializerHeadTrackingMode.RELATIVE_SCREEN;
default: default:
throw(new IllegalArgumentException("Unexpected head tracking mode:" + sdkMode)); throw (new IllegalArgumentException("Unexpected head tracking mode:" + sdkMode));
} }
} }
@@ -1416,7 +1425,7 @@ public class SpatializerHelper {
case SpatializationLevel.SPATIALIZER_MCHAN_BED_PLUS_OBJECTS: case SpatializationLevel.SPATIALIZER_MCHAN_BED_PLUS_OBJECTS:
return Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MCHAN_BED_PLUS_OBJECTS; return Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MCHAN_BED_PLUS_OBJECTS;
default: default:
throw(new IllegalArgumentException("Unexpected spatializer level:" + level)); throw (new IllegalArgumentException("Unexpected spatializer level:" + level));
} }
} }
@@ -1429,18 +1438,19 @@ public class SpatializerHelper {
+ Spatializer.headtrackingModeToString(mActualHeadTrackingMode)); + Spatializer.headtrackingModeToString(mActualHeadTrackingMode));
pw.println("\tmDesiredHeadTrackingMode:" pw.println("\tmDesiredHeadTrackingMode:"
+ Spatializer.headtrackingModeToString(mDesiredHeadTrackingMode)); + Spatializer.headtrackingModeToString(mDesiredHeadTrackingMode));
String modesString = ""; pw.println("\tsupports binaural:" + mBinauralSupported + " / transaural:"
+ mTransauralSupported);
StringBuilder modesString = new StringBuilder();
int[] modes = getSupportedHeadTrackingModes(); int[] modes = getSupportedHeadTrackingModes();
for (int mode : modes) { for (int mode : modes) {
modesString += Spatializer.headtrackingModeToString(mode) + " "; modesString.append(Spatializer.headtrackingModeToString(mode)).append(" ");
} }
pw.println("\tsupports binaural:" + mBinauralSupported + " / transaural"
+ mTransauralSupported);
pw.println("\tsupported head tracking modes:" + modesString); pw.println("\tsupported head tracking modes:" + modesString);
pw.println("\theadtracker available:" + mHeadTrackerAvailable);
pw.println("\tmSpatOutput:" + mSpatOutput); pw.println("\tmSpatOutput:" + mSpatOutput);
pw.println("\tdevices:\n"); pw.println("\tdevices:");
for (SADeviceState device : mSADevices) { for (SADeviceState device : mSADevices) {
pw.println("\t\t" + device + "\n"); pw.println("\t\t" + device);
} }
} }
@@ -1463,6 +1473,25 @@ public class SpatializerHelper {
} }
} }
private static String spatStateString(int state) {
switch (state) {
case STATE_UNINITIALIZED:
return "STATE_UNINITIALIZED";
case STATE_NOT_SUPPORTED:
return "STATE_NOT_SUPPORTED";
case STATE_DISABLED_UNAVAILABLE:
return "STATE_DISABLED_UNAVAILABLE";
case STATE_ENABLED_UNAVAILABLE:
return "STATE_ENABLED_UNAVAILABLE";
case STATE_ENABLED_AVAILABLE:
return "STATE_ENABLED_AVAILABLE";
case STATE_DISABLED_AVAILABLE:
return "STATE_DISABLED_AVAILABLE";
default:
return "invalid state";
}
}
private static boolean isWireless(int deviceType) { private static boolean isWireless(int deviceType) {
for (int type : WIRELESS_TYPES) { for (int type : WIRELESS_TYPES) {
if (type == deviceType) { if (type == deviceType) {
@@ -1473,7 +1502,7 @@ public class SpatializerHelper {
} }
private static boolean isWirelessSpeaker(int deviceType) { private static boolean isWirelessSpeaker(int deviceType) {
for (int type: WIRELESS_SPEAKER_TYPES) { for (int type : WIRELESS_SPEAKER_TYPES) {
if (type == deviceType) { if (type == deviceType) {
return true; return true;
} }
@@ -1515,4 +1544,14 @@ public class SpatializerHelper {
} }
return screenHandle; return screenHandle;
} }
private static void loglogi(String msg) {
AudioService.sSpatialLogger.loglogi(msg, TAG);
}
private static String logloge(String msg) {
AudioService.sSpatialLogger.loglog(msg, AudioEventLogger.Event.ALOGE, TAG);
return msg;
}
} }