diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp index efe65bb299..3e91717d23 100644 --- a/media/libaudioclient/AudioSystem.cpp +++ b/media/libaudioclient/AudioSystem.cpp @@ -1315,6 +1315,13 @@ status_t AudioSystem::setA11yServicesUids(const std::vector& uids) return aps->setA11yServicesUids(uids); } +bool AudioSystem::isHapticPlaybackSupported() +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return false; + return aps->isHapticPlaybackSupported(); +} + // --------------------------------------------------------------------------- diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp index 86e417a1a5..0ce8b16f47 100644 --- a/media/libaudioclient/IAudioPolicyService.cpp +++ b/media/libaudioclient/IAudioPolicyService.cpp @@ -89,6 +89,7 @@ enum { REMOVE_SOURCE_DEFAULT_EFFECT, SET_ASSISTANT_UID, SET_A11Y_SERVICES_UIDS, + IS_HAPTIC_PLAYBACK_SUPPORTED, }; #define MAX_ITEMS_PER_LIST 1024 @@ -978,6 +979,17 @@ public: return static_cast (reply.readInt32()); } + virtual bool isHapticPlaybackSupported() + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + status_t status = remote()->transact(IS_HAPTIC_PLAYBACK_SUPPORTED, data, &reply); + if (status != NO_ERROR) { + return false; + } + return reply.readBool(); + } + }; IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); @@ -1795,6 +1807,13 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } + case IS_HAPTIC_PLAYBACK_SUPPORTED: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + bool isSupported = isHapticPlaybackSupported(); + reply->writeBool(isSupported); + return NO_ERROR; + } + default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h index ca1879fc4e..74156caf9a 100644 --- a/media/libaudioclient/include/media/AudioSystem.h +++ b/media/libaudioclient/include/media/AudioSystem.h @@ -345,6 +345,8 @@ public: static status_t setAssistantUid(uid_t uid); static status_t setA11yServicesUids(const std::vector& uids); + static bool isHapticPlaybackSupported(); + // ---------------------------------------------------------------------------- class AudioPortCallback : public RefBase diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h index e3386a4688..61f3b27d6f 100644 --- a/media/libaudioclient/include/media/IAudioPolicyService.h +++ b/media/libaudioclient/include/media/IAudioPolicyService.h @@ -185,6 +185,8 @@ public: virtual status_t setAssistantUid(uid_t uid) = 0; virtual status_t setA11yServicesUids(const std::vector& uids) = 0; + + virtual bool isHapticPlaybackSupported() = 0; }; diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index c1db78be96..ea6389ca6b 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -228,6 +228,8 @@ public: bool reported) = 0; virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) = 0; + virtual bool isHapticPlaybackSupported() = 0; + virtual void setAppState(uid_t uid, app_state_t state); }; diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index fb0e436273..2a634938b7 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -3655,6 +3655,23 @@ void AudioPolicyManager::setAppState(uid_t uid, app_state_t state) } } +bool AudioPolicyManager::isHapticPlaybackSupported() +{ + for (const auto& hwModule : mHwModules) { + const OutputProfileCollection &outputProfiles = hwModule->getOutputProfiles(); + for (const auto &outProfile : outputProfiles) { + struct audio_port audioPort; + outProfile->toAudioPort(&audioPort); + for (size_t i = 0; i < audioPort.num_channel_masks; i++) { + if (audioPort.channel_masks[i] & AUDIO_CHANNEL_HAPTIC_ALL) { + return true; + } + } + } + } + return false; +} + status_t AudioPolicyManager::disconnectAudioSource(const sp& sourceDesc) { ALOGV("%s port Id %d", __FUNCTION__, sourceDesc->portId()); diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index 709cce0683..7f2412e919 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -247,6 +247,8 @@ public: virtual void setAppState(uid_t uid, app_state_t state); + virtual bool isHapticPlaybackSupported(); + protected: // A constructor that allows more fine-grained control over initialization process, // used in automatic tests. diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index ae92ae5d00..439764be89 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -1133,4 +1133,15 @@ status_t AudioPolicyService::setA11yServicesUids(const std::vector& uids) return NO_ERROR; } +bool AudioPolicyService::isHapticPlaybackSupported() +{ + if (mAudioPolicyManager == NULL) { + ALOGW("%s, mAudioPolicyManager == NULL", __func__); + return false; + } + Mutex::Autolock _l(mLock); + AutoCallerClear acc; + return mAudioPolicyManager->isHapticPlaybackSupported(); +} + } // namespace android diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index f490fb9a06..23c3daace5 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -218,6 +218,8 @@ public: virtual status_t setAssistantUid(uid_t uid); virtual status_t setA11yServicesUids(const std::vector& uids); + virtual bool isHapticPlaybackSupported(); + status_t doStopOutput(audio_port_handle_t portId); void doReleaseOutput(audio_port_handle_t portId);