AudioService: optimize service creation
Delay a number of stream and volume initialization steps
to after the creation of the service to reduce system_server
initialization time.
Clean-up:
- class StreamVolumeCommand should be static, it doesn't access
AudioService resources
- make mRmtSbmxFullVolDeathHandlers and mAudioServerStateListeners
final as they are never modified after creation, and used for
synchronization.
Bug: 164516518
Test: atest AudioManagerTest
Change-Id: I9afd7989793f20480b3059ee80ab403c5e4ee969
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index f1561cab..7ad0f21 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -297,6 +297,7 @@
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
+ private static final int MSG_INIT_STREAMS_VOLUMES = 101;
// end of messages handled under wakelock
// retry delay in case of failure to indicate system ready to AudioFlinger
@@ -822,7 +823,34 @@
updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
readPersistedSettings();
readUserRestrictions();
- mSettingsObserver = new SettingsObserver();
+
+ mPlaybackMonitor =
+ new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
+ mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
+
+ readAndSetLowRamDevice();
+
+ mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
+
+ if (mSystemServer.isPrivileged()) {
+ LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
+
+ mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
+
+ mRecordMonitor.initMonitor();
+ }
+
+ mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
+
+ // done with service initialization, continue additional work in our Handler thread
+ queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
+ 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
+ }
+
+ /**
+ * Called by handling of MSG_INIT_STREAMS_VOLUMES
+ */
+ private void onInitStreamsAndVolumes() {
createStreamStates();
// must be called after createStreamStates() as it uses MUSIC volume as default if no
@@ -833,53 +861,11 @@
// relies on audio policy having correct ranges for volume indexes.
mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
- mPlaybackMonitor =
- new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
-
- mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
-
- readAndSetLowRamDevice();
-
- mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
-
// Call setRingerModeInt() to apply correct mute
// state on streams affected by ringer mode.
mRingerAndZenModeMutedStreams = 0;
setRingerModeInt(getRingerModeInternal(), false);
- // Register for device connection intent broadcasts.
- IntentFilter intentFilter =
- new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
- intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
- intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
- intentFilter.addAction(Intent.ACTION_SCREEN_ON);
- intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
- intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
- intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
- intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
- intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
- intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
-
- intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
- mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
- if (mMonitorRotation) {
- RotationHelper.init(mContext, mAudioHandler);
- }
-
- intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
- intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
-
- context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
-
- if (mSystemServer.isPrivileged()) {
- LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
-
- mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
-
- mRecordMonitor.initMonitor();
- }
-
final float[] preScale = new float[3];
preScale[0] = mContext.getResources().getFraction(
com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
@@ -896,10 +882,47 @@
}
}
+ initExternalEventReceivers();
+
// check on volume initialization
checkVolumeRangeInitialization("AudioService()");
}
+ /**
+ * Initialize intent receives and settings observers for this service.
+ * Must be called after createStreamStates() as the handling of some events
+ * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
+ * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer)
+ */
+ private void initExternalEventReceivers() {
+ mSettingsObserver = new SettingsObserver();
+
+ // Register for device connection intent broadcasts.
+ IntentFilter intentFilter =
+ new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+ intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
+ intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
+ intentFilter.addAction(Intent.ACTION_SCREEN_ON);
+ intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+ intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+ intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
+ intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
+ intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+ intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
+
+ intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+ if (mMonitorRotation) {
+ RotationHelper.init(mContext, mAudioHandler);
+ }
+
+ intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
+ intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
+
+ mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
+
+ }
+
public void systemReady() {
sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
0, 0, null, 0);
@@ -2593,7 +2616,7 @@
// StreamVolumeCommand contains the information needed to defer the process of
// setStreamVolume() in case the user has to acknowledge the safe volume warning message.
- class StreamVolumeCommand {
+ static class StreamVolumeCommand {
public final int mStreamType;
public final int mIndex;
public final int mFlags;
@@ -2612,7 +2635,7 @@
.append(mIndex).append(",flags=").append(mFlags).append(",device=")
.append(mDevice).append('}').toString();
}
- };
+ }
private int getNewRingerMode(int stream, int index, int flags) {
// setRingerMode does nothing if the device is single volume,so the value would be unchanged
@@ -3321,7 +3344,7 @@
}
private int mRmtSbmxFullVolRefCount = 0;
- private ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
+ private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
new ArrayList<RmtSbmxFullVolDeathHandler>();
public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
@@ -5882,7 +5905,6 @@
private final Intent mStreamDevicesChanged;
private VolumeStreamState(String settingName, int streamType) {
-
mVolumeIndexSettingName = settingName;
mStreamType = streamType;
@@ -6658,6 +6680,11 @@
mAudioEventWakeLock.release();
break;
+ case MSG_INIT_STREAMS_VOLUMES:
+ onInitStreamsAndVolumes();
+ mAudioEventWakeLock.release();
+ break;
+
case MSG_CHECK_MUSIC_ACTIVE:
onCheckMusicActive((String) msg.obj);
break;
@@ -9216,7 +9243,7 @@
}
}
- private HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
+ private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
new HashMap<IBinder, AsdProxy>();
private void checkMonitorAudioServerStatePermission() {