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

Commit 74f681ee authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "MediaMetrics instrumentation"

parents f2d61833 a7ec6de6
Loading
Loading
Loading
Loading
+101 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
import android.media.IStrategyPreferredDeviceDispatcher;
import android.media.MediaMetrics;
import android.os.Binder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -64,6 +65,10 @@ public class AudioDeviceInventory {
    // lock to synchronize all access to mConnectedDevices and mApmConnectedDevices
    private final Object mDevicesLock = new Object();

    //Audio Analytics ids.
    private static final String mAnalyticsId = "audio.deviceInventory.";
    private static final String mAnalyticsPropEarlyReturn = "earlyReturn";

    // List of connected devices
    // Key for map created from DeviceInfo.makeDeviceListKey()
    @GuardedBy("mDevicesLock")
@@ -242,6 +247,15 @@ public class AudioDeviceInventory {
            final DeviceInfo di = mConnectedDevices.get(key);
            boolean isConnected = di != null;

            new MediaMetrics.Item(mAnalyticsId + "onSetA2dpSinkConnectionState")
                    .putInt("state", state)
                    .putString("address", address)
                    .putInt("a2dpCodec", a2dpCodec)
                    .putInt("a2dpVolume", a2dpVolume)
                    .putString("key", key)
                    .putInt("isConnected", isConnected ? 1 : 0)
                    .record();

            if (isConnected) {
                if (state == BluetoothProfile.STATE_CONNECTED) {
                    // device is already connected, but we are receiving a connection again,
@@ -284,6 +298,13 @@ public class AudioDeviceInventory {
            final DeviceInfo di = mConnectedDevices.get(key);
            boolean isConnected = di != null;

            new MediaMetrics.Item(mAnalyticsId + "onSetA2dpSourceConnectionState")
                    .putInt("state", state)
                    .putString("address", address)
                    .putString("key", key)
                    .putInt("isConnected", isConnected ? 1 : 0)
                    .record();

            if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
                makeA2dpSrcUnavailable(address);
            } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
@@ -307,6 +328,14 @@ public class AudioDeviceInventory {
            final DeviceInfo di = mConnectedDevices.get(key);
            boolean isConnected = di != null;

            new MediaMetrics.Item(mAnalyticsId + "onSetHearingAidConnectionState")
                    .putInt("state", state)
                    .putInt("streamType", streamType)
                    .putString("address", address)
                    .putString("key", key)
                    .putInt("isConnected", isConnected ? 1 : 0)
                    .record();

            if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
                makeHearingAidDeviceUnavailable(address);
            } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
@@ -319,8 +348,13 @@ public class AudioDeviceInventory {
    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
    /*package*/ void onBluetoothA2dpActiveDeviceChange(
            @NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo, int event) {
        MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId
                + "onBluetoothA2dpActiveDeviceChange")
                .putInt("event", event);

        final BluetoothDevice btDevice = btInfo.getBtDevice();
        if (btDevice == null) {
            mmi.putString(mAnalyticsPropEarlyReturn, "btDevice null").record();
            return;
        }
        if (AudioService.DEBUG_DEVICES) {
@@ -341,6 +375,7 @@ public class AudioDeviceInventory {
            if (mDeviceBroker.hasScheduledA2dpSinkConnectionState(btDevice)) {
                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                        "A2dp config change ignored (scheduled connection change)"));
                mmi.putString(mAnalyticsPropEarlyReturn, "A2dp config change ignored").record();
                return;
            }
            final String key = DeviceInfo.makeDeviceListKey(
@@ -348,9 +383,15 @@ public class AudioDeviceInventory {
            final DeviceInfo di = mConnectedDevices.get(key);
            if (di == null) {
                Log.e(TAG, "invalid null DeviceInfo in onBluetoothA2dpActiveDeviceChange");
                mmi.putString(mAnalyticsPropEarlyReturn, "null DeviceInfo").record();
                return;
            }

            mmi.putString("address", address)
                    .putInt("a2dpCodec", a2dpCodec)
                    .putInt("a2dpVolume", a2dpVolume)
                    .putString("key", key);

            if (event == BtHelper.EVENT_ACTIVE_DEVICE_CHANGE) {
                // Device is connected
                if (a2dpVolume != -1) {
@@ -382,12 +423,14 @@ public class AudioDeviceInventory {
                        btDevice, BluetoothA2dp.STATE_DISCONNECTED, BluetoothProfile.A2DP,
                        false /* suppressNoisyIntent */, musicDevice,
                        -1 /* a2dpVolume */);
                mmi.putInt("musicDevice", musicDevice);
            } else {
                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                        "APM handleDeviceConfigChange success for A2DP device addr="
                                + address + " codec=" + a2dpCodec).printLog(TAG));
            }
        }
        mmi.record();
    }

    /*package*/ void onMakeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
@@ -399,6 +442,8 @@ public class AudioDeviceInventory {
    /*package*/ void onReportNewRoutes() {
        int n = mRoutesObservers.beginBroadcast();
        if (n > 0) {
            new MediaMetrics.Item(mAnalyticsId + "onReportNewRoutes")
                    .putInt("routesObservers", n).record();
            AudioRoutesInfo routes;
            synchronized (mCurAudioRoutes) {
                routes = new AudioRoutesInfo(mCurAudioRoutes);
@@ -428,16 +473,24 @@ public class AudioDeviceInventory {
                            AudioDeviceInventory.WiredDeviceConnectionState wdcs) {
        AudioService.sDeviceLogger.log(new AudioServiceEvents.WiredDevConnectEvent(wdcs));

        MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId
                + "onSetWiredDeviceConnectionState")
                .putInt("wdcs.mState", wdcs.mState)
                .putInt("wdcs.mType", wdcs.mType);

        synchronized (mDevicesLock) {
            if ((wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED)
                    && DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(wdcs.mType)) {
                mDeviceBroker.setBluetoothA2dpOnInt(true,
                        "onSetWiredDeviceConnectionState state DISCONNECTED");
                mmi.putInt("setBluetoothA2dpOnInt", 1);
            }

            if (!handleDeviceConnection(wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED,
                    wdcs.mType, wdcs.mAddress, wdcs.mName)) {
                // change of connection state failed, bailout
                mmi.putString(mAnalyticsPropEarlyReturn, "change of connection state failed")
                        .record();
                return;
            }
            if (wdcs.mState != AudioService.CONNECTION_STATE_DISCONNECTED) {
@@ -446,22 +499,30 @@ public class AudioDeviceInventory {
                            "onSetWiredDeviceConnectionState state not DISCONNECTED");
                }
                mDeviceBroker.checkMusicActive(wdcs.mType, wdcs.mCaller);
                mmi.putInt("setBluetoothA2dpOnInt", 0);
            }
            if (wdcs.mType == AudioSystem.DEVICE_OUT_HDMI) {
                mDeviceBroker.checkVolumeCecOnHdmiConnection(wdcs.mState, wdcs.mCaller);
            }
            sendDeviceConnectionIntent(wdcs.mType, wdcs.mState, wdcs.mAddress, wdcs.mName);
            updateAudioRoutes(wdcs.mType, wdcs.mState);

            mmi.putString("wdcs.mAddress", wdcs.mAddress != null ? wdcs.mAddress : "")
                    .putString("wdcs.mName", wdcs.mName != null ? wdcs.mName : "")
                    .record();
        }
    }

    /*package*/ void onToggleHdmi() {
        MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId + "onToggleHdmi");
        synchronized (mDevicesLock) {
            // Is HDMI connected?
            final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HDMI, "");
            final DeviceInfo di = mConnectedDevices.get(key);
            mmi.putString("key", key);
            if (di == null) {
                Log.e(TAG, "invalid null DeviceInfo in onToggleHdmi");
                mmi.putString(mAnalyticsPropEarlyReturn, "invalid null DeviceInfo").record();
                return;
            }
            // Toggle HDMI to retrigger broadcast with proper formats.
@@ -472,6 +533,7 @@ public class AudioDeviceInventory {
                    AudioSystem.DEVICE_STATE_AVAILABLE, "", "",
                    "android"); // reconnect
        }
        mmi.record();
    }

    /*package*/ void onSaveSetPreferredDevice(int strategy, @NonNull AudioDeviceAttributes device) {
@@ -535,6 +597,11 @@ public class AudioDeviceInventory {
                    + Integer.toHexString(device) + " address:" + address
                    + " name:" + deviceName + ")");
        }
        MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId + "handleDeviceConnection")
                .putInt("connect", connect ? 1 : 0)
                .putInt("device", device)
                .putString("address", address != null ? address : "")
                .putString("deviceName", deviceName != null ? deviceName : "");
        synchronized (mDevicesLock) {
            final String deviceKey = DeviceInfo.makeDeviceListKey(device, address);
            if (AudioService.DEBUG_DEVICES) {
@@ -545,6 +612,8 @@ public class AudioDeviceInventory {
            if (AudioService.DEBUG_DEVICES) {
                Slog.i(TAG, "deviceInfo:" + di + " is(already)Connected:" + isConnected);
            }
            mmi.putString("deviceKey", deviceKey)
                    .putInt("isConnected", isConnected ? 1 : 0);
            if (connect && !isConnected) {
                final int res = mAudioSystem.setDeviceConnectionState(device,
                        AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName,
@@ -552,11 +621,14 @@ public class AudioDeviceInventory {
                if (res != AudioSystem.AUDIO_STATUS_OK) {
                    Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device)
                            + " due to command error " + res);
                    mmi.putInt("command error", res)
                            .putInt("result", 0).record();
                    return false;
                }
                mConnectedDevices.put(deviceKey, new DeviceInfo(
                        device, deviceName, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
                mDeviceBroker.postAccessoryPlugMediaUnmute(device);
                mmi.putInt("result", 1).record();
                return true;
            } else if (!connect && isConnected) {
                mAudioSystem.setDeviceConnectionState(device,
@@ -564,11 +636,13 @@ public class AudioDeviceInventory {
                        AudioSystem.AUDIO_FORMAT_DEFAULT);
                // always remove even if disconnection failed
                mConnectedDevices.remove(deviceKey);
                mmi.putInt("result", 1).record();
                return true;
            }
            Log.w(TAG, "handleDeviceConnection() failed, deviceKey=" + deviceKey
                    + ", deviceSpec=" + di + ", connect=" + connect);
        }
        mmi.putInt("result", 0).record();
        return false;
    }

@@ -582,6 +656,8 @@ public class AudioDeviceInventory {
                    toRemove.add(deviceInfo.mDeviceAddress);
                }
            });
            new MediaMetrics.Item(mAnalyticsId + "disconnectA2dp")
                    .putInt("toRemove.size", toRemove.size()).record();
            if (toRemove.size() > 0) {
                final int delay = checkSendBecomingNoisyIntentInt(
                        AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
@@ -602,6 +678,8 @@ public class AudioDeviceInventory {
                    toRemove.add(deviceInfo.mDeviceAddress);
                }
            });
            new MediaMetrics.Item(mAnalyticsId + "disconnectA2dpSink")
                    .putInt("toRemove.size", toRemove.size()).record();
            toRemove.stream().forEach(deviceAddress -> makeA2dpSrcUnavailable(deviceAddress));
        }
    }
@@ -615,6 +693,8 @@ public class AudioDeviceInventory {
                    toRemove.add(deviceInfo.mDeviceAddress);
                }
            });
            new MediaMetrics.Item(mAnalyticsId + "disconnectHearingAid")
                    .putInt("toRemove.size", toRemove.size()).record();
            if (toRemove.size() > 0) {
                final int delay = checkSendBecomingNoisyIntentInt(
                        AudioSystem.DEVICE_OUT_HEARING_AID, 0, AudioSystem.DEVICE_NONE);
@@ -771,18 +851,27 @@ public class AudioDeviceInventory {

    @GuardedBy("mDevicesLock")
    private void makeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
        MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId
                + "makeA2dpDeviceUnavailableNow")
                .putInt("a2dpCodec", a2dpCodec);
        if (address == null) {
            mmi.putString(mAnalyticsPropEarlyReturn, "address null").record();
            return;
        }
        final String deviceToRemoveKey =
                DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);

        mmi.putString("address", address)
                .putString("deviceToRemoveKey", deviceToRemoveKey);

        mConnectedDevices.remove(deviceToRemoveKey);
        if (!deviceToRemoveKey
                .equals(mApmConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP))) {
            // removing A2DP device not currently used by AudioPolicy, log but don't act on it
            AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
                    "A2DP device " + address + " made unavailable, was not used")).printLog(TAG));
            mmi.putString(mAnalyticsPropEarlyReturn, "A2DP device made unavailable, was not used")
                    .record();
            return;
        }

