| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 1 | /* | 
 | 2 | ** | 
 | 3 | ** Copyright 2021, The Android Open Source Project | 
 | 4 | ** | 
 | 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 6 | ** you may not use this file except in compliance with the License. | 
 | 7 | ** You may obtain a copy of the License at | 
 | 8 | ** | 
 | 9 | **     http://www.apache.org/licenses/LICENSE-2.0 | 
 | 10 | ** | 
 | 11 | ** Unless required by applicable law or agreed to in writing, software | 
 | 12 | ** distributed under the License is distributed on an "AS IS" BASIS, | 
 | 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 14 | ** See the License for the specific language governing permissions and | 
 | 15 | ** limitations under the License. | 
 | 16 | */ | 
 | 17 |  | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 18 | #include <string> | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 19 | #define LOG_TAG "Spatializer" | 
 | 20 | //#define LOG_NDEBUG 0 | 
 | 21 | #include <utils/Log.h> | 
 | 22 |  | 
| Andy Hung | cd6c106 | 2023-03-09 20:45:36 -0800 | [diff] [blame] | 23 | #include <algorithm> | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 24 | #include <inttypes.h> | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 25 | #include <limits.h> | 
 | 26 | #include <stdint.h> | 
 | 27 | #include <sys/types.h> | 
 | 28 |  | 
 | 29 | #include <android/content/AttributionSourceState.h> | 
 | 30 | #include <audio_utils/fixedfft.h> | 
 | 31 | #include <cutils/bitops.h> | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 32 | #include <hardware/sensors.h> | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 33 | #include <media/stagefright/foundation/AHandler.h> | 
 | 34 | #include <media/stagefright/foundation/AMessage.h> | 
