Merge "MediaMetrics: Update Audio Java logging"

This commit is contained in:
Andy Hung
2020-04-22 15:26:54 +00:00
committed by Android (Google) Code Review
9 changed files with 782 additions and 262 deletions

View File

@@ -2712,6 +2712,32 @@ public class AudioManager {
}
}
/**
* @hide
*/
public static String audioFocusToString(int focus) {
switch (focus) {
case AUDIOFOCUS_NONE:
return "AUDIOFOCUS_NONE";
case AUDIOFOCUS_GAIN:
return "AUDIOFOCUS_GAIN";
case AUDIOFOCUS_GAIN_TRANSIENT:
return "AUDIOFOCUS_GAIN_TRANSIENT";
case AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
return "AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK";
case AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
return "AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE";
case AUDIOFOCUS_LOSS:
return "AUDIOFOCUS_LOSS";
case AUDIOFOCUS_LOSS_TRANSIENT:
return "AUDIOFOCUS_LOSS_TRANSIENT";
case AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // Note CAN_DUCK not MAY_DUCK.
return "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK";
default:
return "AUDIO_FOCUS_UNKNOWN(" + focus + ")";
}
}
/**
* Used to indicate no audio focus has been gained or lost, or requested.
*/

View File

@@ -214,6 +214,175 @@ public class AudioSystem
}
}
/**
* @hide
* Convert a native audio format integer constant to a string.
*/
public static String audioFormatToString(int audioFormat) {
switch (audioFormat) {
case /* AUDIO_FORMAT_INVALID */ 0xFFFFFFFF:
return "AUDIO_FORMAT_INVALID";
case /* AUDIO_FORMAT_DEFAULT */ 0:
return "AUDIO_FORMAT_DEFAULT";
case /* AUDIO_FORMAT_MP3 */ 0x01000000:
return "AUDIO_FORMAT_MP3";
case /* AUDIO_FORMAT_AMR_NB */ 0x02000000:
return "AUDIO_FORMAT_AMR_NB";
case /* AUDIO_FORMAT_AMR_WB */ 0x03000000:
return "AUDIO_FORMAT_AMR_WB";
case /* AUDIO_FORMAT_AAC */ 0x04000000:
return "AUDIO_FORMAT_AAC";
case /* AUDIO_FORMAT_HE_AAC_V1 */ 0x05000000:
return "AUDIO_FORMAT_HE_AAC_V1";
case /* AUDIO_FORMAT_HE_AAC_V2 */ 0x06000000:
return "AUDIO_FORMAT_HE_AAC_V2";
case /* AUDIO_FORMAT_VORBIS */ 0x07000000:
return "AUDIO_FORMAT_VORBIS";
case /* AUDIO_FORMAT_OPUS */ 0x08000000:
return "AUDIO_FORMAT_OPUS";
case /* AUDIO_FORMAT_AC3 */ 0x09000000:
return "AUDIO_FORMAT_AC3";
case /* AUDIO_FORMAT_E_AC3 */ 0x0A000000:
return "AUDIO_FORMAT_E_AC3";
case /* AUDIO_FORMAT_DTS */ 0x0B000000:
return "AUDIO_FORMAT_DTS";
case /* AUDIO_FORMAT_DTS_HD */ 0x0C000000:
return "AUDIO_FORMAT_DTS_HD";
case /* AUDIO_FORMAT_IEC61937 */ 0x0D000000:
return "AUDIO_FORMAT_IEC61937";
case /* AUDIO_FORMAT_DOLBY_TRUEHD */ 0x0E000000:
return "AUDIO_FORMAT_DOLBY_TRUEHD";
case /* AUDIO_FORMAT_EVRC */ 0x10000000:
return "AUDIO_FORMAT_EVRC";
case /* AUDIO_FORMAT_EVRCB */ 0x11000000:
return "AUDIO_FORMAT_EVRCB";
case /* AUDIO_FORMAT_EVRCWB */ 0x12000000:
return "AUDIO_FORMAT_EVRCWB";
case /* AUDIO_FORMAT_EVRCNW */ 0x13000000:
return "AUDIO_FORMAT_EVRCNW";
case /* AUDIO_FORMAT_AAC_ADIF */ 0x14000000:
return "AUDIO_FORMAT_AAC_ADIF";
case /* AUDIO_FORMAT_WMA */ 0x15000000:
return "AUDIO_FORMAT_WMA";
case /* AUDIO_FORMAT_WMA_PRO */ 0x16000000:
return "AUDIO_FORMAT_WMA_PRO";
case /* AUDIO_FORMAT_AMR_WB_PLUS */ 0x17000000:
return "AUDIO_FORMAT_AMR_WB_PLUS";
case /* AUDIO_FORMAT_MP2 */ 0x18000000:
return "AUDIO_FORMAT_MP2";
case /* AUDIO_FORMAT_QCELP */ 0x19000000:
return "AUDIO_FORMAT_QCELP";
case /* AUDIO_FORMAT_DSD */ 0x1A000000:
return "AUDIO_FORMAT_DSD";
case /* AUDIO_FORMAT_FLAC */ 0x1B000000:
return "AUDIO_FORMAT_FLAC";
case /* AUDIO_FORMAT_ALAC */ 0x1C000000:
return "AUDIO_FORMAT_ALAC";
case /* AUDIO_FORMAT_APE */ 0x1D000000:
return "AUDIO_FORMAT_APE";
case /* AUDIO_FORMAT_AAC_ADTS */ 0x1E000000:
return "AUDIO_FORMAT_AAC_ADTS";
case /* AUDIO_FORMAT_SBC */ 0x1F000000:
return "AUDIO_FORMAT_SBC";
case /* AUDIO_FORMAT_APTX */ 0x20000000:
return "AUDIO_FORMAT_APTX";
case /* AUDIO_FORMAT_APTX_HD */ 0x21000000:
return "AUDIO_FORMAT_APTX_HD";
case /* AUDIO_FORMAT_AC4 */ 0x22000000:
return "AUDIO_FORMAT_AC4";
case /* AUDIO_FORMAT_LDAC */ 0x23000000:
return "AUDIO_FORMAT_LDAC";
case /* AUDIO_FORMAT_MAT */ 0x24000000:
return "AUDIO_FORMAT_MAT";
case /* AUDIO_FORMAT_AAC_LATM */ 0x25000000:
return "AUDIO_FORMAT_AAC_LATM";
case /* AUDIO_FORMAT_CELT */ 0x26000000:
return "AUDIO_FORMAT_CELT";
case /* AUDIO_FORMAT_APTX_ADAPTIVE */ 0x27000000:
return "AUDIO_FORMAT_APTX_ADAPTIVE";
case /* AUDIO_FORMAT_LHDC */ 0x28000000:
return "AUDIO_FORMAT_LHDC";
case /* AUDIO_FORMAT_LHDC_LL */ 0x29000000:
return "AUDIO_FORMAT_LHDC_LL";
case /* AUDIO_FORMAT_APTX_TWSP */ 0x2A000000:
return "AUDIO_FORMAT_APTX_TWSP";
/* Aliases */
case /* AUDIO_FORMAT_PCM_16_BIT */ 0x1:
return "AUDIO_FORMAT_PCM_16_BIT"; // (PCM | PCM_SUB_16_BIT)
case /* AUDIO_FORMAT_PCM_8_BIT */ 0x2:
return "AUDIO_FORMAT_PCM_8_BIT"; // (PCM | PCM_SUB_8_BIT)
case /* AUDIO_FORMAT_PCM_32_BIT */ 0x3:
return "AUDIO_FORMAT_PCM_32_BIT"; // (PCM | PCM_SUB_32_BIT)
case /* AUDIO_FORMAT_PCM_8_24_BIT */ 0x4:
return "AUDIO_FORMAT_PCM_8_24_BIT"; // (PCM | PCM_SUB_8_24_BIT)
case /* AUDIO_FORMAT_PCM_FLOAT */ 0x5:
return "AUDIO_FORMAT_PCM_FLOAT"; // (PCM | PCM_SUB_FLOAT)
case /* AUDIO_FORMAT_PCM_24_BIT_PACKED */ 0x6:
return "AUDIO_FORMAT_PCM_24_BIT_PACKED"; // (PCM | PCM_SUB_24_BIT_PACKED)
case /* AUDIO_FORMAT_AAC_MAIN */ 0x4000001:
return "AUDIO_FORMAT_AAC_MAIN"; // (AAC | AAC_SUB_MAIN)
case /* AUDIO_FORMAT_AAC_LC */ 0x4000002:
return "AUDIO_FORMAT_AAC_LC"; // (AAC | AAC_SUB_LC)
case /* AUDIO_FORMAT_AAC_SSR */ 0x4000004:
return "AUDIO_FORMAT_AAC_SSR"; // (AAC | AAC_SUB_SSR)
case /* AUDIO_FORMAT_AAC_LTP */ 0x4000008:
return "AUDIO_FORMAT_AAC_LTP"; // (AAC | AAC_SUB_LTP)
case /* AUDIO_FORMAT_AAC_HE_V1 */ 0x4000010:
return "AUDIO_FORMAT_AAC_HE_V1"; // (AAC | AAC_SUB_HE_V1)
case /* AUDIO_FORMAT_AAC_SCALABLE */ 0x4000020:
return "AUDIO_FORMAT_AAC_SCALABLE"; // (AAC | AAC_SUB_SCALABLE)
case /* AUDIO_FORMAT_AAC_ERLC */ 0x4000040:
return "AUDIO_FORMAT_AAC_ERLC"; // (AAC | AAC_SUB_ERLC)
case /* AUDIO_FORMAT_AAC_LD */ 0x4000080:
return "AUDIO_FORMAT_AAC_LD"; // (AAC | AAC_SUB_LD)
case /* AUDIO_FORMAT_AAC_HE_V2 */ 0x4000100:
return "AUDIO_FORMAT_AAC_HE_V2"; // (AAC | AAC_SUB_HE_V2)
case /* AUDIO_FORMAT_AAC_ELD */ 0x4000200:
return "AUDIO_FORMAT_AAC_ELD"; // (AAC | AAC_SUB_ELD)
case /* AUDIO_FORMAT_AAC_XHE */ 0x4000300:
return "AUDIO_FORMAT_AAC_XHE"; // (AAC | AAC_SUB_XHE)
case /* AUDIO_FORMAT_AAC_ADTS_MAIN */ 0x1e000001:
return "AUDIO_FORMAT_AAC_ADTS_MAIN"; // (AAC_ADTS | AAC_SUB_MAIN)
case /* AUDIO_FORMAT_AAC_ADTS_LC */ 0x1e000002:
return "AUDIO_FORMAT_AAC_ADTS_LC"; // (AAC_ADTS | AAC_SUB_LC)
case /* AUDIO_FORMAT_AAC_ADTS_SSR */ 0x1e000004:
return "AUDIO_FORMAT_AAC_ADTS_SSR"; // (AAC_ADTS | AAC_SUB_SSR)
case /* AUDIO_FORMAT_AAC_ADTS_LTP */ 0x1e000008:
return "AUDIO_FORMAT_AAC_ADTS_LTP"; // (AAC_ADTS | AAC_SUB_LTP)
case /* AUDIO_FORMAT_AAC_ADTS_HE_V1 */ 0x1e000010:
return "AUDIO_FORMAT_AAC_ADTS_HE_V1"; // (AAC_ADTS | AAC_SUB_HE_V1)
case /* AUDIO_FORMAT_AAC_ADTS_SCALABLE */ 0x1e000020:
return "AUDIO_FORMAT_AAC_ADTS_SCALABLE"; // (AAC_ADTS | AAC_SUB_SCALABLE)
case /* AUDIO_FORMAT_AAC_ADTS_ERLC */ 0x1e000040:
return "AUDIO_FORMAT_AAC_ADTS_ERLC"; // (AAC_ADTS | AAC_SUB_ERLC)
case /* AUDIO_FORMAT_AAC_ADTS_LD */ 0x1e000080:
return "AUDIO_FORMAT_AAC_ADTS_LD"; // (AAC_ADTS | AAC_SUB_LD)
case /* AUDIO_FORMAT_AAC_ADTS_HE_V2 */ 0x1e000100:
return "AUDIO_FORMAT_AAC_ADTS_HE_V2"; // (AAC_ADTS | AAC_SUB_HE_V2)
case /* AUDIO_FORMAT_AAC_ADTS_ELD */ 0x1e000200:
return "AUDIO_FORMAT_AAC_ADTS_ELD"; // (AAC_ADTS | AAC_SUB_ELD)
case /* AUDIO_FORMAT_AAC_ADTS_XHE */ 0x1e000300:
return "AUDIO_FORMAT_AAC_ADTS_XHE"; // (AAC_ADTS | AAC_SUB_XHE)
case /* AUDIO_FORMAT_AAC_LATM_LC */ 0x25000002:
return "AUDIO_FORMAT_AAC_LATM_LC"; // (AAC_LATM | AAC_SUB_LC)
case /* AUDIO_FORMAT_AAC_LATM_HE_V1 */ 0x25000010:
return "AUDIO_FORMAT_AAC_LATM_HE_V1"; // (AAC_LATM | AAC_SUB_HE_V1)
case /* AUDIO_FORMAT_AAC_LATM_HE_V2 */ 0x25000100:
return "AUDIO_FORMAT_AAC_LATM_HE_V2"; // (AAC_LATM | AAC_SUB_HE_V2)
case /* AUDIO_FORMAT_E_AC3_JOC */ 0xA000001:
return "AUDIO_FORMAT_E_AC3_JOC"; // (E_AC3 | E_AC3_SUB_JOC)
case /* AUDIO_FORMAT_MAT_1_0 */ 0x24000001:
return "AUDIO_FORMAT_MAT_1_0"; // (MAT | MAT_SUB_1_0)
case /* AUDIO_FORMAT_MAT_2_0 */ 0x24000002:
return "AUDIO_FORMAT_MAT_2_0"; // (MAT | MAT_SUB_2_0)
case /* AUDIO_FORMAT_MAT_2_1 */ 0x24000003:
return "AUDIO_FORMAT_MAT_2_1"; // (MAT | MAT_SUB_2_1)
default:
return "AUDIO_FORMAT_(" + audioFormat + ")";
}
}
/* Routing bits for the former setRouting/getRouting API */
/** @hide @deprecated */
@Deprecated public static final int ROUTE_EARPIECE = (1 << 0);