@@ -804,6 +893,7 @@ public class AudioDeviceInventory {
        mApmConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
        // Remove A2DP routes as well
        setCurrentAudioRouteNameIfPossible(null);
        mmi.record();
    }

    @GuardedBy("mDevicesLock")
@@ -873,6 +963,8 @@ public class AudioDeviceInventory {
                DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address));
        // Remove Hearing Aid routes as well
        setCurrentAudioRouteNameIfPossible(null);
        new MediaMetrics.Item(mAnalyticsId + "makeHearingAidDeviceUnavailable")
                .putString("address", address != null ? address : "").record();
    }

    @GuardedBy("mDevicesLock")
@@ -919,10 +1011,17 @@ public class AudioDeviceInventory {
    @GuardedBy("mDevicesLock")
    private int checkSendBecomingNoisyIntentInt(int device,
            @AudioService.ConnectionState int state, int musicDevice) {
        MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId
                + "checkSendBecomingNoisyIntentInt")
                .putInt("device", device)
                .putInt("state", state)
                .putInt("musicDevice", musicDevice);
        if (state != AudioService.CONNECTION_STATE_DISCONNECTED) {
            mmi.putString(mAnalyticsPropEarlyReturn, "CONNECTION_STATE_DISCONNECTED").record();
            return 0;
        }
        if (!BECOMING_NOISY_INTENT_DEVICES_SET.contains(device)) {
            mmi.putString(mAnalyticsPropEarlyReturn, "doesn't contains device").record();
            return 0;
        }
        int delay = 0;
@@ -950,12 +1049,14 @@ public class AudioDeviceInventory {
                // the pausing of some apps that are playing remotely
                AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
                        "dropping ACTION_AUDIO_BECOMING_NOISY")).printLog(TAG));
                mmi.putString(mAnalyticsPropEarlyReturn, "no media playback").record();
                return 0;
            }
            mDeviceBroker.postBroadcastBecomingNoisy();
            delay = AudioService.BECOMING_NOISY_DELAY_MS;
        }

        mmi.putInt("delay", delay).record();
        return delay;
    }

