Merge "AudioService: check calls to AudioSystem.initStreamVolume" into rvc-qpr-dev am: c2c99464e6
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12541026 Change-Id: I41ccf14ab8e97fa451424761a508dedaeb71e63f
This commit is contained in:
@@ -60,7 +60,36 @@ public class AudioEventLogger {
|
|||||||
* @return the same instance of the event
|
* @return the same instance of the event
|
||||||
*/
|
*/
|
||||||
public Event printLog(String tag) {
|
public Event printLog(String tag) {
|
||||||
Log.i(tag, eventToString());
|
return printLog(ALOGI, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int ALOGI = 0;
|
||||||
|
public static final int ALOGE = 1;
|
||||||
|
public static final int ALOGW = 2;
|
||||||
|
public static final int ALOGV = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as {@link #printLog(String)} with a log type
|
||||||
|
* @param type one of {@link #ALOGI}, {@link #ALOGE}, {@link #ALOGV}
|
||||||
|
* @param tag
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Event printLog(int type, String tag) {
|
||||||
|
switch (type) {
|
||||||
|
case ALOGI:
|
||||||
|
Log.i(tag, eventToString());
|
||||||
|
break;
|
||||||
|
case ALOGE:
|
||||||
|
Log.e(tag, eventToString());
|
||||||
|
break;
|
||||||
|
case ALOGW:
|
||||||
|
Log.w(tag, eventToString());
|
||||||
|
break;
|
||||||
|
case ALOGV:
|
||||||
|
default:
|
||||||
|
Log.v(tag, eventToString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
|
|||||||
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
|
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
|
||||||
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
|
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
|
||||||
|
|
||||||
|
import static com.android.server.audio.AudioEventLogger.Event.ALOGE;
|
||||||
|
import static com.android.server.audio.AudioEventLogger.Event.ALOGI;
|
||||||
|
import static com.android.server.audio.AudioEventLogger.Event.ALOGW;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -284,6 +288,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
|
private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
|
||||||
private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30;
|
private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30;
|
||||||
private static final int MSG_CHECK_MODE_FOR_UID = 31;
|
private static final int MSG_CHECK_MODE_FOR_UID = 31;
|
||||||
|
private static final int MSG_REINIT_VOLUMES = 32;
|
||||||
// start of messages handled under wakelock
|
// start of messages handled under wakelock
|
||||||
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
|
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
|
||||||
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
|
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
|
||||||
@@ -673,6 +678,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
|
|
||||||
public AudioService(Context context, AudioSystemAdapter audioSystem,
|
public AudioService(Context context, AudioSystemAdapter audioSystem,
|
||||||
SystemServerAdapter systemServer) {
|
SystemServerAdapter systemServer) {
|
||||||
|
sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()"));
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mContentResolver = context.getContentResolver();
|
mContentResolver = context.getContentResolver();
|
||||||
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
|
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
|
||||||
@@ -892,6 +898,9 @@ public class AudioService extends IAudioService.Stub
|
|||||||
mPrescaleAbsoluteVolume[i] = preScale[i];
|
mPrescaleAbsoluteVolume[i] = preScale[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check on volume initialization
|
||||||
|
checkVolumeRangeInitialization("AudioService()");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void systemReady() {
|
public void systemReady() {
|
||||||
@@ -1019,11 +1028,15 @@ public class AudioService extends IAudioService.Stub
|
|||||||
if (!mSystemReady ||
|
if (!mSystemReady ||
|
||||||
(AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
|
(AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
|
||||||
Log.e(TAG, "Audioserver died.");
|
Log.e(TAG, "Audioserver died.");
|
||||||
|
sLifecycleLogger.log(new AudioEventLogger.StringEvent(
|
||||||
|
"onAudioServerDied() audioserver died"));
|
||||||
sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
|
sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
|
||||||
null, 500);
|
null, 500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log.e(TAG, "Audioserver started.");
|
Log.i(TAG, "Audioserver started.");
|
||||||
|
sLifecycleLogger.log(new AudioEventLogger.StringEvent(
|
||||||
|
"onAudioServerDied() audioserver started"));
|
||||||
|
|
||||||
updateAudioHalPids();
|
updateAudioHalPids();
|
||||||
|
|
||||||
@@ -1058,14 +1071,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
|
mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
|
||||||
|
|
||||||
// Restore stream volumes
|
// Restore stream volumes
|
||||||
int numStreamTypes = AudioSystem.getNumStreamTypes();
|
onReinitVolumes("after audioserver restart");
|
||||||
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
|
|
||||||
VolumeStreamState streamState = mStreamStates[streamType];
|
|
||||||
AudioSystem.initStreamVolume(
|
|
||||||
streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
|
|
||||||
|
|
||||||
streamState.applyAllVolumes();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore audio volume groups
|
// Restore audio volume groups
|
||||||
restoreVolumeGroups();
|
restoreVolumeGroups();
|
||||||
@@ -1163,6 +1169,72 @@ public class AudioService extends IAudioService.Stub
|
|||||||
setMicMuteFromSwitchInput();
|
setMicMuteFromSwitchInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onReinitVolumes(@NonNull String caller) {
|
||||||
|
final int numStreamTypes = AudioSystem.getNumStreamTypes();
|
||||||
|
// keep track of any error during stream volume initialization
|
||||||
|
int status = AudioSystem.AUDIO_STATUS_OK;
|
||||||
|
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
|
||||||
|
VolumeStreamState streamState = mStreamStates[streamType];
|
||||||
|
final int res = AudioSystem.initStreamVolume(
|
||||||
|
streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
|
||||||
|
if (res != AudioSystem.AUDIO_STATUS_OK) {
|
||||||
|
status = res;
|
||||||
|
Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType);
|
||||||
|
// stream volume initialization failed, no need to try the others, it will be
|
||||||
|
// attempted again when MSG_REINIT_VOLUMES is handled
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
streamState.applyAllVolumes();
|
||||||
|
}
|
||||||
|
|
||||||
|
// did it work? check based on status
|
||||||
|
if (status != AudioSystem.AUDIO_STATUS_OK) {
|
||||||
|
sLifecycleLogger.log(new AudioEventLogger.StringEvent(
|
||||||
|
caller + ": initStreamVolume failed with " + status + " will retry")
|
||||||
|
.printLog(ALOGE, TAG));
|
||||||
|
sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
|
||||||
|
caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// did it work? check based on min/max values of some basic streams
|
||||||
|
if (!checkVolumeRangeInitialization(caller)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// success
|
||||||
|
sLifecycleLogger.log(new AudioEventLogger.StringEvent(
|
||||||
|
caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check volume ranges were properly initialized
|
||||||
|
* @return true if volume ranges were successfully initialized
|
||||||
|
*/
|
||||||
|
private boolean checkVolumeRangeInitialization(String caller) {
|
||||||
|
boolean success = true;
|
||||||
|
final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING,
|
||||||
|
AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL,
|
||||||
|
AudioSystem.STREAM_ACCESSIBILITY };
|
||||||
|
for (int streamType : basicStreams) {
|
||||||
|
final AudioAttributes aa = new AudioAttributes.Builder()
|
||||||
|
.setInternalLegacyStreamType(streamType).build();
|
||||||
|
if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0
|
||||||
|
|| AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) {
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
sLifecycleLogger.log(new AudioEventLogger.StringEvent(
|
||||||
|
caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry")
|
||||||
|
.printLog(ALOGW, TAG));
|
||||||
|
sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
|
||||||
|
caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
private void onDispatchAudioServerStateChange(boolean state) {
|
private void onDispatchAudioServerStateChange(boolean state) {
|
||||||
synchronized (mAudioServerStateListeners) {
|
synchronized (mAudioServerStateListeners) {
|
||||||
for (AsdProxy asdp : mAudioServerStateListeners.values()) {
|
for (AsdProxy asdp : mAudioServerStateListeners.values()) {
|
||||||
@@ -5579,7 +5651,15 @@ public class AudioService extends IAudioService.Stub
|
|||||||
mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
|
mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
|
||||||
mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
|
mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
|
||||||
mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
|
mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
|
||||||
AudioSystem.initStreamVolume(streamType, mIndexMin / 10, mIndexMax / 10);
|
final int status = AudioSystem.initStreamVolume(
|
||||||
|
streamType, mIndexMin / 10, mIndexMax / 10);
|
||||||
|
if (status != AudioSystem.AUDIO_STATUS_OK) {
|
||||||
|
sLifecycleLogger.log(new AudioEventLogger.StringEvent(
|
||||||
|
"VSS() stream:" + streamType + " initStreamVolume=" + status)
|
||||||
|
.printLog(ALOGE, TAG));
|
||||||
|
sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
|
||||||
|
"VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
|
||||||
|
}
|
||||||
|
|
||||||
readSettings();
|
readSettings();
|
||||||
mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
|
mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
|
||||||
@@ -6433,6 +6513,10 @@ public class AudioService extends IAudioService.Stub
|
|||||||
mModeLogger.log(new PhoneStateEvent(h.getPackage(), h.getPid()));
|
mModeLogger.log(new PhoneStateEvent(h.getPackage(), h.getPid()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_REINIT_VOLUMES:
|
||||||
|
onReinitVolumes((String) msg.obj);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7363,12 +7447,16 @@ public class AudioService extends IAudioService.Stub
|
|||||||
//==========================================================================================
|
//==========================================================================================
|
||||||
// AudioService logging and dumpsys
|
// AudioService logging and dumpsys
|
||||||
//==========================================================================================
|
//==========================================================================================
|
||||||
|
static final int LOG_NB_EVENTS_LIFECYCLE = 20;
|
||||||
static final int LOG_NB_EVENTS_PHONE_STATE = 20;
|
static final int LOG_NB_EVENTS_PHONE_STATE = 20;
|
||||||
static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 30;
|
static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 30;
|
||||||
static final int LOG_NB_EVENTS_FORCE_USE = 20;
|
static final int LOG_NB_EVENTS_FORCE_USE = 20;
|
||||||
static final int LOG_NB_EVENTS_VOLUME = 40;
|
static final int LOG_NB_EVENTS_VOLUME = 40;
|
||||||
static final int LOG_NB_EVENTS_DYN_POLICY = 10;
|
static final int LOG_NB_EVENTS_DYN_POLICY = 10;
|
||||||
|
|
||||||
|
static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE,
|
||||||
|
"audio services lifecycle");
|
||||||
|
|
||||||
final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
|
final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
|
||||||
"phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
|
"phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
|
||||||
|
|
||||||
@@ -7445,6 +7533,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||||
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
|
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
|
||||||
|
|
||||||
|
sLifecycleLogger.dump(pw);
|
||||||
if (mAudioHandler != null) {
|
if (mAudioHandler != null) {
|
||||||
pw.println("\nMessage handler (watch for unhandled messages):");
|
pw.println("\nMessage handler (watch for unhandled messages):");
|
||||||
mAudioHandler.dump(new PrintWriterPrinter(pw), " ");
|
mAudioHandler.dump(new PrintWriterPrinter(pw), " ");
|
||||||
|
|||||||
Reference in New Issue
Block a user