mirror of
https://github.com/openharmony/multimedia_av_session.git
synced 2026-08-25 06:18:12 -04:00
b6b549003f
Signed-off-by: LiYimeng <liyimeng2@huawei.com> Co-Authored-By: Agent
1143 lines
44 KiB
C++
1143 lines
44 KiB
C++
/*
|
|
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <chrono>
|
|
#include <thread>
|
|
|
|
#include "migrate_avsession_proxy.h"
|
|
|
|
#include "avsession_log.h"
|
|
#include "avsession_utils.h"
|
|
#include "avsession_service.h"
|
|
#include "softbus/softbus_session_utils.h"
|
|
#include "int_wrapper.h"
|
|
#include "string_wrapper.h"
|
|
#include "bool_wrapper.h"
|
|
|
|
namespace OHOS::AVSession {
|
|
|
|
MigrateAVSessionProxy::MigrateAVSessionProxy(AVSessionService *ptr, int32_t mode, std::string deviceId)
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
|
|
SLOGI("migrateproxy construct with mode:%{public}d,localDevId:%{public}s.", mode,
|
|
SoftbusSessionUtils::AnonymizeDeviceId(deviceId).c_str());
|
|
mMode_ = mode;
|
|
servicePtr_ = ptr;
|
|
localDeviceId_ = deviceId;
|
|
}
|
|
|
|
MigrateAVSessionProxy::~MigrateAVSessionProxy()
|
|
{
|
|
if (checkConnectWorker_.joinable()) {
|
|
checkConnectWorker_.join();
|
|
}
|
|
SLOGI("MigrateAVSessionProxy destruct with disconnect process.");
|
|
OnDisconnectServer(deviceId_);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::SetUserId(int32_t userId)
|
|
{
|
|
userId_ = userId;
|
|
}
|
|
|
|
void MigrateAVSessionProxy::OnConnectServer(const std::string &deviceId)
|
|
{
|
|
SLOGI("MigrateAVSessionProxy OnConnectServer:%{public}s.",
|
|
SoftbusSessionUtils::AnonymizeDeviceId(deviceId).c_str());
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
|
|
deviceId_ = deviceId;
|
|
}
|
|
if (mMode_ == MSG_HEAD_MODE) {
|
|
OnConnectForSuper();
|
|
} else {
|
|
OnConnectForNext();
|
|
}
|
|
}
|
|
|
|
void MigrateAVSessionProxy::OnConnectForNext()
|
|
{
|
|
SendSpecialKeepAliveData();
|
|
PrepareSessionFromRemote();
|
|
CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "OnConnectServer find service ptr null!");
|
|
sptr<AVControllerItem> controller;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
controller = preSetController_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(controller != nullptr, "OnConnectServer find preSetController null!");
|
|
std::vector<sptr<IRemoteObject>> sessionControllers;
|
|
sessionControllers.push_back(controller);
|
|
servicePtr_->NotifyRemoteDistributedSessionControllersChanged(sessionControllers);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::OnDisconnectServer(const std::string &deviceId)
|
|
{
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
|
|
SLOGI("MigrateAVSessionProxy OnDisconnectServer:%{public}s.",
|
|
SoftbusSessionUtils::AnonymizeDeviceId(deviceId).c_str());
|
|
if (deviceId != deviceId_) {
|
|
SLOGE("proxy onDisconnect but not:%{public}s.", SoftbusSessionUtils::AnonymizeDeviceId(deviceId_).c_str());
|
|
return;
|
|
}
|
|
deviceId_ = "";
|
|
}
|
|
if (mMode_ == MSG_HEAD_MODE) {
|
|
OnDisconnectForSuper();
|
|
} else {
|
|
OnDisconnectForNext();
|
|
}
|
|
}
|
|
|
|
void MigrateAVSessionProxy::OnDisconnectForNext()
|
|
{
|
|
{
|
|
std::lock_guard<std::mutex> lock(keepAliveMtx_);
|
|
keepAliveCv_.notify_all();
|
|
}
|
|
if (keepAliveWorker_.joinable()) {
|
|
keepAliveWorker_.join();
|
|
}
|
|
std::vector<sptr<IRemoteObject>> sessionControllers;
|
|
CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "OnDisconnectServer find service ptr null!");
|
|
servicePtr_->NotifyRemoteDistributedSessionControllersChanged(sessionControllers);
|
|
ReleaseSessionFromRemote();
|
|
servicePtr_->NotifyRemoteBundleChange("");
|
|
elementName_.SetAbilityName("");
|
|
elementName_.SetBundleName("");
|
|
SLOGI("MigrateAVSessionProxy OnDisconnectServer complete");
|
|
}
|
|
|
|
int32_t MigrateAVSessionProxy::GetCharacteristic()
|
|
{
|
|
return mMode_;
|
|
}
|
|
|
|
//LCOV_EXCL_START
|
|
void MigrateAVSessionProxy::OnBytesReceived(const std::string &deviceId, const std::string &data)
|
|
{
|
|
if (mMode_ == MSG_HEAD_MODE) {
|
|
OnBytesRecvForSuper(deviceId, data);
|
|
} else {
|
|
OnBytesRecvForNext(deviceId, data);
|
|
}
|
|
}
|
|
|
|
void MigrateAVSessionProxy::OnBytesRecvForNext(const std::string &deviceId, const std::string &data)
|
|
{
|
|
CHECK_AND_RETURN_LOG(data.length() > MSG_HEAD_LENGTH, "OnBytesReceived too short to process");
|
|
int32_t infoType = data[1];
|
|
SLOGI("OnBytesReceived with infoType: %{public}d", infoType);
|
|
std::string jsonStr = data.substr(MSG_HEAD_LENGTH);
|
|
if (infoType == SYNC_FOCUS_MEDIA_IMAGE) {
|
|
ProcessMediaImage(jsonStr);
|
|
return;
|
|
} else if (infoType == SYNC_FOCUS_BUNDLE_IMG) {
|
|
ProcessBundleImg(jsonStr);
|
|
return;
|
|
}
|
|
cJSON* jsonValue = nullptr;
|
|
CHECK_AND_RETURN_LOG(SoftbusSessionUtils::TransferStrToJson(jsonStr, jsonValue), "OnBytes err parse json");
|
|
|
|
switch (infoType) {
|
|
case SYNC_PROTOCOL_VERSION:
|
|
ProcessProtocolVersion(jsonValue, deviceId);
|
|
break;
|
|
case SYNC_FOCUS_SESSION_INFO:
|
|
ProcessSessionInfo(jsonValue);
|
|
break;
|
|
case SYNC_FOCUS_META_INFO:
|
|
ProcessMetaData(jsonValue);
|
|
break;
|
|
case SYNC_FOCUS_PLAY_STATE:
|
|
ProcessPlaybackState(jsonValue);
|
|
break;
|
|
case SYNC_FOCUS_VALID_COMMANDS:
|
|
ProcessValidCommands(jsonValue);
|
|
break;
|
|
case SYNC_SET_VOLUME_COMMAND:
|
|
ProcessVolumeControlCommand(jsonValue);
|
|
break;
|
|
case SYNC_AVAIL_DEVICES_LIST:
|
|
ProcessAvailableDevices(jsonValue);
|
|
break;
|
|
case SYNC_CURRENT_DEVICE:
|
|
ProcessPreferredOutputDevice(jsonValue);
|
|
break;
|
|
case SYNC_LONG_PAUSE_NOTIFY:
|
|
ProcessLongPauseNotify(jsonValue);
|
|
break;
|
|
default:
|
|
SLOGE("OnBytesReceived with unknow infoType:%{public}d", infoType);
|
|
break;
|
|
}
|
|
if (jsonValue != nullptr) {
|
|
cJSON_Delete(jsonValue);
|
|
}
|
|
}
|
|
//LCOV_EXCL_STOP
|
|
|
|
void MigrateAVSessionProxy::HandlePlay()
|
|
{
|
|
SendControlCommandMsg(AVControlCommand::SESSION_CMD_PLAY, DEFAULT_STRING);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::HandlePause()
|
|
{
|
|
SendControlCommandMsg(AVControlCommand::SESSION_CMD_PAUSE, DEFAULT_STRING);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::HandlePlayNext()
|
|
{
|
|
SendControlCommandMsg(AVControlCommand::SESSION_CMD_PLAY_NEXT, DEFAULT_STRING);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::HandlePlayPrevious()
|
|
{
|
|
SendControlCommandMsg(AVControlCommand::SESSION_CMD_PLAY_PREVIOUS, DEFAULT_STRING);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::HandleToggleFavorite(const std::string& mediaId)
|
|
{
|
|
SendControlCommandMsg(AVControlCommand::SESSION_CMD_TOGGLE_FAVORITE, mediaId);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::HandleCommonCommand(const std::string& commonCommand, const AAFwk::WantParams& commandArgs)
|
|
{
|
|
SLOGI("HandleCommonCommand with command:%{public}s", commonCommand.c_str());
|
|
}
|
|
|
|
void MigrateAVSessionProxy::GetDistributedSessionControllerList(std::vector<sptr<IRemoteObject>>& controllerList)
|
|
{
|
|
if (mMode_ == MSG_HEAD_MODE) {
|
|
GetControllerListForSuper(controllerList);
|
|
} else {
|
|
GetControllerListForNext(controllerList);
|
|
}
|
|
}
|
|
|
|
void MigrateAVSessionProxy::GetControllerListForNext(std::vector<sptr<IRemoteObject>>& controllerList)
|
|
{
|
|
sptr<AVControllerItem> controller;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
controller = preSetController_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(controller != nullptr, "GetDistributedSessionControllerList with controller null");
|
|
controllerList.insert(controllerList.begin(), controller);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::PrepareSessionFromRemote()
|
|
{
|
|
SLOGI("PrepareSessionFromRemote in");
|
|
AVSessionDescriptor descriptor;
|
|
descriptor.sessionId_ = DEFAULT_STRING;
|
|
descriptor.sessionTag_ = DEFAULT_STRING;
|
|
descriptor.sessionType_ = AVSession::SESSION_TYPE_AUDIO;
|
|
descriptor.elementName_.SetBundleName(DEFAULT_STRING);
|
|
descriptor.elementName_.SetAbilityName(DEFAULT_STRING);
|
|
descriptor.isThirdPartyApp_ = false;
|
|
|
|
sptr<AVSessionItem> sessionItem = new(std::nothrow) AVSessionItem(descriptor);
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "create avsession but get nullptr");
|
|
sessionItem->SetPid(DEFAULT_NUM);
|
|
sessionItem->SetUid(DEFAULT_NUM);
|
|
|
|
OutputDeviceInfo outputDeviceInfo;
|
|
DeviceInfo deviceInfo;
|
|
deviceInfo.castCategory_ = AVCastCategory::CATEGORY_REMOTE;
|
|
deviceInfo.deviceId_ = DEFAULT_STRING;
|
|
deviceInfo.deviceName_ = DEFAULT_STRING;
|
|
outputDeviceInfo.deviceInfos_.emplace_back(deviceInfo);
|
|
sessionItem->SetOutputDevice(outputDeviceInfo);
|
|
|
|
std::weak_ptr<MigrateAVSessionProxy> migrateProxyWeak(shared_from_this());
|
|
std::shared_ptr<AVSessionObserver> callback =
|
|
std::make_shared<AVSessionObserver>(sessionItem->GetSessionId(), migrateProxyWeak);
|
|
sessionItem->RegisterAVSessionCallback(callback);
|
|
PrepareControllerOfRemoteSession(sessionItem);
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
remoteSession_ = sessionItem;
|
|
}
|
|
SLOGI("PrepareSessionFromRemote done");
|
|
}
|
|
|
|
void MigrateAVSessionProxy::PrepareControllerOfRemoteSession(sptr<AVSessionItem> sessionItem)
|
|
{
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "PrepareControllerOfRemoteSession with remote session null");
|
|
sptr<AVControllerItem> controller = new(std::nothrow) AVControllerItem(DEFAULT_NUM, sessionItem);
|
|
CHECK_AND_RETURN_LOG(controller != nullptr, "PrepareControllerOfRemoteSession with controller create null");
|
|
migrateProxyCallback_ = MigrateAVSessionProxyControllerCallback();
|
|
controller->RegisterMigrateAVSessionProxyCallback(migrateProxyCallback_);
|
|
sessionItem->AddController(DEFAULT_NUM, controller);
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
preSetController_ = controller;
|
|
}
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ReleaseSessionFromRemote()
|
|
{
|
|
SLOGI("ReleaseSessionFromRemote in");
|
|
ReleaseControllerOfRemoteSession();
|
|
sptr<AVSessionItem> sessionItem = nullptr;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
sessionItem = remoteSession_;
|
|
remoteSession_ = nullptr;
|
|
}
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "ReleaseSessionFromRemote with remoteSession null");
|
|
sessionItem->RegisterAVSessionCallback(nullptr);
|
|
sessionItem->DestroyTask();
|
|
SLOGI("ReleaseSessionFromRemote done.");
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ReleaseControllerOfRemoteSession()
|
|
{
|
|
sptr<AVControllerItem> controller;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
controller = preSetController_;
|
|
preSetController_ = nullptr;
|
|
}
|
|
CHECK_AND_RETURN_LOG(controller != nullptr, "ReleaseControllerOfRemoteSession with preSetController null");
|
|
controller->RegisterMigrateAVSessionProxyCallback(nullptr);
|
|
controller->DestroyWithoutReply();
|
|
SLOGI("ReleaseControllerOfRemoteSession done.");
|
|
}
|
|
|
|
const MigrateAVSessionProxyControllerCallbackFunc MigrateAVSessionProxy::MigrateAVSessionProxyControllerCallback()
|
|
{
|
|
return [this](const std::string& extraEvent, AAFwk::WantParams& extras) {
|
|
const auto& it = AUDIO_EVENT_MAPS.find(extraEvent);
|
|
if (it == AUDIO_EVENT_MAPS.end()) {
|
|
SLOGE("extraEvent %{public}s not support", extraEvent.c_str());
|
|
return ERR_COMMAND_NOT_SUPPORT;
|
|
}
|
|
switch (it->second) {
|
|
case AUDIO_NUM_SET_VOLUME:
|
|
SetVolume(extras);
|
|
break;
|
|
case AUDIO_NUM_SELECT_OUTPUT_DEVICE:
|
|
SelectOutputDevice(extras);
|
|
break;
|
|
case AUDIO_NUM_GET_VOLUME:
|
|
GetVolume(extras);
|
|
break;
|
|
case AUDIO_NUM_GET_AVAILABLE_DEVICES:
|
|
GetAvailableDevices(extras);
|
|
break;
|
|
case AUDIO_NUM_GET_PREFERRED_OUTPUT_DEVICE_FOR_RENDERER_INFO:
|
|
GetPreferredOutputDeviceForRendererInfo(extras);
|
|
break;
|
|
case SESSION_NUM_COLD_START_FROM_PROXY:
|
|
if (mMode_ == MSG_HEAD_MODE) {
|
|
ColdStartForSuper(extras);
|
|
} else {
|
|
ColdStartFromProxy();
|
|
}
|
|
break;
|
|
case SESSION_NUM_SET_MEDIACONTROL_NEED_STATE:
|
|
NotifyMediaControlNeedStateChange(extras);
|
|
break;
|
|
case SESSION_NUM_SET_MEDIACONTROL_SYNC_TIME:
|
|
NotifyMediaControlSyncTime(extras);
|
|
break;
|
|
case AUDIO_NUM_GET_VERSION:
|
|
GetVersion(extras);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return AVSESSION_SUCCESS;
|
|
};
|
|
}
|
|
|
|
void MigrateAVSessionProxy::SetVolume(const AAFwk::WantParams& extras)
|
|
{
|
|
SLOGI("proxy send in SetVolume case");
|
|
CHECK_AND_RETURN_LOG(extras.HasParam(AUDIO_SET_VOLUME), "extras not have event");
|
|
auto volume = extras.GetParam(AUDIO_SET_VOLUME);
|
|
AAFwk::IInteger* ao = AAFwk::IInteger::Query(volume);
|
|
CHECK_AND_RETURN_LOG(ao != nullptr, "extras have no value");
|
|
|
|
volumeNum_.store(OHOS::AAFwk::Integer::Unbox(ao));
|
|
cJSON* value = SoftbusSessionUtils::GetNewCJSONObject();
|
|
if (value == nullptr) {
|
|
SLOGE("get json value fail");
|
|
return;
|
|
}
|
|
if (!SoftbusSessionUtils::AddIntToJson(value, AUDIO_VOLUME, volumeNum_.load())) {
|
|
SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail", AUDIO_VOLUME, volumeNum_.load());
|
|
cJSON_Delete(value);
|
|
return;
|
|
}
|
|
std::string msg = std::string({mMode_, SYNC_SET_VOLUME_COMMAND});
|
|
SoftbusSessionUtils::TransferJsonToStr(value, msg);
|
|
cJSON_Delete(value);
|
|
SendByteForNext(deviceId_, msg);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::SelectOutputDevice(const AAFwk::WantParams& extras)
|
|
{
|
|
SLOGI("proxy send in SelectOutputDevice case");
|
|
CHECK_AND_RETURN_LOG(extras.HasParam(AUDIO_SELECT_OUTPUT_DEVICE), "extras not have event");
|
|
auto value = extras.GetParam(AUDIO_SELECT_OUTPUT_DEVICE);
|
|
AAFwk::IString* stringValue = AAFwk::IString::Query(value);
|
|
CHECK_AND_RETURN_LOG(stringValue != nullptr, "extras have no value");
|
|
|
|
std::string deviceValue = AAFwk::String::Unbox(stringValue);
|
|
std::string msg = std::string({mMode_, SYNC_SWITCH_AUDIO_DEVICE_COMMAND});
|
|
SendJsonStringByte(deviceId_, msg + deviceValue);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::GetVolume(AAFwk::WantParams& extras)
|
|
{
|
|
SLOGI("proxy send in GetVolume case");
|
|
extras.SetParam(AUDIO_GET_VOLUME, OHOS::AAFwk::Integer::Box(volumeNum_.load()));
|
|
}
|
|
|
|
void MigrateAVSessionProxy::GetAvailableDevices(AAFwk::WantParams& extras)
|
|
{
|
|
SLOGI("proxy send in GetAvailableDevices case");
|
|
cJSON* jsonData;
|
|
{
|
|
std::lock_guard<std::mutex> lock(devicesLock_);
|
|
jsonData = MigrateAVSessionServer::ConvertAudioDeviceDescriptorsToJson(availableDevices_);
|
|
}
|
|
CHECK_AND_RETURN_LOG(jsonData != nullptr, "get jsonData nullptr");
|
|
if (cJSON_IsInvalid(jsonData) || cJSON_IsNull(jsonData)) {
|
|
SLOGE("get jsonData invalid");
|
|
cJSON_Delete(jsonData);
|
|
return;
|
|
}
|
|
|
|
cJSON* jsonArray = cJSON_GetObjectItem(jsonData, MEDIA_AVAILABLE_DEVICES_LIST);
|
|
if (jsonArray == nullptr || cJSON_IsInvalid(jsonArray) || cJSON_IsNull(jsonArray)) {
|
|
SLOGE("get jsonArray invalid");
|
|
cJSON_Delete(jsonData);
|
|
return;
|
|
}
|
|
std::string jsonStr;
|
|
SoftbusSessionUtils::TransferJsonToStr(jsonArray, jsonStr);
|
|
if (jsonStr.empty()) {
|
|
SLOGE("get jsonStr empty");
|
|
cJSON_Delete(jsonData);
|
|
return;
|
|
}
|
|
extras.SetParam(AUDIO_GET_AVAILABLE_DEVICES, OHOS::AAFwk::String::Box(jsonStr));
|
|
cJSON_Delete(jsonData);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::GetPreferredOutputDeviceForRendererInfo(AAFwk::WantParams& extras)
|
|
{
|
|
SLOGI("proxy send in GetPreferredOutputDeviceForRendererInfo case");
|
|
cJSON* jsonData;
|
|
{
|
|
std::lock_guard<std::mutex> lock(devicesLock_);
|
|
jsonData = MigrateAVSessionServer::ConvertAudioDeviceDescriptorsToJson(preferredOutputDevice_);
|
|
}
|
|
CHECK_AND_RETURN_LOG(jsonData != nullptr, "get jsonData nullptr");
|
|
if (cJSON_IsInvalid(jsonData) || cJSON_IsNull(jsonData)) {
|
|
SLOGE("get jsonData invalid");
|
|
cJSON_Delete(jsonData);
|
|
return;
|
|
}
|
|
|
|
cJSON* jsonArray = cJSON_GetObjectItem(jsonData, MEDIA_AVAILABLE_DEVICES_LIST);
|
|
if (jsonArray == nullptr || cJSON_IsInvalid(jsonArray) || cJSON_IsNull(jsonArray)) {
|
|
SLOGE("get jsonArray invalid");
|
|
cJSON_Delete(jsonData);
|
|
return;
|
|
}
|
|
std::string jsonStr;
|
|
SoftbusSessionUtils::TransferJsonToStr(jsonArray, jsonStr);
|
|
if (jsonStr.empty()) {
|
|
SLOGE("get jsonStr empty");
|
|
cJSON_Delete(jsonData);
|
|
return;
|
|
}
|
|
extras.SetParam(AUDIO_GET_PREFERRED_OUTPUT_DEVICE_FOR_RENDERER_INFO, OHOS::AAFwk::String::Box(jsonStr));
|
|
cJSON_Delete(jsonData);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::GetVersion(AAFwk::WantParams& extras)
|
|
{
|
|
std::lock_guard<std::mutex> lock(versionMapMtx_);
|
|
auto it = deviceVersionMap_.find(deviceId_);
|
|
if (it != deviceVersionMap_.end()) {
|
|
SLOGI("GetVersion for device:%{public}s version:%{public}d", deviceId_.c_str(), it->second);
|
|
extras.SetParam(AUDIO_GET_VERSION, OHOS::AAFwk::Integer::Box(it->second));
|
|
} else {
|
|
SLOGI("GetVersion no version for device:%{public}s", deviceId_.c_str());
|
|
extras.SetParam(AUDIO_GET_VERSION, OHOS::AAFwk::Integer::Box(AVSESSION_DEFAULT_VERSION));
|
|
}
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ColdStartFromProxy()
|
|
{
|
|
SLOGI("proxy send in ColdStartFromProxy case with bundleName:%{public}s", elementName_.GetAbilityName().c_str());
|
|
std::string msg = std::string({mMode_, COLD_START});
|
|
|
|
cJSON* controlMsg = SoftbusSessionUtils::GetNewCJSONObject();
|
|
if (controlMsg == nullptr) {
|
|
SLOGE("get controlMsg fail");
|
|
return;
|
|
}
|
|
if (!SoftbusSessionUtils::AddStringToJson(controlMsg, MIGRATE_BUNDLE_NAME, elementName_.GetAbilityName())) {
|
|
SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail", MIGRATE_BUNDLE_NAME,
|
|
elementName_.GetAbilityName().c_str());
|
|
cJSON_Delete(controlMsg);
|
|
return;
|
|
}
|
|
|
|
SoftbusSessionUtils::TransferJsonToStr(controlMsg, msg);
|
|
SendByteForNext(deviceId_, msg);
|
|
cJSON_Delete(controlMsg);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessSessionInfo(cJSON* jsonValue)
|
|
{
|
|
sptr<AVSessionItem> sessionItem = nullptr;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
sessionItem = remoteSession_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "ProcessSessionInfo with remote session null");
|
|
if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
|
|
SLOGE("get jsonValue invalid");
|
|
return;
|
|
}
|
|
std::string bundleNameBef = elementName_.GetBundleName();
|
|
std::string bundleName = SoftbusSessionUtils::GetStringFromJson(jsonValue, MIGRATE_BUNDLE_NAME);
|
|
bundleName = bundleName.empty() ? DEFAULT_STRING : bundleName;
|
|
elementName_.SetBundleName(bundleName);
|
|
std::string abilityName = SoftbusSessionUtils::GetStringFromJson(jsonValue, MIGRATE_ABILITY_NAME);
|
|
abilityName = abilityName.empty() ? DEFAULT_STRING : abilityName;
|
|
elementName_.SetAbilityName(abilityName);
|
|
std::string sessionId = SoftbusSessionUtils::GetStringFromJson(jsonValue, MIGRATE_SESSION_ID);
|
|
sessionId = sessionId.empty() ? DEFAULT_STRING : sessionId;
|
|
if (sessionId.empty() || sessionId == DEFAULT_STRING || sessionId == EMPTY_SESSION) {
|
|
sessionItem->Deactivate();
|
|
elementName_.SetAbilityName(elementName_.GetBundleName());
|
|
elementName_.SetBundleName("");
|
|
} else {
|
|
sessionItem->Activate();
|
|
}
|
|
SLOGI("ProcessSessionInfo with sessionId:%{public}s|bundleName:%{public}s done.",
|
|
SoftbusSessionUtils::AnonymizeDeviceId(sessionId).c_str(), bundleName.c_str());
|
|
servicePtr_->NotifyRemoteBundleChange(elementName_.GetBundleName());
|
|
if (bundleNameBef != elementName_.GetBundleName()) {
|
|
AVPlaybackState playbackState;
|
|
playbackState.SetState(0);
|
|
playbackState.SetFavorite(false);
|
|
sessionItem->SetAVPlaybackState(playbackState);
|
|
|
|
AVMetaData metaData;
|
|
metaData.SetAssetId(DEFAULT_STRING);
|
|
metaData.SetWriter(bundleName);
|
|
metaData.SetTitle("");
|
|
metaData.SetArtist("");
|
|
metaData.SetPreviousAssetId("");
|
|
sessionItem->SetAVMetaData(metaData);
|
|
}
|
|
SendMediaControlNeedStateMsg();
|
|
}
|
|
|
|
bool MigrateAVSessionProxy::CheckMediaAlive()
|
|
{
|
|
return !elementName_.GetBundleName().empty();
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessMetaData(cJSON* jsonValue)
|
|
{
|
|
sptr<AVSessionItem> sessionItem = nullptr;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
sessionItem = remoteSession_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "ProcessMetaData with remote session null");
|
|
if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
|
|
SLOGE("get jsonValue invalid");
|
|
return;
|
|
}
|
|
AVMetaData metaData;
|
|
if (AVSESSION_SUCCESS != sessionItem->GetAVMetaData(metaData)) {
|
|
SLOGE("ProcessMetaData GetAVMetaData fail");
|
|
}
|
|
|
|
if (cJSON_HasObjectItem(jsonValue, METADATA_ASSET_ID)) {
|
|
std::string assetId = SoftbusSessionUtils::GetStringFromJson(jsonValue, METADATA_ASSET_ID);
|
|
if (assetId.empty()) {
|
|
assetId = DEFAULT_STRING;
|
|
}
|
|
std::string oldAsset = metaData.GetAssetId();
|
|
if (oldAsset != assetId) {
|
|
metaData.SetTitle("");
|
|
metaData.SetArtist("");
|
|
}
|
|
metaData.SetAssetId(assetId);
|
|
}
|
|
if (cJSON_HasObjectItem(jsonValue, METADATA_TITLE)) {
|
|
std::string title = SoftbusSessionUtils::GetStringFromJson(jsonValue, METADATA_TITLE);
|
|
if (title.empty()) {
|
|
title = DEFAULT_STRING;
|
|
}
|
|
metaData.SetTitle(title);
|
|
}
|
|
if (cJSON_HasObjectItem(jsonValue, METADATA_ARTIST)) {
|
|
std::string artist = SoftbusSessionUtils::GetStringFromJson(jsonValue, METADATA_ARTIST);
|
|
if (artist.empty()) {
|
|
artist = DEFAULT_STRING;
|
|
}
|
|
metaData.SetArtist(artist);
|
|
}
|
|
|
|
sessionItem->SetAVMetaData(metaData);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessPlaybackState(cJSON* jsonValue)
|
|
{
|
|
sptr<AVSessionItem> sessionItem = nullptr;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
sessionItem = remoteSession_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "ProcessPlaybackState with remote session null");
|
|
if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
|
|
SLOGE("get jsonValue invalid");
|
|
return;
|
|
}
|
|
|
|
AVPlaybackState playbackState;
|
|
if (AVSESSION_SUCCESS != sessionItem->GetAVPlaybackState(playbackState)) {
|
|
SLOGE("ProcessPlaybackState GetAVPlaybackState fail");
|
|
}
|
|
|
|
if (cJSON_HasObjectItem(jsonValue, PLAYBACK_STATE)) {
|
|
int state = SoftbusSessionUtils::GetIntFromJson(jsonValue, PLAYBACK_STATE);
|
|
playbackState.SetState(state);
|
|
}
|
|
if (cJSON_HasObjectItem(jsonValue, FAVOR_STATE)) {
|
|
int isFavor = SoftbusSessionUtils::GetBoolFromJson(jsonValue, FAVOR_STATE);
|
|
playbackState.SetFavorite(isFavor);
|
|
}
|
|
|
|
sessionItem->SetAVPlaybackState(playbackState);
|
|
SLOGI("ProcessPlaybackState set state:%{public}d | isFavor:%{public}d",
|
|
playbackState.GetState(), playbackState.GetFavorite());
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessValidCommands(cJSON* jsonValue)
|
|
{
|
|
sptr<AVSessionItem> sessionItem = nullptr;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
sessionItem = remoteSession_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "ProcessValidCommands with remote session null");
|
|
if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
|
|
SLOGE("get jsonValue invalid");
|
|
return;
|
|
}
|
|
|
|
std::vector<int32_t> commands;
|
|
if (cJSON_HasObjectItem(jsonValue, VALID_COMMANDS)) {
|
|
std::string commandsStr = SoftbusSessionUtils::GetStringFromJson(jsonValue, VALID_COMMANDS);
|
|
if (commandsStr.empty()) {
|
|
commandsStr = DEFAULT_STRING;
|
|
}
|
|
for (unsigned long i = 0; i < commandsStr.length(); i++) {
|
|
commands.insert(commands.begin(), static_cast<int>(commandsStr[i] - '0'));
|
|
}
|
|
sessionItem->SetSupportCommand(commands);
|
|
}
|
|
|
|
SLOGI("ProcessValidCommands set cmd size:%{public}d", static_cast<int>(commands.size()));
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessVolumeControlCommand(cJSON* jsonValue)
|
|
{
|
|
SLOGI("proxy recv in ProcessVolumeControlCommand case");
|
|
if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
|
|
SLOGE("get jsonValue invalid");
|
|
return;
|
|
}
|
|
|
|
if (!cJSON_HasObjectItem(jsonValue, AUDIO_VOLUME)) {
|
|
SLOGE("json parse with error member");
|
|
return;
|
|
}
|
|
|
|
int32_t volume = SoftbusSessionUtils::GetIntFromJson(jsonValue, AUDIO_VOLUME);
|
|
CHECK_AND_RETURN_LOG(volume >= 0, "Invalid volume value: %{public}d", volume);
|
|
volumeNum_.store(volume);
|
|
|
|
AAFwk::WantParams args;
|
|
args.SetParam(AUDIO_CALLBACK_VOLUME, OHOS::AAFwk::Integer::Box(volumeNum_.load()));
|
|
sptr<AVControllerItem> controller;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
controller = preSetController_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(controller != nullptr, "preSetController_ is nullptr");
|
|
controller->HandleSetSessionEvent(AUDIO_CALLBACK_VOLUME, args);
|
|
}
|
|
|
|
void DevicesJsonArrayToVector(cJSON* jsonArray, AudioDeviceDescriptors& devices)
|
|
{
|
|
if (jsonArray == nullptr || cJSON_IsInvalid(jsonArray) || !cJSON_IsArray(jsonArray)) {
|
|
SLOGE("get jsonArray invalid");
|
|
return;
|
|
}
|
|
devices.clear();
|
|
cJSON* jsonObject = nullptr;
|
|
cJSON_ArrayForEach(jsonObject, jsonArray) {
|
|
CHECK_AND_CONTINUE(jsonObject != nullptr && !cJSON_IsInvalid(jsonObject));
|
|
int deviceCategory = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_CATEGORY);
|
|
int deviceType = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_TYPE);
|
|
int deviceRole = SoftbusSessionUtils::GetIntFromJson(jsonObject, AUDIO_DEVICE_ROLE);
|
|
std::string networkId = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_NETWORK_ID);
|
|
std::string deviceName = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_DEVICE_NAME);
|
|
std::string macAddress = SoftbusSessionUtils::GetStringFromJson(jsonObject, AUDIO_MAC_ADDRESS);
|
|
|
|
std::shared_ptr<AudioDeviceDescriptor> device = std::make_shared<AudioDeviceDescriptor>();
|
|
CHECK_AND_RETURN_LOG(device != nullptr, "AudioDeviceDescriptor make shared_ptr is nullptr");
|
|
device->deviceCategory_ = static_cast<AudioStandard::DeviceCategory>(deviceCategory);
|
|
device->deviceType_ = static_cast<AudioStandard::DeviceType>(deviceType);
|
|
device->deviceRole_ = static_cast<AudioStandard::DeviceRole>(deviceRole);
|
|
device->networkId_ = networkId;
|
|
device->deviceName_ = deviceName;
|
|
device->macAddress_ = macAddress;
|
|
devices.push_back(device);
|
|
}
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessAvailableDevices(cJSON* jsonValue)
|
|
{
|
|
SLOGI("proxy recv in ProcessAvailableDevices case");
|
|
|
|
if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
|
|
SLOGE("get jsonValue invalid");
|
|
return;
|
|
}
|
|
CHECK_AND_RETURN_LOG(cJSON_HasObjectItem(jsonValue, MEDIA_AVAILABLE_DEVICES_LIST), "json parse with error member");
|
|
cJSON* jsonArray = cJSON_GetObjectItem(jsonValue, MEDIA_AVAILABLE_DEVICES_LIST);
|
|
CHECK_AND_RETURN_LOG(jsonArray != nullptr && !cJSON_IsInvalid(jsonArray) && cJSON_IsArray(jsonArray),
|
|
"json object is not array");
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lock(devicesLock_);
|
|
DevicesJsonArrayToVector(jsonArray, availableDevices_);
|
|
}
|
|
|
|
std::string jsonStr;
|
|
SoftbusSessionUtils::TransferJsonToStr(jsonArray, jsonStr);
|
|
AAFwk::WantParams args;
|
|
args.SetParam(AUDIO_CALLBACK_AVAILABLE_DEVICES, OHOS::AAFwk::String::Box(jsonStr));
|
|
sptr<AVControllerItem> controller;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
controller = preSetController_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(controller != nullptr, "preSetController_ is nullptr");
|
|
controller->HandleSetSessionEvent(AUDIO_CALLBACK_AVAILABLE_DEVICES, args);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessPreferredOutputDevice(cJSON* jsonValue)
|
|
{
|
|
SLOGI("proxy recv in ProcessPreferredOutputDevice case");
|
|
|
|
if (jsonValue == nullptr || cJSON_IsInvalid(jsonValue) || cJSON_IsNull(jsonValue)) {
|
|
SLOGE("get jsonValue invalid");
|
|
return;
|
|
}
|
|
CHECK_AND_RETURN_LOG(cJSON_HasObjectItem(jsonValue, MEDIA_AVAILABLE_DEVICES_LIST), "json parse with error member");
|
|
cJSON* jsonArray = cJSON_GetObjectItem(jsonValue, MEDIA_AVAILABLE_DEVICES_LIST);
|
|
CHECK_AND_RETURN_LOG(jsonArray != nullptr && !cJSON_IsInvalid(jsonArray) && cJSON_IsArray(jsonArray),
|
|
"json object is not array");
|
|
|
|
{
|
|
std::lock_guard<std::mutex> lock(devicesLock_);
|
|
DevicesJsonArrayToVector(jsonArray, preferredOutputDevice_);
|
|
}
|
|
|
|
std::string jsonStr;
|
|
SoftbusSessionUtils::TransferJsonToStr(jsonArray, jsonStr);
|
|
AAFwk::WantParams args;
|
|
args.SetParam(AUDIO_CALLBACK_PREFERRED_OUTPUT_DEVICE_FOR_RENDERER_INFO, OHOS::AAFwk::String::Box(jsonStr));
|
|
sptr<AVControllerItem> controller;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
controller = preSetController_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(controller != nullptr, "preSetController_ is nullptr");
|
|
controller->HandleSetSessionEvent(AUDIO_CALLBACK_PREFERRED_OUTPUT_DEVICE_FOR_RENDERER_INFO, args);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessBundleImg(std::string bundleIconStr)
|
|
{
|
|
sptr<AVSessionItem> sessionItem = nullptr;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
sessionItem = remoteSession_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "ProcessBundleImg with remote session null");
|
|
AVMetaData metaData;
|
|
if (AVSESSION_SUCCESS != sessionItem->GetAVMetaData(metaData)) {
|
|
SLOGE("ProcessBundleImg GetAVMetaData fail");
|
|
}
|
|
if (metaData.GetAssetId().empty()) {
|
|
metaData.SetAssetId(DEFAULT_STRING);
|
|
}
|
|
std::vector<uint8_t> imgVec(bundleIconStr.begin(), bundleIconStr.end());
|
|
if (imgVec.empty()) {
|
|
SLOGE("ProcessBundleImg with empty img, return");
|
|
return;
|
|
}
|
|
std::shared_ptr<AVSessionPixelMap> innerPixelMap = std::make_shared<AVSessionPixelMap>();
|
|
innerPixelMap->SetInnerImgBuffer(imgVec);
|
|
metaData.SetBundleIcon(innerPixelMap);
|
|
|
|
sessionItem->SetAVMetaData(metaData);
|
|
SLOGI("ProcessBundleImg set img size:%{public}d", static_cast<int>(metaData.GetBundleIcon() == nullptr ?
|
|
-1 : metaData.GetBundleIcon()->GetInnerImgBuffer().size()));
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessMediaImage(std::string mediaImageStr)
|
|
{
|
|
sptr<AVSessionItem> sessionItem = nullptr;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
sessionItem = remoteSession_;
|
|
}
|
|
CHECK_AND_RETURN_LOG(sessionItem != nullptr, "ProcessMediaImage with remote session null");
|
|
size_t insertPos = mediaImageStr.find('|');
|
|
CHECK_AND_RETURN_LOG(insertPos != std::string::npos && insertPos > 0 && insertPos < mediaImageStr.size(),
|
|
"mediaImgStr do not contain assetId, return");
|
|
std::string assetIdForMediaImg = mediaImageStr.substr(0, insertPos);
|
|
mediaImageStr.erase(0, insertPos + 1);
|
|
AVMetaData metaData;
|
|
if (AVSESSION_SUCCESS != sessionItem->GetAVMetaData(metaData)) {
|
|
SLOGE("ProcessMediaImage GetAVMetaData fail");
|
|
}
|
|
if (metaData.GetAssetId().empty()) {
|
|
metaData.SetAssetId(assetIdForMediaImg);
|
|
}
|
|
metaData.SetPreviousAssetId(assetIdForMediaImg);
|
|
std::vector<uint8_t> imgVec(mediaImageStr.begin(), mediaImageStr.end());
|
|
if (imgVec.empty()) {
|
|
metaData.SetMediaImageUri(DEFAULT_STRING);
|
|
metaData.SetMediaImage(nullptr);
|
|
} else {
|
|
std::shared_ptr<AVSessionPixelMap> innerPixelMap = std::make_shared<AVSessionPixelMap>();
|
|
innerPixelMap->SetInnerImgBuffer(imgVec);
|
|
metaData.SetMediaImageUri("");
|
|
metaData.SetMediaImage(innerPixelMap);
|
|
}
|
|
SLOGI("ProcessMediaImage set img size:%{public}d", static_cast<int>(metaData.GetMediaImage() == nullptr ?
|
|
-1 : metaData.GetMediaImage()->GetInnerImgBuffer().size()));
|
|
sessionItem->SetAVMetaData(metaData);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessProtocolVersion(cJSON* jsonValue, const std::string& deviceId)
|
|
{
|
|
SLOGI("Received protocol version from phone");
|
|
int32_t newVersion = SoftbusSessionUtils::GetIntFromJson(jsonValue, "protocolVersion");
|
|
|
|
bool versionChanged = false;
|
|
{
|
|
std::lock_guard<std::mutex> lock(versionMapMtx_);
|
|
auto it = deviceVersionMap_.find(deviceId);
|
|
if (it == deviceVersionMap_.end() || it->second != newVersion) {
|
|
versionChanged = true;
|
|
}
|
|
deviceVersionMap_[deviceId] = newVersion;
|
|
}
|
|
|
|
sptr<AVControllerItem> controller;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyRemoteSessionLock_);
|
|
controller = preSetController_;
|
|
}
|
|
if (versionChanged && controller != nullptr) {
|
|
AAFwk::WantParams args;
|
|
args.SetParam(AUDIO_GET_VERSION, OHOS::AAFwk::Integer::Box(newVersion));
|
|
controller->HandleSetSessionEvent(AUDIO_GET_VERSION, args);
|
|
SLOGI("Protocol version changed, notify controller");
|
|
}
|
|
}
|
|
|
|
void MigrateAVSessionProxy::ProcessLongPauseNotify(cJSON* jsonValue)
|
|
{
|
|
CHECK_AND_RETURN_LOG(servicePtr_ != nullptr, "servicePtr_ is nullptr");
|
|
bool isLongPause = SoftbusSessionUtils::GetBoolFromJson(jsonValue, LONG_PAUSE_STATE);
|
|
SLOGI("ProcessLongPauseNotify isLongPause:%{public}d", isLongPause);
|
|
int32_t event = isLongPause ? REMOTE_MEDIA_LONG_PAUSE : REMOTE_MEDIA_LONG_PAUSE_RESUME;
|
|
servicePtr_->PublishMediaControlState(event);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::SendControlCommandMsg(int32_t commandCode, std::string commandArgsStr)
|
|
{
|
|
SLOGI("SendControlCommandMsg with code:%{public}d", commandCode);
|
|
std::string msg = std::string({mMode_, SYNC_COMMAND});
|
|
|
|
cJSON* controlMsg = SoftbusSessionUtils::GetNewCJSONObject();
|
|
if (controlMsg == nullptr) {
|
|
SLOGE("get controlMsg fail");
|
|
return;
|
|
}
|
|
if (!SoftbusSessionUtils::AddIntToJson(controlMsg, COMMAND_CODE, commandCode)) {
|
|
SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail", COMMAND_CODE, commandCode);
|
|
cJSON_Delete(controlMsg);
|
|
return;
|
|
}
|
|
if (!SoftbusSessionUtils::AddStringToJson(controlMsg, COMMAND_ARGS, commandArgsStr)) {
|
|
SLOGE("AddStringToJson with key:%{public}s|value:%{public}s fail", COMMAND_ARGS, commandArgsStr.c_str());
|
|
cJSON_Delete(controlMsg);
|
|
return;
|
|
}
|
|
|
|
SoftbusSessionUtils::TransferJsonToStr(controlMsg, msg);
|
|
SendByteForNext(deviceId_, msg);
|
|
cJSON_Delete(controlMsg);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::SendMediaControlNeedStateMsg(bool isMock)
|
|
{
|
|
SLOGI("SendMediaControlNeedStateMsg with state:%{public}d|mock:%{public}d", isNeedByMediaControl.load(), isMock);
|
|
std::string msg = std::string({mMode_, SYNC_MEDIA_CONTROL_NEED_STATE});
|
|
|
|
cJSON* controlMsg = SoftbusSessionUtils::GetNewCJSONObject();
|
|
if (controlMsg == nullptr) {
|
|
SLOGE("get controlMsg fail");
|
|
return;
|
|
}
|
|
if (!SoftbusSessionUtils::AddBoolToJson(controlMsg, NEED_STATE, isMock ? true : isNeedByMediaControl.load())) {
|
|
SLOGE("AddBoolToJson with key:%{public}s|value:%{public}d fail", NEED_STATE, isNeedByMediaControl.load());
|
|
cJSON_Delete(controlMsg);
|
|
return;
|
|
}
|
|
|
|
SoftbusSessionUtils::TransferJsonToStr(controlMsg, msg);
|
|
SendByteForNext(deviceId_, msg);
|
|
cJSON_Delete(controlMsg);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::SendMediaControlSyncTime(int32_t timeoutMs)
|
|
{
|
|
SLOGI("SendMediaControlSyncTime with state:%{public}d|timeout:%{public}d",
|
|
isNeedByMediaControl.load(), timeoutMs);
|
|
std::string msg = std::string({MSG_HEAD_MODE_FOR_NEXT, SYNC_MEDIA_CONTROL_NEED_STATE});
|
|
|
|
cJSON* controlMsg = SoftbusSessionUtils::GetNewCJSONObject();
|
|
if (controlMsg == nullptr) {
|
|
SLOGE("get controlMsg fail");
|
|
return;
|
|
}
|
|
if (!SoftbusSessionUtils::AddIntToJson(controlMsg, AVSESSION_PROXY_CURRENT_VERSION, AVSESSION_PROXY_VERSION)) {
|
|
SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail",
|
|
AVSESSION_PROXY_CURRENT_VERSION, AVSESSION_PROXY_VERSION);
|
|
cJSON_Delete(controlMsg);
|
|
return;
|
|
}
|
|
if (!SoftbusSessionUtils::AddIntToJson(controlMsg, MEDIACONTROL_NEED_STATE_TIMEOUT_MS, timeoutMs)) {
|
|
SLOGE("AddIntToJson with key:%{public}s|value:%{public}d fail",
|
|
MEDIACONTROL_NEED_STATE_TIMEOUT_MS, timeoutMs);
|
|
cJSON_Delete(controlMsg);
|
|
return;
|
|
}
|
|
|
|
SoftbusSessionUtils::TransferJsonToStr(controlMsg, msg);
|
|
SendByteForNext(deviceId_, msg);
|
|
cJSON_Delete(controlMsg);
|
|
}
|
|
|
|
void MigrateAVSessionProxy::SendSpecialKeepAliveData()
|
|
{
|
|
checkConnectWorker_ = std::thread([this]() {
|
|
SendMediaControlNeedStateMsg(true);
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(CHECK_CONNECT_TIME_FOR_NEXT));
|
|
SendMediaControlNeedStateMsg();
|
|
if (volumeNum_.load() == DEFAULT_FAKE_VOLUME) {
|
|
SLOGE("no bytes recv aft connect, disconnect process");
|
|
std::string deviceIdSnapshot;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
|
|
deviceIdSnapshot = this->deviceId_;
|
|
}
|
|
OnDisconnectServer(deviceIdSnapshot);
|
|
} else {
|
|
SLOGI("volume recv aft connect:%{public}d", volumeNum_.load());
|
|
}
|
|
});
|
|
keepAliveWorker_ = std::thread([this]() {
|
|
bool isDeviceIdEmpty = false;
|
|
std::string deviceIdSnapshot;
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
|
|
isDeviceIdEmpty = this->deviceId_.empty();
|
|
deviceIdSnapshot = this->deviceId_;
|
|
}
|
|
while (!isDeviceIdEmpty) {
|
|
SLOGI("SendSpecialKeepAliveData for deviceId:%{public}s.",
|
|
SoftbusSessionUtils::AnonymizeDeviceId(deviceIdSnapshot).c_str());
|
|
std::string data = std::string({mMode_, SYNC_HEARTBEAT});
|
|
SendByteForNext(deviceIdSnapshot, data);
|
|
|
|
std::unique_lock<std::mutex> lock(keepAliveMtx_);
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
|
|
isDeviceIdEmpty = this->deviceId_.empty();
|
|
CHECK_AND_RETURN_LOG(!isDeviceIdEmpty, "SendSpecialKeepAliveData quit for deviceId empty");
|
|
}
|
|
if (!isNeedByMediaControl.load()) {
|
|
SLOGI("silent bytes waiting.");
|
|
keepAliveCv_.wait_for(lock, std::chrono::milliseconds(SILENT_HEART_BEAT_TIME_FOR_NEXT));
|
|
} else {
|
|
keepAliveCv_.wait_for(lock, std::chrono::milliseconds(HEART_BEAT_TIME_FOR_NEXT));
|
|
}
|
|
{
|
|
std::lock_guard lockGuard(migrateProxyDeviceIdLock_);
|
|
isDeviceIdEmpty = this->deviceId_.empty();
|
|
deviceIdSnapshot = this->deviceId_;
|
|
}
|
|
}
|
|
SLOGI("SendSpecialKeepAliveData exit.");
|
|
});
|
|
}
|
|
|
|
void MigrateAVSessionProxy::NotifyMediaControlNeedStateChange(AAFwk::WantParams& extras)
|
|
{
|
|
CHECK_AND_RETURN_LOG(extras.HasParam(MEDIACONTROL_NEED_STATE), "extras not have NeedState");
|
|
auto value = extras.GetParam(MEDIACONTROL_NEED_STATE);
|
|
AAFwk::IBoolean* boolValue = AAFwk::IBoolean::Query(value);
|
|
CHECK_AND_RETURN_LOG(boolValue != nullptr, "extras have no NeedState after query");
|
|
bool isNeed = OHOS::AAFwk::Boolean::Unbox(boolValue);
|
|
SLOGI("refresh NeedState:%{public}d", isNeed);
|
|
isNeedByMediaControl.store(isNeed);
|
|
SendMediaControlNeedStateMsg();
|
|
}
|
|
|
|
void MigrateAVSessionProxy::NotifyMediaControlSyncTime(AAFwk::WantParams& extras)
|
|
{
|
|
CHECK_AND_RETURN_LOG(extras.HasParam(MEDIACONTROL_NEED_STATE), "extras not have NeedState");
|
|
auto value = extras.GetParam(MEDIACONTROL_NEED_STATE);
|
|
AAFwk::IBoolean* boolValue = AAFwk::IBoolean::Query(value);
|
|
CHECK_AND_RETURN_LOG(boolValue != nullptr, "extras have no NeedState after query");
|
|
bool isNeed = OHOS::AAFwk::Boolean::Unbox(boolValue);
|
|
SLOGI("refresh NeedStateWithTimeout:%{public}d", isNeed);
|
|
isNeedByMediaControl.store(isNeed);
|
|
|
|
int32_t timeoutMs = NEED_STATE_TIMER_INTERVAL;
|
|
if (extras.HasParam(MEDIACONTROL_NEED_STATE_TIMEOUT_MS)) {
|
|
auto timeoutValue = extras.GetParam(MEDIACONTROL_NEED_STATE_TIMEOUT_MS);
|
|
AAFwk::IInteger* timeoutInt = AAFwk::IInteger::Query(timeoutValue);
|
|
if (timeoutInt != nullptr) {
|
|
timeoutMs = OHOS::AAFwk::Integer::Unbox(timeoutInt);
|
|
SLOGI("Use custom timeout:%{public}d ms", timeoutMs);
|
|
}
|
|
}
|
|
SendMediaControlSyncTime(timeoutMs);
|
|
}
|
|
|
|
AVSessionObserver::AVSessionObserver(const std::string &playerId, std::weak_ptr<MigrateAVSessionProxy> migrateProxy)
|
|
{
|
|
playerId_ = playerId;
|
|
migrateProxy_ = migrateProxy;
|
|
}
|
|
|
|
void AVSessionObserver::OnPlay(const AVControlCommand& cmd)
|
|
{
|
|
std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
|
|
CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
|
|
if (proxy->GetCharacteristic() == MSG_HEAD_MODE) {
|
|
proxy->HandlePlayForSuper(playerId_);
|
|
} else {
|
|
proxy->HandlePlay();
|
|
}
|
|
}
|
|
|
|
void AVSessionObserver::OnPause()
|
|
{
|
|
std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
|
|
CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
|
|
if (proxy->GetCharacteristic() == MSG_HEAD_MODE) {
|
|
proxy->HandlePauseForSuper(playerId_);
|
|
} else {
|
|
proxy->HandlePause();
|
|
}
|
|
}
|
|
|
|
void AVSessionObserver::OnPlayNext(const AVControlCommand& cmd)
|
|
{
|
|
std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
|
|
CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
|
|
if (proxy->GetCharacteristic() == MSG_HEAD_MODE) {
|
|
proxy->HandlePlayNextForSuper(playerId_);
|
|
} else {
|
|
proxy->HandlePlayNext();
|
|
}
|
|
}
|
|
|
|
void AVSessionObserver::OnPlayPrevious(const AVControlCommand& cmd)
|
|
{
|
|
std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
|
|
CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
|
|
if (proxy->GetCharacteristic() == MSG_HEAD_MODE) {
|
|
proxy->HandlePlayPreviousForSuper(playerId_);
|
|
} else {
|
|
proxy->HandlePlayPrevious();
|
|
}
|
|
}
|
|
|
|
void AVSessionObserver::OnSeek(int64_t time)
|
|
{
|
|
std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
|
|
CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
|
|
if (proxy->GetCharacteristic() == MSG_HEAD_MODE) {
|
|
proxy->HandleSeekForSuper(playerId_, time);
|
|
}
|
|
}
|
|
|
|
void AVSessionObserver::OnToggleFavorite(const std::string& mediaId)
|
|
{
|
|
std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
|
|
CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
|
|
if (proxy->GetCharacteristic() == MSG_HEAD_MODE) {
|
|
proxy->HandleToggleFavoriteForSuper(playerId_, mediaId);
|
|
} else {
|
|
proxy->HandleToggleFavorite(mediaId);
|
|
}
|
|
}
|
|
|
|
void AVSessionObserver::OnSetLoopMode(int32_t loopMode)
|
|
{
|
|
std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
|
|
CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
|
|
if (proxy->GetCharacteristic() == MSG_HEAD_MODE) {
|
|
proxy->HandleSetLoopModeForSuper(playerId_, loopMode);
|
|
}
|
|
}
|
|
|
|
void AVSessionObserver::OnCommonCommand(const std::string& commonCommand, const AAFwk::WantParams& commandArgs)
|
|
{
|
|
std::shared_ptr<MigrateAVSessionProxy> proxy = migrateProxy_.lock();
|
|
CHECK_AND_RETURN_LOG(proxy != nullptr, "check migrate proxy nullptr!");
|
|
proxy->HandleCommonCommand(commonCommand, commandArgs);
|
|
}
|
|
} // namespace OHOS::AVSession
|