diff options
| author | Eric Laurent <elaurent@google.com> | 2014-05-06 10:49:04 -0700 |
|---|---|---|
| committer | Eric Laurent <elaurent@google.com> | 2014-05-06 10:49:04 -0700 |
| commit | 4a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3 (patch) | |
| tree | 28a357f9dd84cede672e2f8d6281a130b6d4ce7b | |
| parent | ebb9e69513b690881a5bad7bf45c6f32e0fc7062 (diff) | |
| download | frameworks_base-4a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3.zip frameworks_base-4a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3.tar.gz frameworks_base-4a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3.tar.bz2 | |
AudioService/WireAccessoryManager: change boot completion detection method
BOOT_COMPLETED intent is not a reliable way for system services
to detect boot completion. The intent broadcast can be significantly
delayed and there is no guaranty that system services
receive it before apps.
Use a systemReady() method called by SystemServer instead.
Bug: 14323903.
Change-Id: I781596a3545e7a1e719799982347cbcd9a4c9009
4 files changed, 77 insertions, 47 deletions
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 0c8a823..724022b 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -149,6 +149,7 @@ public class AudioService extends IAudioService.Stub { private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 18; private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 19; private static final int MSG_UNLOAD_SOUND_EFFECTS = 20; + private static final int MSG_SYSTEM_READY = 21; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) @@ -370,7 +371,7 @@ public class AudioService extends IAudioService.Stub { private int mScoConnectionState; // true if boot sequence has been completed - private boolean mBootCompleted; + private boolean mSystemReady; // listener for SoundPool sample load completion indication private SoundPoolCallback mSoundPoolCallBack; // thread for SoundPool listener @@ -525,7 +526,6 @@ public class AudioService extends IAudioService.Stub { intentFilter.addAction(Intent.ACTION_DOCK_EVENT); intentFilter.addAction(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG); intentFilter.addAction(Intent.ACTION_USB_AUDIO_DEVICE_PLUG); - intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); @@ -559,6 +559,43 @@ public class AudioService extends IAudioService.Stub { } + public void systemReady() { + sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, + 0, 0, null, 0); + } + + public void onSystemReady() { + mSystemReady = true; + sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, + 0, 0, null, 0); + + mKeyguardManager = + (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); + mScoConnectionState = AudioManager.SCO_AUDIO_STATE_ERROR; + resetBluetoothSco(); + getBluetoothHeadset(); + //FIXME: this is to maintain compatibility with deprecated intent + // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate. + Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED); + newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, + AudioManager.SCO_AUDIO_STATE_DISCONNECTED); + sendStickyBroadcastToAll(newIntent); + + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + if (adapter != null) { + adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, + BluetoothProfile.A2DP); + } + + sendMsg(mAudioHandler, + MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED, + SENDMSG_REPLACE, + 0, + 0, + null, + SAFE_VOLUME_CONFIGURE_TIMEOUT_MS); + } + private void createAudioSystemThread() { mAudioSystemThread = new AudioSystemThread(); mAudioSystemThread.start(); @@ -1996,7 +2033,7 @@ public class AudioService extends IAudioService.Stub { /** @see AudioManager#startBluetoothSco() */ public void startBluetoothSco(IBinder cb, int targetSdkVersion){ if (!checkAudioSettingsPermission("startBluetoothSco()") || - !mBootCompleted) { + !mSystemReady) { return; } ScoClient client = getScoClient(cb, true); @@ -2013,7 +2050,7 @@ public class AudioService extends IAudioService.Stub { /** @see AudioManager#stopBluetoothSco() */ public void stopBluetoothSco(IBinder cb){ if (!checkAudioSettingsPermission("stopBluetoothSco()") || - !mBootCompleted) { + !mSystemReady) { return; } ScoClient client = getScoClient(cb, false); @@ -3277,7 +3314,7 @@ public class AudioService extends IAudioService.Stub { int status; synchronized (mSoundEffectsLock) { - if (!mBootCompleted) { + if (!mSystemReady) { Log.w(TAG, "onLoadSoundEffects() called before boot complete"); return false; } @@ -3700,6 +3737,10 @@ public class AudioService extends IAudioService.Stub { case MSG_BROADCAST_BT_CONNECTION_STATE: onBroadcastScoConnectionState(msg.arg1); break; + + case MSG_SYSTEM_READY: + onSystemReady(); + break; } } } @@ -4169,36 +4210,6 @@ public class AudioService extends IAudioService.Stub { newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, scoAudioState); sendStickyBroadcastToAll(newIntent); } - } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { - mBootCompleted = true; - sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, - 0, 0, null, 0); - - mKeyguardManager = - (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); - mScoConnectionState = AudioManager.SCO_AUDIO_STATE_ERROR; - resetBluetoothSco(); - getBluetoothHeadset(); - //FIXME: this is to maintain compatibility with deprecated intent - // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate. - Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED); - newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, - AudioManager.SCO_AUDIO_STATE_DISCONNECTED); - sendStickyBroadcastToAll(newIntent); - - BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - if (adapter != null) { - adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, - BluetoothProfile.A2DP); - } - - sendMsg(mAudioHandler, - MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED, - SENDMSG_REPLACE, - 0, - 0, - null, - SAFE_VOLUME_CONFIGURE_TIMEOUT_MS); } else if (action.equals(Intent.ACTION_SCREEN_ON)) { AudioSystem.setParameters("screen_state=on"); } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java index 50cfe48..c32beda 100644 --- a/services/core/java/com/android/server/WiredAccessoryManager.java +++ b/services/core/java/com/android/server/WiredAccessoryManager.java @@ -70,6 +70,7 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks { private static final String NAME_HDMI = "hdmi"; private static final int MSG_NEW_DEVICE_STATE = 1; + private static final int MSG_SYSTEM_READY = 2; private final Object mLock = new Object(); @@ -96,19 +97,9 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks { context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); mObserver = new WiredAccessoryObserver(); - - IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); - filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - context.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context ctx, Intent intent) { - bootCompleted(); - } - }, - filter, null, null); } - private void bootCompleted() { + private void onSystemReady() { if (mUseDevInputEventForAudioJack) { int switchValues = 0; if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_HEADPHONE_INSERT) == 1) { @@ -159,6 +150,16 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks { } } + @Override + public void systemReady() { + synchronized (mLock) { + mWakeLock.acquire(); + + Message msg = mHandler.obtainMessage(MSG_SYSTEM_READY, 0, 0, null); + mHandler.sendMessage(msg); + } + } + /** * Compare the existing headset state with the new state and pass along accordingly. Note * that this only supports a single headset at a time. Inserting both a usb and jacked headset @@ -220,6 +221,11 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks { case MSG_NEW_DEVICE_STATE: setDevicesState(msg.arg1, msg.arg2, (String)msg.obj); mWakeLock.release(); + break; + case MSG_SYSTEM_READY: + onSystemReady(); + mWakeLock.release(); + break; } } }; diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 54cb035..0f5805c 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -323,6 +323,10 @@ public class InputManagerService extends IInputManager.Stub mHandler.sendEmptyMessage(MSG_RELOAD_DEVICE_ALIASES); mHandler.sendEmptyMessage(MSG_UPDATE_KEYBOARD_LAYOUTS); + + if (mWiredAccessoryCallbacks != null) { + mWiredAccessoryCallbacks.systemReady(); + } } private void reloadKeyboardLayouts() { @@ -1588,6 +1592,7 @@ public class InputManagerService extends IInputManager.Stub */ public interface WiredAccessoryCallbacks { public void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask); + public void systemReady(); } /** diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 7c9f7a8..58c43fb 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -333,6 +333,7 @@ public final class SystemServer { InputManagerService inputManager = null; TelephonyRegistry telephonyRegistry = null; ConsumerIrService consumerIr = null; + AudioService audioService = null; boolean onlyCore = false; boolean firstBoot = false; @@ -759,7 +760,8 @@ public final class SystemServer { if (!disableMedia && !"0".equals(SystemProperties.get("system_init.startaudioservice"))) { try { Slog.i(TAG, "Audio Service"); - ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context)); + audioService = new AudioService(context); + ServiceManager.addService(Context.AUDIO_SERVICE, audioService); } catch (Throwable e) { reportWtf("starting Audio Service", e); } @@ -1067,6 +1069,7 @@ public final class SystemServer { final InputManagerService inputManagerF = inputManager; final TelephonyRegistry telephonyRegistryF = telephonyRegistry; final MediaRouterService mediaRouterF = mediaRouter; + final AudioService audioServiceF = audioService; // We now tell the activity manager it is okay to run third party // code. It will call back into us once it has gotten to the state @@ -1135,6 +1138,11 @@ public final class SystemServer { } catch (Throwable e) { reportWtf("making Recognition Service ready", e); } + try { + if (audioServiceF != null) audioServiceF.systemReady(); + } catch (Throwable e) { + reportWtf("Notifying AudioService running", e); + } Watchdog.getInstance().start(); // It is now okay to let the various system services start their |