| Andy Hung | a461a00 | 2022-05-17 10:36:02 -0700 | [diff] [blame] | 35 | #include <media/MediaMetricsItem.h> | 
| Andy Hung | 2a390db | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 36 | #include <media/QuaternionUtil.h> | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 37 | #include <media/ShmemCompat.h> | 
| Andy Hung | b725c69 | 2022-12-14 14:25:49 -0800 | [diff] [blame] | 38 | #include <mediautils/SchedulingPolicyService.h> | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 39 | #include <mediautils/ServiceUtilities.h> | 
 | 40 | #include <utils/Thread.h> | 
 | 41 |  | 
 | 42 | #include "Spatializer.h" | 
 | 43 |  | 
 | 44 | namespace android { | 
 | 45 |  | 
 | 46 | using aidl_utils::statusTFromBinderStatus; | 
 | 47 | using aidl_utils::binderStatusFromStatusT; | 
 | 48 | using android::content::AttributionSourceState; | 
 | 49 | using binder::Status; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 50 | using media::HeadTrackingMode; | 
 | 51 | using media::Pose3f; | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 52 | using media::SpatializationLevel; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 53 | using media::SpatializationMode; | 
| Ytai Ben-Tsvi | a16a9df | 2021-08-05 08:57:06 -0700 | [diff] [blame] | 54 | using media::SpatializerHeadTrackingMode; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 55 | using media::SensorPoseProvider; | 
 | 56 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 57 | using namespace std::chrono_literals; | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 58 |  | 
 | 59 | #define VALUE_OR_RETURN_BINDER_STATUS(x) \ | 
 | 60 |     ({ auto _tmp = (x); \ | 
 | 61 |        if (!_tmp.ok()) return aidl_utils::binderStatusFromStatusT(_tmp.error()); \ | 
 | 62 |        std::move(_tmp.value()); }) | 
 | 63 |  | 
| Andy Hung | 0e3205d | 2022-08-29 14:14:58 -0700 | [diff] [blame] | 64 | static audio_channel_mask_t getMaxChannelMask( | 
 | 65 |         const std::vector<audio_channel_mask_t>& masks, size_t channelLimit = SIZE_MAX) { | 
| Andy Hung | a461a00 | 2022-05-17 10:36:02 -0700 | [diff] [blame] | 66 |     uint32_t maxCount = 0; | 
 | 67 |     audio_channel_mask_t maxMask = AUDIO_CHANNEL_NONE; | 
 | 68 |     for (auto mask : masks) { | 
 | 69 |         const size_t count = audio_channel_count_from_out_mask(mask); | 
| Andy Hung | 0e3205d | 2022-08-29 14:14:58 -0700 | [diff] [blame] | 70 |         if (count > channelLimit) continue;  // ignore masks greater than channelLimit | 
| Andy Hung | a461a00 | 2022-05-17 10:36:02 -0700 | [diff] [blame] | 71 |         if (count > maxCount) { | 
 | 72 |             maxMask = mask; | 
 | 73 |             maxCount = count; | 
 | 74 |         } | 
 | 75 |     } | 
 | 76 |     return maxMask; | 
 | 77 | } | 
 | 78 |  | 
| Andy Hung | 2a390db | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 79 | static std::vector<float> recordFromTranslationRotationVector( | 
 | 80 |         const std::vector<float>& trVector) { | 
 | 81 |     auto headToStageOpt = Pose3f::fromVector(trVector); | 
 | 82 |     if (!headToStageOpt) return {}; | 
 | 83 |  | 
 | 84 |     const auto stageToHead = headToStageOpt.value().inverse(); | 
 | 85 |     const auto stageToHeadTranslation = stageToHead.translation(); | 
| Andy Hung | 82a4eab | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 86 |     constexpr float RAD_TO_DEGREE = 180.f / M_PI; | 
 | 87 |     std::vector<float> record{ | 
| Andy Hung | 2a390db | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 88 |         stageToHeadTranslation[0], stageToHeadTranslation[1], stageToHeadTranslation[2], | 
 | 89 |         0.f, 0.f, 0.f}; | 
 | 90 |     media::quaternionToAngles(stageToHead.rotation(), &record[3], &record[4], &record[5]); | 
 | 91 |     record[3] *= RAD_TO_DEGREE; | 
 | 92 |     record[4] *= RAD_TO_DEGREE; | 
 | 93 |     record[5] *= RAD_TO_DEGREE; | 
| Andy Hung | 82a4eab | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 94 |     return record; | 
 | 95 | } | 
 | 96 |  | 
| Andy Hung | cd6c106 | 2023-03-09 20:45:36 -0800 | [diff] [blame] | 97 | template<typename T> | 
 | 98 | static constexpr const T& safe_clamp(const T& value, const T& low, const T& high) { | 
 | 99 |     if constexpr (std::is_floating_point_v<T>) { | 
 | 100 |         return value != value /* constexpr isnan */ | 
 | 101 |                 ? low : std::clamp(value, low, high); | 
 | 102 |     } else /* constexpr */ { | 
 | 103 |         return std::clamp(value, low, high); | 
 | 104 |     } | 
 | 105 | } | 
 | 106 |  | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 107 | // --------------------------------------------------------------------------- | 
 | 108 |  | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 109 | class Spatializer::EngineCallbackHandler : public AHandler { | 
 | 110 | public: | 
 | 111 |     EngineCallbackHandler(wp<Spatializer> spatializer) | 
 | 112 |             : mSpatializer(spatializer) { | 
 | 113 |     } | 
 | 114 |  | 
 | 115 |     enum { | 
 | 116 |         // Device state callbacks | 
 | 117 |         kWhatOnFramesProcessed,    // AudioEffect::EVENT_FRAMES_PROCESSED | 
 | 118 |         kWhatOnHeadToStagePose,    // SpatializerPoseController::Listener::onHeadToStagePose | 
 | 119 |         kWhatOnActualModeChange,   // SpatializerPoseController::Listener::onActualModeChange | 
| Eric Laurent | df2ece4 | 2022-07-20 13:49:47 +0200 | [diff] [blame] | 120 |         kWhatOnLatencyModesChanged, // Spatializer::onSupportedLatencyModesChanged | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 121 |     }; | 
 | 122 |     static constexpr const char *kNumFramesKey = "numFrames"; | 
 | 123 |     static constexpr const char *kModeKey = "mode"; | 
 | 124 |     static constexpr const char *kTranslation0Key = "translation0"; | 
 | 125 |     static constexpr const char *kTranslation1Key = "translation1"; | 
 | 126 |     static constexpr const char *kTranslation2Key = "translation2"; | 
 | 127 |     static constexpr const char *kRotation0Key = "rotation0"; | 
 | 128 |     static constexpr const char *kRotation1Key = "rotation1"; | 
 | 129 |     static constexpr const char *kRotation2Key = "rotation2"; | 
| Eric Laurent | df2ece4 | 2022-07-20 13:49:47 +0200 | [diff] [blame] | 130 |     static constexpr const char *kLatencyModesKey = "latencyModes"; | 
 | 131 |  | 
 | 132 |     class LatencyModes : public RefBase { | 
 | 133 |     public: | 
 | 134 |         LatencyModes(audio_io_handle_t output, | 
 | 135 |                 const std::vector<audio_latency_mode_t>& latencyModes) | 
 | 136 |             : mOutput(output), mLatencyModes(latencyModes) {} | 
 | 137 |         ~LatencyModes() = default; | 
 | 138 |  | 
 | 139 |         audio_io_handle_t mOutput; | 
 | 140 |         std::vector<audio_latency_mode_t> mLatencyModes; | 
 | 141 |     }; | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 142 |  | 
 | 143 |     void onMessageReceived(const sp<AMessage> &msg) override { | 
| Andy Hung | b725c69 | 2022-12-14 14:25:49 -0800 | [diff] [blame] | 144 |         // No ALooper method to get the tid so update | 
 | 145 |         // Spatializer priority on the first message received. | 
 | 146 |         std::call_once(mPrioritySetFlag, [](){ | 
 | 147 |             const pid_t pid = getpid(); | 
 | 148 |             const pid_t tid = gettid(); | 
 | 149 |             (void)requestSpatializerPriority(pid, tid); | 
 | 150 |         }); | 
 | 151 |  | 
| Eric Laurent | df2ece4 | 2022-07-20 13:49:47 +0200 | [diff] [blame] | 152 |         sp<Spatializer> spatializer = mSpatializer.promote(); | 
 | 153 |         if (spatializer == nullptr) { | 
 | 154 |             ALOGW("%s: Cannot promote spatializer", __func__); | 
 | 155 |             return; | 
 | 156 |         } | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 157 |         switch (msg->what()) { | 
 | 158 |             case kWhatOnFramesProcessed: { | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 159 |                 int numFrames; | 
 | 160 |                 if (!msg->findInt32(kNumFramesKey, &numFrames)) { | 
 | 161 |                     ALOGE("%s: Cannot find num frames!", __func__); | 
 | 162 |                     return; | 
 | 163 |                 } | 
 | 164 |                 if (numFrames > 0) { | 
 | 165 |                     spatializer->calculateHeadPose(); | 
 | 166 |                 } | 
 | 167 |                 } break; | 
 | 168 |             case kWhatOnHeadToStagePose: { | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 169 |                 std::vector<float> headToStage(sHeadPoseKeys.size()); | 
 | 170 |                 for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) { | 
 | 171 |                     if (!msg->findFloat(sHeadPoseKeys[i], &headToStage[i])) { | 
 | 172 |                         ALOGE("%s: Cannot find kTranslation0Key!", __func__); | 
 | 173 |                         return; | 
 | 174 |                     } | 
 | 175 |                 } | 
 | 176 |                 spatializer->onHeadToStagePoseMsg(headToStage); | 
 | 177 |                 } break; | 
 | 178 |             case kWhatOnActualModeChange: { | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 179 |                 int mode; | 
| Eric Laurent | df2ece4 | 2022-07-20 13:49:47 +0200 | [diff] [blame] | 180 |                 if (!msg->findInt32(kModeKey, &mode)) { | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 181 |                     ALOGE("%s: Cannot find actualMode!", __func__); | 
 | 182 |                     return; | 
 | 183 |                 } | 
 | 184 |                 spatializer->onActualModeChangeMsg(static_cast<HeadTrackingMode>(mode)); | 
 | 185 |                 } break; | 
| Eric Laurent | df2ece4 | 2022-07-20 13:49:47 +0200 | [diff] [blame] | 186 |  | 
 | 187 |             case kWhatOnLatencyModesChanged: { | 
 | 188 |                 sp<RefBase> object; | 
 | 189 |                 if (!msg->findObject(kLatencyModesKey, &object)) { | 
 | 190 |                     ALOGE("%s: Cannot find latency modes!", __func__); | 
 | 191 |                     return; | 
 | 192 |                 } | 
 | 193 |                 sp<LatencyModes> latencyModes = static_cast<LatencyModes*>(object.get()); | 
 | 194 |                 spatializer->onSupportedLatencyModesChangedMsg( | 
 | 195 |                     latencyModes->mOutput, std::move(latencyModes->mLatencyModes)); | 
 | 196 |                 } break; | 
 | 197 |  | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 198 |             default: | 
 | 199 |                 LOG_ALWAYS_FATAL("Invalid callback message %d", msg->what()); | 
 | 200 |         } | 
 | 201 |     } | 
 | 202 | private: | 
 | 203 |     wp<Spatializer> mSpatializer; | 
| Andy Hung | b725c69 | 2022-12-14 14:25:49 -0800 | [diff] [blame] | 204 |     std::once_flag mPrioritySetFlag; | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 205 | }; | 
 | 206 |  | 
 | 207 | const std::vector<const char *> Spatializer::sHeadPoseKeys = { | 
 | 208 |     Spatializer::EngineCallbackHandler::kTranslation0Key, | 
 | 209 |     Spatializer::EngineCallbackHandler::kTranslation1Key, | 
 | 210 |     Spatializer::EngineCallbackHandler::kTranslation2Key, | 
 | 211 |     Spatializer::EngineCallbackHandler::kRotation0Key, | 
 | 212 |     Spatializer::EngineCallbackHandler::kRotation1Key, | 
 | 213 |     Spatializer::EngineCallbackHandler::kRotation2Key, | 
 | 214 | }; | 
 | 215 |  | 
 | 216 | // --------------------------------------------------------------------------- | 
| Shunkai Yao | 8f6ad0f | 2023-04-18 23:14:25 +0000 | [diff] [blame] | 217 | sp<Spatializer> Spatializer::create(SpatializerPolicyCallback* callback, | 
 | 218 |                                     const sp<EffectsFactoryHalInterface>& effectsFactoryHal) { | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 219 |     sp<Spatializer> spatializer; | 
 | 220 |  | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 221 |     if (effectsFactoryHal == nullptr) { | 
 | 222 |         ALOGW("%s failed to create effect factory interface", __func__); | 
 | 223 |         return spatializer; | 
 | 224 |     } | 
 | 225 |  | 
 | 226 |     std::vector<effect_descriptor_t> descriptors; | 
| Shunkai Yao | 8f6ad0f | 2023-04-18 23:14:25 +0000 | [diff] [blame] | 227 |     status_t status = effectsFactoryHal->getDescriptors(FX_IID_SPATIALIZER, &descriptors); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 228 |     if (status != NO_ERROR) { | 
 | 229 |         ALOGW("%s failed to get spatializer descriptor, error %d", __func__, status); | 
 | 230 |         return spatializer; | 
 | 231 |     } | 
 | 232 |     ALOG_ASSERT(!descriptors.empty(), | 
 | 233 |             "%s getDescriptors() returned no error but empty list", __func__); | 
 | 234 |  | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 235 |     // TODO: get supported spatialization modes from FX engine or descriptor | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 236 |     sp<EffectHalInterface> effect; | 
 | 237 |     status = effectsFactoryHal->createEffect(&descriptors[0].uuid, AUDIO_SESSION_OUTPUT_STAGE, | 
 | 238 |             AUDIO_IO_HANDLE_NONE, AUDIO_PORT_HANDLE_NONE, &effect); | 
| Mikhail Naganov | 89c22e4 | 2023-06-14 15:49:59 -0700 | [diff] [blame] | 239 |     ALOGI("%s FX create status %d effect %p", __func__, status, effect.get()); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 240 |  | 
 | 241 |     if (status == NO_ERROR && effect != nullptr) { | 
 | 242 |         spatializer = new Spatializer(descriptors[0], callback); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 243 |         if (spatializer->loadEngineConfiguration(effect) != NO_ERROR) { | 
 | 244 |             spatializer.clear(); | 
| Mikhail Naganov | 89c22e4 | 2023-06-14 15:49:59 -0700 | [diff] [blame] | 245 |             ALOGW("%s loadEngine error: %d  effect %p", __func__, status, effect.get()); | 
| Andy Hung | 0e3205d | 2022-08-29 14:14:58 -0700 | [diff] [blame] | 246 |         } else { | 
| Mikhail Naganov | 89c22e4 | 2023-06-14 15:49:59 -0700 | [diff] [blame] | 247 |             spatializer->mLocalLog.log("%s with effect Id %p", __func__, effect.get()); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 248 |         } | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 249 |     } | 
 | 250 |  | 
 | 251 |     return spatializer; | 
 | 252 | } | 
 | 253 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 254 | Spatializer::Spatializer(effect_descriptor_t engineDescriptor, SpatializerPolicyCallback* callback) | 
 | 255 |     : mEngineDescriptor(engineDescriptor), | 
 | 256 |       mPolicyCallback(callback) { | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 257 |     ALOGV("%s", __func__); | 
| Andy Hung | 393de3a | 2022-12-06 16:33:20 -0800 | [diff] [blame] | 258 |     setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 259 | } | 
 | 260 |  | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 261 | void Spatializer::onFirstRef() { | 
 | 262 |     mLooper = new ALooper; | 
 | 263 |     mLooper->setName("Spatializer-looper"); | 
 | 264 |     mLooper->start( | 
 | 265 |             /*runOnCallingThread*/false, | 
 | 266 |             /*canCallJava*/       false, | 
| Andy Hung | 898a39f | 2022-11-07 20:09:20 -0800 | [diff] [blame] | 267 |             PRIORITY_URGENT_AUDIO); | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 268 |  | 
 | 269 |     mHandler = new EngineCallbackHandler(this); | 
 | 270 |     mLooper->registerHandler(mHandler); | 
 | 271 | } | 
 | 272 |  | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 273 | Spatializer::~Spatializer() { | 
 | 274 |     ALOGV("%s", __func__); | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 275 |     if (mLooper != nullptr) { | 
 | 276 |         mLooper->stop(); | 
 | 277 |         mLooper->unregisterHandler(mHandler->id()); | 
 | 278 |     } | 
 | 279 |     mLooper.clear(); | 
 | 280 |     mHandler.clear(); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 281 | } | 
 | 282 |  | 
| Andy Hung | 4442d04 | 2022-08-17 17:27:32 -0700 | [diff] [blame] | 283 | static std::string channelMaskVectorToString( | 
 | 284 |         const std::vector<audio_channel_mask_t>& masks) { | 
 | 285 |     std::stringstream ss; | 
 | 286 |     for (const auto &mask : masks) { | 
 | 287 |         if (ss.tellp() != 0) ss << "|"; | 
 | 288 |         ss << mask; | 
 | 289 |     } | 
 | 290 |     return ss.str(); | 
 | 291 | } | 
 | 292 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 293 | status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) { | 
 | 294 |     ALOGV("%s", __func__); | 
 | 295 |  | 
 | 296 |     std::vector<bool> supportsHeadTracking; | 
 | 297 |     status_t status = getHalParameter<false>(effect, SPATIALIZER_PARAM_HEADTRACKING_SUPPORTED, | 
 | 298 |                                          &supportsHeadTracking); | 
 | 299 |     if (status != NO_ERROR) { | 
| Andy Hung | 119dbdb | 2022-05-11 19:20:13 -0700 | [diff] [blame] | 300 |         ALOGW("%s: cannot get SPATIALIZER_PARAM_HEADTRACKING_SUPPORTED", __func__); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 301 |         return status; | 
 | 302 |     } | 
 | 303 |     mSupportsHeadTracking = supportsHeadTracking[0]; | 
 | 304 |  | 
| Andy Hung | 119dbdb | 2022-05-11 19:20:13 -0700 | [diff] [blame] | 305 |     std::vector<media::SpatializationLevel> spatializationLevels; | 
 | 306 |     status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_LEVELS, | 
 | 307 |             &spatializationLevels); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 308 |     if (status != NO_ERROR) { | 
| Andy Hung | 119dbdb | 2022-05-11 19:20:13 -0700 | [diff] [blame] | 309 |         ALOGW("%s: cannot get SPATIALIZER_PARAM_SUPPORTED_LEVELS", __func__); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 310 |         return status; | 
 | 311 |     } | 