View File

@@ -38,6 +38,117 @@ import java.util.Objects;
public class MediaMetrics {
public static final String TAG = "MediaMetrics";
public static final String SEPARATOR = ".";
/**
* A list of established MediaMetrics names that can be used for Items.
*/
public static class Name {
public static final String AUDIO = "audio";
public static final String AUDIO_BLUETOOTH = AUDIO + SEPARATOR + "bluetooth";
public static final String AUDIO_DEVICE = AUDIO + SEPARATOR + "device";
public static final String AUDIO_FOCUS = AUDIO + SEPARATOR + "focus";
public static final String AUDIO_FORCE_USE = AUDIO + SEPARATOR + "forceUse";
public static final String AUDIO_MIC = AUDIO + SEPARATOR + "mic";
public static final String AUDIO_SERVICE = AUDIO + SEPARATOR + "service";
public static final String AUDIO_VOLUME = AUDIO + SEPARATOR + "volume";
public static final String AUDIO_VOLUME_EVENT = AUDIO_VOLUME + SEPARATOR + "event";
}
/**
* A list of established string values.
*/
public static class Value {
public static final String CONNECT = "connect";
public static final String CONNECTED = "connected";
public static final String DISCONNECT = "disconnect";
public static final String DISCONNECTED = "disconnected";
public static final String DOWN = "down";
public static final String MUTE = "mute";
public static final String NO = "no";
public static final String OFF = "off";
public static final String ON = "on";
public static final String UNMUTE = "unmute";
public static final String UP = "up";
public static final String YES = "yes";
}
/**
* A list of standard property keys for consistent use and type.
*/
public static class Property {
// A use for Bluetooth or USB device addresses
public static final Key<String> ADDRESS = createKey("address", String.class);
// A string representing the Audio Attributes
public static final Key<String> ATTRIBUTES = createKey("attributes", String.class);
// The calling package responsible for the state change
public static final Key<String> CALLING_PACKAGE =
createKey("callingPackage", String.class);
// The client name
public static final Key<String> CLIENT_NAME = createKey("clientName", String.class);
// The device type
public static final Key<Integer> DELAY_MS = createKey("delayMs", Integer.class);
// The device type
public static final Key<String> DEVICE = createKey("device", String.class);
// For volume changes, up or down
public static final Key<String> DIRECTION = createKey("direction", String.class);
// A reason for early return or error
public static final Key<String> EARLY_RETURN =
createKey("earlyReturn", String.class);
// ENCODING_ ... string to match AudioFormat encoding
public static final Key<String> ENCODING = createKey("encoding", String.class);
public static final Key<String> EVENT = createKey("event#", String.class);
// event generated is external (yes, no)
public static final Key<String> EXTERNAL = createKey("external", String.class);
public static final Key<Integer> FLAGS = createKey("flags", Integer.class);
public static final Key<String> FOCUS_CHANGE_HINT =
createKey("focusChangeHint", String.class);
public static final Key<String> FORCE_USE_DUE_TO =
createKey("forceUseDueTo", String.class);
public static final Key<String> FORCE_USE_MODE =
createKey("forceUseMode", String.class);
public static final Key<Double> GAIN_DB =
createKey("gainDb", Double.class);
public static final Key<String> GROUP =
createKey("group", String.class);
// For volume
public static final Key<Integer> INDEX = createKey("index", Integer.class);
public static final Key<Integer> MAX_INDEX = createKey("maxIndex", Integer.class);
public static final Key<Integer> MIN_INDEX = createKey("minIndex", Integer.class);
public static final Key<String> MODE =
createKey("mode", String.class); // audio_mode
public static final Key<String> MUTE =
createKey("mute", String.class); // microphone, on or off.
// Bluetooth or Usb device name
public static final Key<String> NAME =
createKey("name", String.class);
// Number of observers
public static final Key<Integer> OBSERVERS =
createKey("observers", Integer.class);
public static final Key<String> REQUEST =
createKey("request", String.class);
// For Bluetooth
public static final Key<String> SCO_AUDIO_MODE =
createKey("scoAudioMode", String.class);
public static final Key<Integer> SDK = createKey("sdk", Integer.class);
public static final Key<String> STATE = createKey("state", String.class);
public static final Key<Integer> STATUS = createKey("status", Integer.class);
public static final Key<String> STREAM_TYPE = createKey("streamType", String.class);
}
/**
* The TYPE constants below should match those in native MediaMetricsItem.h
*/

View File

@@ -30,6 +30,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.Handler;
import android.os.IBinder;
@@ -668,6 +669,13 @@ import java.io.PrintWriter;
}
AudioService.sForceUseLogger.log(
new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE + MediaMetrics.SEPARATOR
+ AudioSystem.forceUseUsageToString(useCase))
.set(MediaMetrics.Property.EVENT, "onSetForceUse")
.set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
.set(MediaMetrics.Property.FORCE_USE_MODE,
AudioSystem.forceUseConfigToString(config))
.record();
AudioSystem.setForceUse(useCase, config);
}

