Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed967437 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

setDeviceVolume: better logs, clears routing cache

When a call to setDeviceVolume is received, clear the
  AudioSystemAdapter cache for the AudioAttributes to
  audio device. This will eliminate any chance of the
  cache being stale when the evaluation of whether to
  send the VOLUME_CHANGED_ACTION intent is performed.
Clean up log calls to setDeviceVolume, use a dedicated
  logger event, and also log the current device selected by
  getDevicesForStream.
Don't send volume update to VolumeController (sysUI) when a
  device was specified (== call comes from setDeviceVolume).
Fix code path in AudioDeviceBroker where its calls to
  AudioSystem.setForceUse were going directly to
  AudioSystem, instead of going through the adapter (which
  causes a cache clear, whereas it didn't in Broker). This
  is done by injecting into AudioDeviceBroker the same
  AudioSystemAdapter that AudioService uses.
Fix AudioService's obsolete use of ANALOG_DOCK, replaced
  by DIGITAL_DOCK.

Bug: 264302812
Bug: 271473257
Test: atest android.media.audio.cts.AudioDeviceVolumeManagerTest#testSetGetVolume
Change-Id: Ibfa002b51f02302686853a8dea562e75d12d8949
parent 011d00e1
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import java.util.concurrent.atomic.AtomicBoolean;

    private final @NonNull AudioService mAudioService;
    private final @NonNull Context mContext;
    private final @NonNull AudioSystemAdapter mAudioSystem;

    /** ID for Communication strategy retrieved form audio policy manager */
    private int mCommunicationStrategyId = -1;
@@ -159,12 +160,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
    public static final long USE_SET_COMMUNICATION_DEVICE = 243827847L;

    //-------------------------------------------------------------------
    /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service) {
    /*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service,
            @NonNull AudioSystemAdapter audioSystem) {
        mContext = context;
        mAudioService = service;
        mBtHelper = new BtHelper(this);
        mDeviceInventory = new AudioDeviceInventory(this);
        mSystemServer = SystemServerAdapter.getDefaultAdapter(mContext);
        mAudioSystem = audioSystem;

        init();
    }
@@ -173,12 +176,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
     *  in system_server */
    AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service,
                      @NonNull AudioDeviceInventory mockDeviceInventory,
                      @NonNull SystemServerAdapter mockSystemServer) {
                      @NonNull SystemServerAdapter mockSystemServer,
                      @NonNull AudioSystemAdapter audioSystem) {
        mContext = context;
        mAudioService = service;
        mBtHelper = new BtHelper(this);
        mDeviceInventory = mockDeviceInventory;
        mSystemServer = mockSystemServer;
        mAudioSystem = audioSystem;

        init();
    }
@@ -540,7 +545,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
            AudioAttributes attr =
                    AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
                            AudioSystem.STREAM_VOICE_CALL);
            List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes(
            List<AudioDeviceAttributes> devices = mAudioSystem.getDevicesForAttributes(
                    attr, false /* forVolume */);
            if (devices.isEmpty()) {
                if (mAudioService.isPlatformVoice()) {
@@ -1493,7 +1498,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
            Log.v(TAG, "onSetForceUse(useCase<" + useCase + ">, config<" + config + ">, fromA2dp<"
                    + fromA2dp + ">, eventSource<" + eventSource + ">)");
        }
        AudioSystem.setForceUse(useCase, config);
        mAudioSystem.setForceUse(useCase, config);
    }

    private void onSendBecomingNoisyIntent() {
+31 −11
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent;
import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent;
import com.android.server.audio.AudioServiceEvents.VolumeEvent;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
@@ -1214,7 +1215,7 @@ public class AudioService extends IAudioService.Stub
        mUseFixedVolume = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_useFixedVolume);
        mDeviceBroker = new AudioDeviceBroker(mContext, this);
        mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem);
        mRecordMonitor = new RecordingActivityMonitor(mContext);
        mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true);
@@ -1687,7 +1688,7 @@ public class AudioService extends IAudioService.Stub
        synchronized (mSettingsLock) {
            final int forDock = mDockAudioMediaEnabled ?
                    AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE;
                    AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE;
            mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
            sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
            sendEnabledSurroundFormats(mContentResolver, true);
@@ -2323,9 +2324,10 @@ public class AudioService extends IAudioService.Stub
                SENDMSG_QUEUE,
                AudioSystem.FOR_DOCK,
                mDockAudioMediaEnabled ?
                        AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE,
                        AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE,
                new String("readDockAudioSettings"),
                0);
    }