| Andy Hung | 119dbdb | 2022-05-11 19:20:13 -0700 | [diff] [blame] | 312 |     bool noneLevelFound = false; | 
 | 313 |     bool activeLevelFound = false; | 
 | 314 |     for (const auto spatializationLevel : spatializationLevels) { | 
 | 315 |         if (!aidl_utils::isValidEnum(spatializationLevel)) { | 
 | 316 |             ALOGW("%s: ignoring spatializationLevel:%d", __func__, (int)spatializationLevel); | 
 | 317 |             continue; | 
 | 318 |         } | 
 | 319 |         if (spatializationLevel == media::SpatializationLevel::NONE) { | 
 | 320 |             noneLevelFound = true; | 
 | 321 |         } else { | 
 | 322 |             activeLevelFound = true; | 
 | 323 |         } | 
 | 324 |         // we don't detect duplicates. | 
 | 325 |         mLevels.emplace_back(spatializationLevel); | 
 | 326 |     } | 
 | 327 |     if (!noneLevelFound || !activeLevelFound) { | 
 | 328 |         ALOGW("%s: SPATIALIZER_PARAM_SUPPORTED_LEVELS must include NONE" | 
 | 329 |                 " and another valid level",  __func__); | 
 | 330 |         return BAD_VALUE; | 
 | 331 |     } | 
 | 332 |  | 
 | 333 |     std::vector<media::SpatializationMode> spatializationModes; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 334 |     status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES, | 
| Andy Hung | 119dbdb | 2022-05-11 19:20:13 -0700 | [diff] [blame] | 335 |             &spatializationModes); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 336 |     if (status != NO_ERROR) { | 
| Andy Hung | 119dbdb | 2022-05-11 19:20:13 -0700 | [diff] [blame] | 337 |         ALOGW("%s: cannot get SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES", __func__); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 338 |         return status; | 
 | 339 |     } | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 340 |  | 
| Andy Hung | 119dbdb | 2022-05-11 19:20:13 -0700 | [diff] [blame] | 341 |     for (const auto spatializationMode : spatializationModes) { | 
 | 342 |         if (!aidl_utils::isValidEnum(spatializationMode)) { | 
 | 343 |             ALOGW("%s: ignoring spatializationMode:%d", __func__, (int)spatializationMode); | 
 | 344 |             continue; | 
 | 345 |         } | 
 | 346 |         // we don't detect duplicates. | 
 | 347 |         mSpatializationModes.emplace_back(spatializationMode); | 
 | 348 |     } | 
 | 349 |     if (mSpatializationModes.empty()) { | 
 | 350 |         ALOGW("%s: SPATIALIZER_PARAM_SUPPORTED_SPATIALIZATION_MODES reports empty", __func__); | 
 | 351 |         return BAD_VALUE; | 
 | 352 |     } | 
 | 353 |  | 
 | 354 |     std::vector<audio_channel_mask_t> channelMasks; | 
 | 355 |     status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS, | 
 | 356 |                                  &channelMasks); | 
 | 357 |     if (status != NO_ERROR) { | 
 | 358 |         ALOGW("%s: cannot get SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS", __func__); | 
 | 359 |         return status; | 
 | 360 |     } | 
 | 361 |     for (const auto channelMask : channelMasks) { | 
 | 362 |         if (!audio_is_channel_mask_spatialized(channelMask)) { | 
 | 363 |             ALOGW("%s: ignoring channelMask:%#x", __func__, channelMask); | 
 | 364 |             continue; | 
 | 365 |         } | 
 | 366 |         // we don't detect duplicates. | 
 | 367 |         mChannelMasks.emplace_back(channelMask); | 
 | 368 |     } | 
 | 369 |     if (mChannelMasks.empty()) { | 
 | 370 |         ALOGW("%s: SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS reports empty", __func__); | 
 | 371 |         return BAD_VALUE; | 
 | 372 |     } | 
| Andy Hung | a461a00 | 2022-05-17 10:36:02 -0700 | [diff] [blame] | 373 |  | 
 | 374 |     // Currently we expose only RELATIVE_WORLD. | 
 | 375 |     // This is a limitation of the head tracking library based on a UX choice. | 
 | 376 |     mHeadTrackingModes.push_back(SpatializerHeadTrackingMode::DISABLED); | 
 | 377 |     if (mSupportsHeadTracking) { | 
 | 378 |         mHeadTrackingModes.push_back(SpatializerHeadTrackingMode::RELATIVE_WORLD); | 
 | 379 |     } | 
 | 380 |     mediametrics::LogItem(mMetricsId) | 
 | 381 |         .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE) | 
| Andy Hung | 4442d04 | 2022-08-17 17:27:32 -0700 | [diff] [blame] | 382 |         .set(AMEDIAMETRICS_PROP_CHANNELMASKS, channelMaskVectorToString(mChannelMasks)) | 
| Andy Hung | a461a00 | 2022-05-17 10:36:02 -0700 | [diff] [blame] | 383 |         .set(AMEDIAMETRICS_PROP_LEVELS, aidl_utils::enumsToString(mLevels)) | 
 | 384 |         .set(AMEDIAMETRICS_PROP_MODES, aidl_utils::enumsToString(mSpatializationModes)) | 
 | 385 |         .set(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, aidl_utils::enumsToString(mHeadTrackingModes)) | 
 | 386 |         .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status) | 
 | 387 |         .record(); | 
| Andy Hung | 119dbdb | 2022-05-11 19:20:13 -0700 | [diff] [blame] | 388 |     return NO_ERROR; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 389 | } | 
 | 390 |  | 
