/* * Copyright (C) 2023 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. */ #pragma once #include <android/content/AttributionSourceState.h> #include <binder/AppOpsManager.h> #include <system/audio.h> #include <utils/RefBase.h> #include <cstdint> #include "AudioPolicyService.h" namespace android::media::audiopolicy { using ::android::content::AttributionSourceState; // Checks and monitors app ops for AudioRecordClient class OpRecordAudioMonitor : public RefBase { public: ~OpRecordAudioMonitor() override; bool hasOp() const; int32_t getOp() const { return mAppOp; } static sp<OpRecordAudioMonitor> createIfNeeded( const AttributionSourceState& attributionSource, uint32_t virtualDeviceId, const audio_attributes_t& attr, wp<AudioPolicyService::AudioCommandThread> commandThread); private: OpRecordAudioMonitor(const AttributionSourceState &attributionSource, uint32_t virtualDeviceId, const audio_attributes_t &attr, int32_t appOp, wp<AudioPolicyService::AudioCommandThread> commandThread); void onFirstRef() override; AppOpsManager mAppOpsManager; class RecordAudioOpCallback : public BnAppOpsCallback { public: explicit RecordAudioOpCallback(const wp<OpRecordAudioMonitor>& monitor); void opChanged(int32_t op, const String16& packageName) override; private: const wp<OpRecordAudioMonitor> mMonitor; }; sp<RecordAudioOpCallback> mOpCallback; // called by RecordAudioOpCallback when the app op for this OpRecordAudioMonitor is updated // in AppOp callback and in onFirstRef() // updateUidStates is true when the silenced state of active AudioRecordClients must be // re-evaluated void checkOp(bool updateUidStates = false); std::atomic_bool mHasOp; const AttributionSourceState mAttributionSource; const uint32_t mVirtualDeviceId; const audio_attributes_t mAttr; const int32_t mAppOp; wp<AudioPolicyService::AudioCommandThread> mCommandThread; }; // --- AudioRecordClient --- // Information about each registered AudioRecord client // (between calls to getInputForAttr() and releaseInput()) class AudioRecordClient : public AudioPolicyService::AudioClient { public: AudioRecordClient(const audio_attributes_t attributes, const audio_io_handle_t io, const audio_session_t session, audio_port_handle_t portId, const audio_port_handle_t deviceId, const AttributionSourceState& attributionSource, const uint32_t virtualDeviceId, bool canCaptureOutput, bool canCaptureHotword, wp<AudioPolicyService::AudioCommandThread> commandThread) : AudioClient(attributes, io, attributionSource, session, portId, deviceId), attributionSource(attributionSource), virtualDeviceId(virtualDeviceId), startTimeNs(0), canCaptureOutput(canCaptureOutput), canCaptureHotword(canCaptureHotword), silenced(false), mOpRecordAudioMonitor( OpRecordAudioMonitor::createIfNeeded(attributionSource, virtualDeviceId, attributes, commandThread)) { } ~AudioRecordClient() override = default; bool hasOp() const { return mOpRecordAudioMonitor ? mOpRecordAudioMonitor->hasOp() : true; } const AttributionSourceState attributionSource; // attribution source of client const uint32_t virtualDeviceId; // id of the virtual device associated with the audio device nsecs_t startTimeNs; const bool canCaptureOutput; const bool canCaptureHotword; bool silenced; private: sp<OpRecordAudioMonitor> mOpRecordAudioMonitor; }; }; // namespace android::media::audiopolicy::internal