+198 −14

File changed.

Preview size limit exceeded, changes collapsed.

+36 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.audio;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.MediaMetrics;

import com.android.server.audio.AudioDeviceInventory.WiredDeviceConnectionState;

@@ -108,6 +109,11 @@ public class AudioServiceEvents {
        final String mGroupName;
        final AudioAttributes mAudioAttributes;

        /**
         * Audio Analytics unique Id.
         */
        private static final String mAnalyticsIdRoot = "audio.volumeEvent.";

        /** used for VOL_ADJUST_VOL_UID,
         *           VOL_ADJUST_SUGG_VOL,
         *           VOL_ADJUST_STREAM_VOL,
@@ -120,6 +126,13 @@ public class AudioServiceEvents {
            mCaller = caller;
            mGroupName = null;
            mAudioAttributes = null;

            new MediaMetrics.Item(mAnalyticsIdRoot + mStream)
                    .putInt("op", mOp)
                    .putInt("dir", mVal1)
                    .putInt("flags", mVal2)
                    .putString("from", mCaller)
                    .record();
        }

        /** used for VOL_SET_HEARING_AID_VOL*/
@@ -132,6 +145,12 @@ public class AudioServiceEvents {
            mCaller = null;
            mGroupName = null;
            mAudioAttributes = null;

            new MediaMetrics.Item(mAnalyticsIdRoot + "HA")
                    .putInt("op", mOp)
                    .putInt("index", mVal1)
                    .putInt("gainDb", mVal2)
                    .record();
        }

        /** used for VOL_SET_AVRCP_VOL */
@@ -144,6 +163,11 @@ public class AudioServiceEvents {
            mCaller = null;
            mGroupName = null;
            mAudioAttributes = null;

            new MediaMetrics.Item(mAnalyticsIdRoot + "AVRCP")
                    .putInt("op", mOp)
                    .putInt("index", mVal1)
                    .record();
        }

        /** used for VOL_VOICE_ACTIVITY_HEARING_AID */
@@ -156,6 +180,12 @@ public class AudioServiceEvents {
            mCaller = null;
            mGroupName = null;
            mAudioAttributes = null;

            new MediaMetrics.Item(mAnalyticsIdRoot + mStream)
                    .putInt("op", mOp)
                    .putInt("index", mVal1)
                    .putInt("voiceActive", mVal2)
                    .record();
        }

        /** used for VOL_MODE_CHANGE_HEARING_AID */
@@ -179,6 +209,12 @@ public class AudioServiceEvents {
            mCaller = caller;
            mGroupName = group;
            mAudioAttributes = aa;

            new MediaMetrics.Item(mAnalyticsIdRoot + mStream)
                    .putInt("op", mOp)
                    .putInt("index", mVal1)
                    .putInt("mode", mVal2)
                    .record();
        }

        @Override