| Andy Hung | 757bc81 | 2022-09-13 18:53:06 -0700 | [diff] [blame] | 391 | /* static */ | 
 | 392 | void Spatializer::sendEmptyCreateSpatializerMetricWithStatus(status_t status) { | 
 | 393 |     mediametrics::LogItem(kDefaultMetricsId) | 
 | 394 |         .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE) | 
 | 395 |         .set(AMEDIAMETRICS_PROP_CHANNELMASKS, "") | 
 | 396 |         .set(AMEDIAMETRICS_PROP_LEVELS, "") | 
 | 397 |         .set(AMEDIAMETRICS_PROP_MODES, "") | 
 | 398 |         .set(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, "") | 
 | 399 |         .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status) | 
 | 400 |         .record(); | 
 | 401 | } | 
 | 402 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 403 | /** Gets the channel mask, sampling rate and format set for the spatializer input. */ | 
 | 404 | audio_config_base_t Spatializer::getAudioInConfig() const { | 
 | 405 |     std::lock_guard lock(mLock); | 
 | 406 |     audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER; | 
 | 407 |     // For now use highest supported channel count | 
| Andy Hung | 0e3205d | 2022-08-29 14:14:58 -0700 | [diff] [blame] | 408 |     config.channel_mask = getMaxChannelMask(mChannelMasks, FCC_LIMIT); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 409 |     return config; | 
 | 410 | } | 
 | 411 |  | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 412 | status_t Spatializer::registerCallback( | 
 | 413 |         const sp<media::INativeSpatializerCallback>& callback) { | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 414 |     std::lock_guard lock(mLock); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 415 |     if (callback == nullptr) { | 
 | 416 |         return BAD_VALUE; | 
 | 417 |     } | 
 | 418 |  | 
| Eric Laurent | b57604f | 2022-08-31 16:07:50 +0200 | [diff] [blame] | 419 |     if (mSpatializerCallback != nullptr) { | 
 | 420 |         if (IInterface::asBinder(callback) == IInterface::asBinder(mSpatializerCallback)) { | 
 | 421 |             ALOGW("%s: Registering callback %p again", | 
 | 422 |                 __func__, mSpatializerCallback.get()); | 
 | 423 |             return NO_ERROR; | 
 | 424 |         } | 
 | 425 |         ALOGE("%s: Already one client registered with callback %p", | 
 | 426 |             __func__, mSpatializerCallback.get()); | 
 | 427 |         return INVALID_OPERATION; | 
 | 428 |     } | 
 | 429 |  | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 430 |     sp<IBinder> binder = IInterface::asBinder(callback); | 
 | 431 |     status_t status = binder->linkToDeath(this); | 
 | 432 |     if (status == NO_ERROR) { | 
 | 433 |         mSpatializerCallback = callback; | 
 | 434 |     } | 
 | 435 |     ALOGV("%s status %d", __func__, status); | 
 | 436 |     return status; | 
 | 437 | } | 
 | 438 |  | 
 | 439 | // IBinder::DeathRecipient | 
 | 440 | void Spatializer::binderDied(__unused const wp<IBinder> &who) { | 
 | 441 |     { | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 442 |         std::lock_guard lock(mLock); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 443 |         mLevel = SpatializationLevel::NONE; | 
 | 444 |         mSpatializerCallback.clear(); | 
 | 445 |     } | 
 | 446 |     ALOGV("%s", __func__); | 
 | 447 |     mPolicyCallback->onCheckSpatializer(); | 
 | 448 | } | 
 | 449 |  | 
 | 450 | // ISpatializer | 
 | 451 | Status Spatializer::getSupportedLevels(std::vector<SpatializationLevel> *levels) { | 
 | 452 |     ALOGV("%s", __func__); | 
 | 453 |     if (levels == nullptr) { | 
 | 454 |         return binderStatusFromStatusT(BAD_VALUE); | 
 | 455 |     } | 
| Andy Hung | a461a00 | 2022-05-17 10:36:02 -0700 | [diff] [blame] | 456 |     // SpatializationLevel::NONE is already required from the effect or we don't load it. | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 457 |     levels->insert(levels->end(), mLevels.begin(), mLevels.end()); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 458 |     return Status::ok(); | 
 | 459 | } | 
 | 460 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 461 | Status Spatializer::setLevel(SpatializationLevel level) { | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 462 |     ALOGV("%s level %s", __func__, media::toString(level).c_str()); | 
 | 463 |     mLocalLog.log("%s with %s", __func__, media::toString(level).c_str()); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 464 |     if (level != SpatializationLevel::NONE | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 465 |             && std::find(mLevels.begin(), mLevels.end(), level) == mLevels.end()) { | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 466 |         return binderStatusFromStatusT(BAD_VALUE); | 
 | 467 |     } | 
 | 468 |     sp<media::INativeSpatializerCallback> callback; | 
 | 469 |     bool levelChanged = false; | 
 | 470 |     { | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 471 |         std::lock_guard lock(mLock); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 472 |         levelChanged = mLevel != level; | 
 | 473 |         mLevel = level; | 
 | 474 |         callback = mSpatializerCallback; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 475 |  | 
 | 476 |         if (levelChanged && mEngine != nullptr) { | 
| Eric Laurent | 7ea0d1b | 2022-04-01 14:23:44 +0200 | [diff] [blame] | 477 |             checkEngineState_l(); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 478 |         } | 
| Eric Laurent | 9249d34 | 2022-03-18 11:55:56 +0100 | [diff] [blame] | 479 |         checkSensorsState_l(); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 480 |     } | 
 | 481 |  | 
 | 482 |     if (levelChanged) { | 
 | 483 |         mPolicyCallback->onCheckSpatializer(); | 
 | 484 |         if (callback != nullptr) { | 
 | 485 |             callback->onLevelChanged(level); | 
 | 486 |         } | 
 | 487 |     } | 
 | 488 |     return Status::ok(); | 
 | 489 | } | 
 | 490 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 491 | Status Spatializer::getLevel(SpatializationLevel *level) { | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 492 |     if (level == nullptr) { | 
 | 493 |         return binderStatusFromStatusT(BAD_VALUE); | 
 | 494 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 495 |     std::lock_guard lock(mLock); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 496 |     *level = mLevel; | 
 | 497 |     ALOGV("%s level %d", __func__, (int)*level); | 
 | 498 |     return Status::ok(); | 
 | 499 | } | 
 | 500 |  | 
| Eric Laurent | c87402b | 2021-09-17 16:49:42 +0200 | [diff] [blame] | 501 | Status Spatializer::isHeadTrackingSupported(bool *supports) { | 
 | 502 |     ALOGV("%s mSupportsHeadTracking %d", __func__, mSupportsHeadTracking); | 
 | 503 |     if (supports == nullptr) { | 
 | 504 |         return binderStatusFromStatusT(BAD_VALUE); | 
 | 505 |     } | 
 | 506 |     std::lock_guard lock(mLock); | 
 | 507 |     *supports = mSupportsHeadTracking; | 
 | 508 |     return Status::ok(); | 
 | 509 | } | 
 | 510 |  | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 511 | Status Spatializer::getSupportedHeadTrackingModes( | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 512 |         std::vector<SpatializerHeadTrackingMode>* modes) { | 
 | 513 |     std::lock_guard lock(mLock); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 514 |     ALOGV("%s", __func__); | 
 | 515 |     if (modes == nullptr) { | 
 | 516 |         return binderStatusFromStatusT(BAD_VALUE); | 
 | 517 |     } | 
| Andy Hung | a461a00 | 2022-05-17 10:36:02 -0700 | [diff] [blame] | 518 |     modes->insert(modes->end(), mHeadTrackingModes.begin(), mHeadTrackingModes.end()); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 519 |     return Status::ok(); | 
 | 520 | } | 
 | 521 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 522 | Status Spatializer::setDesiredHeadTrackingMode(SpatializerHeadTrackingMode mode) { | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 523 |     ALOGV("%s mode %s", __func__, media::toString(mode).c_str()); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 524 |  | 
 | 525 |     if (!mSupportsHeadTracking) { | 
 | 526 |         return binderStatusFromStatusT(INVALID_OPERATION); | 
 | 527 |     } | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 528 |     mLocalLog.log("%s with %s", __func__, media::toString(mode).c_str()); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 529 |     std::lock_guard lock(mLock); | 
 | 530 |     switch (mode) { | 
 | 531 |         case SpatializerHeadTrackingMode::OTHER: | 
 | 532 |             return binderStatusFromStatusT(BAD_VALUE); | 
 | 533 |         case SpatializerHeadTrackingMode::DISABLED: | 
 | 534 |             mDesiredHeadTrackingMode = HeadTrackingMode::STATIC; | 
 | 535 |             break; | 
 | 536 |         case SpatializerHeadTrackingMode::RELATIVE_WORLD: | 
 | 537 |             mDesiredHeadTrackingMode = HeadTrackingMode::WORLD_RELATIVE; | 
 | 538 |             break; | 
 | 539 |         case SpatializerHeadTrackingMode::RELATIVE_SCREEN: | 
 | 540 |             mDesiredHeadTrackingMode = HeadTrackingMode::SCREEN_RELATIVE; | 
 | 541 |             break; | 
 | 542 |     } | 
 | 543 |  | 
| Eric Laurent | 1109417 | 2022-04-05 18:27:42 +0200 | [diff] [blame] | 544 |     checkPoseController_l(); | 
 | 545 |     checkSensorsState_l(); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 546 |  | 
 | 547 |     return Status::ok(); | 
 | 548 | } | 
 | 549 |  | 
 | 550 | Status Spatializer::getActualHeadTrackingMode(SpatializerHeadTrackingMode *mode) { | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 551 |     if (mode == nullptr) { | 
 | 552 |         return binderStatusFromStatusT(BAD_VALUE); | 
 | 553 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 554 |     std::lock_guard lock(mLock); | 
 | 555 |     *mode = mActualHeadTrackingMode; | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 556 |     ALOGV("%s mode %d", __func__, (int)*mode); | 
 | 557 |     return Status::ok(); | 
 | 558 | } | 
 | 559 |  | 
| Ytai Ben-Tsvi | a16a9df | 2021-08-05 08:57:06 -0700 | [diff] [blame] | 560 | Status Spatializer::recenterHeadTracker() { | 
| Eric Laurent | 780be4a | 2021-09-16 10:44:24 +0200 | [diff] [blame] | 561 |     if (!mSupportsHeadTracking) { | 
 | 562 |         return binderStatusFromStatusT(INVALID_OPERATION); | 
 | 563 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 564 |     std::lock_guard lock(mLock); | 
 | 565 |     if (mPoseController != nullptr) { | 
 | 566 |         mPoseController->recenter(); | 
 | 567 |     } | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 568 |     return Status::ok(); | 
 | 569 | } | 
 | 570 |  | 
 | 571 | Status Spatializer::setGlobalTransform(const std::vector<float>& screenToStage) { | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 572 |     ALOGV("%s", __func__); | 
| Eric Laurent | 780be4a | 2021-09-16 10:44:24 +0200 | [diff] [blame] | 573 |     if (!mSupportsHeadTracking) { | 
 | 574 |         return binderStatusFromStatusT(INVALID_OPERATION); | 
 | 575 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 576 |     std::optional<Pose3f> maybePose = Pose3f::fromVector(screenToStage); | 
 | 577 |     if (!maybePose.has_value()) { | 
 | 578 |         ALOGW("Invalid screenToStage vector."); | 
 | 579 |         return binderStatusFromStatusT(BAD_VALUE); | 
 | 580 |     } | 
 | 581 |     std::lock_guard lock(mLock); | 
 | 582 |     if (mPoseController != nullptr) { | 
| Andy Hung | 82a4eab | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 583 |         mLocalLog.log("%s with screenToStage %s", __func__, | 
 | 584 |                 media::VectorRecorder::toString<float>(screenToStage).c_str()); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 585 |         mPoseController->setScreenToStagePose(maybePose.value()); | 
 | 586 |     } | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 587 |     return Status::ok(); | 
 | 588 | } | 
 | 589 |  | 
 | 590 | Status Spatializer::release() { | 
 | 591 |     ALOGV("%s", __func__); | 
 | 592 |     bool levelChanged = false; | 
 | 593 |     { | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 594 |         std::lock_guard lock(mLock); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 595 |         if (mSpatializerCallback == nullptr) { | 
 | 596 |             return binderStatusFromStatusT(INVALID_OPERATION); | 
 | 597 |         } | 
 | 598 |  | 
 | 599 |         sp<IBinder> binder = IInterface::asBinder(mSpatializerCallback); | 
 | 600 |         binder->unlinkToDeath(this); | 
 | 601 |         mSpatializerCallback.clear(); | 
 | 602 |  | 
 | 603 |         levelChanged = mLevel != SpatializationLevel::NONE; | 
 | 604 |         mLevel = SpatializationLevel::NONE; | 
 | 605 |     } | 
 | 606 |  | 
 | 607 |     if (levelChanged) { | 
 | 608 |         mPolicyCallback->onCheckSpatializer(); | 
 | 609 |     } | 
 | 610 |     return Status::ok(); | 
 | 611 | } | 
 | 612 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 613 | Status Spatializer::setHeadSensor(int sensorHandle) { | 
 | 614 |     ALOGV("%s sensorHandle %d", __func__, sensorHandle); | 
| Eric Laurent | 780be4a | 2021-09-16 10:44:24 +0200 | [diff] [blame] | 615 |     if (!mSupportsHeadTracking) { | 
 | 616 |         return binderStatusFromStatusT(INVALID_OPERATION); | 
 | 617 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 618 |     std::lock_guard lock(mLock); | 
| Andy Hung | ba2a61a | 2022-05-20 12:00:28 -0700 | [diff] [blame] | 619 |     if (mHeadSensor != sensorHandle) { | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 620 |         mLocalLog.log("%s with 0x%08x", __func__, sensorHandle); | 
| Andy Hung | ba2a61a | 2022-05-20 12:00:28 -0700 | [diff] [blame] | 621 |         mHeadSensor = sensorHandle; | 
 | 622 |         checkPoseController_l(); | 
 | 623 |         checkSensorsState_l(); | 
 | 624 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 625 |     return Status::ok(); | 
 | 626 | } | 
 | 627 |  | 
 | 628 | Status Spatializer::setScreenSensor(int sensorHandle) { | 
 | 629 |     ALOGV("%s sensorHandle %d", __func__, sensorHandle); | 
| Eric Laurent | 780be4a | 2021-09-16 10:44:24 +0200 | [diff] [blame] | 630 |     if (!mSupportsHeadTracking) { | 
 | 631 |         return binderStatusFromStatusT(INVALID_OPERATION); | 
 | 632 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 633 |     std::lock_guard lock(mLock); | 
| Andy Hung | ba2a61a | 2022-05-20 12:00:28 -0700 | [diff] [blame] | 634 |     if (mScreenSensor != sensorHandle) { | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 635 |         mLocalLog.log("%s with 0x%08x", __func__, sensorHandle); | 
| Andy Hung | ba2a61a | 2022-05-20 12:00:28 -0700 | [diff] [blame] | 636 |         mScreenSensor = sensorHandle; | 
 | 637 |         // TODO: consider a new method setHeadAndScreenSensor() | 
 | 638 |         // because we generally set both at the same time. | 
 | 639 |         // This will avoid duplicated work and recentering. | 
 | 640 |         checkSensorsState_l(); | 
 | 641 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 642 |     return Status::ok(); | 
 | 643 | } | 
 | 644 |  | 
 | 645 | Status Spatializer::setDisplayOrientation(float physicalToLogicalAngle) { | 
 | 646 |     ALOGV("%s physicalToLogicalAngle %f", __func__, physicalToLogicalAngle); | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 647 |     mLocalLog.log("%s with %f", __func__, physicalToLogicalAngle); | 
| Andy Hung | cd6c106 | 2023-03-09 20:45:36 -0800 | [diff] [blame] | 648 |     const float angle = safe_clamp(physicalToLogicalAngle, 0.f, (float)(2. * M_PI)); | 
 | 649 |     // It is possible due to numerical inaccuracies to exceed the boundaries of 0 to 2 * M_PI. | 
 | 650 |     ALOGI_IF(angle != physicalToLogicalAngle, | 
 | 651 |             "%s: clamping %f to %f", __func__, physicalToLogicalAngle, angle); | 
 | 652 |     std::lock_guard lock(mLock); | 
 | 653 |     mDisplayOrientation = angle; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 654 |     if (mPoseController != nullptr) { | 
| Andy Hung | cd6c106 | 2023-03-09 20:45:36 -0800 | [diff] [blame] | 655 |         // This turns on the rate-limiter. | 
 | 656 |         mPoseController->setDisplayOrientation(angle); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 657 |     } | 
| Eric Laurent | 16ddaf4 | 2021-09-17 15:00:35 +0200 | [diff] [blame] | 658 |     if (mEngine != nullptr) { | 
 | 659 |         setEffectParameter_l( | 
| Andy Hung | cd6c106 | 2023-03-09 20:45:36 -0800 | [diff] [blame] | 660 |             SPATIALIZER_PARAM_DISPLAY_ORIENTATION, std::vector<float>{angle}); | 
| Eric Laurent | 16ddaf4 | 2021-09-17 15:00:35 +0200 | [diff] [blame] | 661 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 662 |     return Status::ok(); | 
 | 663 | } | 
 | 664 |  | 
 | 665 | Status Spatializer::setHingeAngle(float hingeAngle) { | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 666 |     ALOGV("%s hingeAngle %f", __func__, hingeAngle); | 
| Andy Hung | cd6c106 | 2023-03-09 20:45:36 -0800 | [diff] [blame] | 667 |     mLocalLog.log("%s with %f", __func__, hingeAngle); | 
 | 668 |     const float angle = safe_clamp(hingeAngle, 0.f, (float)(2. * M_PI)); | 
 | 669 |     // It is possible due to numerical inaccuracies to exceed the boundaries of 0 to 2 * M_PI. | 
 | 670 |     ALOGI_IF(angle != hingeAngle, | 
 | 671 |             "%s: clamping %f to %f", __func__, hingeAngle, angle); | 
 | 672 |     std::lock_guard lock(mLock); | 
 | 673 |     mHingeAngle = angle; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 674 |     if (mEngine != nullptr) { | 
| Andy Hung | cd6c106 | 2023-03-09 20:45:36 -0800 | [diff] [blame] | 675 |         setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE, std::vector<float>{angle}); | 
 | 676 |     } | 
 | 677 |     return Status::ok(); | 
 | 678 | } | 
 | 679 |  | 
 | 680 | Status Spatializer::setFoldState(bool folded) { | 
 | 681 |     ALOGV("%s foldState %d", __func__, (int)folded); | 
 | 682 |     mLocalLog.log("%s with %d", __func__, (int)folded); | 
 | 683 |     std::lock_guard lock(mLock); | 
 | 684 |     mFoldedState = folded; | 
 | 685 |     if (mEngine != nullptr) { | 
 | 686 |         // we don't suppress multiple calls with the same folded state - that's | 
 | 687 |         // done at the caller. | 
 | 688 |         setEffectParameter_l(SPATIALIZER_PARAM_FOLD_STATE, std::vector<uint8_t>{mFoldedState}); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 689 |     } | 
 | 690 |     return Status::ok(); | 
 | 691 | } | 
 | 692 |  | 
 | 693 | Status Spatializer::getSupportedModes(std::vector<SpatializationMode> *modes) { | 
 | 694 |     ALOGV("%s", __func__); | 
 | 695 |     if (modes == nullptr) { | 
 | 696 |         return binderStatusFromStatusT(BAD_VALUE); | 
 | 697 |     } | 
 | 698 |     *modes = mSpatializationModes; | 
 | 699 |     return Status::ok(); | 
 | 700 | } | 
 | 701 |  | 
| Eric Laurent | 67816e3 | 2021-09-16 15:18:40 +0200 | [diff] [blame] | 702 | Status Spatializer::registerHeadTrackingCallback( | 
 | 703 |         const sp<media::ISpatializerHeadTrackingCallback>& callback) { | 
 | 704 |     ALOGV("%s callback %p", __func__, callback.get()); | 
 | 705 |     std::lock_guard lock(mLock); | 
 | 706 |     if (!mSupportsHeadTracking) { | 
 | 707 |         return binderStatusFromStatusT(INVALID_OPERATION); | 
 | 708 |     } | 
 | 709 |     mHeadTrackingCallback = callback; | 
 | 710 |     return Status::ok(); | 
 | 711 | } | 
 | 712 |  | 
| Eric Laurent | c87402b | 2021-09-17 16:49:42 +0200 | [diff] [blame] | 713 | Status Spatializer::setParameter(int key, const std::vector<unsigned char>& value) { | 
 | 714 |     ALOGV("%s key %d", __func__, key); | 
 | 715 |     std::lock_guard lock(mLock); | 
 | 716 |     status_t status = INVALID_OPERATION; | 
 | 717 |     if (mEngine != nullptr) { | 
 | 718 |         status = setEffectParameter_l(key, value); | 
 | 719 |     } | 
 | 720 |     return binderStatusFromStatusT(status); | 
 | 721 | } | 
 | 722 |  | 
 | 723 | Status Spatializer::getParameter(int key, std::vector<unsigned char> *value) { | 
| Greg Kaiser | f7249f8 | 2021-09-21 07:10:12 -0700 | [diff] [blame] | 724 |     ALOGV("%s key %d value size %d", __func__, key, | 
 | 725 |           (value != nullptr ? (int)value->size() : -1)); | 
| Eric Laurent | c87402b | 2021-09-17 16:49:42 +0200 | [diff] [blame] | 726 |     if (value == nullptr) { | 
| George Burgess IV | 2238622 | 2021-09-22 12:09:31 -0700 | [diff] [blame] | 727 |         return binderStatusFromStatusT(BAD_VALUE); | 
| Eric Laurent | c87402b | 2021-09-17 16:49:42 +0200 | [diff] [blame] | 728 |     } | 
 | 729 |     std::lock_guard lock(mLock); | 
 | 730 |     status_t status = INVALID_OPERATION; | 
 | 731 |     if (mEngine != nullptr) { | 
 | 732 |         ALOGV("%s key %d mEngine %p", __func__, key, mEngine.get()); | 
 | 733 |         status = getEffectParameter_l(key, value); | 
 | 734 |     } | 
 | 735 |     return binderStatusFromStatusT(status); | 
 | 736 | } | 
 | 737 |  | 
 | 738 | Status Spatializer::getOutput(int *output) { | 
 | 739 |     ALOGV("%s", __func__); | 
 | 740 |     if (output == nullptr) { | 
 | 741 |         binderStatusFromStatusT(BAD_VALUE); | 
 | 742 |     } | 
 | 743 |     std::lock_guard lock(mLock); | 
 | 744 |     *output = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_io_handle_t_int32_t(mOutput)); | 
 | 745 |     ALOGV("%s got output %d", __func__, *output); | 
 | 746 |     return Status::ok(); | 
 | 747 | } | 
 | 748 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 749 | // SpatializerPoseController::Listener | 
 | 750 | void Spatializer::onHeadToStagePose(const Pose3f& headToStage) { | 
 | 751 |     ALOGV("%s", __func__); | 
| Eric Laurent | 780be4a | 2021-09-16 10:44:24 +0200 | [diff] [blame] | 752 |     LOG_ALWAYS_FATAL_IF(!mSupportsHeadTracking, | 
 | 753 |             "onHeadToStagePose() called with no head tracking support!"); | 
 | 754 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 755 |     auto vec = headToStage.toVector(); | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 756 |     LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(), | 
 | 757 |             "%s invalid head to stage vector size %zu", __func__, vec.size()); | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 758 |     sp<AMessage> msg = | 
 | 759 |             new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler); | 
 | 760 |     for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) { | 
 | 761 |         msg->setFloat(sHeadPoseKeys[i], vec[i]); | 
 | 762 |     } | 
 | 763 |     msg->post(); | 
 | 764 | } | 
 | 765 |  | 
| Eric Laurent | 3c48ad9 | 2022-10-21 11:28:32 +0200 | [diff] [blame] | 766 | void Spatializer::resetEngineHeadPose_l() { | 
 | 767 |     ALOGV("%s mEngine %p", __func__, mEngine.get()); | 
 | 768 |     if (mEngine == nullptr) { | 
 | 769 |         return; | 
 | 770 |     } | 
 | 771 |     const std::vector<float> headToStage(6, 0.0); | 
 | 772 |     setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage); | 
 | 773 |     setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE, | 
 | 774 |             std::vector<SpatializerHeadTrackingMode>{SpatializerHeadTrackingMode::DISABLED}); | 
 | 775 | } | 
 | 776 |  | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 777 | void Spatializer::onHeadToStagePoseMsg(const std::vector<float>& headToStage) { | 
 | 778 |     ALOGV("%s", __func__); | 
| Eric Laurent | 67816e3 | 2021-09-16 15:18:40 +0200 | [diff] [blame] | 779 |     sp<media::ISpatializerHeadTrackingCallback> callback; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 780 |     { | 
 | 781 |         std::lock_guard lock(mLock); | 
| Eric Laurent | 67816e3 | 2021-09-16 15:18:40 +0200 | [diff] [blame] | 782 |         callback = mHeadTrackingCallback; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 783 |         if (mEngine != nullptr) { | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 784 |             setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage); | 
| Andy Hung | 2a390db | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 785 |             const auto record = recordFromTranslationRotationVector(headToStage); | 
 | 786 |             mPoseRecorder.record(record); | 
 | 787 |             mPoseDurableRecorder.record(record); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 788 |         } | 
 | 789 |     } | 
 | 790 |  | 
 | 791 |     if (callback != nullptr) { | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 792 |         callback->onHeadToSoundStagePoseUpdated(headToStage); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 793 |     } | 
 | 794 | } | 
 | 795 |  | 
 | 796 | void Spatializer::onActualModeChange(HeadTrackingMode mode) { | 
| Shunkai Yao | 5137945 | 2022-08-30 03:14:50 +0000 | [diff] [blame] | 797 |     std::string modeStr = media::toString(mode); | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 798 |     ALOGV("%s(%s)", __func__, modeStr.c_str()); | 
| Shunkai Yao | 5137945 | 2022-08-30 03:14:50 +0000 | [diff] [blame] | 799 |     sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler); | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 800 |     msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode)); | 
 | 801 |     msg->post(); | 
 | 802 | } | 
 | 803 |  | 
 | 804 | void Spatializer::onActualModeChangeMsg(HeadTrackingMode mode) { | 
 | 805 |     ALOGV("%s(%d)", __func__, (int) mode); | 
| Eric Laurent | 67816e3 | 2021-09-16 15:18:40 +0200 | [diff] [blame] | 806 |     sp<media::ISpatializerHeadTrackingCallback> callback; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 807 |     SpatializerHeadTrackingMode spatializerMode; | 
 | 808 |     { | 
 | 809 |         std::lock_guard lock(mLock); | 
 | 810 |         if (!mSupportsHeadTracking) { | 
 | 811 |             spatializerMode = SpatializerHeadTrackingMode::DISABLED; | 
 | 812 |         } else { | 
 | 813 |             switch (mode) { | 
 | 814 |                 case HeadTrackingMode::STATIC: | 
 | 815 |                     spatializerMode = SpatializerHeadTrackingMode::DISABLED; | 
 | 816 |                     break; | 
 | 817 |                 case HeadTrackingMode::WORLD_RELATIVE: | 
 | 818 |                     spatializerMode = SpatializerHeadTrackingMode::RELATIVE_WORLD; | 
 | 819 |                     break; | 
 | 820 |                 case HeadTrackingMode::SCREEN_RELATIVE: | 
 | 821 |                     spatializerMode = SpatializerHeadTrackingMode::RELATIVE_SCREEN; | 
 | 822 |                     break; | 
 | 823 |                 default: | 
 | 824 |                     LOG_ALWAYS_FATAL("Unknown mode: %d", mode); | 
 | 825 |             } | 
 | 826 |         } | 
 | 827 |         mActualHeadTrackingMode = spatializerMode; | 
| Eric Laurent | e51f80e | 2022-04-14 10:20:38 +0200 | [diff] [blame] | 828 |         if (mEngine != nullptr) { | 
| Eric Laurent | 3c48ad9 | 2022-10-21 11:28:32 +0200 | [diff] [blame] | 829 |             if (spatializerMode == SpatializerHeadTrackingMode::DISABLED) { | 
 | 830 |                 resetEngineHeadPose_l(); | 
 | 831 |             } else { | 
 | 832 |                 setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE, | 
 | 833 |                                      std::vector<SpatializerHeadTrackingMode>{spatializerMode}); | 
 | 834 |             } | 
| Eric Laurent | 7ea0d1b | 2022-04-01 14:23:44 +0200 | [diff] [blame] | 835 |         } | 
| Eric Laurent | 67816e3 | 2021-09-16 15:18:40 +0200 | [diff] [blame] | 836 |         callback = mHeadTrackingCallback; | 
| Andy Hung | 79ccfda | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 837 |         mLocalLog.log("%s: updating mode to %s", __func__, media::toString(mode).c_str()); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 838 |     } | 
| Eric Laurent | e51f80e | 2022-04-14 10:20:38 +0200 | [diff] [blame] | 839 |     if (callback != nullptr) { | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 840 |         callback->onHeadTrackingModeChanged(spatializerMode); | 
 | 841 |     } | 
 | 842 | } | 
 | 843 |  | 
