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

Commit c2c99464 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "AudioService: check calls to AudioSystem.initStreamVolume" into rvc-qpr-dev

parents acbb253b 44caf0ed
Loading
Loading
Loading
Loading
+30 −1
Original line number Diff line number Diff line
@@ -60,7 +60,36 @@ public class AudioEventLogger {
         * @return the same instance of the event
         */
        public Event printLog(String tag) {
            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;
        }

+99 −10
Original line number Diff line number Diff line
@@ -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_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.annotation.IntDef;
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_BROADCAST_MICROPHONE_MUTE = 30;
    private static final int MSG_CHECK_MODE_FOR_UID = 31;
    private static final int MSG_REINIT_VOLUMES = 32;
    // start of messages handled under wakelock
    //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
    //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
@@ -673,6 +678,7 @@ public class AudioService extends IAudioService.Stub

    public AudioService(Context context, AudioSystemAdapter audioSystem,
            SystemServerAdapter systemServer) {
        sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()"));
        mContext = context;
        mContentResolver = context.getContentResolver();
        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
@@ -892,6 +898,9 @@ public class AudioService extends IAudioService.Stub
                mPrescaleAbsoluteVolume[i] = preScale[i];
            }
        }

        // check on volume initialization
        checkVolumeRangeInitialization("AudioService()");
    }

    public void systemReady() {
@@ -1019,11 +1028,15 @@ public class AudioService extends IAudioService.Stub
        if (!mSystemReady ||
                (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
            Log.e(TAG, "Audioserver died.");
            sLifecycleLogger.log(new AudioEventLogger.StringEvent(
                    "onAudioServerDied() audioserver died"));
            sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
                    null, 500);
            return;
        }
        Log.e(TAG, "Audioserver started.");
        Log.i(TAG, "Audioserver started.");
        sLifecycleLogger.log(new AudioEventLogger.StringEvent(
                "onAudioServerDied() audioserver started"));

        updateAudioHalPids();

@@ -1058,14 +1071,7 @@ public class AudioService extends IAudioService.Stub
        mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");

        // Restore stream volumes
        int numStreamTypes = AudioSystem.getNumStreamTypes();
        for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
            VolumeStreamState streamState = mStreamStates[streamType];
            AudioSystem.initStreamVolume(
                streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);

            streamState.applyAllVolumes();
        }
        onReinitVolumes("after audioserver restart");

        // Restore audio volume groups
        restoreVolumeGroups();
@@ -1163,6 +1169,72 @@ public class AudioService extends IAudioService.Stub
        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) {
        synchronized (mAudioServerStateListeners) {
            for (AsdProxy asdp : mAudioServerStateListeners.values()) {
@@ -5579,7 +5651,15 @@ public class AudioService extends IAudioService.Stub
            mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
            mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
            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();
            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()));
                    }
                    break;

                case MSG_REINIT_VOLUMES:
                    onReinitVolumes((String) msg.obj);
                    break;
            }
        }
    }
@@ -7363,12 +7447,16 @@ public class AudioService extends IAudioService.Stub
    //==========================================================================================
    // 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_DEVICE_CONNECTION = 30;
    static final int LOG_NB_EVENTS_FORCE_USE = 20;
    static final int LOG_NB_EVENTS_VOLUME = 40;
    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,
            "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) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;

        sLifecycleLogger.dump(pw);
        if (mAudioHandler != null) {
            pw.println("\nMessage handler (watch for unhandled messages):");
            mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");