View File

@@ -66,13 +66,68 @@ public class AudioDeviceInventory {
private final Object mDevicesLock = new Object();
//Audio Analytics ids.
private static final String mAnalyticsId = "audio.deviceInventory.";
private static final String mAnalyticsPropEarlyReturn = "earlyReturn";
private static final String mMetricsId = "audio.device.";
// List of connected devices
// Key for map created from DeviceInfo.makeDeviceListKey()
@GuardedBy("mDevicesLock")
private final LinkedHashMap<String, DeviceInfo> mConnectedDevices = new LinkedHashMap<>();
private final LinkedHashMap<String, DeviceInfo> mConnectedDevices = new LinkedHashMap<>() {
@Override
public DeviceInfo put(String key, DeviceInfo value) {
final DeviceInfo result = super.put(key, value);
record("put", true /* connected */, key, value);
return result;
}
@Override
public DeviceInfo putIfAbsent(String key, DeviceInfo value) {
final DeviceInfo result = super.putIfAbsent(key, value);
if (result == null) {
record("putIfAbsent", true /* connected */, key, value);
}
return result;
}
@Override
public DeviceInfo remove(Object key) {
final DeviceInfo result = super.remove(key);
if (result != null) {
record("remove", false /* connected */, (String) key, result);
}
return result;
}
@Override
public boolean remove(Object key, Object value) {
final boolean result = super.remove(key, value);
if (result) {
record("remove", false /* connected */, (String) key, (DeviceInfo) value);
}
return result;
}
// Not overridden
// clear
// compute
// computeIfAbsent
// computeIfPresent
// merge
// putAll
// replace
// replaceAll
private void record(String event, boolean connected, String key, DeviceInfo value) {
// DeviceInfo - int mDeviceType;
// DeviceInfo - int mDeviceCodecFormat;
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+ MediaMetrics.SEPARATOR + AudioSystem.getDeviceName(value.mDeviceType))
.set(MediaMetrics.Property.ADDRESS, value.mDeviceAddress)
.set(MediaMetrics.Property.EVENT, event)
.set(MediaMetrics.Property.NAME, value.mDeviceName)
.set(MediaMetrics.Property.STATE, connected
? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
.record();
}
};
// List of devices actually connected to AudioPolicy (through AudioSystem), only one
// by device type, which is used as the key, value is the DeviceInfo generated key.
@@ -241,21 +296,22 @@ public class AudioDeviceInventory {
+ " codec=" + a2dpCodec
+ " vol=" + a2dpVolume));
new MediaMetrics.Item(mMetricsId + "a2dp")
.set(MediaMetrics.Property.ADDRESS, address)
.set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(a2dpCodec))
.set(MediaMetrics.Property.EVENT, "onSetA2dpSinkConnectionState")
.set(MediaMetrics.Property.INDEX, a2dpVolume)
.set(MediaMetrics.Property.STATE,
state == BluetoothProfile.STATE_CONNECTED
? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
.record();
synchronized (mDevicesLock) {
final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
btDevice.getAddress());
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,
@@ -298,11 +354,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)
new MediaMetrics.Item(mMetricsId + "onSetA2dpSourceConnectionState")
.set(MediaMetrics.Property.ADDRESS, address)
.set(MediaMetrics.Property.DEVICE,
AudioSystem.getDeviceName(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP))
.set(MediaMetrics.Property.STATE,
state == BluetoothProfile.STATE_CONNECTED
? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
.record();
if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
@@ -322,20 +380,23 @@ public class AudioDeviceInventory {
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
"onSetHearingAidConnectionState addr=" + address));
new MediaMetrics.Item(mMetricsId + "onSetHearingAidConnectionState")
.set(MediaMetrics.Property.ADDRESS, address)
.set(MediaMetrics.Property.DEVICE,
AudioSystem.getDeviceName(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP))
.set(MediaMetrics.Property.STATE,
state == BluetoothProfile.STATE_CONNECTED
? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
.set(MediaMetrics.Property.STREAM_TYPE,
AudioSystem.streamToString(streamType))
.record();
synchronized (mDevicesLock) {
final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID,
btDevice.getAddress());
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) {
@@ -346,15 +407,15 @@ public class AudioDeviceInventory {
}
@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ void onBluetoothA2dpActiveDeviceChange(
/*package*/ void onBluetoothA2dpActiveDeviceChange(
@NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo, int event) {
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
+ "onBluetoothA2dpActiveDeviceChange")
.putInt("event", event);
.set(MediaMetrics.Property.EVENT, BtHelper.a2dpDeviceEventToString(event));
final BluetoothDevice btDevice = btInfo.getBtDevice();
if (btDevice == null) {
mmi.putString(mAnalyticsPropEarlyReturn, "btDevice null").record();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "btDevice null").record();
return;
}
if (AudioService.DEBUG_DEVICES) {
@@ -375,7 +436,8 @@ 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();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "A2dp config change ignored")
.record();
return;
}
final String key = DeviceInfo.makeDeviceListKey(
@@ -383,14 +445,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();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "null DeviceInfo").record();
return;
}
mmi.putString("address", address)
.putInt("a2dpCodec", a2dpCodec)
.putInt("a2dpVolume", a2dpVolume)
.putString("key", key);
mmi.set(MediaMetrics.Property.ADDRESS, address)
.set(MediaMetrics.Property.ENCODING,
AudioSystem.audioFormatToString(a2dpCodec))
.set(MediaMetrics.Property.INDEX, a2dpVolume)
.set(MediaMetrics.Property.NAME, di.mDeviceName);
if (event == BtHelper.EVENT_ACTIVE_DEVICE_CHANGE) {
// Device is connected
@@ -423,7 +486,6 @@ 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="
@@ -442,8 +504,9 @@ public class AudioDeviceInventory {
/*package*/ void onReportNewRoutes() {
int n = mRoutesObservers.beginBroadcast();
if (n > 0) {
new MediaMetrics.Item(mAnalyticsId + "onReportNewRoutes")
.putInt("routesObservers", n).record();
new MediaMetrics.Item(mMetricsId + "onReportNewRoutes")
.set(MediaMetrics.Property.OBSERVERS, n)
.record();
AudioRoutesInfo routes;
synchronized (mCurAudioRoutes) {
routes = new AudioRoutesInfo(mCurAudioRoutes);
@@ -473,23 +536,24 @@ public class AudioDeviceInventory {
AudioDeviceInventory.WiredDeviceConnectionState wdcs) {
AudioService.sDeviceLogger.log(new AudioServiceEvents.WiredDevConnectEvent(wdcs));
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
+ "onSetWiredDeviceConnectionState")
.putInt("wdcs.mState", wdcs.mState)
.putInt("wdcs.mType", wdcs.mType);
.set(MediaMetrics.Property.ADDRESS, wdcs.mAddress)
.set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(wdcs.mType))
.set(MediaMetrics.Property.STATE,
wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED
? MediaMetrics.Value.DISCONNECTED : MediaMetrics.Value.CONNECTED);
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")
mmi.set(MediaMetrics.Property.EARLY_RETURN, "change of connection state failed")
.record();
return;
}
@@ -499,30 +563,27 @@ 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();
}
mmi.record();
}
/*package*/ void onToggleHdmi() {
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId + "onToggleHdmi");
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onToggleHdmi")
.set(MediaMetrics.Property.DEVICE,
AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HDMI));
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();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "invalid null DeviceInfo").record();
return;
}
// Toggle HDMI to retrigger broadcast with proper formats.
@@ -597,11 +658,12 @@ 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 : "");
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "handleDeviceConnection")
.set(MediaMetrics.Property.ADDRESS, address)
.set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(device))
.set(MediaMetrics.Property.MODE, connect
? MediaMetrics.Value.CONNECT : MediaMetrics.Value.DISCONNECT)
.set(MediaMetrics.Property.NAME, deviceName);
synchronized (mDevicesLock) {
final String deviceKey = DeviceInfo.makeDeviceListKey(device, address);
if (AudioService.DEBUG_DEVICES) {
@@ -612,23 +674,23 @@ 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,
AudioSystem.AUDIO_FORMAT_DEFAULT);
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();
final String reason = "not connecting device 0x" + Integer.toHexString(device)
+ " due to command error " + res;
Slog.e(TAG, reason);
mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
.set(MediaMetrics.Property.STATE, MediaMetrics.Value.DISCONNECTED)
.record();
return false;
}
mConnectedDevices.put(deviceKey, new DeviceInfo(
device, deviceName, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
mDeviceBroker.postAccessoryPlugMediaUnmute(device);
mmi.putInt("result", 1).record();
mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.CONNECTED).record();
return true;
} else if (!connect && isConnected) {
mAudioSystem.setDeviceConnectionState(device,
@@ -636,13 +698,13 @@ public class AudioDeviceInventory {
AudioSystem.AUDIO_FORMAT_DEFAULT);
// always remove even if disconnection failed
mConnectedDevices.remove(deviceKey);
mmi.putInt("result", 1).record();
mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.CONNECTED).record();
return true;
}
Log.w(TAG, "handleDeviceConnection() failed, deviceKey=" + deviceKey
+ ", deviceSpec=" + di + ", connect=" + connect);
}
mmi.putInt("result", 0).record();
mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.DISCONNECTED).record();
return false;
}
@@ -656,8 +718,8 @@ public class AudioDeviceInventory {
toRemove.add(deviceInfo.mDeviceAddress);
}
});
new MediaMetrics.Item(mAnalyticsId + "disconnectA2dp")
.putInt("toRemove.size", toRemove.size()).record();
new MediaMetrics.Item(mMetricsId + "disconnectA2dp")
.record();
if (toRemove.size() > 0) {
final int delay = checkSendBecomingNoisyIntentInt(
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
@@ -678,8 +740,8 @@ public class AudioDeviceInventory {
toRemove.add(deviceInfo.mDeviceAddress);
}
});
new MediaMetrics.Item(mAnalyticsId + "disconnectA2dpSink")
.putInt("toRemove.size", toRemove.size()).record();
new MediaMetrics.Item(mMetricsId + "disconnectA2dpSink")
.record();
toRemove.stream().forEach(deviceAddress -> makeA2dpSrcUnavailable(deviceAddress));
}
}
@@ -693,8 +755,8 @@ public class AudioDeviceInventory {
toRemove.add(deviceInfo.mDeviceAddress);
}
});
new MediaMetrics.Item(mAnalyticsId + "disconnectHearingAid")
.putInt("toRemove.size", toRemove.size()).record();
new MediaMetrics.Item(mMetricsId + "disconnectHearingAid")
.record();
if (toRemove.size() > 0) {
final int delay = checkSendBecomingNoisyIntentInt(
AudioSystem.DEVICE_OUT_HEARING_AID, 0, AudioSystem.DEVICE_NONE);
@@ -823,6 +885,8 @@ public class AudioDeviceInventory {
final int res = mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
AudioSystem.DEVICE_STATE_AVAILABLE, address, name, a2dpCodec);
// TODO: log in MediaMetrics once distinction between connection failure and
// double connection is made.
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
"APM failed to make available A2DP device addr=" + address
@@ -851,26 +915,25 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private void makeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId
+ "makeA2dpDeviceUnavailableNow")
.putInt("a2dpCodec", a2dpCodec);
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "a2dp." + address)
.set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(a2dpCodec))
.set(MediaMetrics.Property.EVENT, "makeA2dpDeviceUnavailableNow");
if (address == null) {
mmi.putString(mAnalyticsPropEarlyReturn, "address null").record();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "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")
mmi.set(MediaMetrics.Property.EARLY_RETURN,
"A2DP device made unavailable, was not used")
.record();
return;
}
@@ -952,6 +1015,14 @@ public class AudioDeviceInventory {
mDeviceBroker.postApplyVolumeOnDevice(streamType,
AudioSystem.DEVICE_OUT_HEARING_AID, "makeHearingAidDeviceAvailable");
setCurrentAudioRouteNameIfPossible(name);
new MediaMetrics.Item(mMetricsId + "makeHearingAidDeviceAvailable")
.set(MediaMetrics.Property.ADDRESS, address != null ? address : "")
.set(MediaMetrics.Property.DEVICE,
AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HEARING_AID))
.set(MediaMetrics.Property.NAME, name)
.set(MediaMetrics.Property.STREAM_TYPE,
AudioSystem.streamToString(streamType))
.record();
}
@GuardedBy("mDevicesLock")
@@ -963,8 +1034,11 @@ 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();
new MediaMetrics.Item(mMetricsId + "makeHearingAidDeviceUnavailable")
.set(MediaMetrics.Property.ADDRESS, address != null ? address : "")
.set(MediaMetrics.Property.DEVICE,
AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HEARING_AID))
.record();
}
@GuardedBy("mDevicesLock")
@@ -1011,17 +1085,18 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private int checkSendBecomingNoisyIntentInt(int device,
@AudioService.ConnectionState int state, int musicDevice) {
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
+ "checkSendBecomingNoisyIntentInt")
.putInt("device", device)
.putInt("state", state)
.putInt("musicDevice", musicDevice);
.set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(device))
.set(MediaMetrics.Property.STATE,
state == AudioService.CONNECTION_STATE_CONNECTED
? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED);
if (state != AudioService.CONNECTION_STATE_DISCONNECTED) {
mmi.putString(mAnalyticsPropEarlyReturn, "CONNECTION_STATE_DISCONNECTED").record();
mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return
return 0;
}
if (!BECOMING_NOISY_INTENT_DEVICES_SET.contains(device)) {
mmi.putString(mAnalyticsPropEarlyReturn, "doesn't contains device").record();
mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return
return 0;
}
int delay = 0;
@@ -1049,14 +1124,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();
mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return
return 0;
}
mDeviceBroker.postBroadcastBecomingNoisy();
delay = AudioService.BECOMING_NOISY_DELAY_MS;
}
mmi.putInt("delay", delay).record();
mmi.set(MediaMetrics.Property.DELAY_MS, delay).record();
return delay;
}

