diff --git a/frameworks/native/player/player_impl.cpp b/frameworks/native/player/player_impl.cpp index a83e0a8a89a738e5fb468ecd94c568e932ccd001..10869af439c9763111f4251e82bb7cf569516ea7 100644 --- a/frameworks/native/player/player_impl.cpp +++ b/frameworks/native/player/player_impl.cpp @@ -914,7 +914,8 @@ int32_t PlayerImpl::EnableCameraPostprocessing() CHECK_AND_RETURN_RET_LOG(fdsanFd_ != nullptr, MSERR_OK, "source fd does not exist."); int fd = fdsanFd_->Get(); MEDIA_LOGD("PlayerImpl EnableCameraPostprocessing reopen fd: %{public}d ", fd); - FdsanFd reopenFd = FdUtils::ReOpenFd(fd); + bool isLocalFd = IsLocalFd(fd); + FdsanFd reopenFd = FdUtils::ReOpenFdOld(fd, isLocalFd); CHECK_AND_RETURN_RET_LOG(reopenFd.Get() >= 0, MSERR_UNKNOWN, "EnableCameraPostprocessing: reopen failed"); auto ret = SetReopenFd(reopenFd.Get()); reopenFd.Reset(); @@ -923,6 +924,14 @@ int32_t PlayerImpl::EnableCameraPostprocessing() LISTENER(return playerService_->EnableCameraPostprocessing(), "EnableCameraPostprocessing", false, TIME_OUT_SECOND); } +bool PlayerImpl::IsLocalFd(int32_t fd) +{ + MEDIA_LOGD("PlayerImpl:0x%{public}06" PRIXPTR "IsLocalFd in", FAKE_POINTER(this)); + ScopedTimer timer("IsLocalFd", OVERTIME_WARNING_MS); + CHECK_AND_RETURN_RET_LOG(playerService_ != nullptr, MSERR_SERVICE_DIED, "player service does not exist."); + LISTENER(return playerService_->IsLocalFd(fd), "IsLocalFd", false, TIME_OUT_SECOND); +} + int32_t PlayerImpl::SetCameraPostprocessing(bool isOpen) { MEDIA_LOGD("PlayerImpl:0x%{public}06" PRIXPTR "SetCameraPostprocessing in", FAKE_POINTER(this)); diff --git a/frameworks/native/player/player_impl.h b/frameworks/native/player/player_impl.h index bd36c2171746a4684d90035f228afab107676088..6817fe742d3cec5fe58ab1ea9ab01fd5c96913b2 100644 --- a/frameworks/native/player/player_impl.h +++ b/frameworks/native/player/player_impl.h @@ -106,6 +106,7 @@ private: void ResetSeekVariables(); void HandleSeekDoneInfo(PlayerOnInfoType type, int32_t extra); int32_t SetSourceTask(int32_t fd, int64_t offset, int64_t size); + bool IsLocalFd(int32_t fd); std::recursive_mutex recMutex_; int32_t mCurrentPosition = INT32_MIN; PlayerSeekMode mCurrentSeekMode = PlayerSeekMode::SEEK_PREVIOUS_SYNC; diff --git a/services/include/i_player_service.h b/services/include/i_player_service.h index 3398e22701c3ddf3aeba0e0844a8df4b1988de19..10dfe88c46eb1ed281af1a351bf5b0f38e100efc 100644 --- a/services/include/i_player_service.h +++ b/services/include/i_player_service.h @@ -701,6 +701,12 @@ public: return 0; } + virtual bool IsLocalFd(int32_t fd) + { + (void)fd; + return false; + } + virtual int32_t SetCameraPostprocessing(bool isOpen) { (void)isOpen; diff --git a/services/services/player/client/player_client.cpp b/services/services/player/client/player_client.cpp index 7b30af2ce5b913412f111b0d727dce019e5515f4..d102e519c55dab405a55b4688fd9c175a81c7665 100644 --- a/services/services/player/client/player_client.cpp +++ b/services/services/player/client/player_client.cpp @@ -532,6 +532,13 @@ int32_t PlayerClient::SetReopenFd(int32_t fd) CHECK_AND_RETURN_RET_LOG(playerProxy_ != nullptr, MSERR_SERVICE_DIED, "player service does not exist."); return playerProxy_->SetReopenFd(fd); } + +bool PlayerClient::IsLocalFd(int32_t fd) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(playerProxy_ != nullptr, MSERR_SERVICE_DIED, "player service does not exist."); + return playerProxy_->IsLocalFd(fd); +} int32_t PlayerClient::EnableCameraPostprocessing() { diff --git a/services/services/player/client/player_client.h b/services/services/player/client/player_client.h index 798cc4c11d339660cc17be38a1030f0c80a18ba4..6f1832c5b61f2f977bd1174a089009e551eff1cc 100644 --- a/services/services/player/client/player_client.h +++ b/services/services/player/client/player_client.h @@ -99,6 +99,7 @@ public: int32_t ForceLoadVideo(bool status) override; int32_t SetLoudnessGain(float loudnessGain) override; int32_t GetGlobalInfo(std::shared_ptr &globalInfo) override; + bool IsLocalFd(int32_t fd) override; private: int32_t CreateListenerObject(); diff --git a/services/services/player/ipc/i_standard_player_service.h b/services/services/player/ipc/i_standard_player_service.h index 10a52483534426c250cd4c4bb5566a757e15e605..280e6a06d455700dd741ee0e0e660291fd028067 100644 --- a/services/services/player/ipc/i_standard_player_service.h +++ b/services/services/player/ipc/i_standard_player_service.h @@ -176,6 +176,12 @@ public: return 0; } + virtual bool IsLocalFd(int32_t fd) + { + (void)fd; + return false; + } + virtual int32_t SetCameraPostprocessing(bool isOpen) { (void)isOpen; @@ -278,6 +284,7 @@ public: FORCE_LOAD_VIDEO, SET_LOUDNESSGAIN, SET_CAMERA_POST_POSTPROCESSING, + IS_LOCAL_FD, MAX_IPC_ID, // all IPC codes should be added before MAX_IPC_ID GET_GLOBAL_INFO, }; diff --git a/services/services/player/ipc/player_service_proxy.cpp b/services/services/player/ipc/player_service_proxy.cpp index cb05e8cf4fffad6b550e0ca0d5c764bc36197eec..6c3b05b60cad2cf3f7353df3957965e7c4e07b60 100644 --- a/services/services/player/ipc/player_service_proxy.cpp +++ b/services/services/player/ipc/player_service_proxy.cpp @@ -117,6 +117,7 @@ void PlayerServiceProxy::InitPlayerFuncsPart2() playerFuncs_[ENABLE_REPORT_MEDIA_PROGRESS] = "Player::EnableReportMediaProgress"; playerFuncs_[ENABLE_REPORT_AUDIO_INTERRUPT] = "Player::EnableReportAudioInterrupt"; playerFuncs_[SET_CAMERA_POST_POSTPROCESSING] = "Player::SetCameraPostprocessing"; + playerFuncs_[IS_LOCAL_FD] = "Player::IsLocalFd"; playerFuncs_[GET_GLOBAL_INFO] = "Player::GetGlobalInfo"; } @@ -1255,6 +1256,24 @@ int32_t PlayerServiceProxy::SetReopenFd(int32_t fd) "SetReopenFd failed, error: %{public}d", error); return reply.ReadInt32(); } + +bool PlayerServiceProxy::IsLocalFd(int32_t fd) +{ + MediaTrace trace("PlayerServiceProxy::IsLocalFd"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(PlayerServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + MEDIA_LOGI("IsLocalFd in fd: %{public}d", fd); + (void)data.WriteFileDescriptor(fd); + int32_t error = SendRequest(IS_LOCAL_FD, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "IsLocalFd failed, error: %{public}d", error); + return reply.ReadBool(); +} int32_t PlayerServiceProxy::EnableCameraPostprocessing() { diff --git a/services/services/player/ipc/player_service_proxy.h b/services/services/player/ipc/player_service_proxy.h index 8d8f1d798ab264c4c1408102402c85fb1161f7aa..ec6015104bc307bf6429019c6e82bd8f94c685e6 100644 --- a/services/services/player/ipc/player_service_proxy.h +++ b/services/services/player/ipc/player_service_proxy.h @@ -93,6 +93,7 @@ public: int32_t ForceLoadVideo(bool status) override; int32_t SetLoudnessGain(float loudnessGain) override; int32_t GetGlobalInfo(std::shared_ptr &globalInfo) override; + bool IsLocalFd(int32_t fd) override; private: int32_t SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); void InitPlayerFuncsPart1(); diff --git a/services/services/player/ipc/player_service_stub.cpp b/services/services/player/ipc/player_service_stub.cpp index 6b5a56dff29af3bea24f0a9e73a23ccd8bff5519..97ab9112de23607ed8a3db6d809d607fa558c832 100644 --- a/services/services/player/ipc/player_service_stub.cpp +++ b/services/services/player/ipc/player_service_stub.cpp @@ -262,6 +262,8 @@ void PlayerServiceStub::FillPlayerFuncPart3() [this](MessageParcel &data, MessageParcel &reply) { return SetLoudnessGain(data, reply); } }; playerFuncs_[SET_CAMERA_POST_POSTPROCESSING] = { "Player::SetCameraPostprocessing", [this](MessageParcel &data, MessageParcel &reply) { return SetCameraPostprocessing(data, reply); } }; + playerFuncs_[IS_LOCAL_FD] = { "Player::IsLocalFd", + [this](MessageParcel &data, MessageParcel &reply) { return IsLocalFd(data, reply); } }; playerFuncs_[GET_GLOBAL_INFO] = { "Player::GetGlobalInfo", [this](MessageParcel &data, MessageParcel &reply) { return GetGlobalInfo(data, reply); } }; } @@ -784,6 +786,21 @@ int32_t PlayerServiceStub::SetReopenFd(int32_t fd) return playerServer_->SetReopenFd(fd); } +bool PlayerServiceStub::IsLocalFd(MessageParcel &data, MessageParcel &reply) +{ + int32_t fd = data.ReadFileDescriptor(); + reply.WriteBool(IsLocalFd(fd)); + (void)::close(fd); + return MSERR_OK; +} + +bool PlayerServiceStub::IsLocalFd(int32_t fd) +{ + MediaTrace trace("PlayerServiceStub::IsLocalFd"); + CHECK_AND_RETURN_RET_LOG(playerServer_ != nullptr, MSERR_NO_MEMORY, "player server is nullptr"); + return playerServer_->IsLocalFd(fd); +} + int32_t PlayerServiceStub::SetListenerObject(MessageParcel &data, MessageParcel &reply) { sptr object = data.ReadRemoteObject(); diff --git a/services/services/player/ipc/player_service_stub.h b/services/services/player/ipc/player_service_stub.h index ebe836a24f9dcf48894a72e74bcca4f47bb22202..c2c77890006c38889f27661167af7e188e0fb650 100644 --- a/services/services/player/ipc/player_service_stub.h +++ b/services/services/player/ipc/player_service_stub.h @@ -113,6 +113,7 @@ public: int32_t ForceLoadVideo(bool status) override; int32_t SetLoudnessGain(float loudnessGain) override; int32_t GetGlobalInfo(std::shared_ptr &globalInfo) override; + bool IsLocalFd(int32_t fd) override; protected: PlayerServiceStub(); virtual int32_t Init(); @@ -192,6 +193,7 @@ private: int32_t ForceLoadVideo(MessageParcel &data, MessageParcel &reply); int32_t SetLoudnessGain(MessageParcel &data, MessageParcel &reply); int32_t GetGlobalInfo(MessageParcel &data, MessageParcel &reply); + bool IsLocalFd(MessageParcel &data, MessageParcel &reply); int32_t ReadMediaStreamListFromMessageParcel( MessageParcel &data, const std::shared_ptr &mediaSource); diff --git a/services/services/player/server/player_server.cpp b/services/services/player/server/player_server.cpp index 7fc1256feb2c20d6c7625523e819fc2c8bfd38e8..3e17ba6c802bafe10feb9d60119588fcaf910b08 100644 --- a/services/services/player/server/player_server.cpp +++ b/services/services/player/server/player_server.cpp @@ -36,6 +36,7 @@ #include "audio_info.h" #include "osal/utils/steady_clock.h" #include "common/event.h" +#include "fd_utils.h" using namespace OHOS::QOS; @@ -1393,9 +1394,11 @@ void PlayerServer::HandleEos() auto cancelTask = std::make_shared>([this]() { MEDIA_LOGI("Interrupted seek action"); - playerEngine_->SetEosInLoopForFrozen(false); - taskMgr_.MarkTaskDone("interrupted seek done"); - disableNextSeekDone_ = false; + if (playerEngine_ != nullptr) { + playerEngine_->SetEosInLoopForFrozen(false); + taskMgr_.MarkTaskDone("interrupted seek done"); + disableNextSeekDone_ = false; + } }); int32_t ret = taskMgr_.SeekTask(seekTask, cancelTask, "eos seek", SEEK_PREVIOUS_SYNC, 0); @@ -2384,6 +2387,16 @@ int32_t PlayerServer::SetReopenFd(int32_t fd) CHECK_AND_RETURN_RET_NOLOG(playerEngine_ == nullptr, playerEngine_->SetReopenFd(fd)); return MSERR_OK; } + +bool PlayerServer::IsLocalFd(int32_t fd) +{ + MEDIA_LOGD("IsLocalFd success, fd = %{public}d", fd); + bool isLocalFd = false; +#if __linux__ + isLocalFd = FdUtils::LocalFdOld(fd); +#endif + return isLocalFd; +} int32_t PlayerServer::EnableCameraPostprocessing() { diff --git a/services/services/player/server/player_server.h b/services/services/player/server/player_server.h index 24c79425e739e56be332ade3975d224f23deb699..621cce580624d0f48c11056e2b619217696880c8 100644 --- a/services/services/player/server/player_server.h +++ b/services/services/player/server/player_server.h @@ -162,6 +162,7 @@ public: int32_t ForceLoadVideo(bool status) override; int32_t SetLoudnessGain(float loudnessGain) override; int32_t GetGlobalInfo(std::shared_ptr &globalInfo) override; + bool IsLocalFd(int32_t fd) override; protected: class BaseState; diff --git a/services/utils/include/fd_utils.h b/services/utils/include/fd_utils.h index eef106b29c8686d8abcf05539f326993c46e0984..ac36988ed36bf1607c898718c5928c83a9d63937 100644 --- a/services/utils/include/fd_utils.h +++ b/services/utils/include/fd_utils.h @@ -30,7 +30,7 @@ namespace Media { namespace { constexpr size_t MAX_ATTR_NAME = 64; const std::string CLOUD_LOCATION_ATTR = "user.cloud.location"; -static const std::string LOCAL = "1"; +static const std::string LOCAL_FD = "1"; } #endif @@ -63,6 +63,45 @@ public: return FdsanFd(); } + static FdsanFd ReOpenFdOld(int32_t fd, bool isLocalFd) + { +#ifdef __linux__ + if (fd > 0 && isLocalFd) { + MEDIA_LOGI("ReOpenFdOld In"); + std::stringstream ss; + ss << "/proc/self/fd/" << fd; + std::string fdPathStr = ss.str(); + char realPath[PATH_MAX_REAL]; + ssize_t result = readlink(fdPathStr.c_str(), realPath, sizeof(realPath)); + if (result == RESULT_ERROR) { + MEDIA_LOGW("ReOpenFdOld readlink invalid fd: %{public}d, error: %{public}s", fd, std::strerror(errno)); + return FdsanFd(); + } + int32_t newFd = dup(fd); + if (newFd < 0) { + MEDIA_LOGW("ReOpenFdOld invalid fd: %{public}d, error: %{public}s", fd, std::strerror(errno)); + return FdsanFd(); + } + return FdsanFd(newFd); + } +#endif + MEDIA_LOGW("=== fd is cloud"); + return FdsanFd(); + } + + static bool LocalFdOld(int32_t fd) + { +#ifdef __linux__ + int loc; + int ioResult = ioctl(fd, HMDFS_IOC_GET_LOCATION, &loc); + if (ioResult == 0 && loc != IOCTL_CLOUD) { + return true; + } +#endif + MEDIA_LOGW("fd is cloud"); + return false; + } + private: #if __linux__ static bool LocalFd(int32_t fd) @@ -76,7 +115,7 @@ private: std::string local(value, static_cast(size)); MEDIA_LOGD("Getxattr value, local is %{public}s", local.c_str()); - return local == LOCAL; + return local == LOCAL_FD; } #endif