Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a5eeb9c authored by Eric Laurent's avatar Eric Laurent
Browse files

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
parent ebb9e695
Loading
Loading
Loading
Loading
+46 −35
Original line number Diff line number Diff line
@@ -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)) {
+17 −11
Original line number Diff line number Diff line
@@ -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;
            }
        }
    };
+5 −0
Original line number Diff line number Diff line
@@ -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();
    }

    /**
+9 −1
Original line number Diff line number Diff line
@@ -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