View File

@@ -1881,19 +1881,20 @@ public class AudioService extends IAudioService.Stub
synchronized (mExtVolumeControllerLock) {
extVolCtlr = mExtVolumeController;
}
new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume")
.setUid(Binder.getCallingUid())
.set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
.set(MediaMetrics.Property.CLIENT_NAME, caller)
.set(MediaMetrics.Property.DIRECTION, direction > 0
? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN)
.set(MediaMetrics.Property.EXTERNAL, extVolCtlr != null
? MediaMetrics.Value.YES : MediaMetrics.Value.NO)
.set(MediaMetrics.Property.FLAGS, flags)
.record();
if (extVolCtlr != null) {
sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
direction, 0 /*ignored*/,
extVolCtlr, 0 /*delay*/);
new MediaMetrics.Item(mAnalyticsId + "adjustSuggestedStreamVolume")
.setUid(Binder.getCallingUid())
.putInt("extVolCtlr", extVolCtlr != null ? 1 : 0)
.putInt("direction", direction)
.putInt("flags", flags)
.putString("callingPackage", callingPackage)
.putString("caller", caller)
.record();
} else {
adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage,
caller, Binder.getCallingUid());
@@ -1980,22 +1981,12 @@ public class AudioService extends IAudioService.Stub
if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
+ ", flags=" + flags + ", caller=" + caller);
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId + "adjustStreamVolume")
.setUid(uid)
.setPid(Binder.getCallingPid())
.putInt("streamType", streamType)
.putInt("direction", direction)
.putInt("flags", flags)
.putString("callingPackage", callingPackage)
.putString("caller", caller);
ensureValidDirection(direction);
ensureValidStreamType(streamType);
boolean isMuteAdjust = isMuteAdjust(direction);
if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
mmi.putString(mAnalyticsPropEarlyReturn, "isMuteAdjust").record();
return;
}
@@ -2009,7 +2000,6 @@ public class AudioService extends IAudioService.Stub
!= PackageManager.PERMISSION_GRANTED) {
Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid="
+ Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
mmi.putString(mAnalyticsPropEarlyReturn, "Permission Denial").record();
return;
}
@@ -2041,7 +2031,6 @@ public class AudioService extends IAudioService.Stub
// is not an a2dp device
if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
&& (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
mmi.putString(mAnalyticsPropEarlyReturn, "skip a2dp").record();
return;
}
@@ -2052,7 +2041,6 @@ public class AudioService extends IAudioService.Stub
}
if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)
!= AppOpsManager.MODE_ALLOWED) {
mmi.putString(mAnalyticsPropEarlyReturn, "mode not allowed").record();
return;
}
@@ -2163,15 +2151,6 @@ public class AudioService extends IAudioService.Stub
0,
streamState,
0);
mmi.putInt("device", device)
.putInt("streamType2", streamState.mStreamType)
.putInt("isMuted", streamState.mIsMuted ? 1 : 0)
.putInt("indexMin", streamState.mIndexMin)
.putInt("indexMax", streamState.mIndexMax)
.putInt("observedDevices", streamState.mObservedDevices)
.putInt("flags2", flags)
.putInt("streamTypeAlias", streamTypeAlias);
}
int newIndex = mStreamStates[streamType].getIndex(device);
@@ -2185,7 +2164,6 @@ public class AudioService extends IAudioService.Stub
+ newIndex + "stream=" + streamType);
}
mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
mmi.putInt("postSetAvrcpAbsoluteVolumeIndex", newIndex / 10);
}
// Check if volume update should be send to Hearing Aid
@@ -2231,7 +2209,6 @@ public class AudioService extends IAudioService.Stub
try {
mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true);
mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false);
mmi.putInt("HDMI.sendVolumeKeyEvent", keyCode);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -2245,7 +2222,6 @@ public class AudioService extends IAudioService.Stub
}
}
}
mmi.record();
int index = mStreamStates[streamType].getIndex(device);
sendVolumeUpdate(streamType, oldIndex, index, flags, device);
}
@@ -2885,14 +2861,6 @@ public class AudioService extends IAudioService.Stub
}
}
mVolumeController.postVolumeChanged(streamType, flags);
new MediaMetrics.Item(mAnalyticsId + "sendVolumeUpdate")
.putInt("streamType", streamType)
.putInt("oldIndex", oldIndex)
.putInt("index", index)
.putInt("flags", flags)
.putInt("device", device)
.record();
}
// If Hdmi-CEC system audio mode is on and we are a TV panel, never show volume bar.
@@ -2934,21 +2902,12 @@ public class AudioService extends IAudioService.Stub
int device,
boolean force,
String caller) {
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId + "setStreamVolumeInt")
.putInt("streamType", streamType)
.putInt("index", index)
.putInt("device", device)
.putInt("force", force ? 1 : 0)
.putString("caller", caller);
if (isFullVolumeDevice(device)) {
mmi.putString(mAnalyticsPropEarlyReturn, "mFullVolumeDevices");
return;
}
VolumeStreamState streamState = mStreamStates[streamType];
if (streamState.setIndex(index, device, caller) || force) {
mmi.putInt("sendMsg", 1);
// Post message to set system volume (it in turn will post a message
// to persist).
sendMsg(mAudioHandler,
@@ -2959,7 +2918,6 @@ public class AudioService extends IAudioService.Stub
streamState,
0);
}
mmi.record();
}
private void setSystemAudioMute(boolean state) {
@@ -3194,34 +3152,33 @@ public class AudioService extends IAudioService.Stub
if (uid == android.os.Process.SYSTEM_UID) {
uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
}
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId + "setMicrophoneMute")
MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
.setUid(uid)
.putInt("userId", userId)
.putString("callingPackage", callingPackage);
.set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
.set(MediaMetrics.Property.EVENT, "setMicrophoneMute")
.set(MediaMetrics.Property.REQUEST, on
? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE);
// If OP_MUTE_MICROPHONE is set, disallow unmuting.
if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage)
!= AppOpsManager.MODE_ALLOWED) {
mmi.putString(mAnalyticsPropEarlyReturn, "disallow unmuting").record();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record();
return;
}
if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
mmi.putString(mAnalyticsPropEarlyReturn, "!checkAudioSettingsPermission").record();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record();
return;
}
if (userId != UserHandle.getCallingUserId() &&
mContext.checkCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
mmi.putString(mAnalyticsPropEarlyReturn, "permission").record();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record();
return;
}
mMicMuteFromApi = on;
mmi.record(); // record now, the no caller check will set the mute state.
setMicrophoneMuteNoCallerCheck(userId);
mmi.putInt("mMicMuteFromApi", mMicMuteFromApi ? 1 : 0)
.record();
}
/** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
@@ -3232,9 +3189,11 @@ public class AudioService extends IAudioService.Stub
return;
}
mMicMuteFromSwitch = on;
new MediaMetrics.Item(mAnalyticsId + "setMicrophoneMuteFromSwitch")
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
.setUid(userId)
.putInt("mMicMuteFromSwitch", mMicMuteFromSwitch ? 1 : 0)
.set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch")
.set(MediaMetrics.Property.REQUEST, on
? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
.record();
setMicrophoneMuteNoCallerCheck(userId);
}
@@ -3243,9 +3202,6 @@ public class AudioService extends IAudioService.Stub
InputManager im = mContext.getSystemService(InputManager.class);
final int isMicMuted = im.isMicMuted();
if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
new MediaMetrics.Item(mAnalyticsId + "setMicMuteFromSwitchInput")
.putInt("isMicMuted", isMicMuted)
.record();
setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
}
}
@@ -3273,19 +3229,23 @@ public class AudioService extends IAudioService.Stub
final long identity = Binder.clearCallingIdentity();
final int ret = mAudioSystem.muteMicrophone(muted);
new MediaMetrics.Item(mAnalyticsId + "setMicrophoneMuteNoCallerCheck")
.setUid(userId)
.putInt("muted", muted ? 1 : 0)
.putInt("currentMute", currentMute ? 1 : 0)
.putLong("identity", identity)
.record();
// update cache with the real state independently from what was set
mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
if (ret != AudioSystem.AUDIO_STATUS_OK) {
Log.e(TAG, "Error changing mic mute state to " + muted + " current:"
+ mMicMuteFromSystemCached);
}
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
.setUid(userId)
.set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck")
.set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached
? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
.set(MediaMetrics.Property.REQUEST, muted
? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
.set(MediaMetrics.Property.STATUS, ret)
.record();
try {
// send the intent even if there was a failure to change the actual mute state:
// the AudioManager.setMicrophoneMute API doesn't have a return value to
@@ -3405,13 +3365,6 @@ public class AudioService extends IAudioService.Stub
synchronized (mSettingsLock) {
final int ringerModeInternal = getRingerModeInternal();
final int ringerModeExternal = getRingerModeExternal();
new MediaMetrics.Item(mAnalyticsId + "setRingerMode")
.putInt("ringerMode", ringerMode)
.putInt("external", external ? 1 : 0)
.putString("caller", caller)
.putInt("ringerModeInternal", ringerModeInternal)
.putInt("ringerModeExternal", ringerModeExternal)
.record();
if (external) {
setRingerModeExt(ringerMode);
if (mRingerModeDelegate != null) {
@@ -3925,10 +3878,6 @@ public class AudioService extends IAudioService.Stub
Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
return;
}
new MediaMetrics.Item(mAnalyticsId + "playSoundEffectVolume")
.putInt("effectType", effectType)
.putDouble("volume", volume)
.record();
sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
effectType, (int) (volume * 1000), null, 0);
@@ -3941,12 +3890,7 @@ public class AudioService extends IAudioService.Stub
public boolean loadSoundEffects() {
LoadSoundEffectReply reply = new LoadSoundEffectReply();
sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
boolean loaded = reply.waitForLoaded(3 /*attempts*/);
new MediaMetrics.Item(mAnalyticsId + "loadSoundEffects")
.putInt("loaded", loaded ? 1 : 0)
.record();
return loaded;
return reply.waitForLoaded(3 /*attempts*/);
}
/**
@@ -3955,8 +3899,6 @@ public class AudioService extends IAudioService.Stub
*/
protected void scheduleLoadSoundEffects() {
sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
new MediaMetrics.Item(mAnalyticsId + "scheduleLoadSoundEffects")
.record();
}
/**
@@ -3966,8 +3908,6 @@ public class AudioService extends IAudioService.Stub
*/
public void unloadSoundEffects() {
sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
new MediaMetrics.Item(mAnalyticsId + "unloadSoundEffects")
.record();
}
/** @see AudioManager#reloadAudioSettings() */
@@ -4046,11 +3986,12 @@ public class AudioService extends IAudioService.Stub
.append(") from u/pid:").append(uid).append("/")
.append(pid).toString();
final boolean stateChanged = mDeviceBroker.setSpeakerphoneOn(on, eventSource);
new MediaMetrics.Item(mAnalyticsId + "setSpeakerphoneOn")
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+ MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
.setUid(uid)
.setPid(pid)
.putInt("on", on ? 1 : 0)
.putInt("stateChanged", stateChanged ? 1 : 0)
.set(MediaMetrics.Property.STATE, on
? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
.record();
if (stateChanged) {
@@ -4089,10 +4030,12 @@ public class AudioService extends IAudioService.Stub
.append(") from u/pid:").append(uid).append("/").append(pid).toString();
//bt sco
new MediaMetrics.Item(mAnalyticsId + "setBluetoothScoOn")
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+ MediaMetrics.SEPARATOR + "setBluetoothScoOn")
.setUid(uid)
.setPid(pid)
.putInt("on", on ? 1 : 0)
.set(MediaMetrics.Property.STATE, on
? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
.record();
mDeviceBroker.setBluetoothScoOn(on, eventSource);
@@ -4115,10 +4058,12 @@ public class AudioService extends IAudioService.Stub
.append(") from u/pid:").append(uid).append("/")
.append(pid).toString();
new MediaMetrics.Item(mAnalyticsId + "setBluetoothA2dpOn")
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+ MediaMetrics.SEPARATOR + "setBluetoothA2dpOn")
.setUid(uid)
.setPid(pid)
.putInt("on", on ? 1 : 0)
.set(MediaMetrics.Property.STATE, on
? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
.record();
mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
@@ -4140,10 +4085,12 @@ public class AudioService extends IAudioService.Stub
.append(") from u/pid:").append(uid).append("/")
.append(pid).toString();
new MediaMetrics.Item(mAnalyticsId + "startBluetoothSco")
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
.setUid(uid)
.setPid(pid)
.putInt("scoAudioMode", scoAudioMode)
.set(MediaMetrics.Property.EVENT, "startBluetoothSco")
.set(MediaMetrics.Property.SCO_AUDIO_MODE,
BtHelper.scoAudioModeToString(scoAudioMode))
.record();
startBluetoothScoInt(cb, scoAudioMode, eventSource);
@@ -4157,20 +4104,25 @@ public class AudioService extends IAudioService.Stub
.append(") from u/pid:").append(uid).append("/")
.append(pid).toString();
new MediaMetrics.Item(mAnalyticsId + "startBluetoothScoVirtualCall")
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
.setUid(uid)
.setPid(pid)
.set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall")
.set(MediaMetrics.Property.SCO_AUDIO_MODE,
BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
.record();
startBluetoothScoInt(cb, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
}
void startBluetoothScoInt(IBinder cb, int scoAudioMode, @NonNull String eventSource) {
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId + "startBluetoothScoInt")
.putInt("scoAudioMode", scoAudioMode);
MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
.set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
.set(MediaMetrics.Property.SCO_AUDIO_MODE,
BtHelper.scoAudioModeToString(scoAudioMode));
if (!checkAudioSettingsPermission("startBluetoothSco()") ||
!mSystemReady) {
mmi.putString(mAnalyticsPropEarlyReturn, "permission or systemReady").record();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
return;
}
synchronized (mDeviceBroker.mSetModeLock) {
@@ -4193,9 +4145,12 @@ public class AudioService extends IAudioService.Stub
synchronized (mDeviceBroker.mSetModeLock) {
mDeviceBroker.stopBluetoothScoForClient_Sync(cb, eventSource);
}
new MediaMetrics.Item(mAnalyticsId + "stopBluetoothSco")
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
.setUid(uid)
.setPid(pid)
.set(MediaMetrics.Property.EVENT, "stopBluetoothSco")
.set(MediaMetrics.Property.SCO_AUDIO_MODE,
BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED))
.record();
}
@@ -4958,12 +4913,13 @@ public class AudioService extends IAudioService.Stub
&& state != CONNECTION_STATE_DISCONNECTED) {
throw new IllegalArgumentException("Invalid state " + state);
}
new MediaMetrics.Item(mAnalyticsId + "setWiredDeviceConnectionState")
.putInt("type", type)
.putInt("state", state)
.putString("address", address)
.putString("name", name)
.putString("caller", caller)
new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
.set(MediaMetrics.Property.ADDRESS, address)
.set(MediaMetrics.Property.CLIENT_NAME, caller)
.set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(type))
.set(MediaMetrics.Property.NAME, name)
.set(MediaMetrics.Property.STATE,
state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
.record();
mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller);
}
@@ -5449,7 +5405,32 @@ public class AudioService extends IAudioService.Stub
private String mVolumeIndexSettingName;
private int mObservedDevices;
private final SparseIntArray mIndexMap = new SparseIntArray(8);
private final SparseIntArray mIndexMap = new SparseIntArray(8) {
@Override
public void put(int key, int value) {
super.put(key, value);
record("put", key, value);
}
@Override
public void setValueAt(int index, int value) {
super.setValueAt(index, value);
record("setValueAt", keyAt(index), value);
}
// Record all changes in the VolumeStreamState
private void record(String event, int key, int value) {
final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
: AudioSystem.getOutputDeviceName(key);
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR
+ AudioSystem.streamToString(mStreamType)
+ "." + device)
.set(MediaMetrics.Property.EVENT, event)
.set(MediaMetrics.Property.INDEX, value)
.set(MediaMetrics.Property.MIN_INDEX, mIndexMin)
.set(MediaMetrics.Property.MAX_INDEX, mIndexMax)
.record();
}
};
private final Intent mVolumeChanged;
private final Intent mStreamDevicesChanged;
@@ -6132,6 +6113,13 @@ public class AudioService extends IAudioService.Stub
+ eventSource);
break;
}
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE
+ MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase))
.set(MediaMetrics.Property.EVENT, "setForceUse")
.set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
.set(MediaMetrics.Property.FORCE_USE_MODE,
AudioSystem.forceUseConfigToString(config))
.record();
sForceUseLogger.log(
new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
AudioSystem.setForceUse(useCase, config);
@@ -6633,23 +6621,42 @@ public class AudioService extends IAudioService.Stub
public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
IAudioPolicyCallback pcb, int sdk) {
final int uid = Binder.getCallingUid();
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
.setUid(uid)
//.putInt("durationHint", durationHint)
.set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
.set(MediaMetrics.Property.CLIENT_NAME, clientId)
.set(MediaMetrics.Property.EVENT, "requestAudioFocus")
.set(MediaMetrics.Property.FLAGS, flags);
// permission checks
if (aa != null && !isValidAudioAttributesUsage(aa)) {
Log.w(TAG, "Request using unsupported usage.");
final String reason = "Request using unsupported usage";
Log.w(TAG, reason);
mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
.record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_PHONE_STATE)) {
Log.e(TAG, "Invalid permission to (un)lock audio focus", new Exception());
final String reason = "Invalid permission to (un)lock audio focus";
Log.e(TAG, reason, new Exception());
mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
.record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
} else {
// only a registered audio policy can be used to lock focus
synchronized (mAudioPolicies) {
if (!mAudioPolicies.containsKey(pcb.asBinder())) {
Log.e(TAG, "Invalid unregistered AudioPolicy to (un)lock audio focus");
final String reason =
"Invalid unregistered AudioPolicy to (un)lock audio focus";
Log.e(TAG, reason);
mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
.record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
}
@@ -6657,19 +6664,13 @@ public class AudioService extends IAudioService.Stub
}
if (callingPackageName == null || clientId == null || aa == null) {
Log.e(TAG, "Invalid null parameter to request audio focus");
final String reason = "Invalid null parameter to request audio focus";
Log.e(TAG, reason);
mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
.record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
int uid = Binder.getCallingUid();
new MediaMetrics.Item(mAnalyticsId + "requestAudioFocus")
.setUid(uid)
.putInt("durationHint", durationHint)
.putString("clientId", clientId)
.putString("callingPackage", callingPackageName)
.putInt("flags", flags)
.putInt("sdk", sdk)
.record();
mmi.record();
return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
clientId, callingPackageName, flags, sdk,
forceFocusDuckingForAccessibility(aa, durationHint, uid));
@@ -6677,13 +6678,14 @@ public class AudioService extends IAudioService.Stub
public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
String callingPackageName) {
MediaMetrics.Item mmi = new MediaMetrics.Item(mAnalyticsId + "abandonAudioFocus")
.putString("clientId", clientId)
.putString("callingPackage", callingPackageName);
MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
.set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
.set(MediaMetrics.Property.CLIENT_NAME, clientId)
.set(MediaMetrics.Property.EVENT, "abandonAudioFocus");
if (aa != null && !isValidAudioAttributesUsage(aa)) {
Log.w(TAG, "Request using unsupported usage.");
mmi.putString(mAnalyticsPropEarlyReturn, "unsupported usage").record();
mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
@@ -6692,8 +6694,9 @@ public class AudioService extends IAudioService.Stub
}
public void unregisterAudioFocusClient(String clientId) {
new MediaMetrics.Item(mAnalyticsId + "unregisterAudioFocusClient")
.putString("clientId", clientId)
new MediaMetrics.Item(mMetricsId + "focus")
.set(MediaMetrics.Property.CLIENT_NAME, clientId)
.set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient")
.record();
mMediaFocusControl.unregisterAudioFocusClient(clientId);
}
@@ -7271,8 +7274,8 @@ public class AudioService extends IAudioService.Stub
/**
* Audio Analytics ids.
*/
private static final String mAnalyticsId = "audio.service.";
private static final String mAnalyticsPropEarlyReturn = "earlyReturn";
private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE
+ MediaMetrics.SEPARATOR;
private static String safeMediaVolumeStateToString(int state) {
switch(state) {

View File

@@ -109,11 +109,6 @@ 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,
@@ -126,13 +121,7 @@ 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();
logMetricEvent();
}
/** used for VOL_SET_HEARING_AID_VOL*/
@@ -145,12 +134,7 @@ public class AudioServiceEvents {
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
new MediaMetrics.Item(mAnalyticsIdRoot + "HA")
.putInt("op", mOp)
.putInt("index", mVal1)
.putInt("gainDb", mVal2)
.record();
logMetricEvent();
}
/** used for VOL_SET_AVRCP_VOL */
@@ -163,11 +147,7 @@ public class AudioServiceEvents {
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
new MediaMetrics.Item(mAnalyticsIdRoot + "AVRCP")
.putInt("op", mOp)
.putInt("index", mVal1)
.record();
logMetricEvent();
}
/** used for VOL_VOICE_ACTIVITY_HEARING_AID */
@@ -180,12 +160,7 @@ public class AudioServiceEvents {
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
new MediaMetrics.Item(mAnalyticsIdRoot + mStream)
.putInt("op", mOp)
.putInt("index", mVal1)
.putInt("voiceActive", mVal2)
.record();
logMetricEvent();
}
/** used for VOL_MODE_CHANGE_HEARING_AID */
@@ -198,6 +173,7 @@ public class AudioServiceEvents {
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
logMetricEvent();
}
/** used for VOL_SET_GROUP_VOL */
@@ -209,12 +185,102 @@ public class AudioServiceEvents {
mCaller = caller;
mGroupName = group;
mAudioAttributes = aa;
logMetricEvent();
}
new MediaMetrics.Item(mAnalyticsIdRoot + mStream)
.putInt("op", mOp)
.putInt("index", mVal1)
.putInt("mode", mVal2)
.record();
/**
* Audio Analytics unique Id.
*/
private static final String mMetricsId = MediaMetrics.Name.AUDIO_VOLUME_EVENT;
/**
* Log mediametrics event
*/
private void logMetricEvent() {
switch (mOp) {
case VOL_ADJUST_SUGG_VOL:
case VOL_ADJUST_VOL_UID:
case VOL_ADJUST_STREAM_VOL: {
String eventName;
switch (mOp) {
case VOL_ADJUST_SUGG_VOL:
eventName = "adjustSuggestedStreamVolume";
break;
case VOL_ADJUST_STREAM_VOL:
eventName = "adjustStreamVolume";
break;
case VOL_ADJUST_VOL_UID:
eventName = "adjustStreamVolumeForUid";
break;
default:
return; // not possible, just return here
}
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
.set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
.set(MediaMetrics.Property.EVENT, eventName)
.set(MediaMetrics.Property.FLAGS, mVal2)
.set(MediaMetrics.Property.STREAM_TYPE,
AudioSystem.streamToString(mStream))
.record();
return;
}
case VOL_SET_STREAM_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
.set(MediaMetrics.Property.EVENT, "setStreamVolume")
.set(MediaMetrics.Property.FLAGS, mVal2)
.set(MediaMetrics.Property.INDEX, mVal1)
.set(MediaMetrics.Property.STREAM_TYPE,
AudioSystem.streamToString(mStream))
.record();
return;
case VOL_SET_HEARING_AID_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.EVENT, "setHearingAidVolume")
.set(MediaMetrics.Property.GAIN_DB, (double) mVal2)
.set(MediaMetrics.Property.INDEX, mVal1)
.record();
return;
case VOL_SET_AVRCP_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.EVENT, "setAvrcpVolume")
.set(MediaMetrics.Property.INDEX, mVal1)
.record();
return;
case VOL_VOICE_ACTIVITY_HEARING_AID:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid")
.set(MediaMetrics.Property.INDEX, mVal1)
.set(MediaMetrics.Property.STATE,
mVal2 == 1 ? "active" : "inactive")
.set(MediaMetrics.Property.STREAM_TYPE,
AudioSystem.streamToString(mStream))
.record();
return;
case VOL_MODE_CHANGE_HEARING_AID:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.EVENT, "modeChangeHearingAid")
.set(MediaMetrics.Property.INDEX, mVal1)
.set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mVal2))
.set(MediaMetrics.Property.STREAM_TYPE,
AudioSystem.streamToString(mStream))
.record();
return;
case VOL_SET_GROUP_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.ATTRIBUTES, mAudioAttributes.toString())
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
.set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes")
.set(MediaMetrics.Property.FLAGS, mVal2)
.set(MediaMetrics.Property.GROUP, mGroupName)
.set(MediaMetrics.Property.INDEX, mVal1)
.record();
return;
default:
return;
}
}
@Override

