• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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