| Eric Laurent | 1590359 | 2022-02-24 20:44:36 +0100 | [diff] [blame] | 844 | status_t Spatializer::attachOutput(audio_io_handle_t output, size_t numActiveTracks) { | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 845 |     bool outputChanged = false; | 
 | 846 |     sp<media::INativeSpatializerCallback> callback; | 
 | 847 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 848 |     { | 
 | 849 |         std::lock_guard lock(mLock); | 
 | 850 |         ALOGV("%s output %d mOutput %d", __func__, (int)output, (int)mOutput); | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 851 |         mLocalLog.log("%s with output %d tracks %zu (mOutput %d)", __func__, (int)output, | 
 | 852 |                       numActiveTracks, (int)mOutput); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 853 |         if (mOutput != AUDIO_IO_HANDLE_NONE) { | 
 | 854 |             LOG_ALWAYS_FATAL_IF(mEngine == nullptr, "%s output set without FX engine", __func__); | 
 | 855 |             // remove FX instance | 
 | 856 |             mEngine->setEnabled(false); | 
 | 857 |             mEngine.clear(); | 
| Eric Laurent | 1590359 | 2022-02-24 20:44:36 +0100 | [diff] [blame] | 858 |             mPoseController.reset(); | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 859 |             AudioSystem::removeSupportedLatencyModesCallback(this); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 860 |         } | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 861 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 862 |         // create FX instance on output | 
 | 863 |         AttributionSourceState attributionSource = AttributionSourceState(); | 
 | 864 |         mEngine = new AudioEffect(attributionSource); | 
 | 865 |         mEngine->set(nullptr, &mEngineDescriptor.uuid, 0, Spatializer::engineCallback /* cbf */, | 
 | 866 |                      this /* user */, AUDIO_SESSION_OUTPUT_STAGE, output, {} /* device */, | 
 | 867 |                      false /* probe */, true /* notifyFramesProcessed */); | 
 | 868 |         status_t status = mEngine->initCheck(); | 
 | 869 |         ALOGV("%s mEngine create status %d", __func__, (int)status); | 
 | 870 |         if (status != NO_ERROR) { | 
 | 871 |             return status; | 
 | 872 |         } | 
 | 873 |  | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 874 |         outputChanged = mOutput != output; | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 875 |         mOutput = output; | 
| Eric Laurent | 1109417 | 2022-04-05 18:27:42 +0200 | [diff] [blame] | 876 |         mNumActiveTracks = numActiveTracks; | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 877 |         AudioSystem::addSupportedLatencyModesCallback(this); | 
 | 878 |  | 
 | 879 |         std::vector<audio_latency_mode_t> latencyModes; | 
 | 880 |         status = AudioSystem::getSupportedLatencyModes(mOutput, &latencyModes); | 
 | 881 |         if (status == OK) { | 
 | 882 |             mSupportedLatencyModes = latencyModes; | 
 | 883 |         } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 884 |  | 
| Eric Laurent | 1109417 | 2022-04-05 18:27:42 +0200 | [diff] [blame] | 885 |         checkEngineState_l(); | 
| Eric Laurent | 780be4a | 2021-09-16 10:44:24 +0200 | [diff] [blame] | 886 |         if (mSupportsHeadTracking) { | 
| Eric Laurent | 1109417 | 2022-04-05 18:27:42 +0200 | [diff] [blame] | 887 |             checkPoseController_l(); | 
| Eric Laurent | 9249d34 | 2022-03-18 11:55:56 +0100 | [diff] [blame] | 888 |             checkSensorsState_l(); | 
| Eric Laurent | 780be4a | 2021-09-16 10:44:24 +0200 | [diff] [blame] | 889 |         } | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 890 |         callback = mSpatializerCallback; | 
| Andy Hung | cd6c106 | 2023-03-09 20:45:36 -0800 | [diff] [blame] | 891 |  | 
 | 892 |         // Restore common effect state. | 
 | 893 |         setEffectParameter_l(SPATIALIZER_PARAM_DISPLAY_ORIENTATION, | 
 | 894 |                 std::vector<float>{mDisplayOrientation}); | 
 | 895 |         setEffectParameter_l(SPATIALIZER_PARAM_FOLD_STATE, | 
 | 896 |                 std::vector<uint8_t>{mFoldedState}); | 
 | 897 |         setEffectParameter_l(SPATIALIZER_PARAM_HINGE_ANGLE, | 
 | 898 |                 std::vector<float>{mHingeAngle}); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 899 |     } | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 900 |  | 
 | 901 |     if (outputChanged && callback != nullptr) { | 
 | 902 |         callback->onOutputChanged(output); | 
 | 903 |     } | 
 | 904 |  | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 905 |     return NO_ERROR; | 
 | 906 | } | 
 | 907 |  | 
 | 908 | audio_io_handle_t Spatializer::detachOutput() { | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 909 |     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 910 |     sp<media::INativeSpatializerCallback> callback; | 
 | 911 |  | 
 | 912 |     { | 
 | 913 |         std::lock_guard lock(mLock); | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 914 |         mLocalLog.log("%s with output %d tracks %zu", __func__, (int)mOutput, mNumActiveTracks); | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 915 |         ALOGV("%s mOutput %d", __func__, (int)mOutput); | 
 | 916 |         if (mOutput == AUDIO_IO_HANDLE_NONE) { | 
 | 917 |             return output; | 
 | 918 |         } | 
 | 919 |         // remove FX instance | 
 | 920 |         mEngine->setEnabled(false); | 
 | 921 |         mEngine.clear(); | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 922 |         AudioSystem::removeSupportedLatencyModesCallback(this); | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 923 |         output = mOutput; | 
 | 924 |         mOutput = AUDIO_IO_HANDLE_NONE; | 
 | 925 |         mPoseController.reset(); | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 926 |         callback = mSpatializerCallback; | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 927 |     } | 
| Eric Laurent | 4a87286 | 2021-10-11 17:06:47 +0200 | [diff] [blame] | 928 |  | 
 | 929 |     if (callback != nullptr) { | 
 | 930 |         callback->onOutputChanged(AUDIO_IO_HANDLE_NONE); | 
 | 931 |     } | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 932 |     return output; | 
 | 933 | } | 
 | 934 |  | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 935 | void Spatializer::onSupportedLatencyModesChanged( | 
 | 936 |         audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) { | 
| Eric Laurent | df2ece4 | 2022-07-20 13:49:47 +0200 | [diff] [blame] | 937 |     ALOGV("%s output %d num modes %zu", __func__, (int)output, modes.size()); | 
 | 938 |     sp<AMessage> msg = | 
 | 939 |             new AMessage(EngineCallbackHandler::kWhatOnLatencyModesChanged, mHandler); | 
 | 940 |     msg->setObject(EngineCallbackHandler::kLatencyModesKey, | 
 | 941 |         sp<EngineCallbackHandler::LatencyModes>::make(output, modes)); | 
 | 942 |     msg->post(); | 
 | 943 | } | 
 | 944 |  | 
 | 945 | void Spatializer::onSupportedLatencyModesChangedMsg( | 
 | 946 |         audio_io_handle_t output, std::vector<audio_latency_mode_t>&& modes) { | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 947 |     std::lock_guard lock(mLock); | 
| Eric Laurent | df2ece4 | 2022-07-20 13:49:47 +0200 | [diff] [blame] | 948 |     ALOGV("%s output %d mOutput %d num modes %zu", | 
 | 949 |             __func__, (int)output, (int)mOutput, modes.size()); | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 950 |     if (output == mOutput) { | 
| Eric Laurent | df2ece4 | 2022-07-20 13:49:47 +0200 | [diff] [blame] | 951 |         mSupportedLatencyModes = std::move(modes); | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 952 |         checkSensorsState_l(); | 
 | 953 |     } | 
 | 954 | } | 
 | 955 |  | 
