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

Commit 24bfbe26 authored by Ytai Ben-tsvi's avatar Ytai Ben-tsvi Committed by Android (Google) Code Review
Browse files

Merge changes from topic "invert-capture"

* changes:
  Expose capture state listener in AudioSystem
  Invert how sound trigger capture is notified
  Introduce CaptureStateNotifier
parents 80de6d53 95ce2028
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ cc_library_shared {
        "AudioVolumeGroup.cpp",
    ],
    shared_libs: [
        "capture_state_listener-aidl-cpp",
        "libaudiofoundation",
        "libaudioutils",
        "libbinder",
@@ -34,6 +35,9 @@ cc_library_shared {
    ],
    include_dirs: ["system/media/audio_utils/include"],
    export_include_dirs: ["include"],
    export_shared_lib_headers: [
        "capture_state_listener-aidl-cpp",
    ],
}

cc_library_shared {
@@ -73,6 +77,7 @@ cc_library_shared {
        "TrackPlayerBase.cpp",
    ],
    shared_libs: [
        "capture_state_listener-aidl-cpp",
        "libaudiofoundation",
        "libaudioutils",
        "libaudiopolicy",
@@ -148,3 +153,11 @@ filegroup {
    ],
    path: "aidl",
}

aidl_interface {
    name: "capture_state_listener-aidl",
    local_include_dir: "aidl",
    srcs: [
        "aidl/android/media/ICaptureStateListener.aidl",
    ],
}
+48 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
//#define LOG_NDEBUG 0

#include <utils/Log.h>

#include <android/media/BnCaptureStateListener.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
@@ -44,6 +46,10 @@ std::set<audio_error_callback> AudioSystem::gAudioErrorCallbacks;
dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
record_config_callback AudioSystem::gRecordConfigCallback = NULL;

// Required to be held while calling into gSoundTriggerCaptureStateListener.
Mutex gSoundTriggerCaptureStateListenerLock;
sp<AudioSystem::CaptureStateListener> gSoundTriggerCaptureStateListener = nullptr;

// establish binder interface to AudioFlinger service
const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
{
@@ -1623,6 +1629,48 @@ status_t AudioSystem::getPreferredDeviceForStrategy(product_strategy_t strategy,
    return aps->getPreferredDeviceForStrategy(strategy, device);
}

class CaptureStateListenerImpl : public media::BnCaptureStateListener,
                                 public IBinder::DeathRecipient {
public:
    binder::Status setCaptureState(bool active) override {
        Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
        gSoundTriggerCaptureStateListener->onStateChanged(active);
        return binder::Status::ok();
    }

    void binderDied(const wp<IBinder>&) override {
        Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
        gSoundTriggerCaptureStateListener->onServiceDied();
        gSoundTriggerCaptureStateListener = nullptr;
    }
};

status_t AudioSystem::registerSoundTriggerCaptureStateListener(
    const sp<CaptureStateListener>& listener) {
    const sp<IAudioPolicyService>& aps =
            AudioSystem::get_audio_policy_service();
    if (aps == 0) {
        return PERMISSION_DENIED;
    }

    sp<CaptureStateListenerImpl> wrapper = new CaptureStateListenerImpl();

    Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);

    bool active;
    status_t status =
        aps->registerSoundTriggerCaptureStateListener(wrapper, &active);
    if (status != NO_ERROR) {
        listener->onServiceDied();
        return NO_ERROR;
    }
    gSoundTriggerCaptureStateListener = listener;
    listener->onStateChanged(active);
    sp<IBinder> binder = IInterface::asBinder(aps);
    binder->linkToDeath(wrapper);
    return NO_ERROR;
}

// ---------------------------------------------------------------------------

int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
+52 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <math.h>
#include <sys/types.h>

#include <android/media/ICaptureStateListener.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <media/AudioEffect.h>
@@ -32,6 +33,8 @@

namespace android {

using media::ICaptureStateListener;

enum {
    SET_DEVICE_CONNECTION_STATE = IBinder::FIRST_CALL_TRANSACTION,
    GET_DEVICE_CONNECTION_STATE,
@@ -115,6 +118,7 @@ enum {
    GET_DEVICES_FOR_ATTRIBUTES,
    AUDIO_MODULES_UPDATED,  // oneway
    SET_CURRENT_IME_UID,
    REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER,
};

#define MAX_ITEMS_PER_LIST 1024
@@ -1470,6 +1474,27 @@ public:
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        remote()->transact(AUDIO_MODULES_UPDATED, data, &reply, IBinder::FLAG_ONEWAY);
    }

    status_t registerSoundTriggerCaptureStateListener(
            const sp<media::ICaptureStateListener>& listener,
            bool* result) override {
        Parcel data, reply;
        status_t status;
        status =
            data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        if (status != NO_ERROR) return status;
        status = data.writeStrongBinder(IInterface::asBinder(listener));
        if (status != NO_ERROR) return status;
        status =
            remote()->transact(REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER,
                               data,
                               &reply,
                               0);
        if (status != NO_ERROR) return status;
        status = reply.readBool(result);
        if (status != NO_ERROR) return status;
        return NO_ERROR;
    }
};

IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1543,7 +1568,8 @@ status_t BnAudioPolicyService::onTransact(
        case GET_DEVICES_FOR_ATTRIBUTES:
        case SET_ALLOWED_CAPTURE_POLICY:
        case AUDIO_MODULES_UPDATED:
        case SET_CURRENT_IME_UID: {
        case SET_CURRENT_IME_UID:
        case REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER: {
            if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                      __func__, code, IPCThreadState::self()->getCallingPid(),
@@ -2706,6 +2732,31 @@ status_t BnAudioPolicyService::onTransact(
            return NO_ERROR;
        }

        case REGISTER_SOUNDTRIGGER_CAPTURE_STATE_LISTENER: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            sp<IBinder> binder = data.readStrongBinder();
            if (binder == nullptr) {
                return BAD_VALUE;
            }
            sp<ICaptureStateListener>
                listener = interface_cast<ICaptureStateListener>(
                binder);
            if (listener == nullptr) {
                return BAD_VALUE;
            }
            bool ret;
            status_t status =
                registerSoundTriggerCaptureStateListener(listener, &ret);
            LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
                                "Server returned unexpected status code: %d",
                                status);
            status = reply->writeBool(ret);
            if (status != NO_ERROR) {
                return status;
            }
            return NO_ERROR;
        } break;

        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+21 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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;

interface ICaptureStateListener {
    void setCaptureState(boolean active);
}
+24 −0
Original line number Diff line number Diff line
@@ -436,6 +436,30 @@ public:
    static status_t getDeviceForStrategy(product_strategy_t strategy,
            AudioDeviceTypeAddr &device);

    // A listener for capture state changes.
    class CaptureStateListener : public RefBase {
    public:
        // Called whenever capture state changes.
        virtual void onStateChanged(bool active) = 0;
        // Called whenever the service dies (and hence our listener is no longer
        // registered).
        virtual void onServiceDied() = 0;

        virtual ~CaptureStateListener() = default;
    };

    // Regiseters a listener for sound trigger capture state changes.
    // There may only be one such listener registered at any point.
    // The listener onStateChanged() method will be invoked sychronously from
    // this call with the initial value.
    // The listener onServiceDied() method will be invoked sychronously from
    // this call if initial attempt to register failed.
    // If the audio policy service cannot be reached, this method will return
    // PERMISSION_DENIED and will not invoke the callback, otherwise, it will
    // return NO_ERROR.
    static status_t registerSoundTriggerCaptureStateListener(
            const sp<CaptureStateListener>& listener);

    // ----------------------------------------------------------------------------

    class AudioVolumeGroupCallback : public RefBase
Loading