View File

@@ -113,6 +113,24 @@ public class BtHelper {
private static final int BT_HEARING_AID_GAIN_MIN = -128;
/**
* Returns a string representation of the scoAudioMode.
*/
public static String scoAudioModeToString(int scoAudioMode) {
switch (scoAudioMode) {
case SCO_MODE_UNDEFINED:
return "SCO_MODE_UNDEFINED";
case SCO_MODE_VIRTUAL_CALL:
return "SCO_MODE_VIRTUAL_CALL";
case SCO_MODE_RAW:
return "SCO_MODE_RAW";
case SCO_MODE_VR:
return "SCO_MODE_VR";
default:
return "SCO_MODE_(" + scoAudioMode + ")";
}
}
//----------------------------------------------------------------------
/*package*/ static class BluetoothA2dpDeviceInfo {
private final @NonNull BluetoothDevice mBtDevice;
@@ -965,4 +983,27 @@ public class BtHelper {
return AudioSystem.AUDIO_FORMAT_DEFAULT;
}
}
/**
* Returns the String equivalent of the btCodecType.
*
* This uses an "ENCODING_" prefix for consistency with Audio;
* we could alternately use the "SOURCE_CODEC_TYPE_" prefix from Bluetooth.
*/
public static String bluetoothCodecToEncodingString(int btCodecType) {
switch (btCodecType) {
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
return "ENCODING_SBC";
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
return "ENCODING_AAC";
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
return "ENCODING_APTX";
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
return "ENCODING_APTX_HD";
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
return "ENCODING_LDAC";
default:
return "ENCODING_BT_CODEC_TYPE(" + btCodecType + ")";
}
}
}