| Eric Laurent | 1590359 | 2022-02-24 20:44:36 +0100 | [diff] [blame] | 956 | void Spatializer::updateActiveTracks(size_t numActiveTracks) { | 
 | 957 |     std::lock_guard lock(mLock); | 
| Eric Laurent | 7ea0d1b | 2022-04-01 14:23:44 +0200 | [diff] [blame] | 958 |     if (mNumActiveTracks != numActiveTracks) { | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 959 |         mLocalLog.log("%s from %zu to %zu", __func__, mNumActiveTracks, numActiveTracks); | 
| Eric Laurent | 7ea0d1b | 2022-04-01 14:23:44 +0200 | [diff] [blame] | 960 |         mNumActiveTracks = numActiveTracks; | 
 | 961 |         checkEngineState_l(); | 
 | 962 |         checkSensorsState_l(); | 
 | 963 |     } | 
| Eric Laurent | 1590359 | 2022-02-24 20:44:36 +0100 | [diff] [blame] | 964 | } | 
 | 965 |  | 
| Eric Laurent | 9249d34 | 2022-03-18 11:55:56 +0100 | [diff] [blame] | 966 | void Spatializer::checkSensorsState_l() { | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 967 |     audio_latency_mode_t requestedLatencyMode = AUDIO_LATENCY_MODE_FREE; | 
| Andy Hung | c0896c7 | 2022-10-21 17:30:30 -0700 | [diff] [blame] | 968 |     const bool supportsSetLatencyMode = !mSupportedLatencyModes.empty(); | 
 | 969 |     const bool supportsLowLatencyMode = supportsSetLatencyMode && std::find( | 
 | 970 |             mSupportedLatencyModes.begin(), mSupportedLatencyModes.end(), | 
 | 971 |             AUDIO_LATENCY_MODE_LOW) != mSupportedLatencyModes.end(); | 
| Eric Laurent | 3c48ad9 | 2022-10-21 11:28:32 +0200 | [diff] [blame] | 972 |     if (mSupportsHeadTracking) { | 
 | 973 |         if (mPoseController != nullptr) { | 
| Andy Hung | c0896c7 | 2022-10-21 17:30:30 -0700 | [diff] [blame] | 974 |             // TODO(b/253297301, b/255433067) reenable low latency condition check | 
 | 975 |             // for Head Tracking after Bluetooth HAL supports it correctly. | 
 | 976 |             if (mNumActiveTracks > 0 && mLevel != SpatializationLevel::NONE | 
| Eric Laurent | 3c48ad9 | 2022-10-21 11:28:32 +0200 | [diff] [blame] | 977 |                 && mDesiredHeadTrackingMode != HeadTrackingMode::STATIC | 
 | 978 |                 && mHeadSensor != SpatializerPoseController::INVALID_SENSOR) { | 
 | 979 |                 if (mEngine != nullptr) { | 
 | 980 |                     setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE, | 
 | 981 |                             std::vector<SpatializerHeadTrackingMode>{mActualHeadTrackingMode}); | 
 | 982 |                 } | 
 | 983 |                 mPoseController->setHeadSensor(mHeadSensor); | 
 | 984 |                 mPoseController->setScreenSensor(mScreenSensor); | 
| Andy Hung | c0896c7 | 2022-10-21 17:30:30 -0700 | [diff] [blame] | 985 |                 if (supportsLowLatencyMode) requestedLatencyMode = AUDIO_LATENCY_MODE_LOW; | 
| Eric Laurent | 3c48ad9 | 2022-10-21 11:28:32 +0200 | [diff] [blame] | 986 |             } else { | 
 | 987 |                 mPoseController->setHeadSensor(SpatializerPoseController::INVALID_SENSOR); | 
 | 988 |                 mPoseController->setScreenSensor(SpatializerPoseController::INVALID_SENSOR); | 
 | 989 |                 resetEngineHeadPose_l(); | 
 | 990 |             } | 
| Eric Laurent | 1590359 | 2022-02-24 20:44:36 +0100 | [diff] [blame] | 991 |         } else { | 
| Eric Laurent | 3c48ad9 | 2022-10-21 11:28:32 +0200 | [diff] [blame] | 992 |             resetEngineHeadPose_l(); | 
| Eric Laurent | 1590359 | 2022-02-24 20:44:36 +0100 | [diff] [blame] | 993 |         } | 
 | 994 |     } | 