@@ -3972,13 +3974,25 @@ public class AudioService extends IAudioService.Stub
            Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
            return;
        }
        int index = vi.getVolumeIndex();
        if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) {
            throw new IllegalArgumentException(
                    "changing device volume requires a volume index or mute command");
        }
        // TODO handle unmuting if current audio device
        // force a cache clear to force reevaluating stream type to audio device selection
        // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent
        mAudioSystem.clearRoutingCache();
        // log the current device that will be used when evaluating the sending of the
        // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified
        final int currDev = getDeviceForStream(vi.getStreamType());
        AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada,
                currDev, callingPackage));
        // TODO handle unmuting of current audio device
        // if a stream is not muted but the VolumeInfo is for muting, set the volume index
        // for the device to min volume
        if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) {
@@ -4129,11 +4143,11 @@ public class AudioService extends IAudioService.Stub
            return;
        }
        final EventLogger.Event event = (device == null)
                ? new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
                    index/*val1*/, flags/*val2*/, callingPackage)
                : new DeviceVolumeEvent(streamType, index, device, callingPackage);
        sVolumeLogger.enqueue(event);
        if (device == null) {
            // call was already logged in setDeviceVolume()
            sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
                    index/*val1*/, flags/*val2*/, callingPackage));
        }
        setStreamVolume(streamType, index, flags, device,
                callingPackage, callingPackage, attributionTag,
                Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
@@ -4547,8 +4561,12 @@ public class AudioService extends IAudioService.Stub
                maybeSendSystemAudioStatusCommand(false);
            }
        }
        if (ada == null) {
            // only non-null when coming here from setDeviceVolume
            // TODO change test to check early if device is current device or not
            sendVolumeUpdate(streamType, oldIndex, index, flags, device);
        }
    }
    private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo,
            int index) {
@@ -8531,6 +8549,8 @@ public class AudioService extends IAudioService.Stub
                    mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
                    mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
                            mStreamVolumeAlias[mStreamType]);
                    AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent(
                            mStreamType, mStreamVolumeAlias[mStreamType], index));
                    sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions);
                }
            }
@@ -10807,7 +10827,7 @@ public class AudioService extends IAudioService.Stub
    static final int LOG_NB_EVENTS_PHONE_STATE = 20;
    static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50;
    static final int LOG_NB_EVENTS_FORCE_USE = 20;
    static final int LOG_NB_EVENTS_VOLUME = 40;
    static final int LOG_NB_EVENTS_VOLUME = 100;
    static final int LOG_NB_EVENTS_DYN_POLICY = 10;
    static final int LOG_NB_EVENTS_SPATIAL = 30;
    static final int LOG_NB_EVENTS_SOUND_DOSE = 30;
+27 −2
Original line number Diff line number Diff line
@@ -147,19 +147,42 @@ public class AudioServiceEvents {
        }
    }

    static final class VolChangedBroadcastEvent extends EventLogger.Event {
        final int mStreamType;
        final int mAliasStreamType;
        final int mIndex;

        VolChangedBroadcastEvent(int stream, int alias, int index) {
            mStreamType = stream;
            mAliasStreamType = alias;
            mIndex = index;
        }

        @Override
        public String eventToString() {
            return new StringBuilder("sending VOLUME_CHANGED stream:")
                    .append(AudioSystem.streamToString(mStreamType))
                    .append(" index:").append(mIndex)
                    .append(" alias:").append(AudioSystem.streamToString(mAliasStreamType))
                    .toString();
        }
    }

    static final class DeviceVolumeEvent extends EventLogger.Event {
        final int mStream;
        final int mVolIndex;
        final String mDeviceNativeType;
        final String mDeviceAddress;
        final String mCaller;
        final int mDeviceForStream;

        DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device,
                String callingPackage) {
                int deviceForStream, String callingPackage) {
            mStream = streamType;
            mVolIndex = index;
            mDeviceNativeType = "0x" + Integer.toHexString(device.getInternalType());
            mDeviceAddress = device.getAddress();
            mDeviceForStream = deviceForStream;
            mCaller = callingPackage;
            // log metrics
            new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME_EVENT)
@@ -180,7 +203,9 @@ public class AudioServiceEvents {
                    .append(" index:").append(mVolIndex)
                    .append(" device:").append(mDeviceNativeType)
                    .append(" addr:").append(mDeviceAddress)
                    .append(") from ").append(mCaller).toString();
                    .append(") from ").append(mCaller)
                    .append(" currDevForStream:Ox").append(Integer.toHexString(mDeviceForStream))
                    .toString();
        }
    }

+11 −0
Original line number Diff line number Diff line
@@ -161,6 +161,16 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback,
        }
    }

    /**
     * Empties the routing cache if enabled.
     */
    public void clearRoutingCache() {
        if (DEBUG_CACHE) {
            Log.d(TAG, "---- routing cache clear (from java) ----------");
        }
        invalidateRoutingCache();
    }

    /**
     * @see AudioManager#addOnDevicesForAttributesChangedListener(
     *      AudioAttributes, Executor, OnDevicesForAttributesChangedListener)
@@ -464,6 +474,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback,
     * @return
     */
    public int setParameters(String keyValuePairs) {
        invalidateRoutingCache();
        return AudioSystem.setParameters(keyValuePairs);
    }

+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ public class AudioDeviceBrokerTest {
        mSpyDevInventory = spy(new AudioDeviceInventory(mSpyAudioSystem));
        mSpySystemServer = spy(new NoOpSystemServerAdapter());
        mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory,
                mSpySystemServer);
                mSpySystemServer, mSpyAudioSystem);
        mSpyDevInventory.setDeviceBroker(mAudioDeviceBroker);

        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();