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