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

Commit 1d3cdce9 authored by Eric Laurent's avatar Eric Laurent
Browse files

Add audioserver state callback

Add system APIs for components (e.g rild) to monitor native audioserver
state and be able to reaply states after a native audioserver
crash and restart.

Bug: 67317552
Test: manual test.

Change-Id: I2afba9da5fc32b3768ca5ca0d5f97cc68707c408
parent b6ff8364
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -425,6 +425,7 @@ java_library {
        "media/java/android/media/IAudioFocusDispatcher.aidl",
        "media/java/android/media/IAudioRoutesObserver.aidl",
        "media/java/android/media/IAudioService.aidl",
        "media/java/android/media/IAudioServerStateDispatcher.aidl",
        "media/java/android/media/IMediaHTTPConnection.aidl",
        "media/java/android/media/IMediaHTTPService.aidl",
        "media/java/android/media/IMediaResourceMonitor.aidl",
+9 −0
Original line number Diff line number Diff line
@@ -2519,12 +2519,15 @@ package android.media {

  public class AudioManager {
    method public deprecated int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
    method public void clearAudioServerStateCallback();
    method public int dispatchAudioFocusChange(android.media.AudioFocusInfo, int, android.media.audiopolicy.AudioPolicy);
    method public boolean isAudioServerRunning();
    method public boolean isHdmiSystemAudioSupported();
    method public int registerAudioPolicy(android.media.audiopolicy.AudioPolicy);
    method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
    method public deprecated int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException;
    method public int requestAudioFocus(android.media.AudioFocusRequest, android.media.audiopolicy.AudioPolicy);
    method public void setAudioServerStateCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioServerStateCallback);
    method public void setFocusRequestResult(android.media.AudioFocusInfo, int, android.media.audiopolicy.AudioPolicy);
    method public void unregisterAudioPolicyAsync(android.media.audiopolicy.AudioPolicy);
    field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
@@ -2532,6 +2535,12 @@ package android.media {
    field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
  }

  public static abstract class AudioManager.AudioServerStateCallback {
    ctor public AudioManager.AudioServerStateCallback();
    method public void onAudioServerDown();
    method public void onAudioServerUp();
  }

  public final class AudioPlaybackConfiguration implements android.os.Parcelable {
    method public int getClientPid();
    method public int getClientUid();
+111 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.media;

import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -65,6 +66,8 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;


/**
 * AudioManager provides access to volume and ringer mode control.
@@ -4864,6 +4867,114 @@ public class AudioManager {
        }
    }


    /**
     * @hide
     * Abstract class to receive event notification about audioserver process state.
     */
    @SystemApi
    public abstract static class AudioServerStateCallback {
        public void onAudioServerDown() { }
        public void onAudioServerUp() { }
    }

    private Executor mAudioServerStateExec;
    private AudioServerStateCallback mAudioServerStateCb;
    private final Object mAudioServerStateCbLock = new Object();

    private final IAudioServerStateDispatcher mAudioServerStateDispatcher =
            new IAudioServerStateDispatcher.Stub() {
        @Override
        public void dispatchAudioServerStateChange(boolean state) {
            Executor exec;
            AudioServerStateCallback cb;

            synchronized (mAudioServerStateCbLock) {
                exec = mAudioServerStateExec;
                cb = mAudioServerStateCb;
            }

            if ((exec == null) || (cb == null)) {
                return;
            }
            if (state) {
                exec.execute(() -> cb.onAudioServerUp());
            } else {
                exec.execute(() -> cb.onAudioServerDown());
            }
        }
    };

    /**
     * @hide
     * Registers a callback for notification of audio server state changes.
     * @param executor {@link Executor} to handle the callbacks
     * @param stateCallback the callback to receive the audio server state changes
     *        To remove the callabck, pass a null reference for both executor and stateCallback.
     */
    @SystemApi
    public void setAudioServerStateCallback(@NonNull Executor executor,
            @NonNull AudioServerStateCallback stateCallback) {
        if (stateCallback == null) {
            throw new IllegalArgumentException("Illegal null AudioServerStateCallback");
        }
        if (executor == null) {
            throw new IllegalArgumentException(
                    "Illegal null Executor for the AudioServerStateCallback");
        }

        synchronized (mAudioServerStateCbLock) {
            if (mAudioServerStateCb != null) {
                throw new IllegalStateException(
                    "setAudioServerStateCallback called with already registered callabck");
            }
            final IAudioService service = getService();
            try {
                service.registerAudioServerStateDispatcher(mAudioServerStateDispatcher);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
            mAudioServerStateExec = executor;
            mAudioServerStateCb = stateCallback;
        }
    }

    /**
     * @hide
     * Unregisters the callback for notification of audio server state changes.
     */
    @SystemApi
    public void clearAudioServerStateCallback() {
        synchronized (mAudioServerStateCbLock) {
            if (mAudioServerStateCb != null) {
                final IAudioService service = getService();
                try {
                    service.unregisterAudioServerStateDispatcher(
                            mAudioServerStateDispatcher);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            mAudioServerStateExec = null;
            mAudioServerStateCb = null;
        }
    }

    /**
     * @hide
     * Checks if native audioservice is running or not.
     * @return true if native audioservice runs, false otherwise.
     */
    @SystemApi
    public boolean isAudioServerRunning() {
        final IAudioService service = getService();
        try {
            return service.isAudioServerRunning();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    //---------------------------------------------------------
    // Inner classes
    //--------------------
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

/**
 * AIDL for the AudioService to signal audio server state changes
 *
 * {@hide}
 */
oneway interface IAudioServerStateDispatcher {

    void dispatchAudioServerStateChange(boolean state);

}
+8 −0
Original line number Diff line number Diff line
@@ -24,10 +24,12 @@ import android.media.AudioRecordingConfiguration;
import android.media.AudioRoutesInfo;
import android.media.IAudioFocusDispatcher;
import android.media.IAudioRoutesObserver;
import android.media.IAudioServerStateDispatcher;
import android.media.IPlaybackConfigDispatcher;
import android.media.IRecordingConfigDispatcher;
import android.media.IRingtonePlayer;
import android.media.IVolumeController;
import android.media.IVolumeController;
import android.media.PlayerBase;
import android.media.VolumePolicy;
import android.media.audiopolicy.AudioPolicyConfig;
@@ -208,6 +210,12 @@ interface IAudioService {
    oneway void setFocusRequestResultFromExtPolicy(in AudioFocusInfo afi, int requestResult,
            in IAudioPolicyCallback pcb);

    void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd);

    oneway void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd);

    boolean isAudioServerRunning();

    // WARNING: read warning at top of file, new methods that need to be used by native
    // code via IAudioManager.h need to be added to the top section.
}
Loading