View File

@@ -25,6 +25,7 @@ import android.media.AudioFocusInfo;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.IAudioFocusDispatcher;
import android.media.MediaMetrics;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.os.Binder;
import android.os.Build;
@@ -144,6 +145,8 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
private static final AudioEventLogger mEventLogger = new AudioEventLogger(50,
"focus commands as seen by MediaFocusControl");
private static final String mMetricsId = MediaMetrics.Name.AUDIO_FOCUS;
/*package*/ void noFocusForSuspendedApp(@NonNull String packageName, int uid) {
synchronized (mAudioFocusLock) {
final Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
@@ -823,6 +826,17 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
protected int requestAudioFocus(@NonNull AudioAttributes aa, int focusChangeHint, IBinder cb,
IAudioFocusDispatcher fd, @NonNull String clientId, @NonNull String callingPackageName,
int flags, int sdk, boolean forceDuck) {
new MediaMetrics.Item(mMetricsId)
.setUid(Binder.getCallingUid())
.set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
.set(MediaMetrics.Property.CLIENT_NAME, clientId)
.set(MediaMetrics.Property.EVENT, "requestAudioFocus")
.set(MediaMetrics.Property.FLAGS, flags)
.set(MediaMetrics.Property.FOCUS_CHANGE_HINT,
AudioManager.audioFocusToString(focusChangeHint))
//.set(MediaMetrics.Property.SDK, sdk)
.record();
mEventLogger.log((new AudioEventLogger.StringEvent(
"requestAudioFocus() from uid/pid " + Binder.getCallingUid()
+ "/" + Binder.getCallingPid()
@@ -987,6 +1001,13 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
* */
protected int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId, AudioAttributes aa,
String callingPackageName) {
new MediaMetrics.Item(mMetricsId)
.setUid(Binder.getCallingUid())
.set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
.set(MediaMetrics.Property.CLIENT_NAME, clientId)
.set(MediaMetrics.Property.EVENT, "abandonAudioFocus")
.record();
// AudioAttributes are currently ignored, to be used for zones / a11y
mEventLogger.log((new AudioEventLogger.StringEvent(
"abandonAudioFocus() from uid/pid " + Binder.getCallingUid()