1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <chrono>
17 #include <thread>
18
19 #include "migrate_avsession_proxy.h"
20
21 #include "avsession_log.h"
22 #include "avsession_service.h"
23 #include "softbus/softbus_session_utils.h"
24 #include "int_wrapper.h"
25 #include "string_wrapper.h"
26 #include "bool_wrapper.h"
27
28 namespace OHOS::AVSession {
29
MigrateAVSessionProxy(AVSessionService * ptr,int32_t mode,std::string deviceId)30 MigrateAVSessionProxy::MigrateAVSessionProxy(AVSessionService *ptr, int32_t mode, std::string deviceId)
31 {
32 std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
33 SLOGI("migrateproxy construct with mode:%{public}d,localDevId:%{public}s.", mode,
34 SoftbusSessionUtils::AnonymizeDeviceId(deviceId).c_str());
35 mMode_ = mode;
36 servicePtr_ = ptr;
37 localDeviceId_ = deviceId;
38 }
39
~MigrateAVSessionProxy()40 MigrateAVSessionProxy::~MigrateAVSessionProxy()
41 {
42 SLOGI("MigrateAVSessionProxy destruct with disconnect process");
43 OnDisconnectServer(deviceId_);
44 }
45
OnConnectServer(const std::string & deviceId)46 void MigrateAVSessionProxy::OnConnectServer(const std::string &deviceId)
47 {
48 SLOGI("MigrateAVSessionProxy OnConnectServer:%{public}s.",
49 SoftbusSessionUtils::AnonymizeDeviceId(deviceId).c_str());
50 {
51 std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
52 deviceId_ = deviceId;
53 }
54 SendSpecialKeepAliveData();
55 PrepareSessionFromRemote();
56 CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "OnConnectServer find service ptr null!");
57 CHECK_AND_RETURN_LOG(preSetController_ != nullptr, "OnConnectServer find preSetController null!");
58 std::vector<sptr<IRemoteObject>> sessionControllers;
59 sessionControllers.push_back(preSetController_);
60 servicePtr_->NotifyRemoteDistributedSessionControllersChanged(sessionControllers);
61 }
62
OnDisconnectServer(const std::string & deviceId)63 void MigrateAVSessionProxy::OnDisconnectServer(const std::string &deviceId)
64 {
65 {
66 std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
67 SLOGI("MigrateAVSessionProxy OnDisconnectServer:%{public}s.",
68 SoftbusSessionUtils::AnonymizeDeviceId(deviceId).c_str());
69 if (deviceId != deviceId_) {
70 SLOGE("proxy onDisconnect but not:%{public}s.", SoftbusSessionUtils::AnonymizeDeviceId(deviceId_).c_str());
71 return;
72 }
73 deviceId_ = "";
74 }
75 {
76 std::lock_guard<std::mutex> lock(keepAliveMtx_);
77 keepAliveCv_.notify_all();
78 }
79 if (keepAliveworker_.joinable()) {
80 keepAliveworker_.join();
81 }
82 std::vector<sptr<IRemoteObject>> sessionControllers;
83 CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "OnDisconnectServer find service ptr null!");
84 servicePtr_->NotifyRemoteDistributedSessionControllersChanged(sessionControllers);
85 ReleaseSessionFromRemote();
86 servicePtr_->NotifyRemoteBundleChange("");
87 elementName_.SetAbilityName("");
88 elementName_.SetBundleName("");
89 SLOGI("MigrateAVSessionProxy OnDisconnectServer complete");
90 }
91
GetCharacteristic()92 int32_t MigrateAVSessionProxy::GetCharacteristic()
93 {
94 return mMode_;
95 }
96
97 //LCOV_EXCL_START
OnBytesReceived(const std::string & deviceId,const std::string & data)98 void MigrateAVSessionProxy::OnBytesReceived(const std::string &deviceId, const std::string &data)
99 {
100 if (data.length() <= MSG_HEAD_LENGTH) {
101 SLOGE("OnBytesReceived too short to process");
102 return;
103 }
104 int32_t infoType = data[1];
105 SLOGI("OnBytesReceived with infoType: %{public}d", infoType);
106 std::string jsonStr = data.substr(MSG_HEAD_LENGTH);
107 if (infoType == SYNC_FOCUS_MEDIA_IMAGE) {
108 ProcessMediaImage(jsonStr);
109 return;
110 } else if (infoType == SYNC_FOCUS_BUNDLE_IMG) {
111 ProcessBundleImg(jsonStr);
112 return;
113 }
114
115 cJSON* jsonValue = nullptr;
116 if (!SoftbusSessionUtils::TransferStrToJson(jsonStr, jsonValue)) {
117 SLOGE("OnBytesReceived parse json fail");
118 return;
119 }
120
121 switch (infoType) {
122 case SYNC_FOCUS_SESSION_INFO:
123 ProcessSessionInfo(jsonValue);
124 break;
125 case SYNC_FOCUS_META_INFO:
126 ProcessMetaData(jsonValue);
127 break;
128 case SYNC_FOCUS_PLAY_STATE:
129 ProcessPlaybackState(jsonValue);
130 break;
131 case SYNC_FOCUS_VALID_COMMANDS:
132 ProcessValidCommands(jsonValue);
133 break;
134 case SYNC_SET_VOLUME_COMMAND:
135 ProcessVolumeControlCommand(jsonValue);
136 break;
137 case SYNC_AVAIL_DEVICES_LIST:
138 ProcessAvailableDevices(jsonValue);
139 break;
140 case SYNC_CURRENT_DEVICE:
141 ProcessPreferredOutputDevice(jsonValue);
142 break;
143 default:
144 SLOGE("OnBytesReceived with unknow infoType:%{public}d", infoType);
145 break;
146 }
147 if (jsonValue != nullptr) {
148 cJSON_Delete(jsonValue);
149 }
150 }
151 //LCOV_EXCL_STOP
152
HandlePlay()153 void MigrateAVSessionProxy::HandlePlay()
154 {
155 SendControlCommandMsg(AVControlCommand::SESSION_CMD_PLAY, DEFAULT_STRING);
156 }
157
HandlePause()158 void MigrateAVSessionProxy::HandlePause()
159 {
160 SendControlCommandMsg(AVControlCommand::SESSION_CMD_PAUSE, DEFAULT_STRING);
161 }
162
HandlePlayNext()163 void MigrateAVSessionProxy::HandlePlayNext()
164 {
165 SendControlCommandMsg(AVControlCommand::SESSION_CMD_PLAY_NEXT, DEFAULT_STRING);
166 }
167
HandlePlayPrevious()168 void MigrateAVSessionProxy::HandlePlayPrevious()
169 {
170 SendControlCommandMsg(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS, DEFAULT_STRING);
171 }
172
HandleToggleFavorite(const std::string & mediaId)173 void MigrateAVSessionProxy::HandleToggleFavorite(const std::string& mediaId)
174 {
175 SendControlCommandMsg(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE, mediaId);
176 }
177
HandleCommonCommand(const std::string & commonCommand,const AAFwk::WantParams & commandArgs)178 void MigrateAVSessionProxy::HandleCommonCommand(const std::string& commonCommand, const AAFwk::WantParams& commandArgs)
179 {
180 SLOGI("HandleCommonCommand with command:%{public}s", commonCommand.c_str());
181 }
182
GetDistributedSessionControllerList(std::vector<sptr<IRemoteObject>> & controllerList)183 void MigrateAVSessionProxy::GetDistributedSessionControllerList(std::vector<sptr<IRemoteObject>>& controllerList)
184 {
185 CHECK_AND_RETURN_LOG(preSetController_ != nullptr, "GetDistributedSessionControllerList with controller null");
186 controllerList.insert(controllerList.begin(), preSetController_);
187 }
188
PrepareSessionFromRemote()189 void MigrateAVSessionProxy::PrepareSessionFromRemote()
190 {
191 SLOGI("PrepareSessionFromRemote in");
192 AVSessionDescriptor descriptor;
193 descriptor.sessionId_ = DEFAULT_STRING;
194 descriptor.sessionTag_ = DEFAULT_STRING;
195 descriptor.sessionType_ = AVSession::SESSION_TYPE_AUDIO;
196 descriptor.elementName_.SetBundleName(DEFAULT_STRING);
197 descriptor.elementName_.SetAbilityName(DEFAULT_STRING);
198 descriptor.isThirdPartyApp_ = false;
199
200 remoteSession_ = new(std::nothrow) AVSessionItem(descriptor);
201 CHECK_AND_RETURN_LOG(remoteSession_ != nullptr, "create avsession but get nullptr");
202 remoteSession_->SetPid(DEFAULT_NUM);
203 remoteSession_->SetUid(DEFAULT_NUM);
204
205 OutputDeviceInfo outputDeviceInfo;
206 DeviceInfo deviceInfo;
207 deviceInfo.castCategory_ = AVCastCategory::CATEGORY_REMOTE;
208 deviceInfo.deviceId_ = DEFAULT_STRING;
209 deviceInfo.deviceName_ = DEFAULT_STRING;
210 outputDeviceInfo.deviceInfos_.emplace_back(deviceInfo);
211 remoteSession_->SetOutputDevice(outputDeviceInfo);
212
213 std::weak_ptr<MigrateAVSessionProxy> migrateProxyWeak(shared_from_this());
214 std::shared_ptr<AVSessionObserver> callback =
215 std::make_shared<AVSessionObserver>(remoteSession_->GetSessionId(), migrateProxyWeak);
216 remoteSession_->RegisterAVSessionCallback(callback);
217 PrepareControllerOfRemoteSession(remoteSession_);
218 SLOGI("PrepareSessionFromRemote done");
219 }
220
PrepareControllerOfRemoteSession(sptr<AVSessionItem> sessionItem)221 void MigrateAVSessionProxy::PrepareControllerOfRemoteSession(sptr<AVSessionItem> sessionItem)
222 {
223 CHECK_AND_RETURN_LOG(sessionItem != nullptr, "PrepareControllerOfRemoteSession with remote session null");
224 preSetController_ = new(std::nothrow) AVControllerItem(DEFAULT_NUM, sessionItem);
225 CHECK_AND_RETURN_LOG(preSetController_ != nullptr, "PrepareControllerOfRemoteSession with controller create null");
226 migrateProxyCallback_ = MigrateAVSessionProxyControllerCallback();
227 preSetController_->RegisterMigrateAVSessionProxyCallback(migrateProxyCallback_);
228 sessionItem->AddController(DEFAULT_NUM, preSetController_);
229 }
230
ReleaseSessionFromRemote()231 void MigrateAVSessionProxy::ReleaseSessionFromRemote()
232 {
233 SLOGI("ReleaseSessionFromRemote in");
234 ReleaseControllerOfRemoteSession();
235 CHECK_AND_RETURN_LOG(remoteSession_ != nullptr, "ReleaseSessionFromRemote with remoteSession null");
236 remoteSession_->RegisterAVSessionCallback(nullptr);
237 remoteSession_->DestroyTask();
238 remoteSession_ = nullptr;
239 SLOGI("ReleaseSessionFromRemote done.");
240 }
241
ReleaseControllerOfRemoteSession()242 void MigrateAVSessionProxy::ReleaseControllerOfRemoteSession()
243 {
244 CHECK_AND_RETURN_LOG(preSetController_ != nullptr, "ReleaseControllerOfRemoteSession with preSetController null");
245 preSetController_->RegisterMigrateAVSessionProxyCallback(nullptr);
246 preSetController_->DestroyWithoutReply();
247 preSetController_ = nullptr;
248 SLOGI("ReleaseControllerOfRemoteSession done.");
249 }
250
MigrateAVSessionProxyControllerCallback()251 const MigrateAVSessionProxyControllerCallbackFunc MigrateAVSessionProxy::MigrateAVSessionProxyControllerCallback()
252 {
253 return [this](const std::string& extraEvent, AAFwk::WantParams& extras) {
254 const auto& it = AUDIO_EVENT_MAPS.find(extraEvent);
255 if (it == AUDIO_EVENT_MAPS.end()) {
256 SLOGE("extraEvent %{public}s not support", extraEvent.c_str());
257 return ERR_COMMAND_NOT_SUPPORT;
258 }
259 switch (it->second) {
260 case AUDIO_NUM_SET_VOLUME:
261 SetVolume(extras);
262 break;
263 case AUDIO_NUM_SELECT_OUTPUT_DEVICE:
264 SelectOutputDevice(extras);
265 break;
266 case AUDIO_NUM_GET_VOLUME:
267 GetVolume(extras);
268 break;
269 case AUDIO_NUM_GET_AVAILABLE_DEVICES:
270 GetAvailableDevices(extras);
271 break;
272 case AUDIO_NUM_GET_PREFERRED_OUTPUT_DEVICE_FOR_RENDERER_INFO:
273 GetPreferredOutputDeviceForRendererInfo(extras);
274 break;
275 case SESSION_NUM_COLD_START_FROM_PROXY:
276 ColdStartFromProxy();
277 break;
278 case SESSION_NUM_SET_MEDIACONTROL_NEED_STATE:
279 NotifyMediaControlNeedStateChange(extras);
280 break;
281 default:
282 break;
283 }
284 return AVSESSION_SUCCESS;
285 };
286 }
287
SetVolume(const AAFwk::WantParams & extras)288 void MigrateAVSessionProxy::SetVolume(const AAFwk::WantParams& extras)
289 {
290 SLOGI("proxy send in SetVolume case");
291 CHECK_AND_RETURN_LOG(extras.HasParam(AUDIO_SET_VOLUME), "extras not have event");
292 auto volume = extras.GetParam(AUDIO_SET_VOLUME);
293 AAFwk::IInteger* ao = AAFwk::IInteger::Query(volume);
294 CHECK_AND_RETURN_LOG(ao != nullptr, "extras have no value");
295
296 volumeNum_ = OHOS::AAFwk::Integer::Unbox(ao);
297 cJSON* value = SoftbusSessionUtils::GetNewCJSONObject();
298 if (value == nullptr) {
299 SLOGE("get json value fail");
300 return;
301 }
302 if (!SoftbusSessionUtils::AddIntToJson(value, AUDIO_VOLUME, volumeNum_)) {
303 SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail", AUDIO_VOLUME, volumeNum_);
304 cJSON_Delete(value);
305 return;
306 }
307 std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_SET_VOLUME_COMMAND});
308 SoftbusSessionUtils::TransferJsonToStr(value, msg);
309 cJSON_Delete(value);
310 SendByteForNext(deviceId_, msg);
311 }
312
SelectOutputDevice(const AAFwk::WantParams & extras)313 void MigrateAVSessionProxy::SelectOutputDevice(const AAFwk::WantParams& extras)
314 {
315 SLOGI("proxy send in SelectOutputDevice case");
316 CHECK_AND_RETURN_LOG(extras.HasParam(AUDIO_SELECT_OUTPUT_DEVICE), "extras not have event");
317 auto value = extras.GetParam(AUDIO_SELECT_OUTPUT_DEVICE);
318 AAFwk::IString* stringValue = AAFwk::IString::Query(value);
319 CHECK_AND_RETURN_LOG(stringValue != nullptr, "extras have no value");
320
321 std::string deviceValue = AAFwk::String::Unbox(stringValue);
322 std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_SWITCH_AUDIO_DEVICE_COMMAND});
323 SendJsonStringByte(deviceId_, msg + deviceValue);
324 }
325
GetVolume(AAFwk::WantParams & extras)326 void MigrateAVSessionProxy::GetVolume(AAFwk::WantParams& extras)
327 {
328 SLOGI("proxy send in GetVolume case");
329 extras.SetParam(AUDIO_GET_VOLUME, OHOS::AAFwk::Integer::Box(volumeNum_));
330 }
331
GetAvailableDevices(AAFwk::WantParams & extras)332 void MigrateAVSessionProxy::GetAvailableDevices(AAFwk::WantParams& extras)
333 {
334 SLOGI("proxy send in GetAvailableDevices case");
335 cJSON* jsonData = MigrateAVSessionServer::ConvertAudioDeviceDescriptorsToJson(availableDevices_);
336 CHECK_AND_RETURN_LOG(jsonData != nullptr, "get jsonData nullptr");
337 if (cJSON_IsInvalid(jsonData) || cJSON_IsNull(jsonData)) {
338 SLOGE("get jsonData invalid");
339 cJSON_Delete(jsonData);
340 return;
341 }
342
343 cJSON* jsonArray = cJSON_GetObjectItem(jsonData, MEDIA_AVAILABLE_DEVICES_LIST);
344 if (jsonArray == nullptr || cJSON_IsInvalid(jsonArray) || cJSON_IsNull(jsonArray)) {
345 SLOGE("get jsonArray invalid");
346 cJSON_Delete(jsonData);
347 return;
348 }
349 std::string jsonStr;
350 SoftbusSessionUtils::TransferJsonToStr(jsonArray, jsonStr);
351 if (jsonStr.empty()) {
352 SLOGE("get jsonStr empty");
353 cJSON_Delete(jsonData);
354 return;
355 }
356 extras.SetParam(AUDIO_GET_AVAILABLE_DEVICES, OHOS::AAFwk::String::Box(jsonStr));
357 cJSON_Delete(jsonData);
358 }
359
GetPreferredOutputDeviceForRendererInfo(AAFwk::WantParams & extras)360 void MigrateAVSessionProxy::GetPreferredOutputDeviceForRendererInfo(AAFwk::WantParams& extras)
361 {
362 SLOGI("proxy send in GetPreferredOutputDeviceForRendererInfo case");
363 cJSON* jsonData = MigrateAVSessionServer::ConvertAudioDeviceDescriptorsToJson(preferredOutputDevice_);
364 CHECK_AND_RETURN_LOG(jsonData != nullptr, "get jsonData nullptr");
365 if (cJSON_IsInvalid(jsonData) || cJSON_IsNull(jsonData)) {
366 SLOGE("get jsonData invalid");
367 cJSON_Delete(jsonData);
368 return;
369 }
370
371 cJSON* jsonArray = cJSON_GetObjectItem(jsonData, MEDIA_AVAILABLE_DEVICES_LIST);
372 if (jsonArray == nullptr || cJSON_IsInvalid(jsonArray) || cJSON_IsNull(jsonArray)) {
373 SLOGE("get jsonArray invalid");
374 cJSON_Delete(jsonData);
375 return;
376 }
377 std::string jsonStr;
378 SoftbusSessionUtils::TransferJsonToStr(jsonArray, jsonStr);
379 if (jsonStr.empty()) {
380 SLOGE("get jsonStr empty");
381 cJSON_Delete(jsonData);
382 return;
383 }
384 extras.SetParam(AUDIO_GET_PREFERRED_OUTPUT_DEVICE_FOR_RENDERER_INFO, OHOS::AAFwk::String::Box(jsonStr));
385 cJSON_Delete(jsonData);
386 }
387
ColdStartFromProxy()388 void MigrateAVSessionProxy::ColdStartFromProxy()
389 {
390 SLOGI("proxy send in ColdStartFromProxy case with bundleName:%{public}s", elementName_.GetAbilityName().c_str());
391 std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, COLD_START});
392
393 cJSON* controlMsg = SoftbusSessionUtils::GetNewCJSONObject();
394 if (controlMsg == nullptr) {
395 SLOGE("get controlMsg fail");
396 return;
397 }
398 if (!SoftbusSessionUtils::AddStringToJson(controlMsg, MIGRATE_BUNDLE_NAME, elementName_.GetAbilityName())) {
399 SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail", MIGRATE_BUNDLE_NAME,
400 elementName_.GetAbilityName().c_str());
401 cJSON_Delete(controlMsg);
402 return;
403 }
404
405 SoftbusSessionUtils::TransferJsonToStr(controlMsg, msg);
406 SendByteForNext(deviceId_, msg);
407 cJSON_Delete(controlMsg);
408 }
409
ProcessSessionInfo(cJSON * jsonValue)410 void MigrateAVSessionProxy::ProcessSessionInfo(cJSON* jsonValue)
411 {
412 CHECK_AND_RETURN_LOG(remoteSession_ != nullptr, "ProcessSessionInfo with remote session null");
413 if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
414 SLOGE("get jsonValue invalid");
415 return;
416 }
417 std::string bundleNameBef = elementName_.GetBundleName();
418 std::string bundleName = SoftbusSessionUtils::GetStringFromJson(jsonValue, MIGRATE_BUNDLE_NAME);
419 bundleName = bundleName.empty() ? DEFAULT_STRING : bundleName;
420 size_t insertPos = bundleName.find('|');
421 if (insertPos != std::string::npos && insertPos > 0 && insertPos < bundleName.size()) {
422 elementName_.SetBundleName(bundleName.substr(0, insertPos));
423 } else {
424 SLOGE("get bundleName invalid:%{public}s|%{public}s.", bundleName.c_str(),
425 elementName_.GetBundleName().c_str());
426 }
427 std::string abilityName = SoftbusSessionUtils::GetStringFromJson(jsonValue, MIGRATE_ABILITY_NAME);
428 abilityName = abilityName.empty() ? DEFAULT_STRING : abilityName;
429 elementName_.SetAbilityName(abilityName);
430 std::string sessionId = SoftbusSessionUtils::GetStringFromJson(jsonValue, MIGRATE_SESSION_ID);
431 sessionId = sessionId.empty() ? DEFAULT_STRING : sessionId;
432 if (sessionId.empty() || sessionId == DEFAULT_STRING || sessionId == EMPTY_SESSION) {
433 remoteSession_->Deactivate();
434 elementName_.SetAbilityName(elementName_.GetBundleName());
435 elementName_.SetBundleName("");
436 } else {
437 remoteSession_->Activate();
438 }
439 SLOGI("ProcessSessionInfo with sessionId:%{public}s|bundleName:%{public}s.",
440 SoftbusSessionUtils::AnonymizeDeviceId(sessionId).c_str(), bundleName.c_str());
441 CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "ProcessSessionInfo find service ptr null!");
442 servicePtr_->NotifyRemoteBundleChange(elementName_.GetBundleName());
443 AVPlaybackState playbackState;
444 if (bundleNameBef != elementName_.GetBundleName() &&
445 AVSESSION_SUCCESS == remoteSession_->GetAVPlaybackState(playbackState)) {
446 playbackState.SetState(0);
447 playbackState.SetFavorite(false);
448 remoteSession_->SetAVPlaybackState(playbackState);
449 }
450 AVMetaData metaData;
451 if (bundleNameBef != elementName_.GetBundleName() && AVSESSION_SUCCESS == remoteSession_->GetAVMetaData(metaData)) {
452 metaData.SetAssetId(metaData.GetAssetId().empty() ? DEFAULT_STRING : metaData.GetAssetId());
453 metaData.SetWriter(bundleName);
454 metaData.SetTitle("");
455 metaData.SetArtist("");
456 remoteSession_->SetAVMetaData(metaData);
457 }
458 SendMediaControlNeedStateMsg();
459 }
460
CheckMediaAlive()461 bool MigrateAVSessionProxy::CheckMediaAlive()
462 {
463 return !elementName_.GetBundleName().empty();
464 }
465
ProcessMetaData(cJSON * jsonValue)466 void MigrateAVSessionProxy::ProcessMetaData(cJSON* jsonValue)
467 {
468 CHECK_AND_RETURN_LOG(remoteSession_ != nullptr, "ProcessMetaData with remote session null");
469 if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
470 SLOGE("get jsonValue invalid");
471 return;
472 }
473 AVMetaData metaData;
474 if (AVSESSION_SUCCESS != remoteSession_->GetAVMetaData(metaData)) {
475 SLOGE("ProcessMetaData GetAVMetaData fail");
476 }
477
478 if (cJSON_HasObjectItem(jsonValue, METADATA_ASSET_ID)) {
479 std::string assetId = SoftbusSessionUtils::GetStringFromJson(jsonValue, METADATA_ASSET_ID);
480 if (assetId.empty()) {
481 assetId = DEFAULT_STRING;
482 }
483 std::string oldAsset = metaData.GetAssetId();
484 if (oldAsset != assetId) {
485 metaData.SetTitle("");
486 metaData.SetArtist("");
487 }
488 metaData.SetAssetId(assetId);
489 }
490 if (cJSON_HasObjectItem(jsonValue, METADATA_TITLE)) {
491 std::string title = SoftbusSessionUtils::GetStringFromJson(jsonValue, METADATA_TITLE);
492 if (title.empty()) {
493 title = DEFAULT_STRING;
494 }
495 metaData.SetTitle(title);
496 }
497 if (cJSON_HasObjectItem(jsonValue, METADATA_ARTIST)) {
498 std::string artist = SoftbusSessionUtils::GetStringFromJson(jsonValue, METADATA_ARTIST);
499 if (artist.empty()) {
500 artist = DEFAULT_STRING;
501 }
502 metaData.SetArtist(artist);
503 }
504
505 remoteSession_->SetAVMetaData(metaData);
506 SLOGI("ProcessMetaData set title:%{public}s", metaData.GetTitle().c_str());
507 }
508
ProcessPlaybackState(cJSON * jsonValue)509 void MigrateAVSessionProxy::ProcessPlaybackState(cJSON* jsonValue)
510 {
511 CHECK_AND_RETURN_LOG(remoteSession_ != nullptr, "ProcessPlaybackState with remote session null");
512 if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
513 SLOGE("get jsonValue invalid");
514 return;
515 }
516
517 AVPlaybackState playbackState;
518 if (AVSESSION_SUCCESS != remoteSession_->GetAVPlaybackState(playbackState)) {
519 SLOGE("ProcessPlaybackState GetAVPlaybackState fail");
520 }
521
522 if (cJSON_HasObjectItem(jsonValue, PLAYBACK_STATE)) {
523 int state = SoftbusSessionUtils::GetIntFromJson(jsonValue, PLAYBACK_STATE);
524 playbackState.SetState(state);
525 }
526 if (cJSON_HasObjectItem(jsonValue, FAVOR_STATE)) {
527 bool isFavor = SoftbusSessionUtils::GetBoolFromJson(jsonValue, FAVOR_STATE);
528 playbackState.SetFavorite(isFavor);
529 }
530
531 remoteSession_->SetAVPlaybackState(playbackState);
532 SLOGI("ProcessPlaybackState set state:%{public}d | isFavor:%{public}d",
533 playbackState.GetState(), playbackState.GetFavorite());
534 }
535
ProcessValidCommands(cJSON * jsonValue)536 void MigrateAVSessionProxy::ProcessValidCommands(cJSON* jsonValue)
537 {
538 CHECK_AND_RETURN_LOG(remoteSession_ != nullptr, "ProcessValidCommands with remote session null");
539 if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
540 SLOGE("get jsonValue invalid");
541 return;
542 }
543
544 std::vector<int32_t> commands;
545 if (cJSON_HasObjectItem(jsonValue, VALID_COMMANDS)) {
546 std::string commandsStr = SoftbusSessionUtils::GetStringFromJson(jsonValue, VALID_COMMANDS);
547 if (commandsStr.empty()) {
548 commandsStr = DEFAULT_STRING;
549 }
550 for (unsigned long i = 0; i < commandsStr.length(); i++) {
551 commands.insert(commands.begin(), static_cast<int>(commandsStr[i] - '0'));
552 }
553 remoteSession_->SetSupportCommand(commands);
554 }
555
556 SLOGI("ProcessValidCommands set cmd size:%{public}d", static_cast<int>(commands.size()));
557 }
558
ProcessVolumeControlCommand(cJSON * jsonValue)559 void MigrateAVSessionProxy::ProcessVolumeControlCommand(cJSON* jsonValue)
560 {
561 SLOGI("proxy recv in ProcessVolumeControlCommand case");
562 if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
563 SLOGE("get jsonValue invalid");
564 return;
565 }
566
567 if (!cJSON_HasObjectItem(jsonValue, AUDIO_VOLUME)) {
568 SLOGE("json parse with error member");
569 return;
570 }
571
572 volumeNum_ = SoftbusSessionUtils::GetIntFromJson(jsonValue, AUDIO_VOLUME);
573
574 AAFwk::WantParams args;
575 args.SetParam(AUDIO_CALLBACK_VOLUME, OHOS::AAFwk::Integer::Box(volumeNum_));
576 CHECK_AND_RETURN_LOG(preSetController_ != nullptr, "preSetController_ is nullptr");
577 preSetController_->HandleSetSessionEvent(AUDIO_CALLBACK_VOLUME, args);
578 }
579
DevicesJsonArrayToVector(cJSON * jsonArray,AudioDeviceDescriptors & devices)580 void DevicesJsonArrayToVector(cJSON* jsonArray, AudioDeviceDescriptors& devices)
581 {
582 if (jsonArray == nullptr || cJSON_IsInvalid(jsonArray) || !cJSON_IsArray(jsonArray)) {
583 SLOGE("get jsonArray invalid");
584 return;
585 }
586 devices.clear();
587 cJSON* jsonObject = nullptr;
588 cJSON_ArrayForEach(jsonObject, jsonArray) {
589 CHECK_AND_CONTINUE(jsonObject != nullptr && !cJSON_IsInvalid(jsonObject));
590 int deviceCategory = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_CATEGORY);
591 int deviceType = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_TYPE);
592 int deviceRole = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_ROLE);
593 std::string networkId = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_NETWORK_ID);
594 std::string deviceName = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_DEVICE_NAME);
595 std::string macAddress = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_MAC_ADDRESS);
596
597 std::shared_ptr<AudioDeviceDescriptor> device = std::make_shared<AudioDeviceDescriptor>();
598 CHECK_AND_RETURN_LOG(device != nullptr, "AudioDeviceDescriptor make shared_ptr is nullptr");
599 device->deviceCategory_ = static_cast<AudioStandard::DeviceCategory>(deviceCategory);
600 device->deviceType_ = static_cast<AudioStandard::DeviceType>(deviceType);
601 device->deviceRole_ = static_cast<AudioStandard::DeviceRole>(deviceRole);
602 device->networkId_ = networkId;
603 device->deviceName_ = deviceName;
604 device->macAddress_ = macAddress;
605 devices.push_back(device);
606 }
607 }
608
ProcessAvailableDevices(cJSON * jsonValue)609 void MigrateAVSessionProxy::ProcessAvailableDevices(cJSON* jsonValue)
610 {
611 SLOGI("proxy recv in ProcessAvailableDevices case");
612
613 if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
614 SLOGE("get jsonValue invalid");
615 return;
616 }
617 CHECK_AND_RETURN_LOG(cJSON_HasObjectItem(jsonValue, MEDIA_AVAILABLE_DEVICES_LIST), "json parse with error member");
618 cJSON* jsonArray = cJSON_GetObjectItem(jsonValue, MEDIA_AVAILABLE_DEVICES_LIST);
619 CHECK_AND_RETURN_LOG(jsonArray != nullptr && !cJSON_IsInvalid(jsonArray) && cJSON_IsArray(jsonArray),
620 "json object is not array");
621
622 DevicesJsonArrayToVector(jsonArray, availableDevices_);
623
624 std::string jsonStr;
625 SoftbusSessionUtils::TransferJsonToStr(jsonArray, jsonStr);
626 AAFwk::WantParams args;
627 args.SetParam(AUDIO_CALLBACK_AVAILABLE_DEVICES, OHOS::AAFwk::String::Box(jsonStr));
628 CHECK_AND_RETURN_LOG(preSetController_ != nullptr, "preSetController_ is nullptr");
629 preSetController_->HandleSetSessionEvent(AUDIO_CALLBACK_AVAILABLE_DEVICES, args);
630 }
631
ProcessPreferredOutputDevice(cJSON * jsonValue)632 void MigrateAVSessionProxy::ProcessPreferredOutputDevice(cJSON* jsonValue)
633 {
634 SLOGI("proxy recv in ProcessPreferredOutputDevice case");
635
636 if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
637 SLOGE("get jsonValue invalid");
638 return;
639 }
640 CHECK_AND_RETURN_LOG(cJSON_HasObjectItem(jsonValue, MEDIA_AVAILABLE_DEVICES_LIST), "json parse with error member");
641 cJSON* jsonArray = cJSON_GetObjectItem(jsonValue, MEDIA_AVAILABLE_DEVICES_LIST);
642 CHECK_AND_RETURN_LOG(jsonArray != nullptr && !cJSON_IsInvalid(jsonArray) && cJSON_IsArray(jsonArray),
643 "json object is not array");
644
645 DevicesJsonArrayToVector(jsonArray, preferredOutputDevice_);
646
647 std::string jsonStr;
648 SoftbusSessionUtils::TransferJsonToStr(jsonArray, jsonStr);
649 AAFwk::WantParams args;
650 args.SetParam(AUDIO_CALLBACK_PREFERRED_OUTPUT_DEVICE_FOR_RENDERER_INFO, OHOS::AAFwk::String::Box(jsonStr));
651 CHECK_AND_RETURN_LOG(preSetController_ != nullptr, "preSetController_ is nullptr");
652 preSetController_->HandleSetSessionEvent(AUDIO_CALLBACK_PREFERRED_OUTPUT_DEVICE_FOR_RENDERER_INFO, args);
653 }
654
ProcessBundleImg(std::string bundleIconStr)655 void MigrateAVSessionProxy::ProcessBundleImg(std::string bundleIconStr)
656 {
657 CHECK_AND_RETURN_LOG(remoteSession_ != nullptr, "ProcessBundleImg with remote session null");
658 AVMetaData metaData;
659 if (AVSESSION_SUCCESS != remoteSession_->GetAVMetaData(metaData)) {
660 SLOGE("ProcessBundleImg GetAVMetaData fail");
661 }
662 if (metaData.GetAssetId().empty()) {
663 metaData.SetAssetId(DEFAULT_STRING);
664 }
665 std::vector<uint8_t> imgVec(bundleIconStr.begin(), bundleIconStr.end());
666 if (imgVec.size() <= 0) {
667 SLOGE("ProcessBundleImg with empty img, return");
668 return;
669 }
670 std::shared_ptr<AVSessionPixelMap> innerPixelMap = std::make_shared<AVSessionPixelMap>();
671 innerPixelMap->SetInnerImgBuffer(imgVec);
672 metaData.SetBundleIcon(innerPixelMap);
673
674 remoteSession_->SetAVMetaData(metaData);
675 SLOGI("ProcessBundleImg set img size:%{public}d", static_cast<int>(metaData.GetBundleIcon() == nullptr ?
676 -1 : metaData.GetBundleIcon()->GetInnerImgBuffer().size()));
677 }
678
ProcessMediaImage(std::string mediaImageStr)679 void MigrateAVSessionProxy::ProcessMediaImage(std::string mediaImageStr)
680 {
681 CHECK_AND_RETURN_LOG(remoteSession_ != nullptr, "ProcessMediaImage with remote session null");
682 size_t insertPos = mediaImageStr.find('|');
683 CHECK_AND_RETURN_LOG(insertPos != std::string::npos && insertPos > 0 && insertPos < mediaImageStr.size(),
684 "mediaImgStr do not contain assetId, return");
685 std::string assetIdForMediaImg = mediaImageStr.substr(0, insertPos);
686 mediaImageStr.erase(0, insertPos + 1);
687 AVMetaData metaData;
688 if (AVSESSION_SUCCESS != remoteSession_->GetAVMetaData(metaData)) {
689 SLOGE("ProcessMediaImage GetAVMetaData fail");
690 }
691 if (metaData.GetAssetId().empty()) {
692 metaData.SetAssetId(assetIdForMediaImg);
693 }
694 metaData.SetPreviousAssetId(assetIdForMediaImg);
695 std::vector<uint8_t> imgVec(mediaImageStr.begin(), mediaImageStr.end());
696 if (imgVec.size() <= 0) {
697 metaData.SetMediaImageUri(DEFAULT_STRING);
698 metaData.SetMediaImage(nullptr);
699 } else {
700 std::shared_ptr<AVSessionPixelMap> innerPixelMap = std::make_shared<AVSessionPixelMap>();
701 innerPixelMap->SetInnerImgBuffer(imgVec);
702 metaData.SetMediaImageUri("");
703 metaData.SetMediaImage(innerPixelMap);
704 }
705 SLOGI("ProcessMediaImage set img size:%{public}d", static_cast<int>(metaData.GetMediaImage() == nullptr ?
706 -1 : metaData.GetMediaImage()->GetInnerImgBuffer().size()));
707 remoteSession_->SetAVMetaData(metaData);
708 }
709
SendControlCommandMsg(int32_t commandCode,std::string commandArgsStr)710 void MigrateAVSessionProxy::SendControlCommandMsg(int32_t commandCode, std::string commandArgsStr)
711 {
712 SLOGI("SendControlCommandMsg with code:%{public}d", commandCode);
713 std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_COMMAND});
714
715 cJSON* controlMsg = SoftbusSessionUtils::GetNewCJSONObject();
716 if (controlMsg == nullptr) {
717 SLOGE("get controlMsg fail");
718 return;
719 }
720 if (!SoftbusSessionUtils::AddIntToJson(controlMsg, COMMAND_CODE, commandCode)) {
721 SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail", COMMAND_CODE, commandCode);
722 cJSON_Delete(controlMsg);
723 return;
724 }
725 if (!SoftbusSessionUtils::AddStringToJson(controlMsg, COMMAND_ARGS, commandArgsStr)) {
726 SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail", COMMAND_ARGS, commandArgsStr.c_str());
727 cJSON_Delete(controlMsg);
728 return;
729 }
730
731 SoftbusSessionUtils::TransferJsonToStr(controlMsg, msg);
732 SendByteForNext(deviceId_, msg);
733 cJSON_Delete(controlMsg);
734 }
735
SendMediaControlNeedStateMsg()736 void MigrateAVSessionProxy::SendMediaControlNeedStateMsg()
737 {
738 SLOGI("SendMediaControlNeedStateMsg with state:%{public}d", isNeedByMediaControl.load());
739 std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_MEDIA_CONTROL_NEED_STATE});
740
741 cJSON* controlMsg = SoftbusSessionUtils::GetNewCJSONObject();
742 if (controlMsg == nullptr) {
743 SLOGE("get controlMsg fail");
744 return;
745 }
746 if (!SoftbusSessionUtils::AddBoolToJson(controlMsg, NEED_STATE, isNeedByMediaControl.load())) {
747 SLOGE("AddBoolToJson with key:%{public}s|value:%{public}d fail", NEED_STATE, isNeedByMediaControl.load());
748 cJSON_Delete(controlMsg);
749 return;
750 }
751
752 SoftbusSessionUtils::TransferJsonToStr(controlMsg, msg);
753 SendByteForNext(deviceId_, msg);
754 cJSON_Delete(controlMsg);
755 }
756
SendSpecialKeepAliveData()757 void MigrateAVSessionProxy::SendSpecialKeepAliveData()
758 {
759 keepAliveworker_ = std::thread([this]() {
760 bool isDeviceIdEmpty = false;
761 {
762 std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
763 isDeviceIdEmpty = this->deviceId_.empty();
764 }
765 while (!isDeviceIdEmpty) {
766 SLOGI("SendSpecialKeepAliveData for deviceId:%{public}s.",
767 SoftbusSessionUtils::AnonymizeDeviceId(deviceId_).c_str());
768 std::string data = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_HEARTBEAT});
769 SendByteForNext(deviceId_, data);
770
771 std::unique_lock<std::mutex> lock(keepAliveMtx_);
772 {
773 std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
774 isDeviceIdEmpty = this->deviceId_.empty();
775 CHECK_AND_RETURN_LOG(!isDeviceIdEmpty, "SendSpecialKeepAliveData quit for deviceId empty");
776 }
777 if (!isNeedByMediaControl.load()) {
778 SLOGI("silent bytes waiting.");
779 keepAliveCv_.wait_for(lock, std::chrono::milliseconds(SILENT_HEART_BEAT_TIME_FOR_NEXT));
780 } else {
781 keepAliveCv_.wait_for(lock, std::chrono::milliseconds(HEART_BEAT_TIME_FOR_NEXT));
782 }
783 {
784 std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
785 isDeviceIdEmpty = this->deviceId_.empty();
786 }
787 }
788 SLOGI("SendSpecialKeepAliveData exit.");
789 });
790 }
791
NotifyMediaControlNeedStateChange(AAFwk::WantParams & extras)792 void MigrateAVSessionProxy::NotifyMediaControlNeedStateChange(AAFwk::WantParams& extras)
793 {
794 CHECK_AND_RETURN_LOG(extras.HasParam(MEDIACONTROL_NEED_STATE), "extras not have NeedState");
795 auto value = extras.GetParam(MEDIACONTROL_NEED_STATE);
796 AAFwk::IBoolean* boolValue = AAFwk::IBoolean::Query(value);
797 CHECK_AND_RETURN_LOG(boolValue != nullptr, "extras have no NeedState after query");
798 bool isNeed = OHOS::AAFwk::Boolean::Unbox(boolValue);
799 SLOGI("refresh NeedState:%{public}d", isNeed);
800 isNeedByMediaControl.store(isNeed);
801 SendMediaControlNeedStateMsg();
802 }
803
AVSessionObserver(const std::string & playerId,std::weak_ptr<MigrateAVSessionProxy> migrateProxy)804 AVSessionObserver::AVSessionObserver(const std::string &playerId, std::weak_ptr<MigrateAVSessionProxy> migrateProxy)
805 {
806 playerId_ = playerId;
807 migrateProxy_ = migrateProxy;
808 }
809
OnPlay()810 void AVSessionObserver::OnPlay()
811 {
812 std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
813 CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
814 proxy->HandlePlay();
815 }
816
OnPause()817 void AVSessionObserver::OnPause()
818 {
819 std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
820 CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
821 proxy->HandlePause();
822 }
823
OnPlayNext()824 void AVSessionObserver::OnPlayNext()
825 {
826 std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
827 CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
828 proxy->HandlePlayNext();
829 }
830
OnPlayPrevious()831 void AVSessionObserver::OnPlayPrevious()
832 {
833 std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
834 CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
835 proxy->HandlePlayPrevious();
836 }
837
OnToggleFavorite(const std::string & mediaId)838 void AVSessionObserver::OnToggleFavorite(const std::string& mediaId)
839 {
840 std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
841 CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
842 proxy->HandleToggleFavorite(mediaId);
843 }
844
OnCommonCommand(const std::string & commonCommand,const AAFwk::WantParams & commandArgs)845 void AVSessionObserver::OnCommonCommand(const std::string& commonCommand, const AAFwk::WantParams& commandArgs)
846 {
847 std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
848 CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
849 proxy->HandleCommonCommand(commonCommand, commandArgs);
850 }
851 } // namespace OHOS::AVSession