• 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 "migrate_avsession_server.h"
17 
18 #include <chrono>
19 #include <thread>
20 
21 #include "audio_device_manager.h"
22 #include "avsession_errors.h"
23 #include "avsession_item.h"
24 #include "avsession_log.h"
25 #include "avsession_service.h"
26 #include "softbus/softbus_session_utils.h"
27 #include "migrate_avsession_constant.h"
28 #include "avsession_pixel_map_adapter.h"
29 #include "pixel_map.h"
30 #include "image_packer.h"
31 #include "avsession_event_handler.h"
32 
33 namespace OHOS::AVSession {
34 
RefreshDeviceId(std::string deviceId)35 void MigrateAVSessionServer::RefreshDeviceId(std::string deviceId)
36 {
37     SLOGI("migrate refresh deviceId from:%{public}s to %{public}s.",
38         SoftbusSessionUtils::AnonymizeDeviceId(deviceId_).c_str(),
39         SoftbusSessionUtils::AnonymizeDeviceId(deviceId).c_str());
40     deviceId_ = deviceId;
41 }
42 
LocalFrontSessionArrive(std::string & sessionId)43 void MigrateAVSessionServer::LocalFrontSessionArrive(std::string &sessionId)
44 {
45     if (sessionId.empty()) {
46         SLOGE("LocalFrontSessionArrive with sessionId EMPTY");
47         return;
48     }
49     lastSessionId_ = sessionId;
50     SLOGI("LocalFrontSessionArrive in:%{public}s.", AVSessionUtils::GetAnonySessionId(sessionId).c_str());
51     MigratePostTask(
52         [this, sessionId]() {
53             SLOGI("LocalFrontSessionArrive with sessionId:%{public}s.",
54                 AVSessionUtils::GetAnonySessionId(sessionId).c_str());
55             CreateController(sessionId);
56             sptr<AVControllerItem> controller = nullptr;
57             {
58                 std::lock_guard lockGuard(migrateControllerLock_);
59                 controller = playerIdToControllerMap_[sessionId];
60                 CHECK_AND_RETURN_LOG(controller != nullptr, "LocalFrontSessionArrive but get controller null");
61             }
62 
63             controller->isFromSession_ = false;
64             lastSessionId_ = sessionId;
65             if (isSoftbusConnecting_) {
66                 UpdateFrontSessionInfoToRemote(controller);
67             } else {
68                 SLOGE("LocalFrontSessionArrive without connect");
69             }
70             SLOGI("LocalFrontSessionArrive finish.");
71         },
72         "LocalFrontSessionChange");
73 }
74 
LocalFrontSessionChange(std::string & sessionId)75 void MigrateAVSessionServer::LocalFrontSessionChange(std::string &sessionId)
76 {
77     SLOGI("LocalFrontSessionChange in:%{public}s.", AVSessionUtils::GetAnonySessionId(sessionId).c_str());
78     std::lock_guard lockGuard(migrateControllerLock_);
79     sptr<AVControllerItem> controller = playerIdToControllerMap_[lastSessionId_];
80     if (controller != nullptr) {
81         controller->UnregisterAVControllerCallback();
82     } else {
83         SLOGE("LocalFrontSessionChange but get controller null");
84     }
85     ClearCacheBySessionId(lastSessionId_);
86     auto it = playerIdToControllerMap_.find(lastSessionId_);
87     if (it != playerIdToControllerMap_.end()) {
88         playerIdToControllerMap_.erase(it);
89     } else {
90         SLOGE("LocalFrontSessionChange no find sessionId:%{public}s",
91             AVSessionUtils::GetAnonySessionId(lastSessionId_).c_str());
92     }
93     lastSessionId_ = "";
94     LocalFrontSessionArrive(sessionId);
95 }
96 
LocalFrontSessionLeave(std::string & sessionId)97 void MigrateAVSessionServer::LocalFrontSessionLeave(std::string &sessionId)
98 {
99     SLOGI("LocalFrontSessionLeave in:%{public}s.", AVSessionUtils::GetAnonySessionId(sessionId).c_str());
100     lastSessionId_ = "";
101     MigratePostTask(
102         [this, sessionId]() {
103             std::lock_guard lockGuard(migrateControllerLock_);
104             sptr<AVControllerItem> controller = playerIdToControllerMap_[lastSessionId_];
105             if (controller != nullptr) {
106                 controller->UnregisterAVControllerCallback();
107             } else {
108                 SLOGE("LocalFrontSessionLeave but get controller null");
109             }
110             ClearCacheBySessionId(sessionId);
111             auto it = playerIdToControllerMap_.find(sessionId);
112             if (it != playerIdToControllerMap_.end()) {
113                 playerIdToControllerMap_.erase(it);
114             } else {
115                 SLOGE("LocalFrontSessionLeave no find sessionId:%{public}s",
116                     AVSessionUtils::GetAnonySessionId(sessionId).c_str());
117             }
118             UpdateEmptyInfoToRemote();
119             lastSessionId_ = "";
120             SLOGI("LocalFrontSessionLeave finish.");
121         },
122         "LocalFrontSessionChange");
123 }
124 
HandleFocusPlaybackStateChange(const std::string & sessionId,const AVPlaybackState & state)125 void MigrateAVSessionServer::HandleFocusPlaybackStateChange(const std::string &sessionId, const AVPlaybackState &state)
126 {
127     DoPlaybackStateSyncToRemote(state);
128 }
129 
HandleFocusMetaDataChange(const std::string & sessionId,const AVMetaData & data)130 void MigrateAVSessionServer::HandleFocusMetaDataChange(const std::string &sessionId, const AVMetaData &data)
131 {
132     std::shared_ptr<AVSessionPixelMap> innerPixelMap = data.GetMediaImage();
133     DoMetaDataSyncToRemote(data);
134     if (innerPixelMap != nullptr) {
135         DoMediaImageSyncToRemote(innerPixelMap);
136     }
137 }
138 
HandleFocusValidCommandChange(const std::string & sessionId,const std::vector<int32_t> & cmds)139 void MigrateAVSessionServer::HandleFocusValidCommandChange(const std::string &sessionId,
140     const std::vector<int32_t> &cmds)
141 {
142     DoValidCommandsSyncToRemote(cmds);
143 }
144 
DoMetaDataSyncToRemote(const AVMetaData & data)145 void MigrateAVSessionServer::DoMetaDataSyncToRemote(const AVMetaData& data)
146 {
147     std::lock_guard lockGuard(cacheJsonLock_);
148     bool needRefresh = false;
149     if (data.GetAssetId() != metaDataCache_.GetAssetId()) {
150         metaDataCache_.Reset();
151         metaDataCache_.SetAssetId(data.GetAssetId());
152         curAssetId_ = data.GetAssetId();
153         needRefresh = true;
154     }
155     if (data.GetMetaMask().test(AVMetaData::META_KEY_TITLE) && data.GetTitle() != metaDataCache_.GetTitle()) {
156         metaDataCache_.SetTitle(data.GetTitle());
157         needRefresh = true;
158     }
159     if (data.GetMetaMask().test(AVMetaData::META_KEY_ARTIST) && data.GetArtist() != metaDataCache_.GetArtist()) {
160         metaDataCache_.SetArtist(data.GetArtist());
161         needRefresh = true;
162     } else if (data.GetMetaMask().test(AVMetaData::META_KEY_SUBTITLE) &&
163         data.GetSubTitle() != metaDataCache_.GetArtist()) {
164         metaDataCache_.SetArtist(data.GetSubTitle());
165         needRefresh = true;
166     }
167     CHECK_AND_RETURN_LOG(needRefresh, "metadata no change");
168 
169     cJSON* metaDataItem = SoftbusSessionUtils::GetNewCJSONObject();
170     CHECK_AND_RETURN_LOG(metaDataItem != nullptr, "get metadata json with nullptr");
171     if (!SoftbusSessionUtils::AddStringToJson(metaDataItem, METADATA_TITLE, metaDataCache_.GetTitle().c_str())) {
172         SLOGE("AddStringToJson with title value:%{public}s fail", metaDataCache_.GetTitle().c_str());
173         cJSON_Delete(metaDataItem);
174         return;
175     }
176     if (!SoftbusSessionUtils::AddStringToJson(metaDataItem, METADATA_ARTIST, metaDataCache_.GetArtist().c_str())) {
177         SLOGE("AddStringToJson artist value:%{public}s fail", metaDataCache_.GetArtist().c_str());
178         cJSON_Delete(metaDataItem);
179         return;
180     }
181     if (!SoftbusSessionUtils::AddStringToJson(metaDataItem, METADATA_ASSET_ID, metaDataCache_.GetAssetId().c_str())) {
182         SLOGE("AddStringToJson assetId value:%{public}s fail", metaDataCache_.GetAssetId().c_str());
183         cJSON_Delete(metaDataItem);
184         return;
185     }
186 
187     std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_FOCUS_META_INFO});
188     SoftbusSessionUtils::TransferJsonToStr(metaDataItem, msg);
189     MigratePostTask(
190         [this, msg]() {
191             SendByteForNext(deviceId_, msg);
192         }, "SYNC_FOCUS_META_INFO");
193     SLOGI("DoMetaDataSyncToRemote async Title:%{public}s|len:%{public}d done",
194         metaDataCache_.GetTitle().c_str(), static_cast<int>(msg.size()));
195     cJSON_Delete(metaDataItem);
196 }
197 
DoMediaImageSyncToRemote(std::shared_ptr<AVSessionPixelMap> innerPixelMap)198 void MigrateAVSessionServer::DoMediaImageSyncToRemote(std::shared_ptr<AVSessionPixelMap> innerPixelMap)
199 {
200     CHECK_AND_RETURN_LOG(innerPixelMap != nullptr, "DoMediaImageSyncToRemote with innerPixelMap null");
201     std::vector<uint8_t> imgBuffer = innerPixelMap->GetInnerImgBuffer();
202     SLOGI("DoMediaImageSyncToRemote with img size:%{public}d", static_cast<int>(imgBuffer.size()));
203 
204     if (imgBuffer.size() <= 0) {
205         SLOGE("do mediaImg sync with emptyBuffer, return");
206         return;
207     }
208     std::shared_ptr<Media::PixelMap> pixelMap;
209     pixelMap = AVSessionPixelMapAdapter::ConvertFromInner(innerPixelMap);
210     CHECK_AND_RETURN_LOG(pixelMap != nullptr, "DoMediaImageSyncToRemote with pixelMap null");
211     std::shared_ptr<AVSessionPixelMap> innerPixelMapMin = AVSessionPixelMapAdapter::ConvertToInnerWithMinSize(pixelMap);
212     CHECK_AND_RETURN_LOG(innerPixelMapMin != nullptr, "DoMediaImageSyncToRemote with innerPixelMapMin null");
213     std::vector<uint8_t> imgBufferMin = innerPixelMapMin->GetInnerImgBuffer();
214     std::string assetIdForMediaImg = curAssetId_ + "|";
215     std::string imgStrMin(imgBufferMin.begin(), imgBufferMin.end());
216     std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_FOCUS_MEDIA_IMAGE});
217     msg += assetIdForMediaImg;
218     msg += imgStrMin;
219 
220     MigratePostTask(
221         [this, msg]() {
222             SendByteForNext(deviceId_, msg);
223         },
224         "SYNC_FOCUS_MEDIA_IMAGE");
225     SLOGI("DoMediaImageSyncToRemote async size:%{public}d", static_cast<int>(msg.size()));
226 }
227 
DoPlaybackStateSyncToRemote(const AVPlaybackState & state)228 void MigrateAVSessionServer::DoPlaybackStateSyncToRemote(const AVPlaybackState& state)
229 {
230     std::lock_guard lockGuard(cacheJsonLock_);
231     bool needRefresh = false;
232     if (state.GetMask().test(AVPlaybackState::PLAYBACK_KEY_STATE) &&
233         state.GetState() != playbackStateCache_.GetState()) {
234         playbackStateCache_.SetState(state.GetState());
235         needRefresh = true;
236     }
237     if (state.GetMask().test(AVPlaybackState::PLAYBACK_KEY_IS_FAVORITE) &&
238         state.GetFavorite() != playbackStateCache_.GetFavorite()) {
239         playbackStateCache_.SetFavorite(state.GetFavorite());
240         needRefresh = true;
241     }
242     CHECK_AND_RETURN_LOG(needRefresh, "playbackstate no change");
243 
244     cJSON* playbackStateItem = SoftbusSessionUtils::GetNewCJSONObject();
245     CHECK_AND_RETURN_LOG(playbackStateItem != nullptr, "get playbackState json with nullptr");
246     if (!SoftbusSessionUtils::AddIntToJson(playbackStateItem, PLAYBACK_STATE, playbackStateCache_.GetState())) {
247         SLOGE("AddStringToJson with state value:%{public}d fail", playbackStateCache_.GetState());
248         cJSON_Delete(playbackStateItem);
249         return;
250     }
251     if (!SoftbusSessionUtils::AddBoolToJson(playbackStateItem, FAVOR_STATE, playbackStateCache_.GetFavorite())) {
252         SLOGE("AddStringToJson with favor value:%{public}d fail", playbackStateCache_.GetFavorite());
253         cJSON_Delete(playbackStateItem);
254         return;
255     }
256 
257     std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_FOCUS_PLAY_STATE});
258     SoftbusSessionUtils::TransferJsonToStr(playbackStateItem, msg);
259     MigratePostTask(
260         [this, msg]() {
261             SendByteForNext(deviceId_, msg);
262         }, "SYNC_FOCUS_PLAY_STATE");
263     SLOGI("DoPlaybackStateSyncToRemote sync state:%{public}d|Favor:%{public}d|len:%{public}d done.",
264         playbackStateCache_.GetState(), playbackStateCache_.GetFavorite(), static_cast<int>(msg.size()));
265     cJSON_Delete(playbackStateItem);
266 }
267 
DoValidCommandsSyncToRemote(const std::vector<int32_t> & commands)268 void MigrateAVSessionServer::DoValidCommandsSyncToRemote(const std::vector<int32_t>& commands)
269 {
270     cJSON* validCommands = SoftbusSessionUtils::GetNewCJSONObject();
271     CHECK_AND_RETURN_LOG(validCommands != nullptr, "get validCommands json with nullptr");
272     std::string commandsStr;
273     for (int32_t cmd : commands) {
274         commandsStr.push_back(static_cast<char>(cmd + '0'));
275     }
276     if (!SoftbusSessionUtils::AddStringToJson(validCommands, VALID_COMMANDS, commandsStr.c_str())) {
277         SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail", VALID_COMMANDS, commandsStr.c_str());
278         cJSON_Delete(validCommands);
279         return;
280     }
281 
282     std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_FOCUS_VALID_COMMANDS});
283     SoftbusSessionUtils::TransferJsonToStr(validCommands, msg);
284     MigratePostTask(
285         [this, msg]() {
286             SendByteForNext(deviceId_, msg);
287         },
288         "SYNC_FOCUS_VALID_COMMANDS");
289     SLOGI("DoValidCommandsSyncToRemote async commands num:%{public}d|content:%{public}s|len:%{public}d done",
290         static_cast<int>(commands.size()), commandsStr.c_str(), static_cast<int>(msg.size()));
291     cJSON_Delete(validCommands);
292 }
293 
DoBundleInfoSyncToRemote(sptr<AVControllerItem> controller)294 void MigrateAVSessionServer::DoBundleInfoSyncToRemote(sptr<AVControllerItem> controller)
295 {
296     CHECK_AND_RETURN_LOG(controller != nullptr, "DoBundleInfoSyncToRemote with controller null");
297     AppExecFwk::ElementName elementName = controller->GetElementOfSession();
298     std::string bundleName = elementName.GetBundleName();
299     std::string abilityName = elementName.GetAbilityName();
300     std::string iconStr;
301     if (!BundleStatusAdapter::GetInstance().GetBundleIcon(bundleName, abilityName, iconStr)) {
302         SLOGE("DoBundleInfoSyncToRemote get bundle icon fail for bundleName:%{public}s", bundleName.c_str());
303     }
304 
305     uint32_t errorCode = 0;
306     Media::SourceOptions opts;
307     auto imageSource = Media::ImageSource::CreateImageSource(reinterpret_cast<const uint8_t*>(iconStr.c_str()),
308         iconStr.length(), opts, errorCode);
309     CHECK_AND_RETURN_LOG(imageSource != nullptr,
310         "DoBundleInfoSyncToRemote CreateImageSource fail for bundleName:%{public}s", bundleName.c_str());
311     Media::DecodeOptions decodeOpts;
312     decodeOpts.allocatorType = Media::AllocatorType::HEAP_ALLOC;
313     std::shared_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
314     CHECK_AND_RETURN_LOG(pixelMap != nullptr,
315         "DoBundleInfoSyncToRemote CreatePixelMap fail for bundleName:%{public}s", bundleName.c_str());
316 
317     std::shared_ptr<AVSessionPixelMap> innerPixelMapMin = AVSessionPixelMapAdapter::ConvertToInnerWithMinSize(pixelMap);
318     CHECK_AND_RETURN_LOG(innerPixelMapMin != nullptr, "DoBundleInfoSyncToRemote with innerPixelMapMin null");
319     std::vector<uint8_t> imgBufferMin = innerPixelMapMin->GetInnerImgBuffer();
320     std::string imgStrMin(imgBufferMin.begin(), imgBufferMin.end());
321     std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_FOCUS_BUNDLE_IMG});
322     msg += imgStrMin;
323 
324     MigratePostTask(
325         [this, msg]() {
326             SendByteForNext(deviceId_, msg);
327         },
328         "SYNC_FOCUS_BUNDLE_IMG");
329     SLOGI("DoBundleInfoSyncToRemote async size:%{public}d", static_cast<int>(msg.size()));
330 }
331 
UpdateFrontSessionInfoToRemote(sptr<AVControllerItem> controller)332 void MigrateAVSessionServer::UpdateFrontSessionInfoToRemote(sptr<AVControllerItem> controller)
333 {
334     CHECK_AND_RETURN_LOG(controller != nullptr, "UpdateFrontSessionInfoToRemote get controller null");
335     SLOGI("UpdateFrontSessionInfoToRemote with sessionId clearCache:%{public}s",
336         AVSessionUtils::GetAnonySessionId(controller->GetSessionId()).c_str());
337 
338     UpdateSessionInfoToRemote(controller);
339     {
340         std::lock_guard lockGuard(cacheJsonLock_);
341         metaDataCache_.Reset();
342         playbackStateCache_.SetState(0);
343         playbackStateCache_.SetFavorite(0);
344     }
345     AVMetaData metaData;
346     int32_t ret = controller->GetAVMetaData(metaData);
347     if (AVSESSION_SUCCESS == ret || ERR_INVALID_PARAM == ret) {
348         DoMetaDataSyncToRemote(metaData);
349         std::shared_ptr<AVSessionPixelMap> innerPixelMap = metaData.GetMediaImage();
350         if (innerPixelMap != nullptr) {
351             DoMediaImageSyncToRemote(innerPixelMap);
352         }
353     } else {
354         SLOGE("UpdateFrontSessionInfoToRemote get metadata fail:%{public}d", ret);
355     }
356 
357     AVPlaybackState playbackState;
358     ret = controller->GetAVPlaybackState(playbackState);
359     if (AVSESSION_SUCCESS == ret) {
360         DoPlaybackStateSyncToRemote(playbackState);
361     } else {
362         SLOGE("UpdateFrontSessionInfoToRemote get playbackstate fail:%{public}d", ret);
363     }
364 
365     std::vector<int32_t> commands;
366     controller->GetValidCommands(commands);
367     DoValidCommandsSyncToRemote(commands);
368     DoBundleInfoSyncToRemote(controller);
369     SLOGI("UpdateFrontSessionInfoToRemote done");
370 }
371 
UpdateSessionInfoToRemote(sptr<AVControllerItem> controller)372 void MigrateAVSessionServer::UpdateSessionInfoToRemote(sptr<AVControllerItem> controller)
373 {
374     CHECK_AND_RETURN_LOG(controller != nullptr, "controller get nullptr");
375     cJSON* sessionInfo = SoftbusSessionUtils::GetNewCJSONObject();
376     CHECK_AND_RETURN_LOG(sessionInfo != nullptr, "get sessionInfo json with nullptr");
377     if (!SoftbusSessionUtils::AddStringToJson(sessionInfo, MIGRATE_SESSION_ID, controller->GetSessionId().c_str())) {
378         SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail",
379             MIGRATE_SESSION_ID, controller->GetSessionId().c_str());
380         cJSON_Delete(sessionInfo);
381         return;
382     }
383     AppExecFwk::ElementName elementName = controller->GetElementOfSession();
384     std::string bundleNameForMigrate = elementName.GetBundleName() + "|" + controller->GetSessionType();
385     if (!SoftbusSessionUtils::AddStringToJson(sessionInfo, MIGRATE_BUNDLE_NAME, bundleNameForMigrate.c_str())) {
386         SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail",
387             MIGRATE_BUNDLE_NAME, bundleNameForMigrate.c_str());
388         cJSON_Delete(sessionInfo);
389         return;
390     }
391     if (!SoftbusSessionUtils::AddStringToJson(sessionInfo, MIGRATE_ABILITY_NAME,
392         elementName.GetAbilityName().c_str())) {
393         SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail",
394             MIGRATE_ABILITY_NAME, elementName.GetAbilityName().c_str());
395         cJSON_Delete(sessionInfo);
396         return;
397     }
398 
399     std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_FOCUS_SESSION_INFO});
400     SoftbusSessionUtils::TransferJsonToStr(sessionInfo, msg);
401     MigratePostTask(
402         [this, msg]() {
403             SendByteForNext(deviceId_, msg);
404         },
405         "SYNC_FOCUS_SESSION_INFO");
406     cJSON_Delete(sessionInfo);
407 }
408 
UpdateEmptyInfoToRemote()409 void MigrateAVSessionServer::UpdateEmptyInfoToRemote()
410 {
411     SLOGI("UpdateEmptyInfoToRemote in async");
412     cJSON* sessionInfo = SoftbusSessionUtils::GetNewCJSONObject();
413     CHECK_AND_RETURN_LOG(sessionInfo != nullptr, "get sessionInfo json with nullptr");
414     if (!SoftbusSessionUtils::AddStringToJson(sessionInfo, MIGRATE_SESSION_ID, EMPTY_SESSION)) {
415         SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail",
416             MIGRATE_SESSION_ID, EMPTY_SESSION);
417         cJSON_Delete(sessionInfo);
418         return;
419     }
420 
421     std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_FOCUS_SESSION_INFO});
422     SoftbusSessionUtils::TransferJsonToStr(sessionInfo, msg);
423     MigratePostTask(
424         [this, msg]() {
425             SendByteForNext(deviceId_, msg);
426         },
427         "SYNC_FOCUS_SESSION_INFO");
428     cJSON_Delete(sessionInfo);
429 }
430 
ProcFromNext(const std::string & deviceId,const std::string & data)431 void MigrateAVSessionServer::ProcFromNext(const std::string &deviceId, const std::string &data)
432 {
433     if (data.length() <= MSG_HEAD_LENGTH) {
434         SLOGE("ProcFromNext with data too short:%{public}s", data.c_str());
435         return;
436     }
437     int32_t messageType = data[1];
438     std::string commandStr = data.substr(MSG_HEAD_LENGTH);
439     cJSON* commandJsonValue = nullptr;
440     if (!SoftbusSessionUtils::TransferStrToJson(commandStr, commandJsonValue)) {
441         SLOGE("ProcFromNext parse json fail");
442         return;
443     }
444 
445     switch (messageType) {
446         case SYNC_COMMAND:
447             ProcControlCommandFromNext(commandJsonValue);
448             break;
449         case SYNC_SET_VOLUME_COMMAND:
450             VolumeControlCommand(commandJsonValue);
451             break;
452         case SYNC_SWITCH_AUDIO_DEVICE_COMMAND:
453             SwitchAudioDeviceCommand(commandJsonValue);
454             break;
455         case COLD_START:
456             ProcessColdStartFromNext(commandJsonValue);
457             break;
458         case SYNC_MEDIA_CONTROL_NEED_STATE:
459             ProcessMediaControlNeedStateFromNext(commandJsonValue);
460             break;
461         default:
462             SLOGE("messageType %{public}d not support", messageType);
463             break;
464     }
465     cJSON_Delete(commandJsonValue);
466 }
467 
ProcControlCommandFromNext(cJSON * commandJsonValue)468 void MigrateAVSessionServer::ProcControlCommandFromNext(cJSON* commandJsonValue)
469 {
470     if (commandJsonValue == nullptr || cJSON_IsInvalid(commandJsonValue) || cJSON_IsNull(commandJsonValue)) {
471         SLOGE("get commandJsonValue invalid");
472         return;
473     }
474 
475     int32_t commandCode = -1;
476     std::string commandArgs;
477     if (cJSON_HasObjectItem(commandJsonValue, COMMAND_CODE)) {
478         commandCode = SoftbusSessionUtils::GetIntFromJson(commandJsonValue, COMMAND_CODE);
479     }
480     if (cJSON_HasObjectItem(commandJsonValue, COMMAND_ARGS)) {
481         commandArgs = SoftbusSessionUtils::GetStringFromJson(commandJsonValue, COMMAND_ARGS);
482     }
483 
484     sptr<AVControllerItem> controller = nullptr;
485     {
486         std::lock_guard lockGuard(migrateControllerLock_);
487         controller = playerIdToControllerMap_[lastSessionId_];
488         CHECK_AND_RETURN_LOG(controller != nullptr, "ProcControlCommandFromNext but get controller null");
489     }
490     AVControlCommand command;
491     if (AVSESSION_SUCCESS != command.SetCommand(commandCode)) {
492         SLOGE("ProcControlCommandFromNext parse invalid command type:%{public}d", commandCode);
493         return;
494     }
495     if (commandCode == AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE) {
496         commandArgs = (commandArgs.empty() || commandArgs == DEFAULT_STRING) ? curAssetId_ : commandArgs;
497         command.SetAssetId(commandArgs);
498         SLOGI("ProcControlCommandFromNext toggle fav for:%{public}s", commandArgs.c_str());
499     }
500     controller->SendControlCommand(command);
501     SLOGI("ProcNextCommand code:%{public}d done", commandCode);
502 }
503 
ProcessColdStartFromNext(cJSON * commandJsonValue)504 void MigrateAVSessionServer::ProcessColdStartFromNext(cJSON* commandJsonValue)
505 {
506     if (commandJsonValue == nullptr || cJSON_IsInvalid(commandJsonValue) || cJSON_IsNull(commandJsonValue)) {
507         SLOGE("get commandJsonValue invalid");
508         return;
509     }
510 
511     std::string bundleName;
512     if (cJSON_HasObjectItem(commandJsonValue, MIGRATE_BUNDLE_NAME)) {
513         bundleName = SoftbusSessionUtils::GetStringFromJson(commandJsonValue, MIGRATE_BUNDLE_NAME);
514     }
515     SLOGI("ProcessColdStartFromNext with bundleName:%{public}s", bundleName.c_str());
516     CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "ProcessColdStartFromNext without servicePtr, return");
517     AVControlCommand cmd;
518     cmd.SetCommand(AVControlCommand::SESSION_CMD_PLAY);
519     servicePtr_->SendSystemControlCommand(cmd);
520 }
521 
ProcessMediaControlNeedStateFromNext(cJSON * commandJsonValue)522 void MigrateAVSessionServer::ProcessMediaControlNeedStateFromNext(cJSON* commandJsonValue)
523 {
524     if (commandJsonValue == nullptr || cJSON_IsInvalid(commandJsonValue) || cJSON_IsNull(commandJsonValue)) {
525         SLOGE("get commandJsonValue invalid");
526         return;
527     }
528 
529     if (cJSON_HasObjectItem(commandJsonValue, NEED_STATE)) {
530         bool newListenerSetState = SoftbusSessionUtils::GetBoolFromJson(commandJsonValue, NEED_STATE);
531         if (!isNeedByRemote.load() && newListenerSetState) {
532             SLOGI("isNeed refresh data");
533             isNeedByRemote.store(true);
534             LocalFrontSessionArrive(lastSessionId_);
535             TriggerAudioCallback();
536         } else {
537             isNeedByRemote.store(newListenerSetState);
538         }
539     }
540     SLOGI("isNeedSet:%{public}d", isNeedByRemote.load());
541 }
542 
GetVolumeKeyEventCallbackFunc()543 std::function<void(int32_t)> MigrateAVSessionServer::GetVolumeKeyEventCallbackFunc()
544 {
545     return [this](int32_t volumeNum) {
546         std::lock_guard lockGuard(migrateDeviceChangeLock_);
547         cJSON* value = SoftbusSessionUtils::GetNewCJSONObject();
548         CHECK_AND_RETURN_LOG(value != nullptr, "get value json with nullptr");
549         std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_SET_VOLUME_COMMAND});
550         if (!SoftbusSessionUtils::AddIntToJson(value, AUDIO_VOLUME, volumeNum)) {
551             SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail", AUDIO_VOLUME, volumeNum);
552             cJSON_Delete(value);
553             return;
554         }
555 
556         SoftbusSessionUtils::TransferJsonToStr(value, msg);
557         SLOGI("server send set volume num async:%{public}d", volumeNum);
558         MigratePostTask(
559             [this, msg]() {
560                 SendByteForNext(deviceId_, msg);
561             },
562             "SYNC_SET_VOLUME_COMMAND");
563         cJSON_Delete(value);
564     };
565 }
566 
GetAvailableDeviceChangeCallbackFunc()567 AudioDeviceDescriptorsCallbackFunc MigrateAVSessionServer::GetAvailableDeviceChangeCallbackFunc()
568 {
569     return [this](const AudioDeviceDescriptors& devices) {
570         std::lock_guard lockGuard(migrateDeviceChangeLock_);
571         cJSON* value = ConvertAudioDeviceDescriptorsToJson(devices);
572         CHECK_AND_RETURN_LOG(value != nullptr, "get value json with nullptr");
573         if (cJSON_IsInvalid(value) || cJSON_IsNull(value)) {
574             SLOGE("get value from ConvertAudioDeviceDescriptorsToJson invalid");
575             cJSON_Delete(value);
576             return;
577         }
578         std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_AVAIL_DEVICES_LIST});
579         SoftbusSessionUtils::TransferJsonToStr(value, msg);
580         SLOGI("server send get available device change callback async");
581         MigratePostTask(
582             [this, msg]() {
583                 SendJsonStringByte(deviceId_, msg);
584             },
585             "SYNC_AVAIL_DEVICES_LIST");
586         cJSON_Delete(value);
587     };
588 }
589 
GetPreferredDeviceChangeCallbackFunc()590 AudioDeviceDescriptorsCallbackFunc MigrateAVSessionServer::GetPreferredDeviceChangeCallbackFunc()
591 {
592     return [this](const AudioDeviceDescriptors& devices) {
593         std::lock_guard lockGuard(migrateDeviceChangeLock_);
594         cJSON* value = ConvertAudioDeviceDescriptorsToJson(devices);
595         CHECK_AND_RETURN_LOG(value != nullptr, "get value json with nullptr");
596         if (cJSON_IsInvalid(value) || cJSON_IsNull(value)) {
597             SLOGE("get value from ConvertAudioDeviceDescriptorsToJson invalid");
598             cJSON_Delete(value);
599             return;
600         }
601         std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_CURRENT_DEVICE});
602         SoftbusSessionUtils::TransferJsonToStr(value, msg);
603         SLOGI("server send get preferred device change callback async");
604         MigratePostTask(
605             [this, msg]() {
606                 SendJsonStringByte(deviceId_, msg);
607             },
608             "SYNC_CURRENT_DEVICE");
609         volumeKeyEventCallbackFunc_(AudioAdapter::GetInstance().GetVolume());
610         cJSON_Delete(value);
611     };
612 }
613 
ConvertAudioDeviceDescriptorsToJson(const AudioDeviceDescriptors & devices)614 cJSON* MigrateAVSessionServer::ConvertAudioDeviceDescriptorsToJson(
615     const AudioDeviceDescriptors& devices)
616 {
617     cJSON* jsonArray = SoftbusSessionUtils::GetNewCJSONArray();
618     CHECK_AND_RETURN_RET_LOG(jsonArray != nullptr, nullptr, "get jsonArray with nullptr");
619 
620     int32_t deviceNum = 0;
621     for (auto& device : devices) {
622         if (device == nullptr) {
623             continue;
624         }
625         cJSON* jsonObject = ConvertAudioDeviceDescriptorToJson(device);
626         cJSON_InsertItemInArray(jsonArray, deviceNum++, jsonObject);
627     }
628     cJSON* jsonData = SoftbusSessionUtils::GetNewCJSONObject();
629     if (jsonData == nullptr) {
630         SLOGE("get jsonData json with nullptr");
631         cJSON_Delete(jsonArray);
632         return nullptr;
633     }
634     if (!SoftbusSessionUtils::AddJsonArrayToJson(jsonData, MEDIA_AVAILABLE_DEVICES_LIST, jsonArray)) {
635         SLOGE("add jsonArray into jsonData fail");
636         cJSON_Delete(jsonData);
637         return nullptr;
638     }
639 
640     return jsonData;
641 }
642 
ConvertAudioDeviceDescriptorToJson(const AudioDeviceDescriptorWithSptr & desc)643 cJSON* MigrateAVSessionServer::ConvertAudioDeviceDescriptorToJson(
644     const AudioDeviceDescriptorWithSptr& desc)
645 {
646     cJSON* device = SoftbusSessionUtils::GetNewCJSONObject();
647     CHECK_AND_RETURN_RET_LOG(device != nullptr, nullptr, "get device with nullptr");
648     CHECK_AND_RETURN_RET_LOG(desc != nullptr, nullptr, "get desc with nullptr");
649 
650     if (!SoftbusSessionUtils::AddIntToJson(device, AUDIO_DEVICE_TYPE, static_cast<int32_t>(desc->deviceType_))) {
651         SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail",
652             AUDIO_DEVICE_TYPE, static_cast<int32_t>(desc->deviceType_));
653         cJSON_Delete(device);
654         return nullptr;
655     }
656     if (!SoftbusSessionUtils::AddStringToJson(device, AUDIO_MAC_ADDRESS, desc->macAddress_)) {
657         SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail",
658             AUDIO_MAC_ADDRESS, AVSessionUtils::GetAnonySessionId(desc->macAddress_).c_str());
659         cJSON_Delete(device);
660         return nullptr;
661     }
662     if (!SoftbusSessionUtils::AddStringToJson(device, AUDIO_NETWORK_ID, desc->networkId_)) {
663         SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail",
664             AUDIO_NETWORK_ID, AVSessionUtils::GetAnonySessionId(desc->networkId_).c_str());
665         cJSON_Delete(device);
666         return nullptr;
667     }
668     if (!SoftbusSessionUtils::AddIntToJson(device, AUDIO_DEVICE_ROLE, static_cast<int32_t>(desc->deviceRole_))) {
669         SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail",
670             AUDIO_DEVICE_ROLE, static_cast<int32_t>(desc->deviceRole_));
671         cJSON_Delete(device);
672         return nullptr;
673     }
674     if (!SoftbusSessionUtils::AddIntToJson(device, AUDIO_DEVICE_CATEGORY,
675         static_cast<int32_t>(desc->deviceCategory_))) {
676         SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail",
677             AUDIO_DEVICE_CATEGORY, static_cast<int32_t>(desc->deviceCategory_));
678         cJSON_Delete(device);
679         return nullptr;
680     }
681     if (!SoftbusSessionUtils::AddStringToJson(device, AUDIO_DEVICE_NAME, desc->deviceName_)) {
682         SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail",
683             AUDIO_DEVICE_NAME, desc->deviceName_.c_str());
684         cJSON_Delete(device);
685         return nullptr;
686     }
687 
688     return device;
689 }
690 
VolumeControlCommand(cJSON * commandJsonValue)691 void MigrateAVSessionServer::VolumeControlCommand(cJSON* commandJsonValue)
692 {
693     if (commandJsonValue == nullptr || cJSON_IsInvalid(commandJsonValue) || cJSON_IsNull(commandJsonValue)) {
694         SLOGE("get commandJsonValue invalid");
695         return;
696     }
697 
698     SLOGI("server recv in VolumeControlCommand case");
699     if (!cJSON_HasObjectItem(commandJsonValue, AUDIO_VOLUME)) {
700         SLOGE("json parse with error member");
701         return;
702     }
703 
704     int32_t audioVolume = SoftbusSessionUtils::GetIntFromJson(commandJsonValue, AUDIO_VOLUME);
705     AudioAdapter::GetInstance().SetVolume(audioVolume);
706 }
707 
SwitchAudioDeviceCommand(cJSON * jsonObject)708 void MigrateAVSessionServer::SwitchAudioDeviceCommand(cJSON* jsonObject)
709 {
710     if (jsonObject == nullptr || cJSON_IsInvalid(jsonObject) || cJSON_IsNull(jsonObject)) {
711         SLOGE("get jsonObject invalid");
712         return;
713     }
714 
715     SLOGI("server recv in SwitchAudioDeviceCommand case");
716     int deviceCategory = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_CATEGORY);
717     int deviceType = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_TYPE);
718     int deviceRole = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_ROLE);
719     std::string networkId = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_NETWORK_ID);
720     std::string deviceName = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_DEVICE_NAME);
721     std::string macAddress = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_MAC_ADDRESS);
722 
723     std::shared_ptr<AudioDeviceDescriptor> device = std::make_shared<AudioDeviceDescriptor>();
724     CHECK_AND_RETURN_LOG(device != nullptr, "AudioDeviceDescriptor make shared_ptr is null");
725     device->deviceCategory_ = static_cast<AudioStandard::DeviceCategory>(deviceCategory);
726     device->deviceType_ = static_cast<AudioStandard::DeviceType>(deviceType);
727     device->deviceRole_ = static_cast<AudioStandard::DeviceRole>(deviceRole);
728     device->networkId_ = networkId;
729     device->deviceName_ = deviceName;
730     device->macAddress_ = macAddress;
731 
732     AudioAdapter::GetInstance().SelectOutputDevice(device);
733 }
734 
DoPostTasksClear()735 void MigrateAVSessionServer::DoPostTasksClear()
736 {
737     SLOGI("DoPostTasksClear for migrate:%{public}s", SoftbusSessionUtils::AnonymizeDeviceId(deviceId_).c_str());
738     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("LocalFrontSessionArrive");
739     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_FOCUS_MEDIA_IMAGE");
740     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_FOCUS_BUNDLE_IMG");
741     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_FOCUS_META_INFO");
742     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_FOCUS_PLAY_STATE");
743     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_FOCUS_VALID_COMMANDS");
744     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_FOCUS_SESSION_INFO");
745     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_SET_VOLUME_COMMAND");
746     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_AVAIL_DEVICES_LIST");
747     AVSessionEventHandler::GetInstance().AVSessionRemoveTask("SYNC_CURRENT_DEVICE");
748 }
749 
MigratePostTask(const AppExecFwk::EventHandler::Callback & callback,const std::string & name,int64_t delayTime)750 bool MigrateAVSessionServer::MigratePostTask(const AppExecFwk::EventHandler::Callback &callback,
751     const std::string &name, int64_t delayTime)
752 {
753     if (!isSoftbusConnecting_) {
754         SLOGE("MigratePostTask:%{public}s without connect", name.c_str());
755         return false;
756     }
757     SLOGD("MigratePostTask with name:%{public}s.", name.c_str());
758     if (!isNeedByRemote.load() && name != "LocalFrontSessionChange" && name != "SYNC_FOCUS_SESSION_INFO") {
759         SLOGI("no send task:%{public}s for no listen", name.c_str());
760         return false;
761     }
762     AVSessionEventHandler::GetInstance().AVSessionRemoveTask(name);
763     return AVSessionEventHandler::GetInstance().AVSessionPostTask(callback, name);
764 }
765 }
766 
767