| Andy Hung | c0896c7 | 2022-10-21 17:30:30 -0700 | [diff] [blame] | 995 |     if (mOutput != AUDIO_IO_HANDLE_NONE && supportsSetLatencyMode) { | 
| Andy Hung | 5d8618d | 2022-11-17 17:21:45 -0800 | [diff] [blame] | 996 |         const status_t status = | 
 | 997 |                 AudioSystem::setRequestedLatencyMode(mOutput, requestedLatencyMode); | 
 | 998 |         ALOGD("%s: setRequestedLatencyMode for output thread(%d) to %s returned %d", | 
 | 999 |                 __func__, mOutput, toString(requestedLatencyMode).c_str(), status); | 
| Eric Laurent | b387fb4 | 2022-05-03 18:19:35 +0200 | [diff] [blame] | 1000 |     } | 
| Eric Laurent | 1590359 | 2022-02-24 20:44:36 +0100 | [diff] [blame] | 1001 | } | 
 | 1002 |  | 
| Eric Laurent | 7ea0d1b | 2022-04-01 14:23:44 +0200 | [diff] [blame] | 1003 | void Spatializer::checkEngineState_l() { | 
 | 1004 |     if (mEngine != nullptr) { | 
 | 1005 |         if (mLevel != SpatializationLevel::NONE && mNumActiveTracks > 0) { | 
 | 1006 |             mEngine->setEnabled(true); | 
 | 1007 |             setEffectParameter_l(SPATIALIZER_PARAM_LEVEL, | 
 | 1008 |                     std::vector<SpatializationLevel>{mLevel}); | 
| Eric Laurent | 7ea0d1b | 2022-04-01 14:23:44 +0200 | [diff] [blame] | 1009 |         } else { | 
 | 1010 |             setEffectParameter_l(SPATIALIZER_PARAM_LEVEL, | 
 | 1011 |                     std::vector<SpatializationLevel>{SpatializationLevel::NONE}); | 
 | 1012 |             mEngine->setEnabled(false); | 
 | 1013 |         } | 
 | 1014 |     } | 
 | 1015 | } | 
 | 1016 |  | 
