Loading media/java/android/media/AudioSystem.java +53 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,17 @@ public class AudioSystem public static final int MODE_IN_COMMUNICATION = 3; public static final int NUM_MODES = 4; public static String modeToString(int mode) { switch (mode) { case MODE_CURRENT: return "MODE_CURRENT"; case MODE_IN_CALL: return "MODE_IN_CALL"; case MODE_IN_COMMUNICATION: return "MODE_IN_COMMUNICATION"; case MODE_INVALID: return "MODE_INVALID"; case MODE_NORMAL: return "MODE_NORMAL"; case MODE_RINGTONE: return "MODE_RINGTONE"; default: return "unknown mode (" + mode + ")"; } } /* Routing bits for the former setRouting/getRouting API */ /** @deprecated */ Loading Loading @@ -498,6 +509,14 @@ public class AudioSystem public static final int DEVICE_STATE_AVAILABLE = 1; private static final int NUM_DEVICE_STATES = 1; public static String deviceStateToString(int state) { switch (state) { case DEVICE_STATE_UNAVAILABLE: return "DEVICE_STATE_UNAVAILABLE"; case DEVICE_STATE_AVAILABLE: return "DEVICE_STATE_AVAILABLE"; default: return "unknown state (" + state + ")"; } } public static final String DEVICE_OUT_EARPIECE_NAME = "earpiece"; public static final String DEVICE_OUT_SPEAKER_NAME = "speaker"; public static final String DEVICE_OUT_WIRED_HEADSET_NAME = "headset"; Loading Loading @@ -693,6 +712,27 @@ public class AudioSystem public static final int NUM_FORCE_CONFIG = 15; public static final int FORCE_DEFAULT = FORCE_NONE; public static String forceUseConfigToString(int config) { switch (config) { case FORCE_NONE: return "FORCE_NONE"; case FORCE_SPEAKER: return "FORCE_SPEAKER"; case FORCE_HEADPHONES: return "FORCE_HEADPHONES"; case FORCE_BT_SCO: return "FORCE_BT_SCO"; case FORCE_BT_A2DP: return "FORCE_BT_A2DP"; case FORCE_WIRED_ACCESSORY: return "FORCE_WIRED_ACCESSORY"; case FORCE_BT_CAR_DOCK: return "FORCE_BT_CAR_DOCK"; case FORCE_BT_DESK_DOCK: return "FORCE_BT_DESK_DOCK"; case FORCE_ANALOG_DOCK: return "FORCE_ANALOG_DOCK"; case FORCE_DIGITAL_DOCK: return "FORCE_DIGITAL_DOCK"; case FORCE_NO_BT_A2DP: return "FORCE_NO_BT_A2DP"; case FORCE_SYSTEM_ENFORCED: return "FORCE_SYSTEM_ENFORCED"; case FORCE_HDMI_SYSTEM_AUDIO_ENFORCED: return "FORCE_HDMI_SYSTEM_AUDIO_ENFORCED"; case FORCE_ENCODED_SURROUND_NEVER: return "FORCE_ENCODED_SURROUND_NEVER"; case FORCE_ENCODED_SURROUND_ALWAYS: return "FORCE_ENCODED_SURROUND_ALWAYS"; default: return "unknown config (" + config + ")" ; } } // usage for setForceUse, must match audio_policy_force_use_t public static final int FOR_COMMUNICATION = 0; public static final int FOR_MEDIA = 1; Loading @@ -703,6 +743,19 @@ public class AudioSystem public static final int FOR_ENCODED_SURROUND = 6; private static final int NUM_FORCE_USE = 7; public static String forceUseUsageToString(int usage) { switch (usage) { case FOR_COMMUNICATION: return "FOR_COMMUNICATION"; case FOR_MEDIA: return "FOR_MEDIA"; case FOR_RECORD: return "FOR_RECORD"; case FOR_DOCK: return "FOR_DOCK"; case FOR_SYSTEM: return "FOR_SYSTEM"; case FOR_HDMI_SYSTEM_AUDIO: return "FOR_HDMI_SYSTEM_AUDIO"; case FOR_ENCODED_SURROUND: return "FOR_ENCODED_SURROUND"; default: return "unknown usage (" + usage + ")" ; } } // usage for AudioRecord.startRecordingSync(), must match AudioSystem::sync_event_t public static final int SYNC_EVENT_NONE = 0; public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1; Loading services/core/java/com/android/server/audio/AudioEventLogger.java 0 → 100644 +97 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.audio; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedList; public class AudioEventLogger { // ring buffer of events to log. private final LinkedList<Event> mEvents; private final String mTitle; // the maximum number of events to keep in log private final int mMemSize; public static abstract class Event { // formatter for timestamps private final static SimpleDateFormat sFormat = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); private final long mTimestamp; Event() { mTimestamp = System.currentTimeMillis(); } public String toString() { return (new StringBuilder(sFormat.format(new Date(mTimestamp)))) .append(" ").append(eventToString()).toString(); } /** * Convert event to String. * This method is only called when the logger history is about to the dumped, * so this method is where expensive String conversions should be made, not when the Event * subclass is created. * Timestamp information will be automatically added, do not include it. * @return a string representation of the event that occurred. */ abstract public String eventToString(); } public static class StringEvent extends Event { private final String mMsg; public StringEvent(String msg) { mMsg = msg; } @Override public String eventToString() { return mMsg; } } /** * Constructor for logger. * @param size the maximum number of events to keep in log * @param title the string displayed before the recorded log */ public AudioEventLogger(int size, String title) { mEvents = new LinkedList<Event>(); mMemSize = size; mTitle = title; } public synchronized void log(Event evt) { if (mEvents.size() >= mMemSize) { mEvents.removeFirst(); } mEvents.add(evt); } public synchronized void dump(PrintWriter pw) { pw.println("Audio event log: " + mTitle); for (Event evt : mEvents) { pw.println(evt.toString()); } } } services/core/java/com/android/server/audio/AudioService.java +162 −42 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +76 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,9 @@ public final class PlaybackActivityMonitor final int index = mBannedUids.indexOf(new Integer(uid)); if (index >= 0) { if (!disable) { if (DEBUG) { // hidden behind DEBUG, too noisy otherwise mEventLogger.log(new AudioEventLogger.StringEvent("unbanning uid:" + uid)); } mBannedUids.remove(index); // nothing else to do, future playback requests from this uid are ok } // no else to handle, uid already present, so disabling again is no-op Loading @@ -112,6 +115,9 @@ public final class PlaybackActivityMonitor for (AudioPlaybackConfiguration apc : mPlayers.values()) { checkBanPlayer(apc, uid); } if (DEBUG) { // hidden behind DEBUG, too noisy otherwise mEventLogger.log(new AudioEventLogger.StringEvent("banning uid:" + uid)); } mBannedUids.add(new Integer(uid)); } // no else to handle, uid already not in list, so enabling again is no-op } Loading Loading @@ -145,6 +151,7 @@ public final class PlaybackActivityMonitor new AudioPlaybackConfiguration(pic, newPiid, Binder.getCallingUid(), Binder.getCallingPid()); apc.init(); mEventLogger.log(new NewPlayerEvent(apc)); synchronized(mPlayerLock) { mPlayers.put(newPiid, apc); } Loading @@ -156,6 +163,7 @@ public final class PlaybackActivityMonitor synchronized(mPlayerLock) { final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); if (checkConfigurationCaller(piid, apc, binderUid)) { mEventLogger.log(new AudioAttrEvent(piid, attr)); change = apc.handleAudioAttributesEvent(attr); } else { Log.e(TAG, "Error updating audio attributes"); Loading @@ -175,10 +183,13 @@ public final class PlaybackActivityMonitor if (apc == null) { return; } mEventLogger.log(new PlayerEvent(piid, event)); if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { for (Integer uidInteger: mBannedUids) { if (checkBanPlayer(apc, uidInteger.intValue())) { // player was banned, do not update its state mEventLogger.log(new AudioEventLogger.StringEvent( "not starting piid:" + piid + " ,is banned")); return; } } Loading Loading @@ -208,6 +219,8 @@ public final class PlaybackActivityMonitor synchronized(mPlayerLock) { final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); if (checkConfigurationCaller(piid, apc, binderUid)) { mEventLogger.log(new AudioEventLogger.StringEvent( "releasing player piid:" + piid)); mPlayers.remove(new Integer(piid)); mDuckingManager.removeReleased(apc); } Loading Loading @@ -250,6 +263,8 @@ public final class PlaybackActivityMonitor pw.print(" " + uid); } pw.println(); // log mEventLogger.dump(pw); } } Loading Loading @@ -672,4 +687,65 @@ public final class PlaybackActivityMonitor } } } //================================================================= // For logging private final static class PlayerEvent extends AudioEventLogger.Event { // only keeping the player interface ID as it uniquely identifies the player in the event final int mPlayerIId; final int mState; PlayerEvent(int piid, int state) { mPlayerIId = piid; mState = state; } @Override public String eventToString() { return new String("player piid:" + mPlayerIId + " state:" + AudioPlaybackConfiguration.toLogFriendlyPlayerState(mState)); } } private final static class NewPlayerEvent extends AudioEventLogger.Event { private final int mPlayerIId; private final int mPlayerType; private final int mClientUid; private final int mClientPid; private final AudioAttributes mPlayerAttr; NewPlayerEvent(AudioPlaybackConfiguration apc) { mPlayerIId = apc.getPlayerInterfaceId(); mPlayerType = apc.getPlayerType(); mClientUid = apc.getClientUid(); mClientPid = apc.getClientPid(); mPlayerAttr = apc.getAudioAttributes(); } @Override public String eventToString() { return new String("new player piid:" + mPlayerIId + " uid/pid:" + mClientUid + "/" + mClientPid + " type:" + AudioPlaybackConfiguration.toLogFriendlyPlayerType(mPlayerType) + " attr:" + mPlayerAttr); } } private final static class AudioAttrEvent extends AudioEventLogger.Event { private final int mPlayerIId; private final AudioAttributes mPlayerAttr; AudioAttrEvent(int piid, AudioAttributes attr) { mPlayerIId = piid; mPlayerAttr = attr; } @Override public String eventToString() { return new String("player piid:" + mPlayerIId + " new AudioAttributes:" + mPlayerAttr); } } private final AudioEventLogger mEventLogger = new AudioEventLogger(100, "playback activity as reported through PlayerBase"); } Loading
media/java/android/media/AudioSystem.java +53 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,17 @@ public class AudioSystem public static final int MODE_IN_COMMUNICATION = 3; public static final int NUM_MODES = 4; public static String modeToString(int mode) { switch (mode) { case MODE_CURRENT: return "MODE_CURRENT"; case MODE_IN_CALL: return "MODE_IN_CALL"; case MODE_IN_COMMUNICATION: return "MODE_IN_COMMUNICATION"; case MODE_INVALID: return "MODE_INVALID"; case MODE_NORMAL: return "MODE_NORMAL"; case MODE_RINGTONE: return "MODE_RINGTONE"; default: return "unknown mode (" + mode + ")"; } } /* Routing bits for the former setRouting/getRouting API */ /** @deprecated */ Loading Loading @@ -498,6 +509,14 @@ public class AudioSystem public static final int DEVICE_STATE_AVAILABLE = 1; private static final int NUM_DEVICE_STATES = 1; public static String deviceStateToString(int state) { switch (state) { case DEVICE_STATE_UNAVAILABLE: return "DEVICE_STATE_UNAVAILABLE"; case DEVICE_STATE_AVAILABLE: return "DEVICE_STATE_AVAILABLE"; default: return "unknown state (" + state + ")"; } } public static final String DEVICE_OUT_EARPIECE_NAME = "earpiece"; public static final String DEVICE_OUT_SPEAKER_NAME = "speaker"; public static final String DEVICE_OUT_WIRED_HEADSET_NAME = "headset"; Loading Loading @@ -693,6 +712,27 @@ public class AudioSystem public static final int NUM_FORCE_CONFIG = 15; public static final int FORCE_DEFAULT = FORCE_NONE; public static String forceUseConfigToString(int config) { switch (config) { case FORCE_NONE: return "FORCE_NONE"; case FORCE_SPEAKER: return "FORCE_SPEAKER"; case FORCE_HEADPHONES: return "FORCE_HEADPHONES"; case FORCE_BT_SCO: return "FORCE_BT_SCO"; case FORCE_BT_A2DP: return "FORCE_BT_A2DP"; case FORCE_WIRED_ACCESSORY: return "FORCE_WIRED_ACCESSORY"; case FORCE_BT_CAR_DOCK: return "FORCE_BT_CAR_DOCK"; case FORCE_BT_DESK_DOCK: return "FORCE_BT_DESK_DOCK"; case FORCE_ANALOG_DOCK: return "FORCE_ANALOG_DOCK"; case FORCE_DIGITAL_DOCK: return "FORCE_DIGITAL_DOCK"; case FORCE_NO_BT_A2DP: return "FORCE_NO_BT_A2DP"; case FORCE_SYSTEM_ENFORCED: return "FORCE_SYSTEM_ENFORCED"; case FORCE_HDMI_SYSTEM_AUDIO_ENFORCED: return "FORCE_HDMI_SYSTEM_AUDIO_ENFORCED"; case FORCE_ENCODED_SURROUND_NEVER: return "FORCE_ENCODED_SURROUND_NEVER"; case FORCE_ENCODED_SURROUND_ALWAYS: return "FORCE_ENCODED_SURROUND_ALWAYS"; default: return "unknown config (" + config + ")" ; } } // usage for setForceUse, must match audio_policy_force_use_t public static final int FOR_COMMUNICATION = 0; public static final int FOR_MEDIA = 1; Loading @@ -703,6 +743,19 @@ public class AudioSystem public static final int FOR_ENCODED_SURROUND = 6; private static final int NUM_FORCE_USE = 7; public static String forceUseUsageToString(int usage) { switch (usage) { case FOR_COMMUNICATION: return "FOR_COMMUNICATION"; case FOR_MEDIA: return "FOR_MEDIA"; case FOR_RECORD: return "FOR_RECORD"; case FOR_DOCK: return "FOR_DOCK"; case FOR_SYSTEM: return "FOR_SYSTEM"; case FOR_HDMI_SYSTEM_AUDIO: return "FOR_HDMI_SYSTEM_AUDIO"; case FOR_ENCODED_SURROUND: return "FOR_ENCODED_SURROUND"; default: return "unknown usage (" + usage + ")" ; } } // usage for AudioRecord.startRecordingSync(), must match AudioSystem::sync_event_t public static final int SYNC_EVENT_NONE = 0; public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1; Loading
services/core/java/com/android/server/audio/AudioEventLogger.java 0 → 100644 +97 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.audio; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedList; public class AudioEventLogger { // ring buffer of events to log. private final LinkedList<Event> mEvents; private final String mTitle; // the maximum number of events to keep in log private final int mMemSize; public static abstract class Event { // formatter for timestamps private final static SimpleDateFormat sFormat = new SimpleDateFormat("MM-dd HH:mm:ss:SSS"); private final long mTimestamp; Event() { mTimestamp = System.currentTimeMillis(); } public String toString() { return (new StringBuilder(sFormat.format(new Date(mTimestamp)))) .append(" ").append(eventToString()).toString(); } /** * Convert event to String. * This method is only called when the logger history is about to the dumped, * so this method is where expensive String conversions should be made, not when the Event * subclass is created. * Timestamp information will be automatically added, do not include it. * @return a string representation of the event that occurred. */ abstract public String eventToString(); } public static class StringEvent extends Event { private final String mMsg; public StringEvent(String msg) { mMsg = msg; } @Override public String eventToString() { return mMsg; } } /** * Constructor for logger. * @param size the maximum number of events to keep in log * @param title the string displayed before the recorded log */ public AudioEventLogger(int size, String title) { mEvents = new LinkedList<Event>(); mMemSize = size; mTitle = title; } public synchronized void log(Event evt) { if (mEvents.size() >= mMemSize) { mEvents.removeFirst(); } mEvents.add(evt); } public synchronized void dump(PrintWriter pw) { pw.println("Audio event log: " + mTitle); for (Event evt : mEvents) { pw.println(evt.toString()); } } }
services/core/java/com/android/server/audio/AudioService.java +162 −42 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +76 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,9 @@ public final class PlaybackActivityMonitor final int index = mBannedUids.indexOf(new Integer(uid)); if (index >= 0) { if (!disable) { if (DEBUG) { // hidden behind DEBUG, too noisy otherwise mEventLogger.log(new AudioEventLogger.StringEvent("unbanning uid:" + uid)); } mBannedUids.remove(index); // nothing else to do, future playback requests from this uid are ok } // no else to handle, uid already present, so disabling again is no-op Loading @@ -112,6 +115,9 @@ public final class PlaybackActivityMonitor for (AudioPlaybackConfiguration apc : mPlayers.values()) { checkBanPlayer(apc, uid); } if (DEBUG) { // hidden behind DEBUG, too noisy otherwise mEventLogger.log(new AudioEventLogger.StringEvent("banning uid:" + uid)); } mBannedUids.add(new Integer(uid)); } // no else to handle, uid already not in list, so enabling again is no-op } Loading Loading @@ -145,6 +151,7 @@ public final class PlaybackActivityMonitor new AudioPlaybackConfiguration(pic, newPiid, Binder.getCallingUid(), Binder.getCallingPid()); apc.init(); mEventLogger.log(new NewPlayerEvent(apc)); synchronized(mPlayerLock) { mPlayers.put(newPiid, apc); } Loading @@ -156,6 +163,7 @@ public final class PlaybackActivityMonitor synchronized(mPlayerLock) { final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); if (checkConfigurationCaller(piid, apc, binderUid)) { mEventLogger.log(new AudioAttrEvent(piid, attr)); change = apc.handleAudioAttributesEvent(attr); } else { Log.e(TAG, "Error updating audio attributes"); Loading @@ -175,10 +183,13 @@ public final class PlaybackActivityMonitor if (apc == null) { return; } mEventLogger.log(new PlayerEvent(piid, event)); if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { for (Integer uidInteger: mBannedUids) { if (checkBanPlayer(apc, uidInteger.intValue())) { // player was banned, do not update its state mEventLogger.log(new AudioEventLogger.StringEvent( "not starting piid:" + piid + " ,is banned")); return; } } Loading Loading @@ -208,6 +219,8 @@ public final class PlaybackActivityMonitor synchronized(mPlayerLock) { final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); if (checkConfigurationCaller(piid, apc, binderUid)) { mEventLogger.log(new AudioEventLogger.StringEvent( "releasing player piid:" + piid)); mPlayers.remove(new Integer(piid)); mDuckingManager.removeReleased(apc); } Loading Loading @@ -250,6 +263,8 @@ public final class PlaybackActivityMonitor pw.print(" " + uid); } pw.println(); // log mEventLogger.dump(pw); } } Loading Loading @@ -672,4 +687,65 @@ public final class PlaybackActivityMonitor } } } //================================================================= // For logging private final static class PlayerEvent extends AudioEventLogger.Event { // only keeping the player interface ID as it uniquely identifies the player in the event final int mPlayerIId; final int mState; PlayerEvent(int piid, int state) { mPlayerIId = piid; mState = state; } @Override public String eventToString() { return new String("player piid:" + mPlayerIId + " state:" + AudioPlaybackConfiguration.toLogFriendlyPlayerState(mState)); } } private final static class NewPlayerEvent extends AudioEventLogger.Event { private final int mPlayerIId; private final int mPlayerType; private final int mClientUid; private final int mClientPid; private final AudioAttributes mPlayerAttr; NewPlayerEvent(AudioPlaybackConfiguration apc) { mPlayerIId = apc.getPlayerInterfaceId(); mPlayerType = apc.getPlayerType(); mClientUid = apc.getClientUid(); mClientPid = apc.getClientPid(); mPlayerAttr = apc.getAudioAttributes(); } @Override public String eventToString() { return new String("new player piid:" + mPlayerIId + " uid/pid:" + mClientUid + "/" + mClientPid + " type:" + AudioPlaybackConfiguration.toLogFriendlyPlayerType(mPlayerType) + " attr:" + mPlayerAttr); } } private final static class AudioAttrEvent extends AudioEventLogger.Event { private final int mPlayerIId; private final AudioAttributes mPlayerAttr; AudioAttrEvent(int piid, AudioAttributes attr) { mPlayerIId = piid; mPlayerAttr = attr; } @Override public String eventToString() { return new String("player piid:" + mPlayerIId + " new AudioAttributes:" + mPlayerAttr); } } private final AudioEventLogger mEventLogger = new AudioEventLogger(100, "playback activity as reported through PlayerBase"); }