| Eric Laurent | 1109417 | 2022-04-05 18:27:42 +0200 | [diff] [blame] | 1017 | void Spatializer::checkPoseController_l() { | 
 | 1018 |     bool isControllerNeeded = mDesiredHeadTrackingMode != HeadTrackingMode::STATIC | 
 | 1019 |             && mHeadSensor != SpatializerPoseController::INVALID_SENSOR; | 
 | 1020 |  | 
 | 1021 |     if (isControllerNeeded && mPoseController == nullptr) { | 
 | 1022 |         mPoseController = std::make_shared<SpatializerPoseController>( | 
 | 1023 |                 static_cast<SpatializerPoseController::Listener*>(this), | 
| Eric Laurent | e51f80e | 2022-04-14 10:20:38 +0200 | [diff] [blame] | 1024 |                 10ms, std::nullopt); | 
| Eric Laurent | 1109417 | 2022-04-05 18:27:42 +0200 | [diff] [blame] | 1025 |         LOG_ALWAYS_FATAL_IF(mPoseController == nullptr, | 
 | 1026 |                             "%s could not allocate pose controller", __func__); | 
 | 1027 |         mPoseController->setDisplayOrientation(mDisplayOrientation); | 
 | 1028 |     } else if (!isControllerNeeded && mPoseController != nullptr) { | 
 | 1029 |         mPoseController.reset(); | 
| Eric Laurent | 3c48ad9 | 2022-10-21 11:28:32 +0200 | [diff] [blame] | 1030 |         resetEngineHeadPose_l(); | 
| Eric Laurent | 1109417 | 2022-04-05 18:27:42 +0200 | [diff] [blame] | 1031 |     } | 
 | 1032 |     if (mPoseController != nullptr) { | 
 | 1033 |         mPoseController->setDesiredMode(mDesiredHeadTrackingMode); | 
 | 1034 |     } | 
 | 1035 | } | 
 | 1036 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 1037 | void Spatializer::calculateHeadPose() { | 
 | 1038 |     ALOGV("%s", __func__); | 
 | 1039 |     std::lock_guard lock(mLock); | 
 | 1040 |     if (mPoseController != nullptr) { | 
 | 1041 |         mPoseController->calculateAsync(); | 
 | 1042 |     } | 
 | 1043 | } | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 1044 |  | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 1045 | void Spatializer::engineCallback(int32_t event, void *user, void *info) { | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 1046 |     if (user == nullptr) { | 
 | 1047 |         return; | 
 | 1048 |     } | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 1049 |     Spatializer* const me = reinterpret_cast<Spatializer *>(user); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 1050 |     switch (event) { | 
 | 1051 |         case AudioEffect::EVENT_FRAMES_PROCESSED: { | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 1052 |             int frames = info == nullptr ? 0 : *(int*)info; | 
| Eric Laurent | 9249d34 | 2022-03-18 11:55:56 +0100 | [diff] [blame] | 1053 |             ALOGV("%s frames processed %d for me %p", __func__, frames, me); | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 1054 |             me->postFramesProcessedMsg(frames); | 
| Eric Laurent | 2be8b29 | 2021-08-23 09:44:33 -0700 | [diff] [blame] | 1055 |         } break; | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 1056 |         default: | 
| Eric Laurent | 9249d34 | 2022-03-18 11:55:56 +0100 | [diff] [blame] | 1057 |             ALOGV("%s event %d", __func__, event); | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 1058 |             break; | 
 | 1059 |     } | 
 | 1060 | } | 
 | 1061 |  | 
| Eric Laurent | 8a4259f | 2021-09-14 16:04:00 +0200 | [diff] [blame] | 1062 | void Spatializer::postFramesProcessedMsg(int frames) { | 
 | 1063 |     sp<AMessage> msg = | 
 | 1064 |             new AMessage(EngineCallbackHandler::kWhatOnFramesProcessed, mHandler); | 
 | 1065 |     msg->setInt32(EngineCallbackHandler::kNumFramesKey, frames); | 
 | 1066 |     msg->post(); | 
 | 1067 | } | 
 | 1068 |  | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 1069 | std::string Spatializer::toString(unsigned level) const { | 
| Andy Hung | 2a390db | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 1070 |     std::string prefixSpace(level, ' '); | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 1071 |     std::string ss = prefixSpace + "Spatializer:\n"; | 
 | 1072 |     bool needUnlock = false; | 
 | 1073 |  | 
 | 1074 |     prefixSpace += ' '; | 
 | 1075 |     if (!mLock.try_lock()) { | 
 | 1076 |         // dumpsys even try_lock failed, information dump can be useful although may not accurate | 
 | 1077 |         ss.append(prefixSpace).append("try_lock failed, dumpsys below maybe INACCURATE!\n"); | 
 | 1078 |     } else { | 
 | 1079 |         needUnlock = true; | 
 | 1080 |     } | 
 | 1081 |  | 
 | 1082 |     // Spatializer class information. | 
 | 1083 |     // 1. Capabilities (mLevels, mHeadTrackingModes, mSpatializationModes, mChannelMasks, etc) | 
 | 1084 |     ss.append(prefixSpace).append("Supported levels: ["); | 
 | 1085 |     for (auto& level : mLevels) { | 
 | 1086 |         base::StringAppendF(&ss, " %s", media::toString(level).c_str()); | 
 | 1087 |     } | 
 | 1088 |     base::StringAppendF(&ss, "], mLevel: %s", media::toString(mLevel).c_str()); | 
 | 1089 |  | 
 | 1090 |     base::StringAppendF(&ss, "\n%smHeadTrackingModes: [", prefixSpace.c_str()); | 
 | 1091 |     for (auto& mode : mHeadTrackingModes) { | 
 | 1092 |         base::StringAppendF(&ss, " %s", media::toString(mode).c_str()); | 
 | 1093 |     } | 
 | 1094 |     base::StringAppendF(&ss, "], Desired: %s, Actual %s\n", | 
| Shunkai Yao | 5137945 | 2022-08-30 03:14:50 +0000 | [diff] [blame] | 1095 |                         media::toString(mDesiredHeadTrackingMode).c_str(), | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 1096 |                         media::toString(mActualHeadTrackingMode).c_str()); | 
 | 1097 |  | 
 | 1098 |     base::StringAppendF(&ss, "%smSpatializationModes: [", prefixSpace.c_str()); | 
 | 1099 |     for (auto& mode : mSpatializationModes) { | 
 | 1100 |         base::StringAppendF(&ss, " %s", media::toString(mode).c_str()); | 
 | 1101 |     } | 
 | 1102 |     ss += "]\n"; | 
 | 1103 |  | 
 | 1104 |     base::StringAppendF(&ss, "%smChannelMasks: ", prefixSpace.c_str()); | 
 | 1105 |     for (auto& mask : mChannelMasks) { | 
 | 1106 |         base::StringAppendF(&ss, "%s", audio_channel_out_mask_to_string(mask)); | 
 | 1107 |     } | 
 | 1108 |     base::StringAppendF(&ss, "\n%smSupportsHeadTracking: %s\n", prefixSpace.c_str(), | 
 | 1109 |                         mSupportsHeadTracking ? "true" : "false"); | 
 | 1110 |     // 2. Settings (Output, tracks) | 
 | 1111 |     base::StringAppendF(&ss, "%smNumActiveTracks: %zu\n", prefixSpace.c_str(), mNumActiveTracks); | 
 | 1112 |     base::StringAppendF(&ss, "%sOutputStreamHandle: %d\n", prefixSpace.c_str(), (int)mOutput); | 
 | 1113 |  | 
 | 1114 |     // 3. Sensors, Effect information. | 
 | 1115 |     base::StringAppendF(&ss, "%sHeadSensorHandle: 0x%08x\n", prefixSpace.c_str(), mHeadSensor); | 
 | 1116 |     base::StringAppendF(&ss, "%sScreenSensorHandle: 0x%08x\n", prefixSpace.c_str(), mScreenSensor); | 
 | 1117 |     base::StringAppendF(&ss, "%sEffectHandle: %p\n", prefixSpace.c_str(), mEngine.get()); | 
 | 1118 |     base::StringAppendF(&ss, "%sDisplayOrientation: %f\n", prefixSpace.c_str(), | 
 | 1119 |                         mDisplayOrientation); | 
 | 1120 |  | 
 | 1121 |     ss.append(prefixSpace + "CommandLog:\n"); | 
 | 1122 |     ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), mMaxLocalLogLine); | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 1123 |  | 
 | 1124 |     // PostController dump. | 
 | 1125 |     if (mPoseController != nullptr) { | 
| Andy Hung | 2a390db | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 1126 |         ss.append(mPoseController->toString(level + 1)) | 
 | 1127 |             .append(prefixSpace) | 
| Andy Hung | 9bcf425 | 2023-02-27 13:36:23 -0800 | [diff] [blame] | 1128 |             .append("Pose (active stage-to-head) [tx, ty, tz : pitch, roll, yaw]:\n") | 
| Andy Hung | 2a390db | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 1129 |             .append(prefixSpace) | 
 | 1130 |             .append(" PerMinuteHistory:\n") | 
| Andy Hung | 9bcf425 | 2023-02-27 13:36:23 -0800 | [diff] [blame] | 1131 |             .append(mPoseDurableRecorder.toString(level + 3)) | 
| Andy Hung | 2a390db | 2023-01-30 11:58:44 -0800 | [diff] [blame] | 1132 |             .append(prefixSpace) | 
 | 1133 |             .append(" PerSecondHistory:\n") | 
| Andy Hung | 9bcf425 | 2023-02-27 13:36:23 -0800 | [diff] [blame] | 1134 |             .append(mPoseRecorder.toString(level + 3)); | 
| Shunkai Yao | 5a251df | 2022-07-22 18:42:27 +0000 | [diff] [blame] | 1135 |     } else { | 
 | 1136 |         ss.append(prefixSpace).append("SpatializerPoseController not exist\n"); | 
 | 1137 |     } | 
 | 1138 |  | 
 | 1139 |     if (needUnlock) { | 
 | 1140 |         mLock.unlock(); | 
 | 1141 |     } | 
 | 1142 |     return ss; | 
 | 1143 | } | 
 | 1144 |  | 
| Eric Laurent | 6d60701 | 2021-07-05 11:54:40 +0200 | [diff] [blame] | 1145 | } // namespace android |