This commit is contained in:
liziran 2023-12-21 19:08:59 +08:00
parent 9c0e6c67ce
commit 1366c3fdaa
129 changed files with 21707 additions and 62 deletions

30
BUILD.gn Normal file
View File

@ -0,0 +1,30 @@
# Copyright (c) 2023 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.
config("cast_engine_default_config") {
cflags = [
"-Wall",
"-Wextra",
"-Werror",
"-Wno-shadow",
"-Wno-unused-parameter",
"-Wno-missing-field-initializers",
"-FS",
"-O2",
"-D_FORTIFY_SOURCE=2",
"-fvisibility=hidden",
"-fvisibility-inlines-hidden"
]
cflags_cc = cflags
ldflags = [ "-Werror" ]
}

176
LICENSE Normal file
View File

@ -0,0 +1,176 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@ -1,36 +0,0 @@
# castengine_cast_framework
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -1,39 +1,41 @@
# castengine_cast_framework
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
## Introduction
#### 软件架构
软件架构说明
Provide audio and video broadcasting capabilities with adaptive Cast+Stream, Wi Fi Display, and DLNA protocols, providing a unified interface and normalized experience for north-south developers.
## Directory Structure
#### 安装教程
```
/foundation/CastEngine/castengine_cast_framework
├── clinet # Implementation on the client side
├── common # common code
├── etc # SA profile file
├── interfaces # Inner api
├── sa_profile # SA profile
├── service # Implementation on the service side
├── LICENSE # Certificate file
├── BUILD.gn # Compilation Entry
├── test # test code
└── bundle.json # Component description file
1. xxxx
2. xxxx
3. xxxx
```
#### 使用说明
## Compilation and Building
1. xxxx
2. xxxx
3. xxxx
```
# Generate the libcast.z.so、libcast_engine_client.z.so、libcast_engine_service.z.so file in the out directory of the product folder through GN compilation.
hb build cast
```
#### 参与贡献
### Usage
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
For details, see[Sample](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/AVSession)。
## Repositories Involved
#### 特技
[castengine_cast_plus_stream](https://gitee.com/openharmony-sig/castengine_cast_plus_stream)
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
[castengine_wifi_display](https://gitee.com/openharmony-sig/castengine_wifi_display)
[castengine_dlna](https://gitee.com/openharmony-sig/castengine_dlna)

41
README_zh.md Normal file
View File

@ -0,0 +1,41 @@
# 音视频投播管理服务框架部件
## 简介
提供自适应Cast+ StreamWi-Fi DisplayDLNA多种协议的音视频投播能力为南北向开发者提供统一的接口及归一化的体验。
## 目录
```
/foundation/CastEngine/castengine_cast_framework # 音视频投播管理服务框架业务代码
├── clinet # 客户端实现
├── common # 公共引用
├── etc # SA描述
├── interfaces # 接口文件
├── sa_profile # SA profile文件
├── service # 服务端实现
├── LICENSE # 证书文件
├── BUILD.gn # 编译入口
├── test # 测试代码
└── bundle.json # 部件描述文件
```
## 编译构建
```
# 通过gn编译,在out目录下对应产品的文件夹中生成libcast.z.so、libcast_engine_client.z.so、libcast_engine_service.z.so
hb build cast
```
### 使用说明
提供整体的投播框架,支持其他投屏协议的接入以及投屏协议自适应选择。
北向接入可参考[Sample](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/AVSession)。
## 相关仓
[castengine_cast_plus_stream](https://gitee.com/openharmony-sig/castengine_cast_plus_stream)
[castengine_wifi_display](https://gitee.com/openharmony-sig/castengine_wifi_display)
[castengine_dlna](https://gitee.com/openharmony-sig/castengine_dlna)

88
bundle.json Normal file
View File

@ -0,0 +1,88 @@
{
"name":"@ohos/cast_engine",
"description":"supply cast engine service",
"version":"3.1",
"license":"",
"publishAs":"binary",
"dirs":{},
"scripts":{},
"component":{
"name":"cast_engine",
"subsystem":"castplus",
"syscap":[
""
],
"features":[],
"adapted_system_type":[
"standard"
],
"rom":"5M",
"ram":"50M",
"hisysevent_config": [
"//foundation/CastEngine/castengine_cast_framework/hisysevent.yaml"
],
"deps":{
"components":[
"hilog",
"hisysevent",
"hitrace",
"access_token",
"audio_framework",
"av_codec",
"ipc",
"init",
"input",
"safwk",
"samgr",
"c_utils",
"dsoftbus",
"device_manager",
"common_event_service",
"bundle_framework",
"ability_base",
"ability_runtime",
"ace_engine",
"napi",
"graphic_2d",
"window_manager",
"player_framework"
],
"third_party":[
"glib",
"json",
"jsoncpp",
"openssl",
"bounds_checking_function"
]
},
"build":{
"sub_component":[
"//foundation/CastEngine/castengine_cast_framework/service:cast_engine_service",
"//foundation/CastEngine/castengine_cast_framework/interfaces/inner_api:cast_engine_client",
"//foundation/CastEngine/castengine_cast_framework/sa_profile:cast_engine_sa_profile",
"//foundation/CastEngine/castengine_cast_framework/etc/init:cast_engine_service.cfg",
"//foundation/CastEngine/castengine_cast_framework/interfaces/kits/js:cast"
],
"inner_kits":[
{
"type": "so",
"name": "//foundation/CastEngine/castengine_cast_framework/interfaces/inner_api:cast_engine_client",
"header": {
"header_base": "//foundation/CastEngine/castengine_cast_framework/interfaces/inner_api/include",
"header_files": [
"cast_engine_common.h",
"cast_session_manager.h",
"i_cast_session.h",
"i_cast_session_manager_adaptor.h",
"i_cast_session_manager_listener.h"
]
}
}
],
"test":[
"//foundation/CastEngine/castengine_cast_framework/test:cast_unittest",
"//foundation/CastEngine/castengine_cast_framework/test/fuzztest:fuzztest"
]
}
}
}

21
cast_engine.gni Normal file
View File

@ -0,0 +1,21 @@
# Copyright (c) 2023 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
#
import("//build/ohos.gni")
import("//build/ohos_var.gni")
cast_engine_root = get_path_info(".", "abspath")
cast_engine_client = "$cast_engine_root/client"
cast_engine_common = "$cast_engine_root/common"
cast_engine_interfaces = "$cast_engine_root/interfaces"
cast_engine_service = "$cast_engine_root/service"
cast_session_stream_path = "//foundation/CastEngine/castengine_cast_plus_stream"
graphic_2d_path = "//foundation/graphic/graphic_2d"
build_flags = [ "-Werror" ]

56
client/BUILD.gn Normal file
View File

@ -0,0 +1,56 @@
# Copyright (c) 2023 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
#
import("//foundation/CastEngine/castengine_cast_framework/cast_engine.gni")
config("cast_client_config") {
include_dirs = [
"include",
"${cast_engine_interfaces}/inner_api/include",
]
}
ohos_static_library("cast_client_inner") {
sources = [
"src/cast_service_listener_impl_stub.cpp",
"src/cast_session.cpp",
"src/cast_session_impl_proxy.cpp",
"src/cast_session_listener_impl_stub.cpp",
"src/cast_session_manager.cpp",
"src/cast_session_manager_adaptor.cpp",
"src/cast_session_manager_service_proxy.cpp",
"src/cast_engine_service_load_callback.cpp",
"src/stream_player_listener_impl_stub.cpp",
"src/mirror_player.cpp",
"src/mirror_player_impl_proxy.cpp",
"src/stream_player.cpp",
"src/stream_player_impl_proxy.cpp",
]
configs = [
":cast_client_config",
"${cast_engine_root}:cast_engine_default_config",
]
public_configs = [ ":cast_client_config" ]
deps = [
"${cast_engine_common}:cast_engine_common_sources",
]
external_deps = [
"c_utils:utils",
"hilog:libhilog",
"ipc:ipc_core",
"samgr:samgr_proxy",
"graphic_2d:surface"
]
subsystem_name = "castplus"
part_name = "cast_engine"
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager service proxy class
* Author: zhuzhibin
* Create: 2022-10-25
*/
#ifndef CAST_ENGINE_SERVICE_LOAD_CALLBACK_H
#define CAST_ENGINE_SERVICE_LOAD_CALLBACK_H
#include "system_ability_load_callback_stub.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class CastEngineServiceLoadCallback : public SystemAbilityLoadCallbackStub {
public:
void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject) override;
void OnLoadSystemAbilityFail(int32_t systemAbilityId) override;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_ENGINE_SERVICE_LOAD_CALLBACK_H

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast service listener implement proxy
* Author: zhangge
* Create: 2022-6-15
*/
#ifndef CAST_SERVICE_LISTENER_IMPL_STUB_H
#define CAST_SERVICE_LISTENER_IMPL_STUB_H
#include "cast_engine_common.h"
#include "cast_stub_helper.h"
#include "i_cast_service_listener_impl.h"
#include "i_cast_session_manager_listener.h"
#include "iremote_stub.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class CastServiceListenerImplStub : public IRemoteStub<ICastServiceListenerImpl> {
public:
CastServiceListenerImplStub(std::shared_ptr<ICastSessionManagerListener> userListener);
int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
private:
DECLARE_STUB_TASK_MAP(CastServiceListenerImplStub);
bool GetCastRemoteDevices(MessageParcel &data, std::vector<CastRemoteDevice> &deviceList);
bool GetCastSession(MessageParcel &data, std::shared_ptr<ICastSession> &castSession);
int32_t DoDeviceFoundTask(MessageParcel &data, MessageParcel &reply);
int32_t DoDeviceOfflineTask(MessageParcel &data, MessageParcel &reply);
int32_t DoSessionCreateTask(MessageParcel &data, MessageParcel &reply);
int32_t DoServiceDieTask(MessageParcel &data, MessageParcel &reply);
void OnDeviceFound(const std::vector<CastRemoteDevice> &deviceList) override;
void OnDeviceOffline(const std::string &deviceId) override;
void OnSessionCreated(const sptr<ICastSessionImpl> &castSession) override;
void OnServiceDied() override;
std::shared_ptr<ICastSessionManagerListener> userListener_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2023 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
*
* Description: supply Cast session definition.
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef CAST_SESSION_H
#define CAST_SESSION_H
#include "cast_engine_common.h"
#include "i_cast_session.h"
#include "i_cast_session_impl.h"
#include "oh_remote_control_event.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class CastSession : public ICastSession {
public:
CastSession(sptr<ICastSessionImpl> proxy) : proxy_(proxy) {};
~CastSession() override;
int32_t RegisterListener(std::shared_ptr<ICastSessionListener> listener) override;
int32_t UnregisterListener() override;
int32_t AddDevice(const CastRemoteDevice &remoteDevice) override;
int32_t RemoveDevice(const std::string &deviceId) override;
int32_t StartAuth(const AuthInfo &authInfo) override;
int32_t GetSessionId(std::string &sessionId) override;
int32_t SetSessionProperty(const CastSessionProperty &property) override;
int32_t SetSessionId(std::string sessionId);
int32_t CreateMirrorPlayer(std::shared_ptr<IMirrorPlayer> &mirrorPlayer) override;
int32_t CreateStreamPlayer(std::shared_ptr<IStreamPlayer> &streamPlayer) override;
int32_t Release() override;
int32_t NotifyEvent(EventId eventId, std::string &jsonParam) override;
int32_t SetCastMode(CastMode mode, std::string &jsonParam) override;
private:
sptr<ICastSessionImpl> proxy_;
std::string sessionId_{};
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session implement proxy
* Author: zhangge
* Create: 2022-5-29
*/
#ifndef CAST_SESSION_IMPL_PROXY_H
#define CAST_SESSION_IMPL_PROXY_H
#include "cast_engine_common.h"
#include "i_cast_session_impl.h"
#include "iremote_proxy.h"
#include "oh_remote_control_event.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class CastSessionImplProxy : public IRemoteProxy<ICastSessionImpl> {
public:
explicit CastSessionImplProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<ICastSessionImpl>(impl) {}
~CastSessionImplProxy() override;
int32_t RegisterListener(sptr<ICastSessionListenerImpl> listener) override;
int32_t UnregisterListener() override;
int32_t AddDevice(const CastRemoteDevice &remoteDevice) override;
int32_t RemoveDevice(const std::string &deviceId) override;
int32_t StartAuth(const AuthInfo &authInfo) override;
int32_t GetSessionId(std::string &sessionId) override;
int32_t GetDeviceState(const std::string &deviceId, DeviceState &deviceState) override;
int32_t SetSessionProperty(const CastSessionProperty &property) override;
int32_t CreateMirrorPlayer(sptr<IMirrorPlayerImpl> &mirrorPlayer) override;
int32_t CreateStreamPlayer(sptr<IStreamPlayerIpc> &streamPlayer) override;
int32_t Release() override;
int32_t NotifyEvent(EventId eventId, std::string &jsonParam) override;
int32_t SetCastMode(CastMode mode, std::string &jsonParam) override;
private:
static inline BrokerDelegator<CastSessionImplProxy> delegator_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_ENGINE_PROXY_H

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session listener implement proxy apis.
* Author: zhangge
* Create: 2022-6-15
*/
#ifndef CAST_SESSION_LISTENER_STUB_H
#define CAST_SESSION_LISTENER_STUB_H
#include "cast_stub_helper.h"
#include "i_cast_session_listener_impl.h"
#include "iremote_stub.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class CastSessionListenerImplStub : public IRemoteStub<ICastSessionListenerImpl> {
public:
CastSessionListenerImplStub(std::shared_ptr<ICastSessionListener> userListener);
int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
private:
DECLARE_STUB_TASK_MAP(CastSessionListenerImplStub);
int32_t DoOnDeviceStateTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnEventTask(MessageParcel &data, MessageParcel &reply);
void OnDeviceState(const DeviceStateInfo &stateInfo) override;
void OnEvent(const EventId &eventId, const std::string &jsonParam) override;
std::shared_ptr<ICastSessionListener> userListener_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager adaptor.
* Author: zhangge
* Create: 2022-5-29
*/
#ifndef CAST_SESSION_MANAGER_ADAPTOR_H
#define CAST_SESSION_MANAGER_ADAPTOR_H
#include <memory>
#include <mutex>
#include <set>
#include "cast_engine_common.h"
#include "cast_session_listener_impl_stub.h"
#include "cast_session_manager_service_proxy.h"
#include "i_cast_session_manager_adaptor.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class CastSessionManagerAdaptor : public ICastSessionManagerAdaptor,
public std::enable_shared_from_this<CastSessionManagerAdaptor> {
public:
CastSessionManagerAdaptor(sptr<CastSessionManagerServiceProxy> proxy) : proxy_(proxy) {}
~CastSessionManagerAdaptor() override;
int32_t RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener,
sptr<IRemoteObject::DeathRecipient> deathRecipient) override;
int32_t UnregisterListener() override;
int32_t Release() override;
int32_t SetLocalDevice(const CastLocalDevice &localDevice) override;
int32_t CreateCastSession(const CastSessionProperty &property, std::shared_ptr<ICastSession> &castSession) override;
int32_t SetSinkSessionCapacity(int sessionCapacity) override;
int32_t StartDiscovery(int protocols) override;
int32_t SetDiscoverable(bool enable) override;
int32_t StopDiscovery() override;
int32_t GetCastSession(std::string sessionId, std::shared_ptr<ICastSession> &castSession) override;
private:
void UnsubscribeDeathRecipient();
sptr<CastSessionManagerServiceProxy> proxy_;
std::mutex mutex_;
wptr<IRemoteObject> remote_;
sptr<IRemoteObject::DeathRecipient> deathRecipient_{ nullptr };
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_SESSION_MANAGER_ADAPTOR_H

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager service proxy class
* Author: zhangge
* Create: 2022-5-29
*/
#ifndef CAST_SESSION_MANAGER_SERVICE_PROXY_H
#define CAST_SESSION_MANAGER_SERVICE_PROXY_H
#include "cast_engine_common.h"
#include "i_cast_session_manager_service.h"
#include "iremote_proxy.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class CastSessionManagerServiceProxy : public IRemoteProxy<ICastSessionManagerService> {
public:
explicit CastSessionManagerServiceProxy(const sptr<IRemoteObject> &impl)
: IRemoteProxy<ICastSessionManagerService>(impl)
{}
int32_t RegisterListener(sptr<ICastServiceListenerImpl> listener) override;
int32_t UnregisterListener() override;
int32_t Release() override;
int32_t SetLocalDevice(const CastLocalDevice &localDevice) override;
int32_t CreateCastSession(const CastSessionProperty &property, sptr<ICastSessionImpl> &castSession) override;
int32_t SetSinkSessionCapacity(int sessionCapacity) override;
int32_t StartDiscovery(int protocols) override;
int32_t SetDiscoverable(bool enable) override;
int32_t StopDiscovery() override;
sptr<IRemoteObject> GetSessionManagerService();
int32_t GetCastSession(std::string sessionId, sptr<ICastSessionImpl> &castSession) override;
private:
static inline BrokerDelegator<CastSessionManagerServiceProxy> delegator_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_ENGINE_PROXY_H

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 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
*
* Description: supply Cast mirror player definition.
* Author: zhangjingnan
* Create: 2023-05-27
*/
#ifndef MIRROR_PLAYER_H
#define MIRROR_PLAYER_H
#include "cast_engine_common.h"
#include "i_mirror_player.h"
#include "i_mirror_player_impl.h"
#include "oh_remote_control_event.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class MirrorPlayer : public IMirrorPlayer {
public:
MirrorPlayer(sptr<IMirrorPlayerImpl> proxy) : proxy_(proxy) {};
~MirrorPlayer() override;
int32_t Play(const std::string &deviceId) override;
int32_t Pause(const std::string &deviceId) override;
int32_t SetSurface(const std::string &surfaceId) override;
int32_t DeliverInputEvent(OHRemoteControlEvent event) override;
int32_t Release() override;
private:
sptr<IMirrorPlayerImpl> proxy_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 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
*
* Description: supply mirror player implement proxy
* Author: zhangjingnan
* Create: 2023-5-27
*/
#ifndef MIRROR_PLAYER_IMPL_PROXY_H
#define MIRROR_PLAYER_IMPL_PROXY_H
#include "cast_engine_common.h"
#include "i_mirror_player_impl.h"
#include "iremote_proxy.h"
#include "oh_remote_control_event.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class MirrorPlayerImplProxy : public IRemoteProxy<IMirrorPlayerImpl> {
public:
explicit MirrorPlayerImplProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IMirrorPlayerImpl>(impl) {}
~MirrorPlayerImplProxy() override;
int32_t Play(const std::string &deviceId) override;
int32_t Pause(const std::string &deviceId) override;
int32_t SetSurface(sptr<IBufferProducer> producer) override;
int32_t DeliverInputEvent(const OHRemoteControlEvent &event) override;
int32_t Release() override;
private:
static inline BrokerDelegator<MirrorPlayerImplProxy> delegator_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_ENGINE_PROXY_H

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 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
*
* Description: supply Stream Player definition.
* Author: huangchanggui
* Create: 2023-01-12
*/
#ifndef STREAM_PLAYER_H
#define STREAM_PLAYER_H
#include "i_stream_player.h"
#include "i_stream_player_ipc.h"
#include "cast_engine_common.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class StreamPlayer : public IStreamPlayer {
public:
explicit StreamPlayer(sptr<IStreamPlayerIpc> proxy) : proxy_(proxy) {}
~StreamPlayer() override;
int32_t RegisterListener(std::shared_ptr<IStreamPlayerListener> listener) override;
int32_t UnregisterListener() override;
int32_t SetSurface(const std::string &surfaceId) override;
int32_t Load(const MediaInfo &mediaInfo) override;
int32_t Play(const MediaInfo &mediaInfo) override;
int32_t Play(int index) override;
int32_t Play() override;
int32_t Pause() override;
int32_t Stop() override;
int32_t Next() override;
int32_t Previous() override;
int32_t Seek(int position) override;
int32_t FastForward(int delta) override;
int32_t FastRewind(int delta) override;
int32_t SetVolume(int volume) override;
int32_t SetLoopMode(const LoopMode mode) override;
int32_t SetSpeed(const PlaybackSpeed speed) override;
int32_t GetPlayerStatus(PlayerStates &playerStates) override;
int32_t GetPosition(int &position) override;
int32_t GetDuration(int &duration) override;
int32_t GetVolume(int &volume, int &maxVolume) override;
int32_t GetLoopMode(LoopMode &loopMode) override;
int32_t GetPlaySpeed(PlaybackSpeed &playbackSpeed) override;
int32_t GetMediaInfoHolder(MediaInfoHolder &mediaInfoHolder) override;
int32_t Release() override;
private:
static const int GET_FAILED = -1;
sptr<IStreamPlayerIpc> proxy_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 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
*
* Description: supply stream player implement proxy
* Author: huangchanggui
* Create: 2023-01-12
*/
#ifndef STREAM_PLAYER_IMPL_PROXY_H
#define STREAM_PLAYER_IMPL_PROXY_H
#include "i_stream_player_ipc.h"
#include "cast_engine_common.h"
#include "iremote_proxy.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class StreamPlayerImplProxy : public IRemoteProxy<IStreamPlayerIpc> {
public:
explicit StreamPlayerImplProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IStreamPlayerIpc>(impl) {}
~StreamPlayerImplProxy() override;
int32_t RegisterListener(sptr<IStreamPlayerListenerImpl> listener) override;
int32_t UnregisterListener() override;
int32_t SetSurface(sptr<IBufferProducer> producer) override;
int32_t Load(const MediaInfo &mediaInfo) override;
int32_t Play(const MediaInfo &mediaInfo) override;
int32_t Play(int index) override;
int32_t Play() override;
int32_t Pause() override;
int32_t Stop() override;
int32_t Next() override;
int32_t Previous() override;
int32_t Seek(int position) override;
int32_t FastForward(int delta) override;
int32_t FastRewind(int delta) override;
int32_t SetVolume(int volume) override;
int32_t SetLoopMode(const LoopMode mode) override;
int32_t SetSpeed(const PlaybackSpeed speed) override;
int32_t GetPlayerStatus(PlayerStates &playerStates) override;
int32_t GetPosition(int &position) override;
int32_t GetDuration(int &duration) override;
int32_t GetVolume(int &volume, int &maxVolume) override;
int32_t GetLoopMode(LoopMode &loopMode) override;
int32_t GetPlaySpeed(PlaybackSpeed &playbackSpeed) override;
int32_t GetMediaInfoHolder(MediaInfoHolder &mediaInfoHolder) override;
int32_t Release() override;
private:
static const int GET_FAILED = -1;
static inline BrokerDelegator<StreamPlayerImplProxy> delegator_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_ENGINE_PROXY_H

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2023 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
*
* Description: supply stream player listener implement proxy apis.
* Author: huangchanggui
* Create: 2023-01-12
*/
#ifndef STREAM_PLAYER_LISTENER_IMPL_STUB_H
#define STREAM_PLAYER_LISTENER_IMPL_STUB_H
#include "i_stream_player_listener_impl.h"
#include "i_stream_player.h"
#include "cast_stub_helper.h"
#include "iremote_stub.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class StreamPlayerListenerImplStub : public IRemoteStub<IStreamPlayerListenerImpl> {
public:
explicit StreamPlayerListenerImplStub(std::shared_ptr<IStreamPlayerListener> userListener);
~StreamPlayerListenerImplStub() override;
int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
private:
DECLARE_STUB_TASK_MAP(StreamPlayerListenerImplStub);
int32_t DoOnStateChangedTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnPositionChangedTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnMediaItemChangedTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnVolumeChangedTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnLoopModeChangedTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnPlaySpeedChangedTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnPlayerErrorTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnVideoSizeChangedTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnNextRequestTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnPreviousRequestTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnSeekDoneTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnEndOfStreamTask(MessageParcel &data, MessageParcel &reply);
int32_t DoOnPlayRequestTask(MessageParcel &data, MessageParcel &reply);
void OnStateChanged(const PlayerStates playbackState, bool isPlayWhenReady) override;
void OnPositionChanged(int position, int bufferPosition, int duration) override;
void OnMediaItemChanged(const MediaInfo &mediaInfo) override;
void OnVolumeChanged(int volume, int maxVolume) override;
void OnPlayerError(int errorCode, const std::string &errorMsg) override;
void OnVideoSizeChanged(int width, int height) override;
void OnLoopModeChanged(const LoopMode loopMode) override;
void OnPlaySpeedChanged(const PlaybackSpeed speed) override;
void OnNextRequest() override;
void OnPreviousRequest() override;
void OnSeekDone(int position) override;
void OnEndOfStream(int isLooping) override;
void OnPlayRequest(const MediaInfo &mediaInfo) override;
std::shared_ptr<IStreamPlayerListener> userListener_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager service proxy class
* Author: zhuzhibin
* Create: 2022-10-25
*/
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "system_ability_definition.h"
#include "cast_engine_service_load_callback.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-LoadServiceCallback");
void CastEngineServiceLoadCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId,
const sptr<IRemoteObject> &remoteObject)
{
CLOGI("In systemAbilityId: %d", systemAbilityId);
if (systemAbilityId != CAST_ENGINE_SA_ID) {
CLOGE("Start aystemabilityId is not sinkSAId!");
return;
}
if (remoteObject == nullptr) {
CLOGE("RemoteObject is nullptr.");
return;
}
}
void CastEngineServiceLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
{
CLOGI("In systemAbilityId: %d.", systemAbilityId);
if (systemAbilityId != CAST_ENGINE_SA_ID) {
CLOGE("Start aystemabilityId is not sinkSAId!");
return;
}
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast service listener implement proxy apis.
* Author: zhangge
* Create: 2022-6-15
*/
#include "cast_service_listener_impl_stub.h"
#include <variant>
#include "cast_engine_common.h"
#include "cast_engine_common_helper.h"
#include "cast_engine_log.h"
#include "cast_session.h"
#include "cast_stub_helper.h"
#include "i_cast_session_manager_listener.h"
#include "iremote_stub.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-ServiceListener");
int CastServiceListenerImplStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
RETRUEN_IF_WRONG_TASK(code, data, reply, option);
return EXECUTE_SINGLE_STUB_TASK(code, data, reply);
}
CastServiceListenerImplStub::CastServiceListenerImplStub(std::shared_ptr<ICastSessionManagerListener> userListener)
: userListener_(userListener)
{
FILL_SINGLE_STUB_TASK(ON_DEVICE_FOUND, &CastServiceListenerImplStub::DoDeviceFoundTask);
FILL_SINGLE_STUB_TASK(ON_DEVICE_OFFLINE, &CastServiceListenerImplStub::DoDeviceOfflineTask);
FILL_SINGLE_STUB_TASK(ON_SESSION_CREATE, &CastServiceListenerImplStub::DoSessionCreateTask);
FILL_SINGLE_STUB_TASK(ON_SERVICE_DIE, &CastServiceListenerImplStub::DoServiceDieTask);
}
int32_t CastServiceListenerImplStub::DoServiceDieTask(MessageParcel &data, MessageParcel &reply)
{
userListener_->OnServiceDied();
return ERR_NONE;
}
bool CastServiceListenerImplStub::GetCastRemoteDevices(MessageParcel &data, std::vector<CastRemoteDevice> &deviceList)
{
auto size = data.ReadInt32();
if (size <= 0 || size > MAX_DEVICE_NUM) {
return false;
}
deviceList.resize(size);
for (int32_t i = 0; i < size; ++i) {
if (!ReadCastRemoteDevice(data, deviceList[i])) {
return false;
}
}
return true;
}
bool CastServiceListenerImplStub::GetCastSession(MessageParcel &data, std::shared_ptr<ICastSession> &castSession)
{
auto object = data.ReadRemoteObject();
auto impl = (object == nullptr) ? nullptr : iface_cast<ICastSessionImpl>(object);
if (impl == nullptr) {
CLOGE("Failed to cast ICastSessionImpl");
return false;
}
auto session = std::make_shared<CastSession>(impl);
if (session == nullptr) {
CLOGE("Failed to malloc cast session");
return false;
}
castSession = session;
return true;
}
int32_t CastServiceListenerImplStub::DoDeviceFoundTask(MessageParcel &data, MessageParcel &reply)
{
CLOGI("DoOnDeviceStatusTask in");
std::vector<CastRemoteDevice> remoteDevices;
if (!GetCastRemoteDevices(data, remoteDevices)) {
CLOGE("DoDeviceFoundTask, failed get remote devices info");
return ERR_INVALID_DATA;
}
userListener_->OnDeviceFound(remoteDevices);
return ERR_NONE;
}
int32_t CastServiceListenerImplStub::DoSessionCreateTask(MessageParcel &data, MessageParcel &reply)
{
CLOGI("DoSessionCreateTask in");
std::shared_ptr<ICastSession> castSession;
if (!GetCastSession(data, castSession)) {
CLOGE("DoSessionCreateTask, failed get cast session info");
return ERR_INVALID_DATA;
}
userListener_->OnSessionCreated(castSession);
return ERR_NONE;
}
int32_t CastServiceListenerImplStub::DoDeviceOfflineTask(MessageParcel &data, MessageParcel &reply)
{
CLOGI("DoDeviceOfflineTask in");
std::string deviceId = data.ReadString();
if (deviceId.empty()) {
CLOGE("DoDeviceOfflineTask, failed get deviceId");
return ERR_INVALID_DATA;
}
userListener_->OnDeviceOffline(deviceId);
return ERR_NONE;
}
void CastServiceListenerImplStub::OnDeviceFound(const std::vector<CastRemoteDevice> &deviceList)
{
static_cast<void>(deviceList);
}
void CastServiceListenerImplStub::OnSessionCreated(const sptr<ICastSessionImpl> &castSession)
{
static_cast<void>(castSession);
}
void CastServiceListenerImplStub::OnServiceDied() {}
void CastServiceListenerImplStub::OnDeviceOffline(const std::string &deviceId)
{
static_cast<void>(deviceId);
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

166
client/src/cast_session.cpp Normal file
View File

@ -0,0 +1,166 @@
/*
* Copyright (c) 2023 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
*
* Description: Cast Session function realization.
* Author: zhangge
* Create: 2022-06-15
*/
#include "cast_session.h"
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
#include "cast_session_listener_impl_stub.h"
#include "surface_utils.h"
#include "stream_player.h"
#include "mirror_player.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-Session");
CastSession::~CastSession()
{
CLOGI("Stop the client cast session.");
}
int32_t CastSession::RegisterListener(std::shared_ptr<ICastSessionListener> listener)
{
if (listener == nullptr) {
CLOGE("The listener is null");
return ERR_INVALID_PARAM;
}
sptr<ICastSessionListenerImpl> listenerStub = new (std::nothrow) CastSessionListenerImplStub(listener);
if (listenerStub == nullptr) {
CLOGE("Failed to new a session listener");
return ERR_NO_MEMORY;
}
return proxy_ ? proxy_->RegisterListener(listenerStub) : CAST_ENGINE_ERROR;
}
int32_t CastSession::SetSessionId(std::string sessionId)
{
sessionId_ = sessionId;
return CAST_ENGINE_SUCCESS;
}
int32_t CastSession::UnregisterListener()
{
return proxy_ ? proxy_->UnregisterListener() : CAST_ENGINE_ERROR;
}
int32_t CastSession::AddDevice(const CastRemoteDevice &remoteDevice)
{
if (remoteDevice.deviceId.empty()) {
CLOGE("The remote device id is null");
return ERR_INVALID_PARAM;
}
return proxy_ ? proxy_->AddDevice(remoteDevice) : CAST_ENGINE_ERROR;
}
int32_t CastSession::RemoveDevice(const std::string &deviceId)
{
if (deviceId.empty()) {
CLOGE("The device id is null");
return ERR_INVALID_PARAM;
}
return proxy_ ? proxy_->RemoveDevice(deviceId) : CAST_ENGINE_ERROR;
}
int32_t CastSession::StartAuth(const AuthInfo &authInfo)
{
if (authInfo.deviceId.empty()) {
CLOGE("The device id is null");
return ERR_INVALID_PARAM;
}
return proxy_ ? proxy_->StartAuth(authInfo) : CAST_ENGINE_ERROR;
}
int32_t CastSession::GetSessionId(std::string &sessionId)
{
if (!proxy_) {
CLOGE("proxy is null");
return CAST_ENGINE_ERROR;
}
int32_t ret = proxy_->GetSessionId(sessionId_);
sessionId = sessionId_;
return ret;
}
int32_t CastSession::SetSessionProperty(const CastSessionProperty &property)
{
return proxy_ ? proxy_->SetSessionProperty(property) : CAST_ENGINE_ERROR;
}
int32_t CastSession::CreateMirrorPlayer(std::shared_ptr<IMirrorPlayer> &mirrorPlayer)
{
if (!proxy_) {
CLOGE("proxy_ is null");
return CAST_ENGINE_ERROR;
}
sptr<IMirrorPlayerImpl> impl;
int32_t ret = proxy_->CreateMirrorPlayer(impl);
CHECK_AND_RETURN_RET_LOG(ret != CAST_ENGINE_SUCCESS, ret, "CastEngine Errors");
if (!impl) {
return CAST_ENGINE_ERROR;
}
auto player = std::make_shared<MirrorPlayer>(impl);
if (!player) {
CLOGE("Failed to malloc mirror player");
return ERR_NO_MEMORY;
}
mirrorPlayer = player;
return ret;
}
int32_t CastSession::CreateStreamPlayer(std::shared_ptr<IStreamPlayer> &streamPlayer)
{
if (!proxy_) {
CLOGE("proxy_ is null");
return CAST_ENGINE_ERROR;
}
sptr<IStreamPlayerIpc> streamPlayerIpc;
int32_t ret = proxy_->CreateStreamPlayer(streamPlayerIpc);
CHECK_AND_RETURN_RET_LOG(ret != CAST_ENGINE_SUCCESS, ret, "CastEngine Errors");
if (!streamPlayerIpc) {
return CAST_ENGINE_ERROR;
}
auto player = std::make_shared<StreamPlayer>(streamPlayerIpc);
if (!player) {
CLOGE("Failed to malloc stream player");
return ERR_NO_MEMORY;
}
streamPlayer = player;
return ret;
}
int32_t CastSession::Release()
{
return proxy_ ? proxy_->Release() : CAST_ENGINE_ERROR;
}
int32_t CastSession::SetCastMode(CastMode mode, std::string &jsonParam)
{
return proxy_ ? proxy_->SetCastMode(mode, jsonParam) : false;
}
int32_t CastSession::NotifyEvent(EventId eventId, std::string &jsonParam)
{
if (proxy_ != nullptr) {
proxy_->NotifyEvent(eventId, jsonParam);
return CAST_ENGINE_SUCCESS;
}
return CAST_ENGINE_ERROR;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,383 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session implement proxy
* Author: zhangge
* Create: 2022-5-29
*/
#include "cast_session_impl_proxy.h"
#include "cast_engine_common_helper.h"
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-Session");
CastSessionImplProxy::~CastSessionImplProxy()
{
CLOGI("Stop the client cast session proxy.");
}
int32_t CastSessionImplProxy::RegisterListener(sptr<ICastSessionListenerImpl> listener)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteRemoteObject(listener->AsObject())) {
CLOGE("Failed to write cast session listener");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(REGISTER_LISTENER, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when registering listener");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionImplProxy::UnregisterListener()
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(UNREGISTER_LISTENER, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when unregistering listener");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionImplProxy::AddDevice(const CastRemoteDevice &remoteDevice)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!WriteCastRemoteDevice(data, remoteDevice)) {
CLOGE("Failed to write the remote device");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(ADD_DEVICE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when adding device");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when adding device");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when adding device");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionImplProxy::RemoveDevice(const std::string &deviceId)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteString(deviceId)) {
CLOGE("Failed to write the the device id");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(REMOVE_DEVICE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when removing device");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when removing device");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when removing device");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionImplProxy::StartAuth(const AuthInfo &authInfo)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return false;
}
if (!WriteAuthInfo(data, authInfo)) {
CLOGE("Failed to write auth info");
return false;
}
int32_t ret = Remote()->SendRequest(START_AUTH, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when starting auth");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when starting auth");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when starting auth");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionImplProxy::GetSessionId(std::string &sessionId)
{
MessageParcel data, reply;
MessageOption option;
sessionId = std::string{};
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(GET_SESSION_ID, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when getting session id");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when getting session id");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
sessionId = reply.ReadString();
return errorCode;
}
int32_t CastSessionImplProxy::GetDeviceState(const std::string &deviceId, DeviceState &deviceState)
{
MessageParcel data, reply;
MessageOption option;
deviceState = DeviceState::DISCONNECTED;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteString(deviceId)) {
CLOGE("Failed to write the the device id");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(GET_DEVICE_STATE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when getting device state");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when getting device state");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when getting device state");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
int state = reply.ReadInt32();
if (IsDeviceState(state)) {
deviceState = static_cast<DeviceState>(state);
}
return errorCode;
}
int32_t CastSessionImplProxy::SetSessionProperty(const CastSessionProperty &property)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!WriteCastSessionProperty(data, property)) {
CLOGE("Failed to write the property");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(SET_SESSION_PROPERTY, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when setting session property");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when setting session property");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionImplProxy::CreateMirrorPlayer(sptr<IMirrorPlayerImpl> &mirrorPlayer)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(CREAT_MIRROR_PLAYER, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when creating mirror player");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when creating mirror player");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
auto object = reply.ReadRemoteObject();
if (!object) {
CLOGE("Failed to get the mirror player object");
return CAST_ENGINE_ERROR;
}
mirrorPlayer = iface_cast<IMirrorPlayerImpl>(object);
return errorCode;
}
int32_t CastSessionImplProxy::CreateStreamPlayer(sptr<IStreamPlayerIpc> &streamPlayer)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(CREAT_STREAM_PLAYER, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when creating stream player");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when creating stream player");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
auto object = reply.ReadRemoteObject();
if (!object) {
CLOGE("Failed to get the cast session object");
return CAST_ENGINE_ERROR;
}
streamPlayer = iface_cast<IStreamPlayerIpc>(object);
return errorCode;
}
int32_t CastSessionImplProxy::Release()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(RELEASE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when releasing the cast session");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when releasing the cast session");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionImplProxy::SetCastMode(CastMode mode, std::string &jsonParam)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(static_cast<int32_t>(mode))) {
CLOGE("Failed to write cast mode");
return CAST_ENGINE_ERROR;
}
if (!data.WriteString(jsonParam)) {
CLOGE("Failed to write json param");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(SET_CAST_MODE, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when set cast mode");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionImplProxy::NotifyEvent(EventId eventId, std::string &jsonParam)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(static_cast<int32_t>(eventId))) {
CLOGE("Failed to write event id");
return CAST_ENGINE_ERROR;
}
if (!data.WriteString(jsonParam)) {
CLOGE("Failed to write json param");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(NOTIFY_EVENT, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when notify event");
return CAST_ENGINE_ERROR;
}
return CAST_ENGINE_SUCCESS;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session listener implement stub.
* Author: zhangge
* Create: 2022-6-15
*/
#include "cast_session_listener_impl_stub.h"
#include "cast_engine_common_helper.h"
#include "cast_stub_helper.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-SessionListener");
int CastSessionListenerImplStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
RETRUEN_IF_WRONG_TASK(code, data, reply, option);
return EXECUTE_SINGLE_STUB_TASK(code, data, reply);
}
CastSessionListenerImplStub::CastSessionListenerImplStub(std::shared_ptr<ICastSessionListener> userListener_)
: userListener_(userListener_)
{
FILL_SINGLE_STUB_TASK(ON_DEVICE_STATE, &CastSessionListenerImplStub::DoOnDeviceStateTask);
FILL_SINGLE_STUB_TASK(ON_EVENT, &CastSessionListenerImplStub::DoOnEventTask);
}
int32_t CastSessionListenerImplStub::DoOnDeviceStateTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
auto stateInfo = ReadDeviceStateInfo(data);
if (stateInfo == nullptr) {
CLOGE("sate info is null");
return ERR_NULL_OBJECT;
}
userListener_->OnDeviceState(*stateInfo);
return ERR_NONE;
}
int32_t CastSessionListenerImplStub::DoOnEventTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t eventId;
std::string param;
if (!ReadEvent(data, eventId, param)) {
CLOGE("read event failed");
return ERR_NULL_OBJECT;
}
userListener_->OnEvent(static_cast<EventId>(eventId), param);
return ERR_NONE;
}
void CastSessionListenerImplStub::OnDeviceState(const DeviceStateInfo &stateInfo)
{
static_cast<void>(stateInfo);
}
void CastSessionListenerImplStub::OnEvent(const EventId &eventId, const std::string &jsonParam)
{
static_cast<void>(eventId);
static_cast<void>(jsonParam);
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,223 @@
/*
* Copyright (c) 2023 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
*
* Description: implement the cast session manager
* Author: zhangge
* Create: 2022-06-15
*/
#include <thread>
#include "cast_session_manager.h"
#include <thread>
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
#include "cast_engine_service_load_callback.h"
#include "cast_session_manager_adaptor.h"
#include "cast_session_manager_service_proxy.h"
#include "i_cast_session.h"
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-SessionManager");
CastSessionManager::CastSessionManager()
{
CLOGI("in");
}
CastSessionManager &CastSessionManager::GetInstance()
{
static CastSessionManager instance {};
return instance;
}
std::shared_ptr<ICastSessionManagerAdaptor> CastSessionManager::GetAdaptor()
{
CLOGI("in");
std::lock_guard<std::mutex> lock(mutex_);
if (adaptor_) {
return adaptor_;
}
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (samgr == nullptr) {
CLOGE("Failed to get SA manager");
return nullptr;
}
sptr<CastEngineServiceLoadCallback> loadCallback = new (std::nothrow) CastEngineServiceLoadCallback();
if (loadCallback == nullptr) {
CLOGE("Failed to new object");
return nullptr;
}
auto result = samgr->LoadSystemAbility(CAST_ENGINE_SA_ID, loadCallback);
if (result != ERR_OK) {
CLOGE("systemAbilityId: %d load failed, result code: %d", CAST_ENGINE_SA_ID, result);
return nullptr;
}
constexpr int32_t sleepTimeMs = 30;
constexpr int32_t retryTimes = 150; // The service startup timeout interval is 4s.
int32_t retryTime = 0;
sptr<IRemoteObject> object;
while ((object = samgr->CheckSystemAbility(CAST_ENGINE_SA_ID)) == nullptr && (retryTime < retryTimes)) {
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
retryTime++;
}
if (object == nullptr) {
CLOGE("Failed to get cast engine manager");
return nullptr;
}
auto proxy = iface_cast<CastSessionManagerServiceProxy>(object);
adaptor_ = std::make_shared<CastSessionManagerAdaptor>(proxy);
return adaptor_;
}
int32_t CastSessionManager::RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener)
{
CLOGI("in");
if (listener == nullptr) {
CLOGE("Failed to init due to the null listener");
return CAST_ENGINE_ERROR;
}
auto adaptor = GetAdaptor();
if (!adaptor) {
return CAST_ENGINE_ERROR;
}
sptr<CastEngineServiceDeathRecipient> deathRecipient(
new (std::nothrow) CastEngineServiceDeathRecipient(listener));
if (!deathRecipient) {
CLOGE("Death recipient malloc failed");
return CAST_ENGINE_ERROR;
}
if (adaptor->RegisterListener(listener, deathRecipient) == CAST_ENGINE_SUCCESS) {
std::lock_guard<std::mutex> lock(mutex_);
deathRecipient_ = deathRecipient;
return CAST_ENGINE_SUCCESS;
}
return CAST_ENGINE_ERROR;
}
int32_t CastSessionManager::UnregisterListener()
{
CLOGI("in");
ReleaseServiceDeathRecipient();
auto adaptor = GetAdaptor();
int32_t ret = adaptor ? adaptor->UnregisterListener() : CAST_ENGINE_ERROR;
std::lock_guard<std::mutex> lock(mutex_);
adaptor_ = nullptr;
return ret;
}
int32_t CastSessionManager::Release()
{
CLOGI("in");
ReleaseServiceDeathRecipient();
auto adaptor = GetAdaptor();
int32_t ret = adaptor ? adaptor->Release() : CAST_ENGINE_ERROR;
std::lock_guard<std::mutex> lock(mutex_);
adaptor_ = nullptr;
return ret;
}
int32_t CastSessionManager::SetLocalDevice(const CastLocalDevice &localDevice)
{
CLOGI("in");
if (localDevice.deviceId.empty()) {
CLOGE("Local device id is null");
return CAST_ENGINE_ERROR;
}
auto adaptor = GetAdaptor();
return adaptor ? adaptor->SetLocalDevice(localDevice) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManager::CreateCastSession(const CastSessionProperty &property,
std::shared_ptr<ICastSession> &castSession)
{
CLOGI("in");
auto adaptor = GetAdaptor();
return adaptor ? adaptor->CreateCastSession(property, castSession) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManager::SetSinkSessionCapacity(int sessionCapacity)
{
CLOGD("in");
auto adaptor = GetAdaptor();
return adaptor ? adaptor->SetSinkSessionCapacity(sessionCapacity) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManager::StartDiscovery(int protocols)
{
CLOGD("in");
auto adaptor = GetAdaptor();
return adaptor ? adaptor->StartDiscovery(protocols) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManager::SetDiscoverable(bool enable)
{
CLOGI("in");
auto adaptor = GetAdaptor();
return adaptor ? adaptor->SetDiscoverable(enable) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManager::StopDiscovery()
{
CLOGI("in");
auto adaptor = GetAdaptor();
return adaptor ? adaptor->StopDiscovery() : CAST_ENGINE_ERROR;
}
int32_t CastSessionManager::GetCastSession(std::string sessionId, std::shared_ptr<ICastSession> &castSession)
{
CLOGI("in");
auto adaptor = GetAdaptor();
return adaptor ? adaptor->GetCastSession(sessionId, castSession) : CAST_ENGINE_ERROR;
}
void CastSessionManager::ReleaseClientResources()
{
CLOGD("Release client resources");
std::lock_guard<std::mutex> lock(mutex_);
std::shared_ptr<ICastSessionManagerListener> listener;
{
if (!!deathRecipient_) {
listener = deathRecipient_->GetListener();
}
deathRecipient_ = nullptr;
adaptor_ = nullptr;
}
if (listener) {
listener->OnServiceDied();
} else {
CLOGE("Report is nullptr");
}
}
void CastSessionManager::ReleaseServiceDeathRecipient()
{
std::lock_guard<std::mutex> lock(mutex_);
deathRecipient_ = nullptr;
}
void CastSessionManager::CastEngineServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
CLOGE("Service died, need release resources");
CastSessionManager::GetInstance().ReleaseClientResources();
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,163 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager adaptor.
* Author: zhangge
* Create: 2022-5-29
*/
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
#include "cast_session_manager_adaptor.h"
#include "cast_service_listener_impl_stub.h"
#include "cast_session.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-ManagerAdaptor");
CastSessionManagerAdaptor::~CastSessionManagerAdaptor()
{
CLOGD("destructor in");
UnsubscribeDeathRecipient();
}
int32_t CastSessionManagerAdaptor::RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener,
sptr<IRemoteObject::DeathRecipient> deathRecipient)
{
sptr<ICastServiceListenerImpl> impl = new (std::nothrow) CastServiceListenerImplStub(listener);
if (impl == nullptr) {
CLOGE("Failed to malloc service listener");
return CAST_ENGINE_ERROR;
}
auto object = proxy_ ? proxy_->GetSessionManagerService() : nullptr;
if (!object) {
CLOGW("Failed to get session manager service");
return CAST_ENGINE_ERROR;
}
int32_t ret = proxy_ ? proxy_->RegisterListener(impl) : CAST_ENGINE_ERROR;
if (ret != CAST_ENGINE_SUCCESS) {
return ret;
}
if (object->AddDeathRecipient(deathRecipient)) {
std::lock_guard<std::mutex> lock(mutex_);
deathRecipient_ = deathRecipient;
remote_ = object;
} else {
CLOGE("Add cast engine service death recipient failed");
}
return CAST_ENGINE_SUCCESS;
}
int32_t CastSessionManagerAdaptor::UnregisterListener()
{
UnsubscribeDeathRecipient();
return proxy_ ? proxy_->UnregisterListener() : CAST_ENGINE_ERROR;
}
int32_t CastSessionManagerAdaptor::Release()
{
UnsubscribeDeathRecipient();
return proxy_ ? proxy_->Release() : CAST_ENGINE_ERROR;
}
int32_t CastSessionManagerAdaptor::SetLocalDevice(const CastLocalDevice &localDevice)
{
return proxy_ ? proxy_->SetLocalDevice(localDevice) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManagerAdaptor::CreateCastSession(const CastSessionProperty &property,
std::shared_ptr<ICastSession> &castSession)
{
if (!proxy_) {
CLOGE("proxy is null");
return CAST_ENGINE_ERROR;
}
sptr<ICastSessionImpl> impl;
int32_t ret = proxy_->CreateCastSession(property, impl);
CHECK_AND_RETURN_RET_LOG(ret != CAST_ENGINE_SUCCESS, ret, "CastEngine Errors");
if (impl == nullptr) {
CLOGE("cast session is NULL");
return CAST_ENGINE_ERROR;
}
auto session = std::make_shared<CastSession>(impl);
if (!session) {
CLOGE("Failed to malloc cast session");
return ERR_NO_MEMORY;
}
std::string sessionId{};
impl->GetSessionId(sessionId);
session->SetSessionId(sessionId);
castSession = session;
return ret;
}
int32_t CastSessionManagerAdaptor::SetSinkSessionCapacity(int sessionCapacity)
{
return proxy_ ? proxy_->SetSinkSessionCapacity(sessionCapacity) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManagerAdaptor::StartDiscovery(int protocols)
{
return proxy_ ? proxy_->StartDiscovery(protocols) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManagerAdaptor::SetDiscoverable(bool enable)
{
return proxy_ ? proxy_->SetDiscoverable(enable) : CAST_ENGINE_ERROR;
}
int32_t CastSessionManagerAdaptor::StopDiscovery()
{
return proxy_ ? proxy_->StopDiscovery() : CAST_ENGINE_ERROR;
}
int32_t CastSessionManagerAdaptor::GetCastSession(std::string sessionId, std::shared_ptr<ICastSession> &castSession)
{
sptr<ICastSessionImpl> impl;
int32_t ret = proxy_->GetCastSession(sessionId, impl);
CHECK_AND_RETURN_RET_LOG(ret != CAST_ENGINE_SUCCESS, ret, "CastEngine Errors");
if (impl == nullptr) {
CLOGE("cast session is NULL");
return CAST_ENGINE_ERROR;
}
auto session = std::make_shared<CastSession>(impl);
if (!session) {
CLOGE("Failed to malloc cast session");
return CAST_ENGINE_ERROR;
}
std::string id{};
impl->GetSessionId(id);
session->SetSessionId(id);
castSession = session;
return ret;
}
void CastSessionManagerAdaptor::UnsubscribeDeathRecipient()
{
std::lock_guard<std::mutex> lock(mutex_);
if (!deathRecipient_) {
CLOGE("deathRecipient is null");
return;
}
sptr<IRemoteObject> remote = remote_.promote();
if (!!remote) {
remote->RemoveDeathRecipient(deathRecipient_);
}
deathRecipient_ = nullptr;
CLOGD("Unsubscribe Death Recipient Success");
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,303 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager service proxy
* Author: zhangge
* Create: 2022-5-29
*/
#include "cast_engine_errors.h"
#include "cast_session_manager_service_proxy.h"
#include "cast_engine_common_helper.h"
#include "cast_engine_log.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-Manager");
int32_t CastSessionManagerServiceProxy::RegisterListener(sptr<ICastServiceListenerImpl> listener)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteRemoteObject(listener->AsObject())) {
CLOGE("Failed to write cast service listener");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(REGISTER_LISTENER, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when initing the cast service");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionManagerServiceProxy::UnregisterListener()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(UNREGISTER_LISTENER, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when unregistering listener");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when unregistering listener");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionManagerServiceProxy::Release()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(RELEASE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when Releasing the cast service");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when Releasing the cast service");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionManagerServiceProxy::SetLocalDevice(const CastLocalDevice &localDevice)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!WriteCastLocalDevice(data, localDevice)) {
CLOGE("Failed to write cast local device");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(SET_LOCAL_DEVICE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when setting local device");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when setting local device");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when setting local device");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionManagerServiceProxy::CreateCastSession(const CastSessionProperty &property,
sptr<ICastSessionImpl> &castSession)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!WriteCastSessionProperty(data, property)) {
CLOGE("Failed to write cast session property");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(CREATE_CAST_SESSION, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when creating cast session");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when creating cast session");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when creating cast session");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
auto object = reply.ReadRemoteObject();
if (object == nullptr) {
CLOGE("Failed to get the cast session object");
return CAST_ENGINE_ERROR;
}
castSession = iface_cast<ICastSessionImpl>(object);
return errorCode;
}
int32_t CastSessionManagerServiceProxy::SetSinkSessionCapacity(int sessionCapacity)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(sessionCapacity)) {
CLOGE("Failed to write the session capacity");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(SET_SINK_SESSION_CAPACITY, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when setting sink session capacity");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when setting sink session capacity");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionManagerServiceProxy::StartDiscovery(int protocols)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(protocols)) {
CLOGE("Failed to write the protocol type");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(START_DISCOVERY, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when starting discovery");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when starting discovery");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when starting discovery");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionManagerServiceProxy::SetDiscoverable(bool enable)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteBool(enable)) {
CLOGE("Failed to write discoverable value");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(SET_DISCOVERABLE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when setting discoverable");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when setting discoverable");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionManagerServiceProxy::StopDiscovery()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(STOP_DISCOVERY, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when setting discoverable");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when setting discoverable");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t CastSessionManagerServiceProxy::GetCastSession(std::string sessionId, sptr<ICastSessionImpl> &castSession)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteString(sessionId)) {
CLOGE("Failed to write session ID");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(GET_CAST_SESSION, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when get cast session");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
auto object = reply.ReadRemoteObject();
if (object == nullptr) {
CLOGE("Failed to get the cast session object");
return CAST_ENGINE_ERROR;
}
castSession = iface_cast<ICastSessionImpl>(object);
return errorCode;
}
sptr<IRemoteObject> CastSessionManagerServiceProxy::GetSessionManagerService()
{
return this->AsObject();
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2023 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
*
* Description: Cast mirror player function realization.
* Author: zhangjingnan
* Create: 2023-05-27
*/
#include "mirror_player.h"
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
#include "surface_utils.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-MirrorPlayer");
MirrorPlayer::~MirrorPlayer()
{
CLOGI("Stop the client mirror player.");
}
int32_t MirrorPlayer::Play(const std::string &deviceId)
{
if (deviceId.empty()) {
CLOGE("The device id is null");
return ERR_INVALID_PARAM;
}
return proxy_ ? proxy_->Play(deviceId) : CAST_ENGINE_ERROR;
}
int32_t MirrorPlayer::Pause(const std::string &deviceId)
{
if (deviceId.empty()) {
CLOGE("The device id is null");
return ERR_INVALID_PARAM;
}
return proxy_ ? proxy_->Pause(deviceId) : CAST_ENGINE_ERROR;
}
int32_t MirrorPlayer::SetSurface(const std::string &surfaceId)
{
errno = 0;
uint64_t surfaceUniqueId = static_cast<uint64_t>(std::strtoll(surfaceId.c_str(), nullptr, 10));
if (errno == ERANGE) {
return ERR_INVALID_PARAM;
}
sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(surfaceUniqueId);
if (!surface) {
CLOGE("surface is null, surface uniqueId %llu", surfaceUniqueId);
return CAST_ENGINE_ERROR;
}
sptr<IBufferProducer> producer = surface->GetProducer();
if (!producer) {
CLOGE("producer is null");
return CAST_ENGINE_ERROR;
}
return proxy_ ? proxy_->SetSurface(producer) : CAST_ENGINE_ERROR;
}
int32_t MirrorPlayer::DeliverInputEvent(OHRemoteControlEvent event)
{
return proxy_ ? proxy_->DeliverInputEvent(event) : CAST_ENGINE_ERROR;
}
int32_t MirrorPlayer::Release()
{
return proxy_ ? proxy_->Release() : CAST_ENGINE_ERROR;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2023 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
*
* Description: supply mirror player implement proxy
* Author: zhangjingnan
* Create: 2023-5-27
*/
#include "mirror_player_impl_proxy.h"
#include "cast_engine_common_helper.h"
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-MirrorPlayer");
MirrorPlayerImplProxy::~MirrorPlayerImplProxy()
{
CLOGI("Stop the client mirror player proxy.");
}
int32_t MirrorPlayerImplProxy::Play(const std::string &deviceId)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteString(deviceId)) {
CLOGE("Failed to write the the device id");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(PLAY, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when executing the playing action");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when executing the playing action");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when executing the playing action");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t MirrorPlayerImplProxy::Pause(const std::string &deviceId)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteString(deviceId)) {
CLOGE("Failed to write the the device id");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(PAUSE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when executing the pausing action");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when executing the pausing action");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when executing the pausing action");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t MirrorPlayerImplProxy::SetSurface(sptr<IBufferProducer> producer)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteRemoteObject(producer->AsObject())) {
CLOGE("Failed to write surface producer");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(SET_SURFACE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when setting surface");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when setting surface");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t MirrorPlayerImplProxy::DeliverInputEvent(const OHRemoteControlEvent &event)
{
MessageParcel data, reply;
MessageOption option;
CLOGD("In, eventType:%d", static_cast<uint32_t>(event.eventType));
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!WriteRemoteControlEvent(data, event)) {
CLOGE("Failed to write the remote control event");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(DELIVER_INPUT_EVENT, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when deliver input event");
return ERR_NO_PERMISSION;
} else if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when deliver input event");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when deliver input event");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t MirrorPlayerImplProxy::Release()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(RELEASE, data, reply, option);
if (ret == ERR_UNKNOWN_TRANSACTION) {
CLOGE("No permission when setting surface");
return ERR_NO_PERMISSION;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when setting surface");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,181 @@
/*
* Copyright (c) 2023 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
*
* Description: Stream Player function realization.
* Author: huangchanggui
* Create: 2023-01-12
*/
#include "stream_player.h"
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
#include "stream_player_listener_impl_stub.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-StreamPlayer");
StreamPlayer::~StreamPlayer()
{
CLOGD("destructor in");
}
int32_t StreamPlayer::RegisterListener(std::shared_ptr<IStreamPlayerListener> listener)
{
if (listener == nullptr) {
CLOGE("listener is null");
return ERR_INVALID_PARAM;
}
sptr<IStreamPlayerListenerImpl> listenerStub = new (std::nothrow) StreamPlayerListenerImplStub(listener);
if (listenerStub == nullptr) {
CLOGE("Failed to new a stream player listener");
return CAST_ENGINE_ERROR;
}
return proxy_ ? proxy_->RegisterListener(listenerStub) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::UnregisterListener()
{
return proxy_ ? proxy_->UnregisterListener() : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::SetSurface(const std::string &surfaceId)
{
errno = 0;
uint64_t surfaceUniqueId = static_cast<uint64_t>(std::strtoll(surfaceId.c_str(), nullptr, 10));
if (errno == ERANGE) {
return ERR_INVALID_PARAM;
}
sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(surfaceUniqueId);
if (!surface) {
CLOGE("surface is null, surface uniqueId %llu", surfaceUniqueId);
return CAST_ENGINE_ERROR;
}
sptr<IBufferProducer> producer = surface->GetProducer();
if (!producer) {
CLOGE("producer is null");
return CAST_ENGINE_ERROR;
}
return proxy_ ? proxy_->SetSurface(producer) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Load(const MediaInfo &mediaInfo)
{
return proxy_ ? proxy_->Load(mediaInfo) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Play(const MediaInfo &mediaInfo)
{
return proxy_ ? proxy_->Play(mediaInfo) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Play(int index)
{
return proxy_ ? proxy_->Play(index) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Play()
{
return proxy_ ? proxy_->Play() : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Pause()
{
return proxy_ ? proxy_->Pause() : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Stop()
{
return proxy_ ? proxy_->Stop() : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Next()
{
return proxy_ ? proxy_->Next() : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Previous()
{
return proxy_ ? proxy_->Previous() : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Seek(int position)
{
return proxy_ ? proxy_->Seek(position) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::FastForward(int delta)
{
return proxy_ ? proxy_->FastForward(delta) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::FastRewind(int delta)
{
return proxy_ ? proxy_->FastRewind(delta) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::SetVolume(int volume)
{
return proxy_ ? proxy_->SetVolume(volume) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::SetLoopMode(const LoopMode mode)
{
return proxy_ ? proxy_->SetLoopMode(mode) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::SetSpeed(const PlaybackSpeed speed)
{
return proxy_ ? proxy_->SetSpeed(speed) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::GetPlayerStatus(PlayerStates &playerStates)
{
return proxy_ ? proxy_->GetPlayerStatus(playerStates) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::GetPosition(int &position)
{
return proxy_ ? proxy_->GetPosition(position) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::GetDuration(int &duration)
{
return proxy_ ? proxy_->GetDuration(duration) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::GetVolume(int &volume, int &maxVolume)
{
return proxy_ ? proxy_->GetVolume(volume, maxVolume) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::GetLoopMode(LoopMode &loopMode)
{
return proxy_ ? proxy_->GetLoopMode(loopMode) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::GetPlaySpeed(PlaybackSpeed &playbackSpeed)
{
return proxy_ ? proxy_->GetPlaySpeed(playbackSpeed) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::GetMediaInfoHolder(MediaInfoHolder &mediaInfoHolder)
{
return proxy_ ? proxy_->GetMediaInfoHolder(mediaInfoHolder) : CAST_ENGINE_ERROR;
}
int32_t StreamPlayer::Release()
{
return proxy_ ? proxy_->Release() : CAST_ENGINE_ERROR;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,576 @@
/*
* Copyright (c) 2023 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
*
* Description: supply stream player implement proxy realization.
* Author: huangchanggui
* Create: 2023-01-12
*/
#include "stream_player_impl_proxy.h"
#include "cast_engine_common_helper.h"
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-StreamPlayer");
StreamPlayerImplProxy::~StreamPlayerImplProxy()
{
CLOGD("destructor in");
}
int32_t StreamPlayerImplProxy::RegisterListener(sptr<IStreamPlayerListenerImpl> listener)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteRemoteObject(listener->AsObject())) {
CLOGE("Failed to write stream player listener");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(REGISTER_LISTENER, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when registering listener");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::UnregisterListener()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(UNREGISTER_LISTENER, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when unregistering listener");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::SetSurface(sptr<IBufferProducer> producer)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteRemoteObject(producer->AsObject())) {
CLOGE("Failed to write surface producer");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(SET_SURFACE, data, reply, option);
if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when setting surface");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when setting surface");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Load(const MediaInfo &mediaInfo)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!WriteMediaInfo(data, mediaInfo)) {
CLOGE("Failed to write the mediaInfo");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(LOAD, data, reply, option);
if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when load");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when load");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Play(const MediaInfo &mediaInfo)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!WriteMediaInfo(data, mediaInfo)) {
CLOGE("Failed to write the mediaInfo");
return CAST_ENGINE_ERROR;
}
int32_t ret = Remote()->SendRequest(START, data, reply, option);
if (ret == ERR_INVALID_DATA) {
CLOGE("Invalid parameter when play");
return ERR_INVALID_PARAM;
} else if (ret != ERR_NONE) {
CLOGE("Failed to send ipc request when play");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Play(int index)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(index)) {
CLOGE("Failed to write the index");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(PLAY_INDEX, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when play");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Pause()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(PAUSE, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when pause");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Play()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(PLAY, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when resume");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Stop()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(STOP, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when stop");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Next()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(NEXT, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when stop");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Previous()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(PREVIOUS, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when stop");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::Seek(int position)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(position)) {
CLOGE("Failed to write the position");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(SEEK, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when seek");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::FastForward(int delta)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(delta)) {
CLOGE("Failed to write the delta");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(FAST_FORWARD, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when fastForward");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::FastRewind(int delta)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(delta)) {
CLOGE("Failed to write the delta");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(FAST_REWIND, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when fastRewind");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::SetVolume(int volume)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(volume)) {
CLOGE("Failed to write the position");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(SET_VOLUME, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when set volume");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::SetLoopMode(const LoopMode mode)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(static_cast<int32_t>(mode))) {
CLOGE("Failed to write the position");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(SET_LOOP_MODE, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when set volume");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::SetSpeed(const PlaybackSpeed speed)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (!data.WriteInt32(static_cast<int32_t>(speed))) {
CLOGE("Failed to write the position");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(SET_SPEED, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when set volume");
return CAST_ENGINE_ERROR;
}
return reply.ReadInt32();
}
int32_t StreamPlayerImplProxy::GetPlayerStatus(PlayerStates &playerStates)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
playerStates = PlayerStates::PLAYER_STATE_ERROR;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(GET_PLAYER_STATUS, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when get player status");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
playerStates = static_cast<PlayerStates>(reply.ReadInt32());
return errorCode;
}
int32_t StreamPlayerImplProxy::GetPosition(int &position)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(GET_POSITION, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when get position");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
position = reply.ReadInt32();
return errorCode;
}
int32_t StreamPlayerImplProxy::GetDuration(int &duration)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(GET_DURATION, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when get duration");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
duration = reply.ReadInt32();
return errorCode;
}
int32_t StreamPlayerImplProxy::GetVolume(int &volume, int &maxVolume)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(GET_VOLUME, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when get duration");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
volume = reply.ReadInt32();
maxVolume = reply.ReadInt32();
return errorCode;
}
int32_t StreamPlayerImplProxy::GetLoopMode(LoopMode &loopMode)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
loopMode = LoopMode::LOOP_MODE_LIST;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(GET_LOOP_MODE, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when get duration");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
loopMode = static_cast<LoopMode>(reply.ReadInt32());
return errorCode;
}
int32_t StreamPlayerImplProxy::GetPlaySpeed(PlaybackSpeed &playbackSpeed)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
playbackSpeed = PlaybackSpeed::SPEED_FORWARD_1_00_X;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(GET_PLAY_SPEED, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when get duration");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
playbackSpeed = static_cast<PlaybackSpeed>(reply.ReadInt32());
return errorCode;
}
int32_t StreamPlayerImplProxy::GetMediaInfoHolder(MediaInfoHolder &mediaInfoHolder)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return CAST_ENGINE_ERROR;
}
if (Remote()->SendRequest(GET_MEDIA_INFO_HOLDER, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when get duration");
return CAST_ENGINE_ERROR;
}
int32_t errorCode = reply.ReadInt32();
CHECK_AND_RETURN_RET_LOG(errorCode != CAST_ENGINE_SUCCESS, errorCode, "CastEngine Errors");
auto mediaInfos = ReadMediaInfoHolder(reply);
if (mediaInfos == nullptr) {
CLOGE("GetMediaInfoHolder, mediaInfoHolder is null");
return CAST_ENGINE_ERROR;
}
mediaInfoHolder = *mediaInfos;
return errorCode;
}
int32_t StreamPlayerImplProxy::Release()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return false;
}
if (Remote()->SendRequest(RELEASE, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when Releasing stream player");
return false;
}
return reply.ReadInt32();
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,261 @@
/*
* Copyright (c) 2023 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
*
* Description: supply stream player listener implement stub realization.
* Author: huangchanggui
* Create: 2023-01-12
*/
#include "stream_player_listener_impl_stub.h"
#include "cast_engine_common_helper.h"
#include "cast_stub_helper.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Client-StreamPlayerListener");
int StreamPlayerListenerImplStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
RETRUEN_IF_WRONG_TASK(code, data, reply, option);
if (userListener_ == nullptr) {
CLOGE("userListener_ is null, code:%{public}d", code);
return ERR_NULL_OBJECT;
}
return EXECUTE_SINGLE_STUB_TASK(code, data, reply);
}
StreamPlayerListenerImplStub::StreamPlayerListenerImplStub(std::shared_ptr<IStreamPlayerListener> userListener)
: userListener_(userListener)
{
FILL_SINGLE_STUB_TASK(ON_PLAYER_STATUS_CHANGED, &StreamPlayerListenerImplStub::DoOnStateChangedTask);
FILL_SINGLE_STUB_TASK(ON_POSITION_CHANGED, &StreamPlayerListenerImplStub::DoOnPositionChangedTask);
FILL_SINGLE_STUB_TASK(ON_MEDIA_ITEM_CHANGED, &StreamPlayerListenerImplStub::DoOnMediaItemChangedTask);
FILL_SINGLE_STUB_TASK(ON_VOLUME_CHANGED, &StreamPlayerListenerImplStub::DoOnVolumeChangedTask);
FILL_SINGLE_STUB_TASK(ON_REPEAT_MODE_CHANGED, &StreamPlayerListenerImplStub::DoOnLoopModeChangedTask);
FILL_SINGLE_STUB_TASK(ON_PLAY_SPEED_CHANGED, &StreamPlayerListenerImplStub::DoOnPlaySpeedChangedTask);
FILL_SINGLE_STUB_TASK(ON_PLAYER_ERROR, &StreamPlayerListenerImplStub::DoOnPlayerErrorTask);
FILL_SINGLE_STUB_TASK(ON_VIDEO_SIZE_CHANGED, &StreamPlayerListenerImplStub::DoOnVideoSizeChangedTask);
FILL_SINGLE_STUB_TASK(ON_NEXT_REQUEST, &StreamPlayerListenerImplStub::DoOnNextRequestTask);
FILL_SINGLE_STUB_TASK(ON_PREVIOUS_REQUEST, &StreamPlayerListenerImplStub::DoOnPreviousRequestTask);
FILL_SINGLE_STUB_TASK(ON_SEEK_DONE, &StreamPlayerListenerImplStub::DoOnSeekDoneTask);
FILL_SINGLE_STUB_TASK(ON_END_OF_STREAM, &StreamPlayerListenerImplStub::DoOnEndOfStreamTask);
FILL_SINGLE_STUB_TASK(ON_PLAY_REQUEST, &StreamPlayerListenerImplStub::DoOnPlayRequestTask);
}
StreamPlayerListenerImplStub::~StreamPlayerListenerImplStub()
{
userListener_ = nullptr;
CLOGE("destructor in");
}
int32_t StreamPlayerListenerImplStub::DoOnStateChangedTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t state = data.ReadInt32();
bool isPlayWhenReady = data.ReadBool();
PlayerStates playbackState = static_cast<PlayerStates>(state);
userListener_->OnStateChanged(playbackState, isPlayWhenReady);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnPositionChangedTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t position = data.ReadInt32();
int32_t bufferPosition = data.ReadInt32();
int32_t duration = data.ReadInt32();
userListener_->OnPositionChanged(position, bufferPosition, duration);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnMediaItemChangedTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
auto mediaInfo = ReadMediaInfo(data);
if (mediaInfo == nullptr) {
CLOGE("DoOnMediaItemChangedTask,mediaInfo is null");
return ERR_NULL_OBJECT;
}
userListener_->OnMediaItemChanged(*mediaInfo);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnVolumeChangedTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t volume = data.ReadInt32();
int32_t maxVolume = data.ReadInt32();
userListener_->OnVolumeChanged(volume, maxVolume);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnLoopModeChangedTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t mode = data.ReadInt32();
LoopMode loopMode = static_cast<LoopMode>(mode);
userListener_->OnLoopModeChanged(loopMode);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnPlaySpeedChangedTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t speed = data.ReadInt32();
PlaybackSpeed speedMode = static_cast<PlaybackSpeed>(speed);
userListener_->OnPlaySpeedChanged(speedMode);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnPlayerErrorTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t errorCode = data.ReadInt32();
std::string errorMsg = data.ReadString();
userListener_->OnPlayerError(errorCode, errorMsg);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnVideoSizeChangedTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t width = data.ReadInt32();
int32_t height = data.ReadInt32();
userListener_->OnVideoSizeChanged(width, height);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnNextRequestTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(data);
static_cast<void>(reply);
userListener_->OnNextRequest();
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnPreviousRequestTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(data);
static_cast<void>(reply);
userListener_->OnPreviousRequest();
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnSeekDoneTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t position = data.ReadInt32();
userListener_->OnSeekDone(position);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnEndOfStreamTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
int32_t isLooping = data.ReadInt32();
userListener_->OnEndOfStream(isLooping);
return ERR_NONE;
}
int32_t StreamPlayerListenerImplStub::DoOnPlayRequestTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
auto mediaInfo = ReadMediaInfo(data);
if (mediaInfo == nullptr) {
CLOGE("DoOnPlayRequestTask, mediaInfo is null");
return ERR_NULL_OBJECT;
}
userListener_->OnPlayRequest(*mediaInfo);
return ERR_NONE;
}
void StreamPlayerListenerImplStub::OnStateChanged(const PlayerStates playbackState, bool isPlayWhenReady)
{
static_cast<void>(playbackState);
static_cast<void>(isPlayWhenReady);
}
void StreamPlayerListenerImplStub::OnPositionChanged(int position, int bufferPosition, int duration)
{
static_cast<void>(position);
static_cast<void>(bufferPosition);
static_cast<void>(duration);
}
void StreamPlayerListenerImplStub::OnMediaItemChanged(const MediaInfo &mediaInfo)
{
static_cast<void>(mediaInfo);
}
void StreamPlayerListenerImplStub::OnVolumeChanged(int volume, int maxVolume)
{
static_cast<void>(volume);
static_cast<void>(maxVolume);
}
void StreamPlayerListenerImplStub::OnLoopModeChanged(const LoopMode loopMode)
{
static_cast<void>(loopMode);
}
void StreamPlayerListenerImplStub::OnPlaySpeedChanged(const PlaybackSpeed speed)
{
static_cast<void>(speed);
}
void StreamPlayerListenerImplStub::OnPlayerError(int errorCode, const std::string &errorMsg)
{
static_cast<void>(errorCode);
static_cast<void>(errorMsg);
}
void StreamPlayerListenerImplStub::OnVideoSizeChanged(int width, int height)
{
static_cast<void>(width);
static_cast<void>(height);
}
void StreamPlayerListenerImplStub::OnNextRequest()
{
}
void StreamPlayerListenerImplStub::OnPreviousRequest()
{
}
void StreamPlayerListenerImplStub::OnSeekDone(int position)
{
static_cast<void>(position);
}
void StreamPlayerListenerImplStub::OnEndOfStream(int isLooping)
{
static_cast<void>(isLooping);
}
void StreamPlayerListenerImplStub::OnPlayRequest(const MediaInfo &mediaInfo)
{
static_cast<void>(mediaInfo);
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

44
common/BUILD.gn Normal file
View File

@ -0,0 +1,44 @@
# Copyright (c) 2023 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
#
import("//foundation/CastEngine/castengine_cast_framework/cast_engine.gni")
config("cast_engine_common_private_config") {
include_dirs = [ "include/private" ]
}
ohos_static_library("cast_engine_common_sources") {
sources = [
"src/cast_engine_common_helper.cpp",
"src/cast_engine_dfx.cpp",
]
configs = [
":cast_engine_common_private_config",
"${cast_engine_root}:cast_engine_default_config",
]
include_dirs = [
"//third_party/json/single_include/nlohmann",
]
public_configs = [
":cast_engine_common_private_config",
"${cast_engine_interfaces}/inner_api:cast_interfaces_config",
]
external_deps = [
"c_utils:utils",
"hilog:libhilog",
"hisysevent:libhisysevent",
"ipc:ipc_core",
]
subsystem_name = "castplus"
part_name = "cast_engine"
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2023 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
*
* Description: supply a helper to write/read common cast engine structures through ipc
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef CAST_ENGINE_COMMON_HELPER_H
#define CAST_ENGINE_COMMON_HELPER_H
#include "cast_engine_common.h"
#include "oh_remote_control_event.h"
namespace OHOS {
namespace CastEngine {
bool WriteCastRemoteDevice(Parcel &parcel, const CastRemoteDevice &device);
std::unique_ptr<CastRemoteDevice> ReadCastRemoteDevice(Parcel &parcel);
bool ReadCastRemoteDevice(Parcel &parcel, CastRemoteDevice &device);
bool WriteMediaInfo(MessageParcel &parcel, const MediaInfo &mediaInfo);
std::unique_ptr<MediaInfo> ReadMediaInfo(MessageParcel &parcel);
bool WriteMediaInfoHolder(MessageParcel &parcel, const MediaInfoHolder &mediaInfoHolder);
std::unique_ptr<MediaInfoHolder> ReadMediaInfoHolder(MessageParcel &parcel);
bool WriteCastLocalDevice(Parcel &parcel, const CastLocalDevice &device);
std::unique_ptr<CastLocalDevice> ReadCastLocalDevice(Parcel &parcel);
bool WriteCastSessionProperty(Parcel &parcel, const CastSessionProperty &property);
std::unique_ptr<CastSessionProperty> ReadCastSessionProperty(Parcel &parcel);
bool WritePropertyContainer(Parcel &parcel, const PropertyContainer &device);
std::unique_ptr<PropertyContainer> ReadPropertyContainer(Parcel &parcel);
bool WriteAuthInfo(Parcel &parcel, const AuthInfo &authInfo);
std::unique_ptr<AuthInfo> ReadAuthInfo(Parcel &parcel);
bool WriteRemoteControlEvent(Parcel &parcel, const OHRemoteControlEvent &event);
std::unique_ptr<OHRemoteControlEvent> ReadRemoteControlEvent(Parcel &parcel);
bool WriteDeviceStateInfo(Parcel &parcel, const DeviceStateInfo &stateInfo);
std::unique_ptr<DeviceStateInfo> ReadDeviceStateInfo(Parcel &parcel);
bool WriteEvent(Parcel &parcel, const EventId &eventId, const std::string &jsonParam);
bool ReadEvent(Parcel &parcel, int32_t &eventId, std::string &jsonParam);
void SetDataCapacity(MessageParcel &parcel, const FileFdMap &fileList, uint32_t tokenSize);
bool WriteFileList(MessageParcel &parcel, const FileFdMap &fileList);
bool ReadFileList(MessageParcel &parcel, FileFdMap &fileList);
bool WriteRcvFdFileMap(MessageParcel &parcel, const RcvFdFileMap &rcvFdFileMap);
bool ReadRcvFdFileMap(MessageParcel &parcel, RcvFdFileMap &rcvFdFileMap);
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2023 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
*
* Description: cast engine dfx.
* Author: wangxueshuang
* Create: 2023-06-05
*/
#ifndef CAST_ENGINE_DFX_H
#define CAST_ENGINE_DFX_H
#include <string>
#include "json.hpp"
namespace OHOS {
namespace CastEngine {
using nlohmann::json;
class CastEngineDfx {
public:
static void WriteErrorEvent(int32_t errorCode);
static void SetStreamInfo(const std::string &streamInfoKey, const std::string &streamInfoValue);
static void SetLocalDeviceInfo(const std::string &localDeviceInfoKey, const std::string &localDeviceInfoValue);
static void SetRemoteDeviceInfo(const std::string &remoteDeviceInfoKey, const std::string &remoteDeviceInfoValue);
static void SetConnectInfo(const std::string &connectInfoKey, const std::string &connectInfoValue);
static std::string GetStreamInfo();
static std::string GetLocalDeviceInfo();
static std::string GetRemoteDeviceInfo();
static std::string GetConnectInfo();
static std::string GetSequentialId();
static std::string GetBizPackageName();
private:
static json jsonSteamInfo_;
static json jsonLocalDeviceInfo_;
static json jsonRemoteDeviceInfo_;
static json jsonConnectInfo_;
static const std::string PACKAGE_NAME;
static const std::string SEQUENTIAL_ID_CHARS;
static const int SN_LENGTH = 32;
static const int SEQUENTIAL_ID_CHARS_LENGTH = 62;
};
// discovery fail error code
static const int32_t START_DISCOVERY_FAIL = 100;
// connection fail error code
static const int32_t AUTHENTICATE_DEVICE_FAIL = 200;
static const int32_t SOURCE_CREATE_SESSION_SERVER_FAIL = 201;
static const int32_t SINK_CREATE_SESSION_SERVER_FAIL = 202;
static const int32_t OPEN_SESSION_FAIL = 203;
static const int32_t SEND_CONSULTION_DATA_FAIL = 204;
// stream fail error code
static const int32_t PLAYER_INIT_FAIL = 300;
static constexpr char CAST_ENGINE_DFX_DOMAIN_NAME[] = "CAST_ENGINE";
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_ENGINE_DFX_H

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2023 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
*
* Description: Log format definitions.
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef CAST_ENGINE_LOG_H
#define CAST_ENGINE_LOG_H
#include "hilog/log_cpp.h"
using OHOS::HiviewDFX::HiLog;
using OHOS::HiviewDFX::HiLogLabel;
namespace OHOS {
namespace CastEngine {
inline constexpr unsigned int CASTPLUS_LOG_BEGIN = 0xD004600;
inline constexpr unsigned int CAST_ENGINE_LOG_ID = CASTPLUS_LOG_BEGIN + 0x01;
inline constexpr unsigned int CASTPLUS_LOG_END = CASTPLUS_LOG_BEGIN + 0x10;
inline constexpr bool DEBUG = false;
#define DEFINE_CAST_ENGINE_LABEL(name) \
static constexpr HiLogLabel CAST_ENGINE_LABEL = { LOG_CORE, OHOS::CastEngine::CAST_ENGINE_LOG_ID, name }
#define CLOGV(format, ...) \
do { \
if (DEBUG) { \
(void)HiLog::Debug(CAST_ENGINE_LABEL, "[%{public}s:%{public}d]: " format, __func__, __LINE__, \
##__VA_ARGS__); \
} \
} while (0)
#define CLOGD(format, ...) \
(void)HiLog::Debug(CAST_ENGINE_LABEL, "[%{public}s:%{public}d]: " format, __func__, __LINE__, ##__VA_ARGS__)
#define CLOGI(format, ...) \
(void)HiLog::Info(CAST_ENGINE_LABEL, "[%{public}s:%{public}d]: " format, __func__, __LINE__, ##__VA_ARGS__)
#define CLOGW(format, ...) \
(void)HiLog::Warn(CAST_ENGINE_LABEL, "[%{public}s:%{public}d]: " format, __func__, __LINE__, ##__VA_ARGS__)
#define CLOGE(format, ...) \
(void)HiLog::Error(CAST_ENGINE_LABEL, "[%{public}s:%{public}d]: " format, __func__, __LINE__, ##__VA_ARGS__)
#define CHECK_AND_RETURN_RET_LOG(cond, ret, fmt, ...) \
do { \
if (cond) { \
CLOGE(fmt, ##__VA_ARGS__); \
return ret; \
} \
} while (0)
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2023 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
*
* Description: Cast engine service related common data stucture definitions.
* Author: zhangge
* Create: 2022-10-26
*/
#ifndef CAST_SERVICE_COMMON_H
#define CAST_SERVICE_COMMON_H
#include <string>
#include "cast_engine_common.h"
namespace OHOS {
namespace CastEngine {
struct CastInnerRemoteDevice {
std::string deviceId;
std::string deviceName;
DeviceType deviceType{ DeviceType::DEVICE_OTHERS };
SubDeviceType subDeviceType{ SubDeviceType::SUB_DEVICE_DEFAULT };
std::string ipAddress;
TriggerType triggerType{ TriggerType::UNSPEC_TAG };
std::string authData;
int sessionId{ INVALID_ID };
ChannelType channelType{ ChannelType::SOFT_BUS };
const uint8_t *sessionKey{ nullptr };
uint32_t sessionKeyLength{ 0 };
};
inline constexpr char PKG_NAME[] = "CastEngineService";
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2023 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
*
* Description: supply a helper to define some methods for stub object.
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef CAST_STUB_HELPER_H
#define CAST_STUB_HELPER_H
#include <map>
#include "cast_engine_log.h"
#include "iremote_stub.h"
namespace OHOS {
namespace CastEngine {
#define DECLARE_STUB_TASK_MAP(className) \
private: \
using className##Func = int32_t (className::*)(MessageParcel &, MessageParcel &); \
std::map<uint32_t, className##Func> taskMap_
#define FILL_SINGLE_STUB_TASK(id, func) taskMap_[id] = (func)
#define RETURN_IF_WRONG_INTERFACE_TOKEN(data) \
if (GetDescriptor() != (data).ReadInterfaceToken()) { \
CLOGE("Invalid interface token"); \
return ERR_FLATTEN_OBJECT; \
}
#define RETRUEN_IF_WRONG_TASK(code, data, reply, option) \
do { \
RETURN_IF_WRONG_INTERFACE_TOKEN(data); \
if (taskMap_.count(code) == 0) { \
CLOGE("Invalid code:%d", code); \
return IPCObjectStub::OnRemoteRequest(code, data, reply, option); \
} \
} while (0)
#define EXECUTE_SINGLE_STUB_TASK(code, data, reply) (this->*taskMap_[code])(data, reply)
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session service listener implement apis.
* Author: zhangge
* Create: 2022-6-15
*/
#ifndef I_CAST_SERVICE_LISTENER_IMPL_H
#define I_CAST_SERVICE_LISTENER_IMPL_H
#include "i_cast_session_manager_listener.h"
#include "iremote_broker.h"
#include "i_cast_session_impl.h"
namespace OHOS {
namespace CastEngine {
class ICastServiceListenerImpl : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CastEngine.ICastServiceListenerImpl");
ICastServiceListenerImpl() = default;
ICastServiceListenerImpl(const ICastServiceListenerImpl &) = delete;
ICastServiceListenerImpl &operator=(const ICastServiceListenerImpl &) = delete;
ICastServiceListenerImpl(ICastServiceListenerImpl &&) = delete;
ICastServiceListenerImpl &operator=(ICastServiceListenerImpl &&) = delete;
~ICastServiceListenerImpl() override = default;
virtual void OnDeviceFound(const std::vector<CastRemoteDevice> &deviceList) = 0;
virtual void OnDeviceOffline(const std::string &deviceId) = 0;
virtual void OnSessionCreated(const sptr<ICastSessionImpl> &castSession) = 0;
virtual void OnServiceDied() = 0;
protected:
enum {
ON_DEVICE_FOUND = 1,
ON_DEVICE_OFFLINE,
ON_SESSION_CREATE,
ON_SERVICE_DIE
};
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session interface.
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef I_CAST_SESSION_IMPL_H
#define I_CAST_SESSION_IMPL_H
#include <string>
#include "cast_engine_common.h"
#include "cast_service_common.h"
#include "i_cast_session.h"
#include "i_cast_session_listener_impl.h"
#include "iremote_broker.h"
#include "oh_remote_control_event.h"
#include "surface_utils.h"
#include "i_stream_player_ipc.h"
#include "i_mirror_player_impl.h"
namespace OHOS {
namespace CastEngine {
class ICastSessionImpl : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CastEngine.ICastSessionImpl");
ICastSessionImpl() = default;
ICastSessionImpl(const ICastSessionImpl &) = delete;
ICastSessionImpl &operator=(const ICastSessionImpl &) = delete;
ICastSessionImpl(ICastSessionImpl &&) = delete;
ICastSessionImpl &operator=(ICastSessionImpl &&) = delete;
~ICastSessionImpl() override = default;
virtual int32_t RegisterListener(sptr<ICastSessionListenerImpl> listener) = 0;
virtual int32_t UnregisterListener() = 0;
virtual int32_t AddDevice(const CastRemoteDevice &remoteDevice) = 0;
virtual int32_t RemoveDevice(const std::string &deviceId) = 0;
virtual int32_t StartAuth(const AuthInfo &authInfo) = 0;
virtual int32_t GetSessionId(std::string &sessionId) = 0;
virtual int32_t GetDeviceState(const std::string &deviceId, DeviceState &deviceState) = 0;
virtual int32_t SetSessionProperty(const CastSessionProperty &property) = 0;
virtual int32_t CreateMirrorPlayer(sptr<IMirrorPlayerImpl> &mirrorPlayer) = 0;
virtual int32_t CreateStreamPlayer(sptr<IStreamPlayerIpc> &streamPlayer) = 0;
virtual int32_t Release() = 0;
virtual int32_t NotifyEvent(EventId eventId, std::string &jsonParam) = 0;
virtual int32_t SetCastMode(CastMode mode, std::string &jsonParam) = 0;
virtual bool AddDevice(const CastInnerRemoteDevice &remoteDevice)
{
return false;
}
virtual bool ReleaseSessionResources(pid_t pid)
{
return false;
}
virtual void Stop() {}
protected:
enum {
REGISTER_LISTENER = 1,
UNREGISTER_LISTENER,
ADD_DEVICE,
REMOVE_DEVICE,
START_AUTH,
GET_SESSION_ID,
GET_DEVICE_STATE,
SET_SESSION_PROPERTY,
CREAT_MIRROR_PLAYER,
CREAT_STREAM_PLAYER,
RELEASE,
NOTIFY_EVENT,
SET_CAST_MODE,
};
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 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
*
* Description: Cast session listener implement interface.
* Author: zhangge
* Create: 2022-6-15
*/
#ifndef I_CAST_SESSION_LISTENER_IMPL_H
#define I_CAST_SESSION_LISTENER_IMPL_H
#include "cast_engine_common.h"
#include "i_cast_session.h"
#include "iremote_broker.h"
namespace OHOS {
namespace CastEngine {
class ICastSessionListenerImpl : public IRemoteBroker, public ICastSessionListener {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CastEngine.ICastSessionListenerImpl");
ICastSessionListenerImpl() = default;
ICastSessionListenerImpl(const ICastSessionListenerImpl &) = delete;
ICastSessionListenerImpl &operator=(const ICastSessionListenerImpl &) = delete;
ICastSessionListenerImpl(ICastSessionListenerImpl &&) = delete;
ICastSessionListenerImpl &operator=(ICastSessionListenerImpl &&) = delete;
~ICastSessionListenerImpl() override = default;
protected:
enum {
ON_DEVICE_STATE = 1,
ON_EVENT
};
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager service base class.
* Author: zhangge
* Create: 2022-6-15
*/
#ifndef I_CAST_SESSION_MANAGER_SERVICE_H
#define I_CAST_SESSION_MANAGER_SERVICE_H
#include "cast_engine_common.h"
#include "i_cast_session_manager_listener.h"
#include "i_cast_session_impl.h"
#include "i_cast_service_listener_impl.h"
#include "iremote_broker.h"
namespace OHOS {
namespace CastEngine {
class ICastSessionManagerService : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CastEngine.ICastSessionManagerService");
ICastSessionManagerService() = default;
ICastSessionManagerService(const ICastSessionManagerService &) = delete;
ICastSessionManagerService &operator=(const ICastSessionManagerService &) = delete;
ICastSessionManagerService(ICastSessionManagerService &&) = delete;
ICastSessionManagerService &operator=(ICastSessionManagerService &&) = delete;
~ICastSessionManagerService() override = default;
virtual int32_t RegisterListener(sptr<ICastServiceListenerImpl> listener) = 0;
virtual int32_t UnregisterListener() = 0;
virtual int32_t Release() = 0;
virtual int32_t SetLocalDevice(const CastLocalDevice &localDevice) = 0;
virtual int32_t CreateCastSession(const CastSessionProperty &property, sptr<ICastSessionImpl> &castSession) = 0;
virtual int32_t SetSinkSessionCapacity(int sessionCapacity) = 0;
virtual int32_t StartDiscovery(int protocols) = 0;
virtual int32_t SetDiscoverable(bool enable) = 0;
virtual int32_t StopDiscovery() = 0;
virtual int32_t GetCastSession(std::string sessionId, sptr<ICastSessionImpl> &castSession) = 0;
protected:
enum {
REGISTER_LISTENER = 0,
UNREGISTER_LISTENER,
RELEASE,
SET_LOCAL_DEVICE,
CREATE_CAST_SESSION,
SET_SINK_SESSION_CAPACITY,
START_DISCOVERY,
SET_DISCOVERABLE,
STOP_DISCOVERY,
GET_CAST_SESSION
};
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast mirror player interface.
* Author: zhangjingnan
* Create: 2023-05-27
*/
#ifndef I_CAST_MIRROR_PLAYER_IMPL_H
#define I_CAST_MIRROR_PLAYER_IMPL_H
#include <string>
#include "iremote_broker.h"
#include "oh_remote_control_event.h"
#include "surface_utils.h"
namespace OHOS {
namespace CastEngine {
class IMirrorPlayerImpl : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CastEngine.IMirrorPlayerImpl");
IMirrorPlayerImpl() = default;
IMirrorPlayerImpl(const IMirrorPlayerImpl &) = delete;
IMirrorPlayerImpl &operator=(const IMirrorPlayerImpl &) = delete;
IMirrorPlayerImpl(IMirrorPlayerImpl &&) = delete;
IMirrorPlayerImpl &operator=(IMirrorPlayerImpl &&) = delete;
~IMirrorPlayerImpl() override = default;
virtual int32_t Play(const std::string &deviceId) = 0;
virtual int32_t Pause(const std::string &deviceId) = 0;
virtual int32_t SetSurface(sptr<IBufferProducer> producer) = 0;
virtual int32_t DeliverInputEvent(const OHRemoteControlEvent &event) = 0;
virtual int32_t Release() = 0;
protected:
enum {
PLAY = 1,
PAUSE,
SET_SURFACE,
DELIVER_INPUT_EVENT,
RELEASE
};
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2023 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
*
* Description: supply stream player implement interface.
* Author: huangchanggui
* Create: 2023-01-12
*/
#ifndef I_STREAM_PLAYER_IMPL_H
#define I_STREAM_PLAYER_IMPL_H
#include <string>
#include "surface_utils.h"
#include "cast_engine_common.h"
#include "cast_service_common.h"
#include "i_stream_player_listener_impl.h"
#include "iremote_broker.h"
namespace OHOS {
namespace CastEngine {
class IStreamPlayerImpl : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CastEngine.IStreamPlayerImpl");
IStreamPlayerImpl() = default;
IStreamPlayerImpl(const IStreamPlayerImpl &) = delete;
IStreamPlayerImpl &operator=(const IStreamPlayerImpl &) = delete;
IStreamPlayerImpl(IStreamPlayerImpl &&) = delete;
IStreamPlayerImpl &operator=(IStreamPlayerImpl &&) = delete;
virtual ~IStreamPlayerImpl() override = default;
virtual int32_t RegisterListener(sptr<IStreamPlayerListenerImpl> listener) = 0;
virtual int32_t UnregisterListener() = 0;
virtual int32_t SetSurface(sptr<IBufferProducer> producer) = 0;
virtual int32_t Load(const MediaInfo &mediaInfo) = 0;
virtual int32_t Play(const MediaInfo &mediaInfo) = 0;
virtual int32_t Play(int index) = 0;
virtual int32_t Play() = 0;
virtual int32_t Pause() = 0;
virtual int32_t Stop() = 0;
virtual int32_t Next() = 0;
virtual int32_t Previous() = 0;
virtual int32_t Seek(int position) = 0;
virtual int32_t SetVolume(int volume) = 0;
virtual int32_t SetLoopMode(const LoopMode mode) = 0;
virtual int32_t SetSpeed(const PlaybackSpeed speed) = 0;
virtual int32_t GetPlayerStatus(PlayerStates &playerStates) = 0;
virtual int32_t GetPosition(int &position) = 0;
virtual int32_t GetDuration(int &duration) = 0;
virtual int32_t GetVolume(int &volume, int &maxVolume) = 0;
virtual int32_t GetLoopMode(LoopMode &loopMode) = 0;
virtual int32_t GetPlaySpeed(PlaybackSpeed &playbackSpeed) = 0;
virtual int32_t GetMediaInfoHolder(MediaInfoHolder &mediaInfoHolder) = 0;
virtual int32_t Release() = 0;
protected:
enum {
REGISTER_LISTENER = 1,
UNREGISTER_LISTENER,
SET_SURFACE,
PLAY_INDEX,
LOAD,
START,
PAUSE,
PLAY,
STOP,
NEXT,
PREVIOUS,
SEEK,
SET_VOLUME,
SET_LOOP_MODE,
SET_SPEED,
GET_PLAYER_STATUS,
GET_POSITION,
GET_DURATION,
GET_VOLUME,
GET_LOOP_MODE,
GET_PLAY_SPEED,
GET_MEDIA_INFO_HOLDER,
RELEASE
};
static const size_t MAX_PLAY_LIST_SIZE = 100;
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2023 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
*
* Description: supply stream player implement ipc interface.
* Author: zhangjingnan
* Create: 2023-08-29
*/
#ifndef I_STREAM_PLAYER_IPC_H
#define I_STREAM_PLAYER_IPC_H
#include <string>
#include "surface_utils.h"
#include "cast_engine_common.h"
#include "cast_service_common.h"
#include "i_stream_player_listener_impl.h"
#include "iremote_broker.h"
namespace OHOS {
namespace CastEngine {
class IStreamPlayerIpc : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CastEngine.IStreamPlayerIpc");
IStreamPlayerIpc() = default;
IStreamPlayerIpc(const IStreamPlayerIpc &) = delete;
IStreamPlayerIpc &operator=(const IStreamPlayerIpc &) = delete;
IStreamPlayerIpc(IStreamPlayerIpc &&) = delete;
IStreamPlayerIpc &operator=(IStreamPlayerIpc &&) = delete;
virtual ~IStreamPlayerIpc() override = default;
virtual int32_t RegisterListener(sptr<IStreamPlayerListenerImpl> listener) = 0;
virtual int32_t UnregisterListener() = 0;
virtual int32_t SetSurface(sptr<IBufferProducer> producer) = 0;
virtual int32_t Load(const MediaInfo &mediaInfo) = 0;
virtual int32_t Play(const MediaInfo &mediaInfo) = 0;
virtual int32_t Play(int index) = 0;
virtual int32_t Play() = 0;
virtual int32_t Pause() = 0;
virtual int32_t Stop() = 0;
virtual int32_t Next() = 0;
virtual int32_t Previous() = 0;
virtual int32_t Seek(int position) = 0;
virtual int32_t FastForward(int delta) = 0;
virtual int32_t FastRewind(int delta) = 0;
virtual int32_t SetVolume(int volume) = 0;
virtual int32_t SetLoopMode(const LoopMode mode) = 0;
virtual int32_t SetSpeed(const PlaybackSpeed speed) = 0;
virtual int32_t GetPlayerStatus(PlayerStates &playerStates) = 0;
virtual int32_t GetPosition(int &position) = 0;
virtual int32_t GetDuration(int &duration) = 0;
virtual int32_t GetVolume(int &volume, int &maxVolume) = 0;
virtual int32_t GetLoopMode(LoopMode &loopMode) = 0;
virtual int32_t GetPlaySpeed(PlaybackSpeed &playbackSpeed) = 0;
virtual int32_t GetMediaInfoHolder(MediaInfoHolder &mediaInfoHolder) = 0;
virtual int32_t Release() = 0;
protected:
enum {
REGISTER_LISTENER = 1,
UNREGISTER_LISTENER,
SET_SURFACE,
PLAY_INDEX,
LOAD,
START,
PAUSE,
PLAY,
STOP,
NEXT,
PREVIOUS,
SEEK,
FAST_FORWARD,
FAST_REWIND,
SET_VOLUME,
SET_LOOP_MODE,
SET_SPEED,
GET_PLAYER_STATUS,
GET_POSITION,
GET_DURATION,
GET_VOLUME,
GET_LOOP_MODE,
GET_PLAY_SPEED,
GET_MEDIA_INFO_HOLDER,
RELEASE
};
static const size_t MAX_PLAY_LIST_SIZE = 100;
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2023 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
*
* Description: Stream player listener implement interface.
* Author: huangchanggui
* Create: 2023-01-12
*/
#ifndef I_STREAM_PLAYER_LISTENER_IMPL_H
#define I_STREAM_PLAYER_LISTENER_IMPL_H
#include "cast_engine_common.h"
#include "iremote_broker.h"
namespace OHOS {
namespace CastEngine {
class IStreamPlayerListenerImpl : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.CastEngine.IStreamPlayerListenerImpl");
IStreamPlayerListenerImpl() = default;
IStreamPlayerListenerImpl(const IStreamPlayerListenerImpl &) = delete;
IStreamPlayerListenerImpl &operator=(const IStreamPlayerListenerImpl &) = delete;
IStreamPlayerListenerImpl(IStreamPlayerListenerImpl &&) = delete;
IStreamPlayerListenerImpl &operator=(IStreamPlayerListenerImpl &&) = delete;
virtual ~IStreamPlayerListenerImpl() override = default;
virtual void OnStateChanged(const PlayerStates playbackState, bool isPlayWhenReady) = 0;
virtual void OnPositionChanged(int position, int bufferPosition, int duration) = 0;
virtual void OnMediaItemChanged(const MediaInfo &mediaInfo) = 0;
virtual void OnVolumeChanged(int volume, int maxVolume) = 0;
virtual void OnPlayerError(int errorCode, const std::string &errorMsg) = 0;
virtual void OnVideoSizeChanged(int width, int height) = 0;
virtual void OnLoopModeChanged(const LoopMode loopMode) = 0;
virtual void OnPlaySpeedChanged(const PlaybackSpeed speed) = 0;
virtual void OnNextRequest() = 0;
virtual void OnPreviousRequest() = 0;
virtual void OnSeekDone(int position) = 0;
virtual void OnEndOfStream(int isLooping) = 0;
virtual void OnPlayRequest(const MediaInfo &mediaInfo) = 0;
protected:
enum {
ON_PLAYER_STATUS_CHANGED = 1,
ON_POSITION_CHANGED,
ON_MEDIA_ITEM_CHANGED,
ON_VOLUME_CHANGED,
ON_REPEAT_MODE_CHANGED,
ON_PLAY_SPEED_CHANGED,
ON_PLAYER_ERROR,
ON_VIDEO_SIZE_CHANGED,
ON_NEXT_REQUEST,
ON_PREVIOUS_REQUEST,
ON_SEEK_DONE,
ON_END_OF_STREAM,
ON_PLAY_REQUEST
};
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,701 @@
/*
* Copyright (c) 2023 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
*
* Description: supply a helper to write/read common cast engine structures through ipc
* Author: zhangge
* Create: 2022-06-15
*/
#include "cast_engine_common_helper.h"
#include <optional>
#include "cast_engine_log.h"
#include "securec.h"
namespace OHOS {
namespace CastEngine {
DEFINE_CAST_ENGINE_LABEL("Cast-Engine-helper");
namespace {
bool WriteVideoSize(Parcel &parcel, const VideoSize &videoSize)
{
return parcel.WriteInt32(videoSize.width) && parcel.WriteInt32(videoSize.height);
}
const VideoSize ReadVideoSize(Parcel &parcel)
{
return { static_cast<uint32_t>(parcel.ReadInt32()), static_cast<uint32_t>(parcel.ReadInt32()) };
}
bool WriteWindowProperty(Parcel &parcel, const WindowProperty &property)
{
return parcel.WriteInt32(property.startX) && parcel.WriteInt32(property.startY) &&
parcel.WriteInt32(property.width) && parcel.WriteInt32(property.height);
}
const WindowProperty ReadWindowProperty(Parcel &parcel)
{
WindowProperty property;
property.startX = static_cast<uint32_t>(parcel.ReadInt32());
property.startY = static_cast<uint32_t>(parcel.ReadInt32());
property.width = static_cast<uint32_t>(parcel.ReadInt32());
property.height = static_cast<uint32_t>(parcel.ReadInt32());
return property;
}
bool WriteVideoProperty(Parcel &parcel, const VideoProperty &property)
{
return parcel.WriteInt32(static_cast<int32_t>(property.videoWidth)) &&
parcel.WriteInt32(static_cast<int32_t>(property.videoHeight)) &&
parcel.WriteInt32(static_cast<int32_t>(property.fps)) &&
parcel.WriteInt32(static_cast<int32_t>(property.codecType)) &&
parcel.WriteInt32(static_cast<int32_t>(property.gop)) &&
parcel.WriteInt32(static_cast<int32_t>(property.bitrate)) &&
parcel.WriteInt32(static_cast<int32_t>(property.minBitrate)) &&
parcel.WriteInt32(static_cast<int32_t>(property.maxBitrate)) &&
parcel.WriteInt32(static_cast<int32_t>(property.dpi)) &&
parcel.WriteInt32(static_cast<int32_t>(property.colorStandard)) &&
parcel.WriteInt32(static_cast<int32_t>(property.screenWidth)) &&
parcel.WriteInt32(static_cast<int32_t>(property.screenHeight)) &&
parcel.WriteInt32(static_cast<int32_t>(property.profile)) &&
parcel.WriteInt32(static_cast<int32_t>(property.level));
}
std::optional<VideoProperty> ReadVideoProperty(Parcel &parcel)
{
VideoProperty property;
property.videoWidth = static_cast<uint32_t>(parcel.ReadInt32());
property.videoHeight = static_cast<uint32_t>(parcel.ReadInt32());
property.fps = static_cast<uint32_t>(parcel.ReadInt32());
auto codecType = parcel.ReadInt32();
property.gop = static_cast<uint32_t>(parcel.ReadInt32());
property.bitrate = static_cast<uint32_t>(parcel.ReadInt32());
property.minBitrate = static_cast<uint32_t>(parcel.ReadInt32());
property.maxBitrate = static_cast<uint32_t>(parcel.ReadInt32());
property.dpi = static_cast<uint32_t>(parcel.ReadInt32());
auto colorStandard = parcel.ReadInt32();
property.screenWidth = static_cast<uint32_t>(parcel.ReadInt32());
property.screenHeight = static_cast<uint32_t>(parcel.ReadInt32());
property.profile = static_cast<uint32_t>(parcel.ReadInt32());
property.level = static_cast<uint32_t>(parcel.ReadInt32());
if (!IsColorStandard(colorStandard) || !IsVideoCodecType(codecType)) {
return std::nullopt;
}
property.codecType = static_cast<VideoCodecType>(codecType);
property.colorStandard = static_cast<ColorStandard>(colorStandard);
return property;
}
bool WriteAudioProperty(Parcel &parcel, const AudioProperty &property)
{
return parcel.WriteInt32(static_cast<int32_t>(property.sampleRate)) &&
parcel.WriteInt32(static_cast<int32_t>(property.sampleBitWidth)) &&
parcel.WriteInt32(static_cast<int32_t>(property.channelConfig)) &&
parcel.WriteInt32(static_cast<int32_t>(property.bitrate)) &&
parcel.WriteInt32(static_cast<int32_t>(property.codec));
}
const AudioProperty ReadAudioProperty(Parcel &parcel)
{
AudioProperty property;
property.sampleRate = static_cast<uint32_t>(parcel.ReadInt32());
property.sampleBitWidth = static_cast<uint8_t>(parcel.ReadInt32());
property.channelConfig = static_cast<uint32_t>(parcel.ReadInt32());
property.bitrate = static_cast<uint32_t>(parcel.ReadInt32());
property.codec = static_cast<uint32_t>(parcel.ReadInt32());
return property;
}
int GetLocalFd(const std::string &url)
{
char *nextPtr = nullptr;
int fd = static_cast<int>(std::strtol(url.c_str(), &nextPtr, DECIMALISM));
if (errno == ERANGE || *nextPtr != '\0') {
return INVALID_VALUE;
}
return fd;
}
} // namespace
bool WriteCastRemoteDevice(Parcel &parcel, const CastRemoteDevice &device)
{
return parcel.WriteInt32(static_cast<int32_t>(device.deviceType)) &&
parcel.WriteInt32(static_cast<int32_t>(device.subDeviceType)) &&
parcel.WriteInt32(static_cast<int32_t>(device.channelType)) && parcel.WriteString(device.deviceId) &&
parcel.WriteString(device.deviceName) && parcel.WriteString(device.ipAddress);
}
bool ReadCastRemoteDevice(Parcel &parcel, CastRemoteDevice &device)
{
auto remote = ReadCastRemoteDevice(parcel);
if (remote == nullptr) {
CLOGE("ReadCastRemoteDevice failed");
return false;
}
device = *remote;
return true;
}
std::unique_ptr<CastRemoteDevice> ReadCastRemoteDevice(Parcel &parcel)
{
auto device = std::make_unique<CastRemoteDevice>();
auto deviceType = parcel.ReadInt32();
auto subDeviceType = parcel.ReadInt32();
auto channelType = parcel.ReadInt32();
device->deviceType = static_cast<DeviceType>(deviceType);
device->subDeviceType = static_cast<SubDeviceType>(subDeviceType);
device->channelType = static_cast<ChannelType>(channelType);
device->deviceId = parcel.ReadString();
device->deviceName = parcel.ReadString();
device->ipAddress = parcel.ReadString();
if (!IsDeviceType(deviceType) || !IsSubDeviceType(subDeviceType) || !IsChannelType(channelType)) {
CLOGE("ReadCastRemoteDevice error");
return nullptr;
}
return device;
}
bool WriteMediaInfo(MessageParcel &parcel, const MediaInfo &mediaInfo)
{
if (mediaInfo.mediaUrl.empty()) {
CLOGE("mediaUrl is empty");
return false;
}
int fd = GetLocalFd(mediaInfo.mediaUrl);
if (fd != INVALID_VALUE) {
if (!parcel.WriteString("localFd") || !parcel.WriteFileDescriptor(fd)) {
CLOGE("Write local fd failed, fd = %{public}d", fd);
return false;
}
} else if (!parcel.WriteString("path") || !parcel.WriteString(mediaInfo.mediaUrl)) {
CLOGE("Write path failed");
return false;
}
return parcel.WriteString(mediaInfo.mediaId) && parcel.WriteString(mediaInfo.mediaName) &&
parcel.WriteString(mediaInfo.mediaType) && parcel.WriteUint32(mediaInfo.mediaSize) &&
parcel.WriteString(mediaInfo.albumCoverUrl) && parcel.WriteString(mediaInfo.albumTitle) &&
parcel.WriteString(mediaInfo.mediaArtist) && parcel.WriteString(mediaInfo.lrcUrl) &&
parcel.WriteString(mediaInfo.lrcContent) && parcel.WriteString(mediaInfo.appIconUrl) &&
parcel.WriteString(mediaInfo.appName) && parcel.WriteUint32(mediaInfo.startPosition) &&
parcel.WriteUint32(mediaInfo.duration) && parcel.WriteUint32(mediaInfo.closingCreditsPosition);
}
std::unique_ptr<MediaInfo> ReadMediaInfo(MessageParcel &parcel)
{
auto mediaInfo = std::make_unique<MediaInfo>();
if (mediaInfo == nullptr) {
CLOGE("Failed to malloc mediaInfo");
return nullptr;
}
std::string urlType = parcel.ReadString();
if (urlType == "localFd") {
CLOGD("localFd");
mediaInfo->mediaUrl = std::to_string(parcel.ReadFileDescriptor());
} else {
CLOGD("online or localPath");
mediaInfo->mediaUrl = parcel.ReadString();
}
mediaInfo->mediaId = parcel.ReadString();
mediaInfo->mediaName = parcel.ReadString();
mediaInfo->mediaType = parcel.ReadString();
mediaInfo->mediaSize = parcel.ReadUint32();
mediaInfo->albumCoverUrl = parcel.ReadString();
mediaInfo->albumTitle = parcel.ReadString();
mediaInfo->mediaArtist = parcel.ReadString();
mediaInfo->lrcUrl = parcel.ReadString();
mediaInfo->lrcContent = parcel.ReadString();
mediaInfo->appIconUrl = parcel.ReadString();
mediaInfo->appName = parcel.ReadString();
mediaInfo->startPosition = parcel.ReadUint32();
mediaInfo->duration = parcel.ReadUint32();
mediaInfo->closingCreditsPosition = parcel.ReadUint32();
return mediaInfo;
}
bool WriteMediaInfoHolder(MessageParcel &parcel, const MediaInfoHolder &mediaInfoHolder)
{
bool ret = parcel.WriteUint32(mediaInfoHolder.currentIndex);
ret = ret && parcel.WriteUint32(mediaInfoHolder.progressRefreshInterval);
ret = ret && parcel.WriteUint32(static_cast<uint32_t>(mediaInfoHolder.mediaInfoList.size()));
for (auto iter = mediaInfoHolder.mediaInfoList.begin(); iter != mediaInfoHolder.mediaInfoList.end(); iter++) {
ret = ret && WriteMediaInfo(parcel, *iter);
}
return ret;
}
std::unique_ptr<MediaInfoHolder> ReadMediaInfoHolder(MessageParcel &parcel)
{
auto mediaInfoHolder = std::make_unique<MediaInfoHolder>();
if (mediaInfoHolder == nullptr) {
CLOGE("Failed to malloc mediaInfoHolder");
return nullptr;
}
mediaInfoHolder->currentIndex = parcel.ReadUint32();
mediaInfoHolder->progressRefreshInterval = parcel.ReadUint32();
uint32_t infoListSize = parcel.ReadUint32();
if (infoListSize > MAX_FILE_NUM) {
CLOGE("The number of list exceeds the upper limit. infoListSize: %{public}u", infoListSize);
return nullptr;
}
for (uint32_t i = 0; i < infoListSize; i++) {
auto mediaInfo = ReadMediaInfo(parcel);
if (mediaInfo == nullptr) {
return nullptr;
}
mediaInfoHolder->mediaInfoList.push_back(*mediaInfo);
}
return mediaInfoHolder;
}
bool WriteCastLocalDevice(Parcel &parcel, const CastLocalDevice &device)
{
return parcel.WriteString(device.deviceId) && parcel.WriteString(device.deviceName) &&
parcel.WriteInt32(static_cast<int32_t>(device.deviceType)) &&
parcel.WriteInt32(static_cast<int32_t>(device.subDeviceType)) && parcel.WriteString(device.ipAddress) &&
parcel.WriteInt32(static_cast<int32_t>(device.triggerType)) && parcel.WriteString(device.authData);
}
std::unique_ptr<CastLocalDevice> ReadCastLocalDevice(Parcel &parcel)
{
auto device = std::make_unique<CastLocalDevice>();
device->deviceId = parcel.ReadString();
device->deviceName = parcel.ReadString();
auto deviceType = parcel.ReadInt32();
auto subDeviceType = parcel.ReadInt32();
device->ipAddress = parcel.ReadString();
auto triggerType = parcel.ReadInt32();
device->authData = parcel.ReadString();
if (!IsDeviceType(deviceType) || !IsSubDeviceType(subDeviceType) || !IsTriggerType(triggerType)) {
CLOGE("ReadCastLocalDevice error");
return nullptr;
}
device->deviceType = static_cast<DeviceType>(deviceType);
device->subDeviceType = static_cast<SubDeviceType>(subDeviceType);
device->triggerType = static_cast<TriggerType>(triggerType);
return device;
}
bool WriteCastSessionProperty(Parcel &parcel, const CastSessionProperty &property)
{
return parcel.WriteInt32(static_cast<int32_t>(property.protocolType)) &&
parcel.WriteInt32(static_cast<int32_t>(property.endType)) &&
WriteAudioProperty(parcel, property.audioProperty) && WriteVideoProperty(parcel, property.videoProperty) &&
WriteWindowProperty(parcel, property.windowProperty);
}
std::unique_ptr<CastSessionProperty> ReadCastSessionProperty(Parcel &parcel)
{
auto property = std::make_unique<CastSessionProperty>();
if (property == nullptr) {
CLOGE("Failed to malloc cast session property");
return nullptr;
}
auto protocolType = parcel.ReadInt32();
if (!IsProtocolType(protocolType)) {
return nullptr;
}
auto endType = parcel.ReadInt32();
if (!IsEndType(endType)) {
return nullptr;
}
property->protocolType = static_cast<ProtocolType>(protocolType);
property->endType = static_cast<EndType>(endType);
property->audioProperty = ReadAudioProperty(parcel);
auto videoProperty = ReadVideoProperty(parcel);
if (videoProperty == std::nullopt) {
return nullptr;
}
property->videoProperty = videoProperty.value();
property->windowProperty = ReadWindowProperty(parcel);
return property;
}
bool WritePropertyContainer(Parcel &parcel, const PropertyContainer &container)
{
return parcel.WriteInt32(static_cast<int32_t>(container.type)) &&
(((container.type == PropertyType::VIDEO_SIZE) && WriteVideoSize(parcel, container.videoSize)) ||
((container.type == PropertyType::VIDEO_FPS) && parcel.WriteInt32(container.videoFps)) ||
((container.type == PropertyType::WINDOW_SIZE) && WriteWindowProperty(parcel, container.windowProperty)));
}
std::unique_ptr<PropertyContainer> ReadPropertyContainer(Parcel &parcel)
{
auto container = std::make_unique<PropertyContainer>();
if (container == nullptr) {
CLOGE("Failed to malloc property container");
return nullptr;
}
int32_t type = parcel.ReadInt32();
if (!IsPropertyType(type)) {
return nullptr;
}
container->type = static_cast<PropertyType>(type);
if (container->type == PropertyType::VIDEO_SIZE) {
container->videoSize = ReadVideoSize(parcel);
} else if (container->type == PropertyType::VIDEO_FPS) {
container->videoFps = static_cast<unsigned int>(parcel.ReadInt32());
} else {
container->windowProperty = ReadWindowProperty(parcel);
}
return container;
}
bool WriteAuthInfo(Parcel &parcel, const AuthInfo &authInfo)
{
return parcel.WriteInt32(static_cast<int32_t>(authInfo.authMode)) &&
parcel.WriteInt32(static_cast<int32_t>(authInfo.authCode)) && parcel.WriteString(authInfo.deviceId);
}
std::unique_ptr<AuthInfo> ReadAuthInfo(Parcel &parcel)
{
auto authInfo = std::make_unique<AuthInfo>();
if (authInfo == nullptr) {
CLOGE("Failed to malloc auth info");
return nullptr;
}
authInfo->authMode = static_cast<int>(parcel.ReadInt32());
authInfo->authCode = static_cast<uint32_t>(parcel.ReadInt32());
authInfo->deviceId = parcel.ReadString();
return authInfo;
}
bool WriteTouchPoint(Parcel &parcel, const OHNativeXcomponentTouchPoint &touchPoint)
{
return parcel.WriteInt32(touchPoint.id) && parcel.WriteFloat(touchPoint.screenX) &&
parcel.WriteFloat(touchPoint.screenY) && parcel.WriteFloat(touchPoint.x) && parcel.WriteFloat(touchPoint.y) &&
parcel.WriteUint32(static_cast<uint32_t>(touchPoint.type)) && parcel.WriteDouble(touchPoint.size) &&
parcel.WriteFloat(touchPoint.force) && parcel.WriteInt64(touchPoint.timeStamp) &&
parcel.WriteBool(touchPoint.isPressed);
}
bool WriteTouchPoints(Parcel &parcel, const OHNativeXcomponentTouchEvent touchEvent)
{
for (uint32_t i = 0; i < touchEvent.numPoints; i++) {
if (!WriteTouchPoint(parcel, touchEvent.touchPoints[i])) {
return false;
}
}
return true;
}
bool WriteTouchEvent(Parcel &parcel, const OHNativeXcomponentTouchEvent &touchEvent)
{
return parcel.WriteInt32(touchEvent.id) && parcel.WriteFloat(touchEvent.screenX) &&
parcel.WriteFloat(touchEvent.screenY) && parcel.WriteFloat(touchEvent.x) && parcel.WriteFloat(touchEvent.y) &&
parcel.WriteUint32(static_cast<uint32_t>(touchEvent.type)) && parcel.WriteDouble(touchEvent.size) &&
parcel.WriteFloat(touchEvent.force) && parcel.WriteInt64(touchEvent.deviceId) &&
parcel.WriteInt64(touchEvent.timeStamp) && parcel.WriteUint32(touchEvent.numPoints) &&
WriteTouchPoints(parcel, touchEvent);
}
bool WriteMouseEvent(Parcel &parcel, const OHNativeXcomponentMouseEvent &mouseEvent)
{
return parcel.WriteFloat(mouseEvent.x) && parcel.WriteFloat(mouseEvent.y) &&
parcel.WriteFloat(mouseEvent.screenX) && parcel.WriteFloat(mouseEvent.screenY) &&
parcel.WriteInt64(mouseEvent.timestamp) && parcel.WriteUint32(static_cast<uint32_t>(mouseEvent.action)) &&
parcel.WriteUint32(static_cast<uint32_t>(mouseEvent.button));
}
bool WriteWhellEvent(Parcel &parcel, const OHNativeXcomponentWheelEvent &wheelEvent)
{
return parcel.WriteUint32(static_cast<uint32_t>(wheelEvent.direction)) &&
parcel.WriteUint8(wheelEvent.indication) && parcel.WriteUint8(wheelEvent.scrollUnit) &&
parcel.WriteUint16(wheelEvent.wheelDis) && parcel.WriteFloat(wheelEvent.x) && parcel.WriteFloat(wheelEvent.y);
}
bool WriteKeyEvent(Parcel &parcel, const OHNativeXcomponentKeyEvent &keyEvent)
{
return parcel.WriteUint8(keyEvent.reserved) && parcel.WriteUint16(keyEvent.keyCode1) &&
parcel.WriteUint16(keyEvent.keyCode2) && parcel.WriteUint32(keyEvent.metaState) &&
parcel.WriteUint32(static_cast<uint32_t>(keyEvent.type));
}
bool WriteContentEvent(Parcel &parcel, const OHNativeXcomponentContentEvent &contentEvent)
{
return parcel.WriteUint16(contentEvent.msgLen) && parcel.WriteCString(contentEvent.inputText);
}
bool WriteFocusEvent(Parcel &parcel, const OHNativeXcomponentFocusEvent &focusEvent)
{
return parcel.WriteUint8(focusEvent.focusStat) && parcel.WriteDouble(focusEvent.cursorX1) &&
parcel.WriteDouble(focusEvent.cursorY1) && parcel.WriteDouble(focusEvent.cursorX2) &&
parcel.WriteDouble(focusEvent.cursorY2);
}
bool WriteInputMethodEvent(Parcel &parcel, const OHNativeXcomponentInputMethodEvent &inputMethodEvent)
{
return parcel.WriteUint32(static_cast<uint32_t>(inputMethodEvent.type)) &&
(((inputMethodEvent.type == OHNativeXcomponentInputMethodEventType::OH_NATIVEXCOMPONENT_INPUT_CONTENT) &&
WriteContentEvent(parcel, inputMethodEvent.contentEvent)) ||
((inputMethodEvent.type == OHNativeXcomponentInputMethodEventType::OH_NATIVEXCOMPONENT_INPUT_FOCUS) &&
WriteFocusEvent(parcel, inputMethodEvent.focusEvent)));
}
bool WriteVirtualKeyEvent(Parcel &parcel, const OHNativeXcomponentVirtualKeyEvent &virtualKeyEvent)
{
return parcel.WriteInt32(static_cast<int32_t>(virtualKeyEvent.type)) && parcel.WriteFloat(virtualKeyEvent.x) &&
parcel.WriteFloat(virtualKeyEvent.y);
}
bool WriteRemoteControlEvent(Parcel &parcel, const OHRemoteControlEvent &event)
{
return parcel.WriteInt32(static_cast<int32_t>(event.eventType)) &&
(((event.eventType == XcomponentEventType::REMOTECONTROL_TOUCH) && WriteTouchEvent(parcel, event.touchEvent)) ||
((event.eventType == XcomponentEventType::REMOTECONTROL_MOUSE) && WriteMouseEvent(parcel, event.mouseEvent)) ||
((event.eventType == XcomponentEventType::REMOTECONTROL_WHEEL) && WriteWhellEvent(parcel, event.wheelEvent)) ||
((event.eventType == XcomponentEventType::REMOTECONTROL_KEY) && WriteKeyEvent(parcel, event.keyEvent)) ||
((event.eventType == XcomponentEventType::REMOTECONTROL_INPUT_METHOD) &&
WriteInputMethodEvent(parcel, event.inputMethodEvent)) ||
((event.eventType == XcomponentEventType::REMOTECONTROL_VIRTUAL_KEY) &&
WriteVirtualKeyEvent(parcel, event.virtualKeyEvent)));
}
const OHNativeXcomponentTouchPoint ReadTouchPoint(Parcel &parcel)
{
return { parcel.ReadInt32(), parcel.ReadFloat(),
parcel.ReadFloat(), parcel.ReadFloat(),
parcel.ReadFloat(), static_cast<OHNativeXcomponentTouchEventType>(parcel.ReadUint32()),
parcel.ReadDouble(), parcel.ReadFloat(),
parcel.ReadInt64(), parcel.ReadBool() };
}
void ReadTouchPoints(Parcel &parcel, uint32_t numPoints, OHNativeXcomponentTouchPoint points[])
{
for (uint32_t i = 0; i < numPoints; i++) {
points[i] = ReadTouchPoint(parcel);
}
}
void ReadTouchEvent(Parcel &parcel, OHNativeXcomponentTouchEvent &touchEvent)
{
touchEvent.id = parcel.ReadInt32();
touchEvent.screenX = parcel.ReadFloat();
touchEvent.screenY = parcel.ReadFloat();
touchEvent.x = parcel.ReadFloat();
touchEvent.y = parcel.ReadFloat();
touchEvent.type = static_cast<OHNativeXcomponentTouchEventType>(parcel.ReadUint32());
touchEvent.size = parcel.ReadDouble();
touchEvent.force = parcel.ReadFloat();
touchEvent.deviceId = parcel.ReadInt64();
touchEvent.timeStamp = parcel.ReadInt64();
touchEvent.numPoints = parcel.ReadUint32();
ReadTouchPoints(parcel, touchEvent.numPoints, touchEvent.touchPoints);
}
const OHNativeXcomponentMouseEvent ReadMouseEvent(Parcel &parcel)
{
return { parcel.ReadFloat(),
parcel.ReadFloat(),
parcel.ReadFloat(),
parcel.ReadFloat(),
parcel.ReadInt64(),
static_cast<OHNativeXcomponentMouseEventAction>(parcel.ReadUint32()),
static_cast<OHNativeXcomponentMouseEventButton>(parcel.ReadUint32()) };
}
const OHNativeXcomponentWheelEvent ReadWhellEvent(Parcel &parcel)
{
return { static_cast<OHNativeXcomponentWheelEventDirection>(parcel.ReadUint32()),
parcel.ReadUint8(),
parcel.ReadUint8(),
parcel.ReadUint16(),
parcel.ReadFloat(),
parcel.ReadFloat() };
}
const OHNativeXcomponentKeyEvent ReadKeyEvent(Parcel &parcel)
{
return { parcel.ReadUint8(), parcel.ReadUint16(), parcel.ReadUint16(), parcel.ReadUint32(),
static_cast<OHNativeXcomponentKeyEventType>(parcel.ReadUint32()) };
}
void ReadContentEvent(Parcel &parcel, OHNativeXcomponentContentEvent &contentEvent)
{
contentEvent.msgLen = parcel.ReadUint16();
if (strcpy_s(contentEvent.inputText, OH_MAX_CONTENT_LEN, parcel.ReadCString()) != EOK) {
CLOGE("Failed copy content to array");
}
}
const OHNativeXcomponentFocusEvent ReadFocusEvent(Parcel &parcel)
{
return { parcel.ReadUint8(), parcel.ReadDouble(), parcel.ReadDouble(), parcel.ReadDouble(), parcel.ReadDouble() };
}
void ReadInputMethodEvent(Parcel &parcel, OHNativeXcomponentInputMethodEvent &inputMethodEvent)
{
inputMethodEvent.type = static_cast<OHNativeXcomponentInputMethodEventType>(parcel.ReadUint16());
if (inputMethodEvent.type == OHNativeXcomponentInputMethodEventType::OH_NATIVEXCOMPONENT_INPUT_CONTENT) {
return ReadContentEvent(parcel, inputMethodEvent.contentEvent);
}
inputMethodEvent.focusEvent = ReadFocusEvent(parcel);
}
const OHNativeXcomponentVirtualKeyEvent ReadVirtualKeyEvent(Parcel &parcel)
{
return { static_cast<OHNativeXcomponentVirtualKeyEventType>(parcel.ReadInt32()), parcel.ReadFloat(),
parcel.ReadFloat() };
}
std::unique_ptr<OHRemoteControlEvent> ReadRemoteControlEvent(Parcel &parcel)
{
auto remoteControlEvent = std::make_unique<OHRemoteControlEvent>();
if (remoteControlEvent == nullptr) {
CLOGE("Failed to malloc remote control event");
return nullptr;
}
remoteControlEvent->eventType = static_cast<XcomponentEventType>(parcel.ReadUint32());
switch (remoteControlEvent->eventType) {
case XcomponentEventType::REMOTECONTROL_TOUCH:
ReadTouchEvent(parcel, remoteControlEvent->touchEvent);
break;
case XcomponentEventType::REMOTECONTROL_MOUSE:
remoteControlEvent->mouseEvent = ReadMouseEvent(parcel);
break;
case XcomponentEventType::REMOTECONTROL_WHEEL:
remoteControlEvent->wheelEvent = ReadWhellEvent(parcel);
break;
case XcomponentEventType::REMOTECONTROL_KEY:
remoteControlEvent->keyEvent = ReadKeyEvent(parcel);
break;
case XcomponentEventType::REMOTECONTROL_INPUT_METHOD:
ReadInputMethodEvent(parcel, remoteControlEvent->inputMethodEvent);
break;
case XcomponentEventType::REMOTECONTROL_VIRTUAL_KEY:
remoteControlEvent->virtualKeyEvent = ReadVirtualKeyEvent(parcel);
break;
default:
CLOGE("Parameter error, event:(%d) not support", static_cast<uint32_t>(remoteControlEvent->eventType));
remoteControlEvent = nullptr;
break;
}
return remoteControlEvent;
}
bool WriteDeviceStateInfo(Parcel &parcel, const DeviceStateInfo &stateInfo)
{
return parcel.WriteInt32(static_cast<int32_t>(stateInfo.deviceState)) && parcel.WriteString(stateInfo.deviceId);
}
std::unique_ptr<DeviceStateInfo> ReadDeviceStateInfo(Parcel &parcel)
{
auto stateInfo = std::make_unique<DeviceStateInfo>();
int32_t state = parcel.ReadInt32();
if (!IsDeviceState(state)) {
CLOGE("incorrect device state");
return nullptr;
}
stateInfo->deviceState = static_cast<DeviceState>(state);
stateInfo->deviceId = parcel.ReadString();
if (stateInfo->deviceId.empty()) {
CLOGE("device id is empty");
return nullptr;
}
return stateInfo;
}
bool WriteEvent(Parcel &parcel, const EventId &eventId, const std::string &jsonParam)
{
return parcel.WriteInt32(static_cast<int32_t>(eventId)) && parcel.WriteString(jsonParam);
}
bool ReadEvent(Parcel &parcel, int32_t &eventId, std::string &jsonParam)
{
eventId = parcel.ReadInt32();
if (!IsEventId(eventId)) {
CLOGE("incorrect event id");
return false;
}
jsonParam = parcel.ReadString();
return true;
}
void SetDataCapacity(MessageParcel &parcel, const FileFdMap &fileList, uint32_t tokenSize)
{
uint32_t totalSize = tokenSize;
totalSize += sizeof(uint32_t);
for (const auto &[srcPath, fdPair] : fileList) {
totalSize += srcPath.length();
totalSize += sizeof(fdPair.first);
totalSize += fdPair.second.length();
}
if (totalSize > parcel.GetDataCapacity()) {
CLOGD("SetDataCapacity totalSize: %d", totalSize);
parcel.SetMaxCapacity(totalSize + totalSize);
parcel.SetDataCapacity(totalSize);
}
}
bool WriteFileList(MessageParcel &parcel, const FileFdMap &fileList)
{
bool ret = parcel.WriteUint32(fileList.size());
for (const auto &[srcPath, fdPair] : fileList) {
ret = ret && parcel.WriteString(srcPath);
ret = ret && parcel.WriteFileDescriptor(fdPair.first);
ret = ret && parcel.WriteString(fdPair.second);
}
return ret;
}
bool ReadFileList(MessageParcel &parcel, FileFdMap &fileList)
{
uint32_t fileListSize = parcel.ReadUint32();
if (fileListSize > MAX_FILE_NUM) {
CLOGE("The number of files exceeds the upper limit. fileListSize: %{public}u", fileListSize);
return false;
}
for (uint32_t i = 0; i < fileListSize; i++) {
std::string src = parcel.ReadString();
int32_t fd = parcel.ReadFileDescriptor();
std::string dst = parcel.ReadString();
fileList[src] = std::make_pair(fd, dst);
}
return true;
}
bool WriteRcvFdFileMap(MessageParcel &parcel, const RcvFdFileMap &rcvFdFileMap)
{
bool ret = parcel.WriteUint32(rcvFdFileMap.size());
for (const auto &[fd, path] : rcvFdFileMap) {
ret = ret && parcel.WriteFileDescriptor(fd);
ret = ret && parcel.WriteString(path);
}
return ret;
}
bool ReadRcvFdFileMap(MessageParcel &parcel, RcvFdFileMap &rcvFdFileMap)
{
uint32_t fileListSize = parcel.ReadUint32();
if (fileListSize > MAX_FILE_NUM) {
CLOGE("The number of files exceeds the upper limit. fileListSize: %{public}u", fileListSize);
return false;
}
for (uint32_t i = 0; i < fileListSize; i++) {
int32_t fd = parcel.ReadFileDescriptor();
std::string path = parcel.ReadString();
rcvFdFileMap[fd] = path;
}
return true;
}
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2023 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
*
* Description: cast engine dfx.
* Author: wangxueshuang
* Create: 2023-06-05
*/
#include "cast_engine_dfx.h"
#include <string>
#include "cast_engine_log.h"
#include "hisysevent.h"
#include "json.hpp"
using nlohmann::json;
namespace OHOS {
namespace CastEngine {
DEFINE_CAST_ENGINE_LABEL("Cast-Dfx");
json CastEngineDfx::jsonSteamInfo_ = {};
json CastEngineDfx::jsonLocalDeviceInfo_ = {};
json CastEngineDfx::jsonRemoteDeviceInfo_ = {};
json CastEngineDfx::jsonConnectInfo_ = {};
const std::string CastEngineDfx::PACKAGE_NAME = "CastEngineService";
const std::string CastEngineDfx::SEQUENTIAL_ID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
void CastEngineDfx::WriteErrorEvent(int32_t errorCode)
{
CLOGD("In.");
HiSysEventWrite(CAST_ENGINE_DFX_DOMAIN_NAME, "CAST_ENGINE_ERR", HiviewDFX::HiSysEvent::EventType::FAULT,
"ERROR_CODE", errorCode);
}
void CastEngineDfx::SetStreamInfo(const std::string &streamInfoKey, const std::string &streamInfoValue)
{
CLOGD("In.");
jsonSteamInfo_[streamInfoKey] = streamInfoValue;
}
std::string CastEngineDfx::GetStreamInfo()
{
CLOGD("In.");
return jsonSteamInfo_.dump();
}
void CastEngineDfx::SetLocalDeviceInfo(const std::string &localDeviceInfoKey, const std::string &localDeviceInfoValue)
{
CLOGD("In.");
jsonLocalDeviceInfo_[localDeviceInfoKey] = localDeviceInfoValue;
}
std::string CastEngineDfx::GetLocalDeviceInfo()
{
CLOGD("In.");
return jsonLocalDeviceInfo_.dump();
}
void CastEngineDfx::SetRemoteDeviceInfo(const std::string &remoteDeviceInfoKey,
const std::string &remoteDeviceInfoValue)
{
CLOGD("In.");
jsonRemoteDeviceInfo_[remoteDeviceInfoKey] = remoteDeviceInfoValue;
}
std::string CastEngineDfx::GetRemoteDeviceInfo()
{
CLOGD("In.");
return jsonRemoteDeviceInfo_.dump();
}
void CastEngineDfx::SetConnectInfo(const std::string &connectInfoKey, const std::string &connectInfoValue)
{
CLOGD("In.");
jsonConnectInfo_[connectInfoKey] = connectInfoValue;
}
std::string CastEngineDfx::GetConnectInfo()
{
CLOGD("In.");
return jsonConnectInfo_.dump();
}
std::string CastEngineDfx::GetSequentialId()
{
CLOGD("In.");
std::string sequentialId = "";
srand(static_cast<unsigned>(time(NULL)));
for (int i = 0; i < SN_LENGTH; i++) {
int number = rand() % SEQUENTIAL_ID_CHARS_LENGTH;
sequentialId.push_back(SEQUENTIAL_ID_CHARS[number]);
}
CLOGD("sequential ID: %s.", sequentialId.c_str());
return sequentialId;
}
std::string CastEngineDfx::GetBizPackageName()
{
CLOGD("In.");
return PACKAGE_NAME;
}
} // namespace CastEngine
} // namespace OHOS

16
etc/init/BUILD.gn Normal file
View File

@ -0,0 +1,16 @@
# Copyright (c) 2023 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
#
import("//build/ohos.gni")
ohos_prebuilt_etc("cast_engine_service.cfg") {
source = "cast_engine_service.cfg"
relative_install_dir = "init"
subsystem_name = "castplus"
part_name = "cast_engine"
}

View File

@ -0,0 +1,25 @@
{
"jobs" : [{
"name" : "post-fs-data",
"cmds" : [
"mkdir /data/service/el1/public/cast_engine_service 0700 cast_engine_service cast_engine_service"
]
}
],
"services" : [{
"name" : "cast_engine_service",
"path" : ["/system/bin/sa_main", "/system/profile/cast_engine_service.json"],
"ondemand" : true,
"uid" : "cast_engine_service",
"gid" : ["cast_engine_service", "shell"],
"permission" : [
"ohos.permission.DISTRIBUTED_DATASYNC",
"ohos.permission.CAPTURE_SCREEN",
"ohos.permission.ACCESS_SERVICE_DM",
"ohos.permission.MICROPHONE"
],
"permission_acls" : ["ohos.permission.CAPTURE_SCREEN"],
"secon" : "u:r:cast_engine_service:s0"
}
]
}

64
hisysevent.yaml Normal file
View File

@ -0,0 +1,64 @@
# Copyright (c) 2023 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
#
# 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
#
# Description: hisysevent
# Author: wangxueshuang
# Create: 2023-01-30
domain: CAST_ENGINE
CAST_ENGINE_ERR:
__BASE: {type: FAULT, level: CRITICAL, desc: projection error events}
SEQUENTIAL_ID: {type: STRING, desc: used to associate projection events}
CAST_SESSION_ID: {type: INT32, desc: projection session ID}
ERROR_CODE: {type: INT32, desc: error code}
SUB_ERR_CODE: {type: INT32, desc: sub error code}
EXT_ERR_INFO: {type: INT32, desc: extended error information}
ERR_MSG: {type: STRING, desc: error information sent from the sink during stream projection}
WIFI_INFO: {type: STRING, desc: wifi information when a projection error occurs}
BIZ_PACKAGE_NAME: {type: STRING, desc: package name}
REMOTE_BIZ_TRUNCATED_UDID: {type: STRING, desc: remote truncated UDID}
NO_DEVICE_FOUND:
__BASE: {type: STATISTIC, level: MINOR, desc: statistics on undiscovered devices}
BT_SWITCH: {type: INT32, desc: bluetooth switch status}
WIFI_INFO: {type: STRING, desc: wifi information when the device is not discovered}
SCAN_TIME: {type: INT32, desc: scan time}
CAST_ENGINE_EVE:
__BASE: {type: STATISTIC, level: MINOR, desc: projection event}
SEQUENTIAL_ID: {type: STRING, desc: used to associate projection events}
CAST_SESSION_ID: {type: INT32, desc: projection session ID}
ERROR_CODE: {type: INT32, desc: error code}
SUB_ERR_CODE: {type: INT32, desc: sub error code}
EXT_ERR_INFO: {type: INT32, desc: extended error information}
ERR_MSG: {type: STRING, desc: error information sent from the sink during stream projection}
LOCAL_DEVICE_INFO: {type: STRING, desc: local device information record}
REMOTE_DEVICE_INFO: {type: STRING, desc: remote device information record}
CONNECT_INFO: {type: STRING, desc: connect information record}
CAST_STREAM_INFO: {type: STRING, desc: stream information record}
WIFI_INFO:
__BASE: {type: STATISTIC, level: MINOR, desc: wifi information}
FREQ: {type: INT32, desc: frequency band of the current wifi connection}
RSSI: {type: INT32, desc: signal strength of the current connection}
LINKSPEED: {type: INT32, desc: TX rate of the current connection}
RXLINKSPEED: {type: INT32, desc: RX rate of the current connection}
SNR: {type: INT32, desc: SNR of the current connection}
CHLOAD: {type: INT32, desc: channel loading of the current connected}
FREQ_P2P: {type: INT32, desc: frequency band of the current P2P wifi connection}
RSSI_P2P: {type: INT32, desc: signal strength of the current P2P connection}
LINKSPEED_P2P: {type: INT32, desc: TX rate of the current P2P connection}
RXLINKSPEED_P2P: {type: INT32, desc: RX rate of the current P2P connection}
SNR_P2P: {type: INT32, desc: SNR of the current P2P connection}
CHLOAD_P2P: {type: INT32, desc: channel loading of the current P2P connected}

View File

@ -0,0 +1,37 @@
# Copyright (c) 2023 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
#
import("//foundation/CastEngine/castengine_cast_framework/cast_engine.gni")
config("cast_interfaces_config") {
include_dirs = [ "include" ]
}
ohos_shared_library("cast_engine_client") {
configs = [
":cast_interfaces_config",
"${cast_engine_root}:cast_engine_default_config",
]
public_configs = [ ":cast_interfaces_config" ]
deps = [
"${cast_engine_client}:cast_client_inner",
"${cast_engine_common}:cast_engine_common_sources",
]
external_deps = [
"c_utils:utils",
"hilog:libhilog",
"ipc:ipc_core",
"samgr:samgr_proxy",
]
subsystem_name = "castplus"
part_name = "cast_engine"
}

View File

@ -0,0 +1,367 @@
/*
* Copyright (c) 2023 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
*
* Description: Cast engine related common data stucture definitions.
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef CAST_ENGINE_COMMON_H
#define CAST_ENGINE_COMMON_H
#include <array>
#include <map>
#include <string>
#include <message_parcel.h>
#define EXPORT __attribute__((visibility("default")))
namespace OHOS {
namespace CastEngine {
enum class EXPORT DeviceType {
DEVICE_OTHERS = 0,
DEVICE_SCREEN_PLAYER = 1,
DEVICE_HW_TV = 2,
DEVICE_SOUND_BOX = 3,
DEVICE_HICAR = 4,
DEVICE_MATEBOOK = 5,
DEVICE_PAD = 6,
DEVICE_CAST_PLUS = 7,
DEVICE_TYPE_2IN1 = 8
};
inline bool EXPORT IsDeviceType(int32_t type)
{
return (type >= static_cast<int32_t>(DeviceType::DEVICE_OTHERS)) &&
(type <= static_cast<int32_t>(DeviceType::DEVICE_TYPE_2IN1));
}
enum class EXPORT SubDeviceType {
SUB_DEVICE_DEFAULT = 0,
SUB_DEVICE_MATEBOOK_PAD = 51,
SUB_DEVICE_CAST_PLUS_WHITEBOARD = 0x00B2
};
inline bool EXPORT IsSubDeviceType(int32_t type)
{
return (type == static_cast<int32_t>(SubDeviceType::SUB_DEVICE_DEFAULT)) ||
(type == static_cast<int32_t>(SubDeviceType::SUB_DEVICE_MATEBOOK_PAD)) ||
(type == static_cast<int32_t>(SubDeviceType::SUB_DEVICE_CAST_PLUS_WHITEBOARD));
}
enum class EXPORT TriggerType {
UNSPEC_TAG = 0,
PASSIVE_MATCH_TAG = 1,
ACTIVE_MATCH_TAG = 2,
PASSIVE_BIND_TAG = 3,
};
inline bool EXPORT IsTriggerType(int32_t type)
{
return (type >= static_cast<int32_t>(TriggerType::UNSPEC_TAG)) &&
(type <= static_cast<int32_t>(TriggerType::PASSIVE_BIND_TAG));
}
enum class EXPORT DeviceState {
CONNECTING,
CONNECTED,
PAUSED,
PLAYING,
DISCONNECTING,
DISCONNECTED,
STREAM,
DEVICE_STATE_MAX,
};
const EXPORT std::array<std::string, static_cast<size_t>(DeviceState::DEVICE_STATE_MAX)> DEVICE_STATE_STRING = {
"CONNECTING", "CONNECTED", "PAUSED", "PLAYING", "DISCONNECTING", "DISCONNECTED", "STREAM",
};
inline bool EXPORT IsDeviceState(int32_t state)
{
return (state >= static_cast<int32_t>(DeviceState::CONNECTING)) &&
(state < static_cast<int32_t>(DeviceState::DEVICE_STATE_MAX));
}
enum class EXPORT ServiceStatus {
DISCONNECTED,
DISCONNECTING,
CONNECTING,
CONNECTED,
};
inline bool EXPORT IsServiceStatus(int32_t status)
{
return (status >= static_cast<int32_t>(ServiceStatus::DISCONNECTED)) &&
(status <= static_cast<int32_t>(ServiceStatus::CONNECTED));
}
enum class EXPORT DeviceStatusState {
DEVICE_AVAILABLE,
DEVICE_CONNECTED,
DEVICE_DISCONNECTED,
DEVICE_CONNECT_REQ,
};
inline bool EXPORT IsDeviceStatus(int32_t status)
{
return (status >= static_cast<int32_t>(DeviceStatusState::DEVICE_AVAILABLE)) &&
(status <= static_cast<int32_t>(DeviceStatusState::DEVICE_CONNECT_REQ));
}
enum class EXPORT PropertyType {
VIDEO_SIZE,
VIDEO_FPS,
WINDOW_SIZE,
};
inline bool EXPORT IsPropertyType(int32_t type)
{
return (type >= static_cast<int32_t>(PropertyType::VIDEO_SIZE)) &&
(type <= static_cast<int32_t>(PropertyType::WINDOW_SIZE));
}
enum class EXPORT ChannelType {
SOFT_BUS,
LEGACY_CHANNEL,
};
inline bool EXPORT IsChannelType(int32_t type)
{
return (type == static_cast<int32_t>(ChannelType::SOFT_BUS)) ||
(type == static_cast<int32_t>(ChannelType::LEGACY_CHANNEL));
}
enum class EXPORT ProtocolType {
CAST_PLUS_MIRROR = 1<<0,
CAST_PLUS_STREAM = 1<<1,
MIRACAST = 1<<2,
DLNA = 1<<3,
COOPERATION = 1<<4
};
inline bool EXPORT IsProtocolType(int32_t type)
{
return (static_cast<uint32_t>(type) & (static_cast<uint32_t>(ProtocolType::CAST_PLUS_MIRROR) |
static_cast<uint32_t>(ProtocolType::CAST_PLUS_STREAM) |
static_cast<uint32_t>(ProtocolType::MIRACAST) |
static_cast<uint32_t>(ProtocolType::DLNA) |
static_cast<uint32_t>(ProtocolType::COOPERATION))) != 0;
}
enum class EXPORT EndType {
CAST_SINK = 0x10,
CAST_SOURCE = 0x11,
};
inline bool EXPORT IsEndType(int32_t type)
{
return (type == static_cast<int32_t>(EndType::CAST_SINK)) || (type == static_cast<int32_t>(EndType::CAST_SOURCE));
}
struct EXPORT DeviceStateInfo {
DeviceState deviceState{ DeviceState::DISCONNECTED };
std::string deviceId{};
};
struct EXPORT VideoSize {
uint32_t width;
uint32_t height;
};
struct EXPORT WindowProperty {
uint32_t startX;
uint32_t startY;
uint32_t width;
uint32_t height;
};
struct EXPORT PropertyContainer {
PropertyType type;
union {
VideoSize videoSize;
uint32_t videoFps;
WindowProperty windowProperty;
};
};
enum class EXPORT ColorStandard {
BT709 = 1,
BT601_PAL = 2,
BT601_NTSC = 3,
BT2020 = 6,
};
inline bool EXPORT IsColorStandard(int32_t color)
{
return (color == static_cast<int32_t>(ColorStandard::BT709)) ||
(color == static_cast<int32_t>(ColorStandard::BT601_PAL)) ||
(color == static_cast<int32_t>(ColorStandard::BT601_NTSC)) ||
(color == static_cast<int32_t>(ColorStandard::BT2020));
}
enum class EXPORT VideoCodecType {
H264 = 1,
H265 = 2,
};
inline bool EXPORT IsVideoCodecType(int32_t type)
{
return (type == static_cast<int32_t>(VideoCodecType::H264)) || type == static_cast<int32_t>(VideoCodecType::H265);
}
struct EXPORT AudioProperty {
uint32_t sampleRate;
uint8_t sampleBitWidth;
uint32_t channelConfig;
uint32_t bitrate;
uint32_t codec;
};
struct EXPORT VideoProperty {
uint32_t videoWidth{ 0 };
uint32_t videoHeight{ 0 };
uint32_t fps{ 0 };
VideoCodecType codecType{ VideoCodecType::H264 };
uint32_t gop{ 0 };
uint32_t bitrate{ 0 };
uint32_t minBitrate{ 0 };
uint32_t maxBitrate{ 0 };
uint32_t dpi{ 0 };
ColorStandard colorStandard{ ColorStandard::BT709 };
uint32_t screenWidth{ 0 };
uint32_t screenHeight{ 0 };
uint32_t profile{ 0 };
uint32_t level{ 0 };
};
struct EXPORT CastSessionProperty {
ProtocolType protocolType{ ProtocolType::CAST_PLUS_MIRROR };
EndType endType{ EndType::CAST_SINK };
AudioProperty audioProperty;
VideoProperty videoProperty;
WindowProperty windowProperty;
};
struct EXPORT CastLocalDevice {
std::string deviceId;
std::string deviceName;
DeviceType deviceType;
SubDeviceType subDeviceType;
std::string ipAddress;
TriggerType triggerType;
std::string authData;
};
struct EXPORT AuthInfo {
int authMode;
uint32_t authCode;
std::string deviceId;
};
struct EXPORT CastRemoteDevice {
std::string deviceId;
std::string deviceName;
DeviceType deviceType;
SubDeviceType subDeviceType;
std::string ipAddress;
ChannelType channelType;
};
enum class EXPORT CastMode {
MIRROR_CAST = 1,
APP_CAST = 2,
};
// Parameters for cast mode
const std::string EXPORT KEY_BUNDLE_NAME = "bundleName";
const std::string EXPORT KEY_PID = "pid";
const std::string EXPORT KEY_UID = "uid";
const std::string EXPORT KEY_APP_MIN_COMPATIBLE_VERSION = "minCompatibleVersionCode";
const std::string EXPORT KEY_APP_TARGET_VERSION = "targetVersion";
const int EXPORT MAX_DEVICE_NUM = 100;
const int32_t EXPORT MAX_FILE_NUM = 16 * 1024;
enum class EXPORT EventId {
EVENT_BEGIN = 1,
EVENT_END = 5000,
};
inline bool EXPORT IsEventId(int32_t state)
{
return (state > static_cast<int32_t>(EventId::EVENT_BEGIN)) && (state < static_cast<int32_t>(EventId::EVENT_END));
}
struct EXPORT MediaInfo {
std::string mediaId;
std::string mediaName;
std::string mediaUrl;
std::string mediaType;
size_t mediaSize;
uint32_t startPosition;
uint32_t duration;
uint32_t closingCreditsPosition;
std::string albumCoverUrl;
std::string albumTitle;
std::string mediaArtist;
std::string lrcUrl;
std::string lrcContent;
std::string appIconUrl;
std::string appName;
};
struct EXPORT MediaInfoHolder {
uint32_t currentIndex;
std::vector<MediaInfo> mediaInfoList;
uint32_t progressRefreshInterval;
};
// <source file, <fd, target file path>>
using FileFdMap = std::map<std::string, std::pair<int, std::string>>;
// <fd, file path>
using RcvFdFileMap = std::map<int, std::string>;
enum class EXPORT PlayerStates {
PLAYER_STATE_ERROR = 0,
PLAYER_IDLE = 1,
PLAYER_INITIALIZED = 2,
PLAYER_PREPARING = 3,
PLAYER_PREPARED = 4,
PLAYER_STARTED = 5,
PLAYER_PAUSED = 6,
PLAYER_STOPPED = 7,
PLAYER_PLAYBACK_COMPLETE = 8,
PLAYER_RELEASED = 9
};
enum class EXPORT LoopMode {
LOOP_MODE_SEQUENCE = 1,
LOOP_MODE_SINGLE = 2,
LOOP_MODE_LIST = 3,
LOOP_MODE_SHUFFLE = 4
};
enum class EXPORT PlaybackSpeed {
SPEED_FORWARD_0_75_X = 0,
SPEED_FORWARD_1_00_X = 1,
SPEED_FORWARD_1_25_X = 2,
SPEED_FORWARD_1_75_X = 3,
SPEED_FORWARD_2_00_X = 4
};
inline constexpr int EXPORT INVALID_ID = -1;
inline constexpr int EXPORT INVALID_VALUE = -1;
inline constexpr int EXPORT DECIMALISM = 10;
inline constexpr int EXPORT SUBSYS_CASTPLUS_SYS_ABILITY_ID_BEGIN = 0x00010000;
inline constexpr int EXPORT CAST_ENGINE_SA_ID = 5526; // SUBSYS_CASTPLUS_SYS_ABILITY_ID_BEGIN + 10; // 65546
inline constexpr int EXPORT SUBSYS_CASTPLUS_SYS_ABILITY_ID_END = 0x0001001f;
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 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
*
* Description: supply errors definition for interfaces.
* Author: zhangjingnan
* Create: 2023-4-11
*/
#ifndef CAST_ENGINE_ERRORS_H
#define CAST_ENGINE_ERRORS_H
#include <cinttypes>
#include "errors.h"
#include "cast_engine_common.h"
namespace OHOS {
namespace CastEngine {
constexpr int32_t EXPORT CAST_ENGINE_ERROR = -1;
constexpr int32_t EXPORT CAST_ENGINE_SUCCESS = 0;
constexpr int32_t EXPORT CAST_ENGINE_ERROR_BASE = 1000;
constexpr int32_t EXPORT ERR_NO_MEMORY = -(CAST_ENGINE_ERROR_BASE + 1);
constexpr int32_t EXPORT ERR_INVALID_PARAM = -(CAST_ENGINE_ERROR_BASE + 2);
constexpr int32_t EXPORT ERR_NO_PERMISSION = -(CAST_ENGINE_ERROR_BASE + 3);
constexpr int32_t EXPORT ERR_SESSION_NOT_EXIST = -(CAST_ENGINE_ERROR_BASE + 4);
constexpr int32_t EXPORT ERR_SERVICE_STATE_NOT_MATCH = -(CAST_ENGINE_ERROR_BASE + 5);
constexpr int32_t EXPORT ERR_SESSION_STATE_NOT_MATCH = -(CAST_ENGINE_ERROR_BASE + 6);
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_ENGINE_ERRORS_H

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2023 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
*
* Description: cast session manager apis.
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef CAST_SESSION_MANAGER_H
#define CAST_SESSION_MANAGER_H
#include <memory>
#include <mutex>
#include "cast_engine_common.h"
#include "i_cast_session.h"
#include "i_cast_session_manager_adaptor.h"
#include "i_cast_session_manager_listener.h"
#include "iremote_object.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class EXPORT CastSessionManager {
public:
static CastSessionManager &GetInstance();
CastSessionManager(const CastSessionManager &) = delete;
CastSessionManager &operator=(const CastSessionManager &) = delete;
CastSessionManager(CastSessionManager &&) = delete;
CastSessionManager &operator=(CastSessionManager &&) = delete;
~CastSessionManager() = default;
int32_t RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener);
int32_t UnregisterListener();
int32_t Release();
int32_t SetLocalDevice(const CastLocalDevice &localDevice);
int32_t CreateCastSession(const CastSessionProperty &property, std::shared_ptr<ICastSession> &castSession);
int32_t SetSinkSessionCapacity(int sessionCapacity);
int32_t StartDiscovery(int protocols);
int32_t SetDiscoverable(bool enable);
int32_t StopDiscovery();
void ReleaseClientResources();
int32_t GetCastSession(std::string sessionId, std::shared_ptr<ICastSession> &castSession);
private:
class CastEngineServiceDeathRecipient : public IRemoteObject::DeathRecipient {
public:
CastEngineServiceDeathRecipient(std::shared_ptr<ICastSessionManagerListener> listener)
: listener_(listener) {};
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
std::shared_ptr<ICastSessionManagerListener> GetListener()
{
return listener_;
}
private:
std::shared_ptr<ICastSessionManagerListener> listener_;
};
CastSessionManager();
void ReleaseServiceDeathRecipient();
std::shared_ptr<ICastSessionManagerAdaptor> GetAdaptor();
std::mutex mutex_;
std::shared_ptr<ICastSessionManagerAdaptor> adaptor_;
sptr<CastEngineServiceDeathRecipient> deathRecipient_{ nullptr };
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2023 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
*
* Description: Cast session interface.
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef I_CAST_SESSION_H
#define I_CAST_SESSION_H
#include "cast_engine_common.h"
#include "oh_remote_control_event.h"
#include "i_stream_player.h"
#include "i_mirror_player.h"
namespace OHOS {
namespace CastEngine {
class EXPORT ICastSessionListener {
public:
ICastSessionListener() = default;
ICastSessionListener(const ICastSessionListener &) = delete;
ICastSessionListener &operator = (const ICastSessionListener &) = delete;
ICastSessionListener(ICastSessionListener &&) = delete;
ICastSessionListener &operator = (ICastSessionListener &&) = delete;
virtual ~ICastSessionListener() = default;
virtual void OnDeviceState(const DeviceStateInfo &stateInfo) = 0;
virtual void OnEvent(const EventId &eventId, const std::string &jsonParam) = 0;
};
class EXPORT ICastSession {
public:
ICastSession() = default;
ICastSession(const ICastSession &) = delete;
ICastSession &operator = (const ICastSession &) = delete;
ICastSession(ICastSession &&) = delete;
ICastSession &operator = (ICastSession &&) = delete;
virtual ~ICastSession() = default;
virtual int32_t RegisterListener(std::shared_ptr<ICastSessionListener> listener) = 0;
virtual int32_t UnregisterListener() = 0;
virtual int32_t AddDevice(const CastRemoteDevice &remoteDevice) = 0;
virtual int32_t RemoveDevice(const std::string &deviceId) = 0;
virtual int32_t StartAuth(const AuthInfo &authInfo) = 0;
virtual int32_t GetSessionId(std::string &sessionId) = 0;
virtual int32_t SetSessionProperty(const CastSessionProperty &property) = 0;
virtual int32_t CreateMirrorPlayer(std::shared_ptr<IMirrorPlayer> &mirrorPlayer) = 0;
virtual int32_t CreateStreamPlayer(std::shared_ptr<IStreamPlayer> &streamPlayer) = 0;
virtual int32_t NotifyEvent(EventId eventId, std::string &jsonParam) = 0;
virtual int32_t SetCastMode(CastMode mode, std::string &jsonParam) = 0;
virtual int32_t Release() = 0;
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager base adaptor
* Author: zhangge
* Create: 2022-5-29
*/
#ifndef I_CAST_SESSION_MANAGER_ADAPTOR_H
#define I_CAST_SESSION_MANAGER_ADAPTOR_H
#include <memory>
#include "cast_engine_common.h"
#include "i_cast_session.h"
#include "i_cast_session_manager_listener.h"
#include "iremote_object.h"
namespace OHOS {
namespace CastEngine {
class EXPORT ICastSessionManagerAdaptor {
public:
ICastSessionManagerAdaptor() = default;
ICastSessionManagerAdaptor(const ICastSessionManagerAdaptor &) = delete;
ICastSessionManagerAdaptor &operator = (const ICastSessionManagerAdaptor &) = delete;
ICastSessionManagerAdaptor(ICastSessionManagerAdaptor &&) = delete;
ICastSessionManagerAdaptor &operator = (ICastSessionManagerAdaptor &&) = delete;
virtual ~ICastSessionManagerAdaptor() = default;
virtual int32_t RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener,
sptr<IRemoteObject::DeathRecipient> deathRecipient) = 0;
virtual int32_t UnregisterListener() = 0;
virtual int32_t Release() = 0;
virtual int32_t SetLocalDevice(const CastLocalDevice &localDevice) = 0;
virtual int32_t CreateCastSession(const CastSessionProperty &property,
std::shared_ptr<ICastSession> &castSession) = 0;
virtual int32_t SetSinkSessionCapacity(int sessionCapacity) = 0;
virtual int32_t StartDiscovery(int protocols) = 0;
virtual int32_t SetDiscoverable(bool enable) = 0;
virtual int32_t StopDiscovery() = 0;
virtual int32_t GetCastSession(std::string sessionId, std::shared_ptr<ICastSession> &castSession) = 0;
};
} // namespace CastEngine
} // namespace OHOS
#endif // I_CAST_SESSION_MANAGER_ADAPTOR_H

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager listener apis.
* Author: zhangge
* Create: 2022-6-15
*/
#ifndef I_CAST_SESSION_MANAGER_LISTENER_H
#define I_CAST_SESSION_MANAGER_LISTENER_H
#include "cast_engine_common.h"
#include "i_cast_session.h"
namespace OHOS {
namespace CastEngine {
class EXPORT ICastSessionManagerListener {
public:
ICastSessionManagerListener() = default;
ICastSessionManagerListener(const ICastSessionManagerListener &) = delete;
ICastSessionManagerListener &operator=(const ICastSessionManagerListener &) = delete;
ICastSessionManagerListener(ICastSessionManagerListener &&) = delete;
ICastSessionManagerListener &operator=(ICastSessionManagerListener &&) = delete;
virtual ~ICastSessionManagerListener() = default;
virtual void OnDeviceFound(const std::vector<CastRemoteDevice> &deviceList) = 0;
virtual void OnDeviceOffline(const std::string &deviceId) = 0;
virtual void OnSessionCreated(const std::shared_ptr<ICastSession> &castSession) = 0;
virtual void OnServiceDied() = 0;
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2023 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
*
* Description: Cast mirror player interface.
* Author: zhangjingnan
* Create: 2023-05-27
*/
#ifndef I_CAST_MIRROR_PLAYER_H
#define I_CAST_MIRROR_PLAYER_H
#include "cast_engine_common.h"
#include "oh_remote_control_event.h"
namespace OHOS {
namespace CastEngine {
class EXPORT IMirrorPlayer {
public:
IMirrorPlayer() = default;
IMirrorPlayer(const IMirrorPlayer &) = delete;
IMirrorPlayer &operator = (const IMirrorPlayer &) = delete;
IMirrorPlayer(IMirrorPlayer &&) = delete;
IMirrorPlayer &operator = (IMirrorPlayer &&) = delete;
virtual ~IMirrorPlayer() = default;
virtual int32_t Play(const std::string &deviceId) = 0;
virtual int32_t Pause(const std::string &deviceId) = 0;
virtual int32_t SetSurface(const std::string &surfaceId) = 0;
virtual int32_t DeliverInputEvent(OHRemoteControlEvent event) = 0;
virtual int32_t Release() = 0;
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2023 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
*
* Description: Stream Player interface.
* Author: huangchanggui
* Create: 2023-01-11
*/
#ifndef I_STREAM_PLAYER_H
#define I_STREAM_PLAYER_H
#include "cast_engine_common.h"
namespace OHOS {
namespace CastEngine {
class EXPORT IStreamPlayerListener {
public:
IStreamPlayerListener() = default;
IStreamPlayerListener(const IStreamPlayerListener &) = delete;
IStreamPlayerListener &operator=(const IStreamPlayerListener &) = delete;
IStreamPlayerListener(IStreamPlayerListener &&) = delete;
IStreamPlayerListener &operator=(IStreamPlayerListener &&) = delete;
virtual ~IStreamPlayerListener() = default;
virtual void OnStateChanged(const PlayerStates playbackState, bool isPlayWhenReady) = 0;
virtual void OnPositionChanged(int position, int bufferPosition, int duration) = 0;
virtual void OnMediaItemChanged(const MediaInfo &mediaInfo) = 0;
virtual void OnVolumeChanged(int volume, int maxVolume) = 0;
virtual void OnLoopModeChanged(const LoopMode loopMode) = 0;
virtual void OnPlaySpeedChanged(const PlaybackSpeed speed) = 0;
virtual void OnPlayerError(int errorCode, const std::string &errorMsg) = 0;
virtual void OnVideoSizeChanged(int width, int height) = 0;
virtual void OnNextRequest() = 0;
virtual void OnPreviousRequest() = 0;
virtual void OnSeekDone(int position) = 0;
virtual void OnEndOfStream(int isLooping) = 0;
virtual void OnPlayRequest(const MediaInfo &mediaInfo) = 0;
};
class EXPORT IStreamPlayer {
public:
IStreamPlayer() = default;
IStreamPlayer(const IStreamPlayer &) = delete;
IStreamPlayer &operator=(const IStreamPlayer &) = delete;
IStreamPlayer(IStreamPlayer &&) = delete;
IStreamPlayer &operator=(IStreamPlayer &&) = delete;
virtual ~IStreamPlayer() = default;
virtual int32_t RegisterListener(std::shared_ptr<IStreamPlayerListener> listener) = 0;
virtual int32_t UnregisterListener() = 0;
virtual int32_t SetSurface(const std::string &surfaceId) = 0;
virtual int32_t Load(const MediaInfo &mediaInfo) = 0;
virtual int32_t Play(const MediaInfo &mediaInfo) = 0;
virtual int32_t Play(int index) = 0;
virtual int32_t Play() = 0;
virtual int32_t Pause() = 0;
virtual int32_t Stop() = 0;
virtual int32_t Next() = 0;
virtual int32_t Previous() = 0;
virtual int32_t Seek(int position) = 0;
virtual int32_t FastForward(int delta) = 0;
virtual int32_t FastRewind(int delta) = 0;
virtual int32_t SetVolume(int volume) = 0;
virtual int32_t SetLoopMode(const LoopMode mode) = 0;
virtual int32_t SetSpeed(const PlaybackSpeed speed) = 0;
virtual int32_t GetPlayerStatus(PlayerStates &playerStates) = 0;
virtual int32_t GetPosition(int &position) = 0;
virtual int32_t GetDuration(int &duration) = 0;
virtual int32_t GetVolume(int &volume, int &maxVolume) = 0;
virtual int32_t GetLoopMode(LoopMode &loopMode) = 0;
virtual int32_t GetPlaySpeed(PlaybackSpeed &playbackSpeed) = 0;
virtual int32_t GetMediaInfoHolder(MediaInfoHolder &mediaInfoHolder) = 0;
virtual int32_t Release() = 0;
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,181 @@
/*
* Copyright (c) 2023 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
*
* Description: Remote Control related data from OH XComponent structure definitions.
* Author: mayihao
* Create: 2022-09-14
*/
#ifndef OH_REMOTE_CONTROL_EVENT_H
#define OH_REMOTE_CONTROL_EVENT_H
#include <stdint.h>
#include "cast_engine_common.h"
namespace OHOS {
namespace CastEngine {
enum class EXPORT XcomponentEventType {
REMOTECONTROL_TOUCH,
REMOTECONTROL_MOUSE,
REMOTECONTROL_PEN,
REMOTECONTROL_WHEEL,
REMOTECONTROL_KEY,
REMOTECONTROL_INPUT_METHOD,
REMOTECONTROL_VIRTUAL_KEY,
REMOTECONTROL_INVALID_EVENT,
};
enum EXPORT OHNativeXcomponentResult {
OH_NATIVEXCOMPONENT_RESULT_SUCCESS = 0,
OH_NATIVEXCOMPONENT_RESULT_FAILED = -1,
OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER = -2,
};
enum EXPORT OHNativeXcomponentTouchEventType {
OH_NATIVEXCOMPONENT_TOUCH_DOWN = 0,
OH_NATIVEXCOMPONENT_TOUCH_UP,
OH_NATIVEXCOMPONENT_TOUCH_MOVE,
OH_NATIVEXCOMPONENT_TOUCH_CANCEL,
};
enum EXPORT OHNativeXcomponentMouseEventAction {
OH_NATIVEXCOMPONENT_MOUSE_PRESS = 0,
OH_NATIVEXCOMPONENT_MOUSE_RELEASE,
OH_NATIVEXCOMPONENT_MOUSE_MOVE,
OH_NATIVEXCOMPONENT_MOUSE_NONE,
};
enum EXPORT OHNativeXcomponentKeyEventType {
OH_NATIVEXCOMPONENT_KEY_DOWN = 0,
OH_NATIVEXCOMPONENT_KEY_UP,
};
enum EXPORT OHNativeXcomponentMouseEventButton {
OH_NATIVEXCOMPONENT_LEFT_BUTTON = 0,
OH_NATIVEXCOMPONENT_MIDDLE_BUTTON,
OH_NATIVEXCOMPONENT_RIGHT_BUTTON,
};
enum EXPORT OHNativeXcomponentInputMethodEventType {
OH_NATIVEXCOMPONENT_INPUT_CONTENT = 0,
OH_NATIVEXCOMPONENT_INPUT_FOCUS,
};
enum EXPORT OHNativeXcomponentWheelEventDirection {
OH_NATIVEXCOMPONENT_WHEEL_VERTICAL = 0,
OH_NATIVEXCOMPONENT_WHEEL_HORIZONTAL
};
enum EXPORT OHNativeXcomponentVirtualKeyEventType {
OH_NATIVEXCOMPONENT_VIRTUALKEY_BACK = 0,
OH_NATIVEXCOMPONENT_VIRTUALKEY_HOME,
OH_NATIVEXCOMPONENT_VIRTUALKEY_RECENT_APP,
OH_NATIVEXCOMPONENT_VIRTUALKEY_QUICK_SETTING
};
const uint32_t EXPORT OH_MAX_TOUCH_POINTS_NUMBER = 10;
const uint32_t EXPORT OH_MAX_CONTENT_LEN = 472;
struct EXPORT OHNativeXcomponentTouchPoint {
int32_t id = 0; // Unique identifier of a finger.
float screenX = 0.0; // X coordinate of the touch point relative to the left edge of the screen.
float screenY = 0.0; // Y coordinate of the touch point relative to the upper edge of the screen.
float x = 0.0; // X coordinate of the touch point relative to the left edge of the element to touch.
float y = 0.0; // Y coordinate of the touch point relative to the upper edge of the element to touch.
OHNativeXcomponentTouchEventType type;
double size = 0.0; // Contact area between the finger pad and the screen.
float force = 0.0; // Pressure of the current touch event.
int64_t timeStamp = 0; // Timestamp of the current touch event.
bool isPressed = false; // Whether the current point is pressed.
};
struct EXPORT OHNativeXcomponentTouchEvent {
int32_t id = 0; // Unique identifier of a finger.
float screenX = 0.0; // X coordinate of the touch point relative to the left edge of the screen.
float screenY = 0.0; // Y coordinate of the touch point relative to the upper edge of the screen.
float x = 0.0; // X coordinate of the touch point relative to the left edge of the element to touch.
float y = 0.0; // Y coordinate of the touch point relative to the upper edge of the element to touch.
OHNativeXcomponentTouchEventType type;
double size = 0.0; // Contact area between the finger pad and the screen.
float force = 0.0; // Pressure of the current touch event.
int64_t deviceId = 0; // ID of the device where the current touch event is generated.
int64_t timeStamp = 0; // Timestamp of the current touch event.
uint32_t numPoints = 0; // Number of current touch points.
OHNativeXcomponentTouchPoint touchPoints[OH_MAX_TOUCH_POINTS_NUMBER]; // Array of the current touch points.
};
struct EXPORT OHNativeXcomponentMouseEvent {
float x = 0.0; // X coordinate of the mouse point relative to the left edge of the element to mouse.
float y = 0.0; // Y coordinate of the mouse point relative to the upper edge of the element to mouse.
float screenX = 0.0; // X coordinate of the mouse point relative to the left edge of the screen.
float screenY = 0.0; // Y coordinate of the mouse point relative to the upper edge of the screen.
int64_t timestamp = 0; // Timestamp of the current mouse event.
OHNativeXcomponentMouseEventAction action;
OHNativeXcomponentMouseEventButton button;
};
struct EXPORT OHNativeXcomponentKeyEvent {
uint8_t reserved;
uint16_t keyCode1; // the first key code
uint16_t keyCode2; // the second key code
uint32_t metaState; // whether meta keys is pressed
OHNativeXcomponentKeyEventType type;
};
struct EXPORT OHNativeXcomponentContentEvent {
uint16_t msgLen;
char inputText[OH_MAX_CONTENT_LEN];
};
struct EXPORT OHNativeXcomponentFocusEvent {
uint8_t focusStat; // is focus on
double cursorX1; // The X position of the upper-left corner of the cursor
double cursorY1; // The Y position of the upper-left corner of the cursor
double cursorX2; // The X position of the lowwer-right corner of the cursor
double cursorY2; // The Y position of the lowwer-right corner of the cursor
};
struct EXPORT OHNativeXcomponentInputMethodEvent {
OHNativeXcomponentInputMethodEventType type;
union {
OHNativeXcomponentContentEvent contentEvent;
OHNativeXcomponentFocusEvent focusEvent;
};
};
struct EXPORT OHNativeXcomponentWheelEvent {
OHNativeXcomponentWheelEventDirection direction;
uint8_t indication = 1; // 0b0:Scrolling to the right/Scrolling down, 0b1:Scrolling to the left/Scrolling up
uint8_t scrollUnit = 2; // 0b00:the unit is a pixel, 0b01:the unit is a mouse notch, 0b10-0b11:Reserved
uint16_t wheelDis; // wheel distance
float x; // X-coordinate when wheel button down
float y; // Y-coordinate when wheel button down
};
struct EXPORT OHNativeXcomponentVirtualKeyEvent {
OHNativeXcomponentVirtualKeyEventType type;
float x;
float y;
};
struct EXPORT OHRemoteControlEvent {
OHRemoteControlEvent() {};
XcomponentEventType eventType = XcomponentEventType::REMOTECONTROL_INVALID_EVENT;
union {
OHNativeXcomponentTouchEvent touchEvent;
OHNativeXcomponentMouseEvent mouseEvent;
OHNativeXcomponentKeyEvent keyEvent;
OHNativeXcomponentInputMethodEvent inputMethodEvent;
OHNativeXcomponentWheelEvent wheelEvent;
OHNativeXcomponentVirtualKeyEvent virtualKeyEvent;
};
};
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,52 @@
# Copyright (c) 2023 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
#
import("//foundation/CastEngine/castengine_cast_framework/cast_engine.gni")
config("cast_config") {
include_dirs = [
"include",
"${cast_engine_interfaces}/inner_api:cast_interfaces_config"
]
}
ohos_shared_library("cast") {
sources = [
"src/napi_cast_session.cpp",
"src/napi_cast_session_listener.cpp",
"src/napi_cast_session_manager.cpp",
"src/napi_cast_session_manager_listener.cpp",
"src/napi_castengine_utils.cpp",
"src/native_module.cpp",
"src/napi_mirror_player.cpp",
"src/napi_stream_player.cpp",
"src/napi_stream_player_listener.cpp",
"src/napi_callback.cpp",
"src/napi_async_work.cpp",
"src/napi_castengine_enum.cpp"
]
configs = [
":cast_config",
"${cast_engine_root}:cast_engine_default_config"
]
deps = [
"${cast_engine_common}:cast_engine_common_sources",
"${cast_engine_interfaces}/inner_api:cast_engine_client",
]
external_deps = [
"hilog:libhilog",
"ipc:ipc_core",
"napi:ace_napi"
]
relative_install_dir = "module"
subsystem_name = "castplus"
part_name = "cast_engine"
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi async work for interfaces.
* Author: zhangjingnan
* Create: 2023-4-11
*/
#ifndef NAPI_CAST_ASYNC_WORK_H
#define NAPI_CAST_ASYNC_WORK_H
#include <functional>
#include <map>
#include <memory>
#include <string>
#include "napi/native_api.h"
#include "napi/native_common.h"
#include "napi/native_node_api.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
using NapiCbInfoParser = std::function<void(size_t argc, napi_value *argv)>;
using NapiAsyncExecute = std::function<void(void)>;
using NapiAsyncComplete = std::function<void(napi_value &)>;
struct NapiAsyncTask {
virtual ~NapiAsyncTask();
void GetJSInfo(napi_env envi, napi_callback_info info, NapiCbInfoParser parser = NapiCbInfoParser(),
bool sync = false);
napi_env env = nullptr;
napi_value output = nullptr;
napi_status status = napi_invalid_arg;
std::string errMessage;
int32_t errCode;
void *native = nullptr;
std::string taskName;
private:
napi_deferred deferred = nullptr;
napi_async_work work = nullptr;
napi_ref callbackRef = nullptr;
NapiAsyncExecute execute = nullptr;
NapiAsyncComplete complete = nullptr;
std::shared_ptr<NapiAsyncTask> hold; /* cross thread data */
static constexpr size_t ARGC_MAX = 4;
friend class NapiAsyncWork;
};
class NapiAsyncWork {
public:
static napi_value Enqueue(napi_env env, std::shared_ptr<NapiAsyncTask> ctxt, const std::string &name,
NapiAsyncExecute execute = NapiAsyncExecute(), NapiAsyncComplete complete = NapiAsyncComplete());
private:
static void GenerateOutput(NapiAsyncTask *napiAsyncTask);
enum {
RESULT_ERROR = 0,
RESULT_DATA = 1,
RESULT_ALL = 2
};
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif // NAPI_CAST_ASYNC_WORK_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi callback for interfaces.
* Author: zhangjingnan
* Create: 2023-4-11
*/
#ifndef NAPI_CALLBACK_H
#define NAPI_CALLBACK_H
#include <functional>
#include "napi/native_api.h"
#include "napi/native_common.h"
#include "napi/native_node_api.h"
#include "uv.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class NapiCallback final {
public:
using NapiArgsGetter = std::function<void(napi_env env, int &argc, napi_value *argv)>;
explicit NapiCallback(napi_env env);
~NapiCallback();
napi_env GetEnv() const;
void Call(napi_ref method, NapiArgsGetter getter);
private:
static void AfterWorkCallback(uv_work_t *work, int status);
struct DataContext {
napi_env env;
napi_ref method;
NapiArgsGetter getter;
};
napi_env env_ = nullptr;
uv_loop_s *loop_ = nullptr;
static constexpr size_t ARGC_MAX = 6;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi interface for cast session.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#ifndef NAPI_CAST_SESSION_H_
#define NAPI_CAST_SESSION_H_
#include <map>
#include <memory>
#include <mutex>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "napi_errors.h"
#include "cast_engine_errors.h"
#include "i_cast_session.h"
#include "napi_cast_session_listener.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class EXPORT NapiCastSession {
public:
using OnEventHandlerType = std::function<napi_status(napi_env, napi_value, NapiCastSession *)>;
using OffEventHandlerType = std::function<napi_status(napi_env, napi_value, NapiCastSession *)>;
static void DefineCastSessionJSClass(napi_env env);
static napi_status CreateNapiCastSession(napi_env env, std::shared_ptr<ICastSession> session, napi_value &out);
std::shared_ptr<NapiCastSessionListener> NapiListenerGetter();
void NapiListenerSetter(std::shared_ptr<NapiCastSessionListener> listener);
NapiCastSession(std::shared_ptr<ICastSession> session) : session_(session) {}
NapiCastSession() = default;
~NapiCastSession() = default;
std::shared_ptr<ICastSession> GetCastSession()
{
std::lock_guard<std::mutex> lock(mutex_);
return session_;
}
void Reset()
{
std::lock_guard<std::mutex> lock(mutex_);
session_.reset();
listener_.reset();
}
private:
static napi_value NapiCastSessionConstructor(napi_env env, napi_callback_info info);
static napi_value AddDevice(napi_env env, napi_callback_info info);
static napi_value RemoveDevice(napi_env env, napi_callback_info info);
static napi_value GetSessionId(napi_env env, napi_callback_info info);
static napi_value SetSessionProperty(napi_env env, napi_callback_info info);
static napi_value CreateMirrorPlayer(napi_env env, napi_callback_info info);
static napi_value CreateStreamPlayer(napi_env env, napi_callback_info info);
static napi_value SetCastMode(napi_env env, napi_callback_info info);
static napi_value Release(napi_env env, napi_callback_info info);
static napi_value OnEvent(napi_env env, napi_callback_info info);
static napi_value OffEvent(napi_env env, napi_callback_info info);
static napi_status OnInnerEvent(napi_env env, napi_value callback, NapiCastSession *napiSession);
static napi_status OnDeviceState(napi_env env, napi_value callback, NapiCastSession *napiSession);
static napi_status OffInnerEvent(napi_env env, napi_value callback, NapiCastSession *napiSession);
static napi_status OffDeviceState(napi_env env, napi_value callback, NapiCastSession *napiSession);
static NapiCastSession *GetNapiCastSession(napi_env env, napi_callback_info info);
static napi_status RegisterNativeSessionListener(NapiCastSession *napiSession);
static std::map<std::string, std::pair<OnEventHandlerType, OffEventHandlerType>> eventHandlers_;
std::mutex mutex_;
std::shared_ptr<ICastSession> session_;
std::shared_ptr<NapiCastSessionListener> listener_;
static thread_local napi_ref consRef_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session listener for napi interface.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#ifndef NAPI_CAST_SESSION_LISTENER_H
#define NAPI_CAST_SESSION_LISTENER_H
#include <memory>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include <list>
#include "i_cast_session.h"
#include "napi_callback.h"
#include "cast_engine_common.h"
#include "napi_castengine_utils.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class NapiCastSessionListener : public ICastSessionListener {
public:
using NapiArgsGetter = std::function<void(napi_env env, int &argc, napi_value *argv)>;
enum {
EVENT_ON_EVENT,
EVENT_DEVICE_STATE,
EVENT_TYPE_MAX
};
NapiCastSessionListener() {};
~NapiCastSessionListener() override;
void OnDeviceState(const DeviceStateInfo &stateEvent) override;
void OnEvent(const EventId &eventId, const std::string &jsonParam) override;
napi_status AddCallback(napi_env env, int32_t event, napi_value callback);
napi_status RemoveCallback(napi_env env, int32_t event, napi_value callback);
private:
void HandleEvent(int32_t event, NapiArgsGetter getter);
napi_status ClearCallback(napi_env env);
std::mutex lock_;
std::shared_ptr<NapiCallback> callback_;
std::list<napi_ref> callbacks_[EVENT_TYPE_MAX] {};
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi interface for cast session manager.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#ifndef NAPI_CAST_SESSION_MANAGER_H_
#define NAPI_CAST_SESSION_MANAGER_H_
#include <map>
#include <memory>
#include <list>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "napi_errors.h"
#include "cast_engine_errors.h"
#include "cast_session_manager.h"
#include "napi_cast_session_manager_listener.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class EXPORT NapiCastSessionManager {
public:
using OnEventHandlerType = std::function<napi_status(napi_env, napi_value)>;
using OffEventHandlerType = std::function<napi_status(napi_env, napi_value)>;
static napi_value Init(napi_env env, napi_value exports);
private:
static napi_value StartDiscovery(napi_env env, napi_callback_info info);
static napi_value StopDiscovery(napi_env env, napi_callback_info info);
static napi_value SetDiscoverable(napi_env env, napi_callback_info info);
static napi_value CreateCastSession(napi_env env, napi_callback_info info);
static napi_value Release(napi_env env, napi_callback_info info);
static napi_value OnEvent(napi_env env, napi_callback_info info);
static napi_value OffEvent(napi_env env, napi_callback_info info);
static napi_status OnServiceDied(napi_env env, napi_value callback);
static napi_status OnDeviceFound(napi_env env, napi_value callback);
static napi_status OnSessionCreated(napi_env env, napi_value callback);
static napi_status OffServiceDie(napi_env env, napi_value callback);
static napi_status OffDeviceFound(napi_env env, napi_value callback);
static napi_status OffSessionCreated(napi_env env, napi_value callback);
static napi_status RegisterNativeSessionManagerListener();
static std::map<std::string, std::pair<OnEventHandlerType, OffEventHandlerType>> eventHandlers_;
static std::shared_ptr<NapiCastSessionManagerListener> listener_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager listener for napi interface.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#ifndef NAPI_CAST_SESSION_MANAGER_LISTENER_H
#define NAPI_CAST_SESSION_MANAGER_LISTENER_H
#include <memory>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include <list>
#include "cast_engine_common.h"
#include "i_cast_session_manager_listener.h"
#include "napi_callback.h"
#include "napi_castengine_utils.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class NapiCastSessionManagerListener : public ICastSessionManagerListener {
public:
using NapiArgsGetter = std::function<void(napi_env env, int &argc, napi_value *argv)>;
enum {
EVENT_SERVICE_DIED,
EVENT_DEVICE_FOUND,
EVENT_SESSION_CREATE,
EVENT_TYPE_MAX
};
NapiCastSessionManagerListener() {};
~NapiCastSessionManagerListener() override;
void OnDeviceFound(const std::vector<CastRemoteDevice> &deviceList) override;
void OnDeviceOffline(const std::string &deviceId) override;
void OnSessionCreated(const std::shared_ptr<ICastSession> &castSession) override;
void OnServiceDied() override;
napi_status AddCallback(napi_env env, int32_t event, napi_value callback);
napi_status RemoveCallback(napi_env env, int32_t event, napi_value callback);
private:
void HandleEvent(int32_t event, NapiArgsGetter getter);
napi_status ClearCallback(napi_env env);
std::mutex lock_;
std::shared_ptr<NapiCallback> callback_;
std::list<napi_ref> callbacks_[EVENT_TYPE_MAX] {};
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi nums for interfaces.
* Author: zhangjingnan
* Create: 2023-4-11
*/
#ifndef NAPI_CASTENGINE_CONST_PROPERTIES_H
#define NAPI_CASTENGINE_CONST_PROPERTIES_H
#include "napi/native_api.h"
#include "napi/native_node_api.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
napi_status InitEnums(napi_env env, napi_value exports);
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2023 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
*
* Description: supply utils for napi interface.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#ifndef NAPI_CASTENGINE_UTILS_H
#define NAPI_CASTENGINE_UTILS_H
#include <list>
#include <uv.h>
#include <variant>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "i_cast_session.h"
#include "oh_remote_control_event.h"
#define CHECK_ARGS_RETURN_VOID(context, condition, message, code) \
do { \
if (!(condition)) { \
(context)->status = napi_invalid_arg; \
(context)->errMessage = std::string(message); \
(context)->errCode = code; \
CLOGE("(" #condition ") failed: " message); \
return; \
} \
} while (0)
#define CHECK_STATUS_RETURN_VOID(context, message, code) \
do { \
if ((context)->status != napi_ok) { \
(context)->errMessage = std::string(message); \
(context)->errCode = code; \
CLOGE("(context->status == napi_ok) failed: " message); \
return; \
} \
} while (0)
#define CHECK_RETURN_VOID(condition, message) \
do { \
if (!(condition)) { \
CLOGE("(" #condition ") failed: " message); \
return; \
} \
} while (0)
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
constexpr int32_t CALLBACK_ARGC_ZERO = 0;
constexpr int32_t CALLBACK_ARGC_ONE = 1;
constexpr int32_t CALLBACK_ARGC_TWO = 2;
constexpr int32_t CALLBACK_ARGC_THERE = 3;
constexpr int32_t CALLBACK_ARGC_FOUR = 4;
std::string ParseString(napi_env env, napi_value args);
int32_t ParseInt32(napi_env env, napi_value args);
bool ParseBool(napi_env env, napi_value args);
std::string JsObjectToString(napi_env env, napi_value &object, const char *fieldStr);
int32_t JsObjectToInt32(napi_env env, napi_value &object, const char *fieldStr);
bool JsObjectToBool(napi_env env, napi_value &object, const char *fieldStr);
uint32_t JsObjectToUint32(napi_env env, napi_value &object, const char *fieldStr);
double JsObjectToDouble(napi_env env, napi_value &object, const char *fieldStr);
int64_t JsObjectToInt64(napi_env env, napi_value &object, const char *fieldStr);
napi_value ConvertDeviceListToJS(napi_env env, const std::vector<CastRemoteDevice> &devices);
napi_value ConvertCastSessionToJS(napi_env env, const std::shared_ptr<ICastSession> &castSession);
napi_value ConvertDeviceStateInfoToJS(napi_env env, const DeviceStateInfo &stateEvent);
napi_value ConvertMediaInfoToJS(napi_env env, const MediaInfo &mediaInfo);
napi_value ConvertMediaInfoHolderToJS(napi_env env, const MediaInfoHolder &mediaInfoHolder);
napi_value ConvertCastRemoteDeviceToJS(napi_env env, const CastRemoteDevice &castRemoteDevice);
CastRemoteDevice GetCastRemoteDeviceFromJS(napi_env env, napi_value &object);
CastSessionProperty GetCastSessionPropertyFromJS(napi_env env, napi_value &object);
AudioProperty GetAudioPropertyFromJS(napi_env env, napi_value &object);
VideoProperty GetVideoPropertyFromJS(napi_env env, napi_value &object);
WindowProperty GetWindowPropertyFromJS(napi_env env, napi_value &object);
bool GetMediaInfoFromJS(napi_env env, napi_value &object, MediaInfo &mediaInfo);
bool GetProtocolTypesFromJS(napi_env env, napi_value &object, int &protocolTypes);
bool GetMediaInfoHolderFromJS(napi_env env, napi_value &object, MediaInfoHolder &mediaInfoHolder);
bool GetJSFuncParams(napi_env env, napi_callback_info info, napi_value argv[], size_t expectedArgc,
napi_valuetype expectedTypes[]);
bool CheckJSParamsType(napi_env env, napi_value argv[], size_t expectedArgc, napi_valuetype expectedTypes[]);
void CallJSFunc(napi_env env, napi_ref func, size_t argc, napi_value argv[]);
napi_value GetUndefinedValue(napi_env env);
bool Equals(napi_env env, napi_value value, napi_ref copy);
napi_status GetRefByCallback(napi_env env, std::list<napi_ref> callbackList, napi_value callback,
napi_ref &callbackRef);
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi errors for interfaces.
* Author: zhangjingnan
* Create: 2023-4-11
*/
#ifndef NAPI_ERRORS_H
#define NAPI_ERRORS_H
#include <map>
#include "cast_engine_errors.h"
namespace OHOS {
namespace CastEngine {
namespace NapiErrors {
static std::map<int32_t, int32_t> errcode_ = {
{ CAST_ENGINE_ERROR, CAST_ENGINE_ERROR },
{ ERR_NO_MEMORY, ERR_NO_MEMORY },
{ ERR_SESSION_NOT_EXIST, ERR_SESSION_NOT_EXIST },
{ ERR_SERVICE_STATE_NOT_MATCH, ERR_SERVICE_STATE_NOT_MATCH },
{ ERR_SESSION_STATE_NOT_MATCH, ERR_SESSION_STATE_NOT_MATCH },
{ ERR_NO_PERMISSION, ERR_NO_PERMISSION },
{ ERR_INVALID_PARAM, ERR_INVALID_PARAM }
};
}
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_ENGINE_ERRORS_H

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi interface for cast mirror player.
* Author: zhangjingnan
* Create: 2023-5-27
*/
#ifndef NAPI_CAST_MIRROR_PLAYER_H_
#define NAPI_CAST_MIRROR_PLAYER_H_
#include <map>
#include <memory>
#include <mutex>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "napi_errors.h"
#include "cast_engine_errors.h"
#include "i_mirror_player.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class NapiMirrorPlayer {
public:
static void DefineMirrorPlayerJSClass(napi_env env);
static napi_status CreateNapiMirrorPlayer(napi_env env, std::shared_ptr<IMirrorPlayer> mirrorPlayer,
napi_value &out);
NapiMirrorPlayer(std::shared_ptr<IMirrorPlayer> mirrorPlayer) : mirrorPlayer_(mirrorPlayer) {}
NapiMirrorPlayer() = default;
~NapiMirrorPlayer() = default;
std::shared_ptr<IMirrorPlayer> GetMirrorPlayer()
{
std::lock_guard<std::mutex> lock(mutex_);
return mirrorPlayer_;
}
void Reset()
{
std::lock_guard<std::mutex> lock(mutex_);
mirrorPlayer_.reset();
}
private:
static napi_value NapiMirrorPlayerConstructor(napi_env env, napi_callback_info info);
static napi_value Play(napi_env env, napi_callback_info info);
static napi_value Pause(napi_env env, napi_callback_info info);
static napi_value SetSurface(napi_env env, napi_callback_info info);
static napi_value Release(napi_env env, napi_callback_info info);
std::mutex mutex_;
std::shared_ptr<IMirrorPlayer> mirrorPlayer_;
static thread_local napi_ref consRef_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi interface for stream player.
* Author: huangchanggui
* Create: 2023-1-11
*/
#ifndef NAPI_STREAM_PLAYER_H
#define NAPI_STREAM_PLAYER_H
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "i_stream_player.h"
#include "napi_stream_player_listener.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class EXPORT NapiStreamPlayer {
public:
using OnEventHandlerType = std::function<napi_status(napi_env, napi_value, NapiStreamPlayer *)>;
using OffEventHandlerType = std::function<napi_status(napi_env, napi_value, NapiStreamPlayer *)>;
static void DefineStreamPlayerJSClass(napi_env env);
static napi_status CreateNapiStreamPlayer(napi_env env, std::shared_ptr<IStreamPlayer> player, napi_value &out);
std::shared_ptr<NapiStreamPlayerListener> NapiListenerGetter();
void NapiListenerSetter(std::shared_ptr<NapiStreamPlayerListener> listener);
explicit NapiStreamPlayer(std::shared_ptr<IStreamPlayer> player) : streamPlayer_(player) {}
NapiStreamPlayer() = default;
~NapiStreamPlayer() = default;
std::shared_ptr<IStreamPlayer> GetStreamPlayer()
{
std::lock_guard<std::mutex> lock(mutex_);
return streamPlayer_;
}
void Reset()
{
std::lock_guard<std::mutex> lock(mutex_);
streamPlayer_.reset();
listener_.reset();
}
private:
static napi_value NapiStreamPlayerConstructor(napi_env env, napi_callback_info info);
static napi_value SetSurface(napi_env env, napi_callback_info info);
static napi_value Load(napi_env env, napi_callback_info info);
static napi_value Start(napi_env env, napi_callback_info info);
static napi_value Play(napi_env env, napi_callback_info info);
static napi_value Pause(napi_env env, napi_callback_info info);
static napi_value Stop(napi_env env, napi_callback_info info);
static napi_value Next(napi_env env, napi_callback_info info);
static napi_value Previous(napi_env env, napi_callback_info info);
static napi_value Seek(napi_env env, napi_callback_info info);
static napi_value FastForward(napi_env env, napi_callback_info info);
static napi_value FastRewind(napi_env env, napi_callback_info info);
static napi_value SetVolume(napi_env env, napi_callback_info info);
static napi_value SetLoopMode(napi_env env, napi_callback_info info);
static napi_value SetSpeed(napi_env env, napi_callback_info info);
static napi_value GetPlayerStatus(napi_env env, napi_callback_info info);
static napi_value GetPosition(napi_env env, napi_callback_info info);
static napi_value GetVolume(napi_env env, napi_callback_info info);
static napi_value GetLoopMode(napi_env env, napi_callback_info info);
static napi_value GetPlaySpeed(napi_env env, napi_callback_info info);
static napi_value GetMediaInfoHolder(napi_env env, napi_callback_info info);
static napi_value Release(napi_env env, napi_callback_info info);
static napi_value OnEvent(napi_env env, napi_callback_info info);
static napi_value OffEvent(napi_env env, napi_callback_info info);
static napi_status OnStateChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnPositionChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnMediaItemChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnVolumeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnVideoSizeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnLoopModeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnPlaySpeedChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnPlayerError(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnNextRequest(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnPreviousRequest(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnSeekDone(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OnEndOfStream(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffStateChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffPositionChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffMediaItemChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffVolumeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffVideoSizeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffLoopModeChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffPlaySpeedChanged(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffPlayerError(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffNextRequest(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffPreviousRequest(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffSeekDone(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static napi_status OffEndOfStream(napi_env env, napi_value callback, NapiStreamPlayer *napiStreamPlayer);
static NapiStreamPlayer *GetNapiStreamPlayer(napi_env env, napi_callback_info info);
static napi_status RegisterNativeStreamPlayerListener(NapiStreamPlayer *napiStreamPlayer);
static std::map<std::string, std::pair<OnEventHandlerType, OffEventHandlerType>> eventHandlers_;
std::mutex mutex_;
std::shared_ptr<IStreamPlayer> streamPlayer_;
std::shared_ptr<NapiStreamPlayerListener> listener_;
static thread_local napi_ref consRef_;
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2023 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
*
* Description: supply stream player listener for napi interface.
* Author: huangchanggui
* Create: 2023-1-11
*/
#ifndef NAPI_STREAM_PLAYER_LISTENER_H
#define NAPI_STREAM_PLAYER_LISTENER_H
#include <memory>
#include <list>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_common.h"
#include "napi_callback.h"
#include "napi_castengine_utils.h"
#include "i_stream_player.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
class NapiStreamPlayerListener : public IStreamPlayerListener {
public:
using NapiArgsGetter = std::function<void(napi_env env, int &argc, napi_value *argv)>;
enum {
EVENT_PLAYER_STATUS_CHANGED,
EVENT_POSITION_CHANGED,
EVENT_MEDIA_ITEM_CHANGED,
EVENT_VOLUME_CHANGED,
EVENT_VIDEO_SIZE_CHANGED,
EVENT_LOOP_MODE_CHANGED,
EVENT_PLAY_SPEED_CHANGED,
EVENT_PLAYER_ERROR,
EVENT_NEXT_REQUEST,
EVENT_PREVIOUS_REQUEST,
EVENT_SEEK_DONE,
EVENT_END_OF_STREAM,
EVENT_PLAY_REQUEST,
EVENT_TYPE_MAX
};
NapiStreamPlayerListener() {};
~NapiStreamPlayerListener() override;
void OnStateChanged(const PlayerStates playbackState, bool isPlayWhenReady) override;
void OnPositionChanged(int position, int bufferPosition, int duration) override;
void OnMediaItemChanged(const MediaInfo &mediaInfo) override;
void OnVolumeChanged(int volume, int maxVolume) override;
void OnVideoSizeChanged(int width, int height) override;
void OnLoopModeChanged(const LoopMode loopMode) override;
void OnPlaySpeedChanged(const PlaybackSpeed speed) override;
void OnPlayerError(int errorCode, const std::string &errorMsg) override;
void OnNextRequest() override;
void OnPreviousRequest() override;
void OnSeekDone(int position) override;
void OnEndOfStream(int isLooping) override;
void OnPlayRequest(const MediaInfo &mediaInfo) override;
napi_status AddCallback(napi_env env, int32_t event, napi_value callback);
napi_status RemoveCallback(napi_env env, int32_t event, napi_value callback);
private:
void HandleEvent(int32_t event, NapiArgsGetter getter);
napi_status ClearCallback(napi_env env);
std::mutex lock_;
std::shared_ptr<NapiCallback> callback_;
std::list<napi_ref> callbacks_[EVENT_TYPE_MAX] {};
};
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,173 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi async work realization for interfaces.
* Author: zhangjingnan
* Create: 2023-4-11
*/
#include "napi_async_work.h"
#include "napi_castengine_utils.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-AsyncWork");
NapiAsyncTask::~NapiAsyncTask()
{
CLOGD("no memory leak after callback or promise[resolved/rejected]");
if (env != nullptr) {
if (work != nullptr) {
NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, work));
}
if (callbackRef != nullptr) {
NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, callbackRef));
}
env = nullptr;
}
}
void NapiAsyncTask::GetJSInfo(napi_env envi, napi_callback_info info, NapiCbInfoParser parser, bool sync)
{
env = envi;
size_t argc = ARGC_MAX;
napi_value argv[ARGC_MAX] = {nullptr};
napi_value thisVar = nullptr;
status = napi_get_cb_info(envi, info, &argc, argv, &thisVar, nullptr);
if (status != napi_ok || argc > ARGC_MAX) {
CLOGE("napi_get_cb_info failed");
return;
}
status = napi_unwrap(envi, thisVar, &native);
if (status != napi_ok) {
CLOGE("napi_unwrap failed");
return;
}
if (native == nullptr) {
CLOGD("thisVar is null");
}
if (!sync && argc > 0) {
// get the last arguments :: <callback>
size_t index = argc - 1;
napi_valuetype type = napi_undefined;
status = napi_typeof(envi, argv[index], &type);
if ((status == napi_ok) && (type == napi_function)) {
status = napi_create_reference(envi, argv[index], 1, &callbackRef);
if (status != napi_ok) {
CLOGE("napi_get_cb_info failed");
return;
}
argc = index;
CLOGD("async callback, no promise");
} else {
CLOGD("no callback, async promise");
}
}
if (parser) {
CLOGD("input parser exists");
parser(argc, argv);
}
}
napi_value NapiAsyncWork::Enqueue(napi_env env, std::shared_ptr<NapiAsyncTask> napiAsyncTask, const std::string &name,
NapiAsyncExecute execute, NapiAsyncComplete complete)
{
CLOGI("name=%{public}s", name.c_str());
napiAsyncTask->execute = std::move(execute);
napiAsyncTask->complete = std::move(complete);
napiAsyncTask->taskName = name;
napi_value promise = nullptr;
if (napiAsyncTask->callbackRef == nullptr) {
NAPI_CALL(napiAsyncTask->env, napi_create_promise(napiAsyncTask->env, &napiAsyncTask->deferred, &promise));
CLOGD("create deferred promise");
} else {
NAPI_CALL(napiAsyncTask->env, napi_get_undefined(napiAsyncTask->env, &promise));
}
napi_value resourceName = nullptr;
NAPI_CALL(napiAsyncTask->env,
napi_create_string_utf8(napiAsyncTask->env, name.c_str(), NAPI_AUTO_LENGTH, &resourceName));
napi_create_async_work(
napiAsyncTask->env, nullptr, resourceName,
[](napi_env env, void *data) {
if (data == nullptr) {
CLOGE("napi_async_execute_callback nullptr");
return;
}
auto task = reinterpret_cast<NapiAsyncTask *>(data);
CLOGD("napi_async_execute_callback status=%{public}d", task->status);
if (task->execute && task->status == napi_ok) {
task->execute();
task->execute = nullptr;
}
},
[](napi_env env, napi_status status, void *data) {
if (data == nullptr) {
CLOGE("napi_async_complete_callback nullptr");
return;
}
auto task = reinterpret_cast<NapiAsyncTask *>(data);
CLOGD("napi_async_complete_callback status=%{public}d, status=%{public}d", status, task->status);
if ((status != napi_ok) && (task->status == napi_ok)) {
task->status = status;
}
if ((task->complete) && (status == napi_ok) && (task->status == napi_ok)) {
task->complete(task->output);
task->complete = nullptr;
}
GenerateOutput(task);
},
reinterpret_cast<void *>(napiAsyncTask.get()), &napiAsyncTask->work);
NAPI_CALL(napiAsyncTask->env, napi_queue_async_work(napiAsyncTask->env, napiAsyncTask->work));
napiAsyncTask->hold = napiAsyncTask; // save crossing-thread ctxt.
return promise;
}
void NapiAsyncWork::GenerateOutput(NapiAsyncTask *napiAsyncTask)
{
napi_value result[RESULT_ALL] = {nullptr};
if (napiAsyncTask->status == napi_ok) {
NAPI_CALL_RETURN_VOID(napiAsyncTask->env, napi_get_undefined(napiAsyncTask->env, &result[RESULT_ERROR]));
if (napiAsyncTask->output == nullptr) {
NAPI_CALL_RETURN_VOID(napiAsyncTask->env, napi_get_undefined(napiAsyncTask->env, &napiAsyncTask->output));
}
result[RESULT_DATA] = napiAsyncTask->output;
} else {
napi_value message = nullptr;
napi_value code = nullptr;
NAPI_CALL_RETURN_VOID(napiAsyncTask->env,
napi_create_string_utf8(napiAsyncTask->env, napiAsyncTask->errMessage.c_str(), NAPI_AUTO_LENGTH, &message));
NAPI_CALL_RETURN_VOID(napiAsyncTask->env,
napi_create_error(napiAsyncTask->env, nullptr, message, &result[RESULT_ERROR]));
NAPI_CALL_RETURN_VOID(napiAsyncTask->env, napi_create_int32(napiAsyncTask->env, napiAsyncTask->errCode, &code));
NAPI_CALL_RETURN_VOID(napiAsyncTask->env,
napi_set_named_property(napiAsyncTask->env, result[RESULT_ERROR], "code", code));
NAPI_CALL_RETURN_VOID(napiAsyncTask->env, napi_get_undefined(napiAsyncTask->env, &result[RESULT_DATA]));
}
if (napiAsyncTask->deferred != nullptr) {
if (napiAsyncTask->status == napi_ok) {
CLOGD("deferred promise resolved");
NAPI_CALL_RETURN_VOID(napiAsyncTask->env,
napi_resolve_deferred(napiAsyncTask->env, napiAsyncTask->deferred, result[RESULT_DATA]));
} else {
CLOGD("deferred promise rejected");
NAPI_CALL_RETURN_VOID(napiAsyncTask->env,
napi_reject_deferred(napiAsyncTask->env, napiAsyncTask->deferred, result[RESULT_ERROR]));
}
} else {
CallJSFunc(napiAsyncTask->env, napiAsyncTask->callbackRef, RESULT_ALL, result);
}
napiAsyncTask->hold.reset(); // release napiAsyncTask.
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi callback realization for interfaces.
* Author: zhangjingnan
* Create: 2023-4-11
*/
#include <memory>
#include "cast_engine_log.h"
#include "napi_callback.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-Callback");
NapiCallback::NapiCallback(napi_env env) : env_(env)
{
if (env != nullptr) {
NAPI_CALL_RETURN_VOID(env, napi_get_uv_event_loop(env, &loop_));
}
}
NapiCallback::~NapiCallback()
{
CLOGD("no memory leak for queue-callback");
env_ = nullptr;
}
napi_env NapiCallback::GetEnv() const
{
return env_;
}
void NapiCallback::AfterWorkCallback(uv_work_t *work, int status)
{
std::shared_ptr<DataContext> context(static_cast<DataContext *>(work->data), [work](DataContext *ptr) {
delete ptr;
delete work;
});
int argc = 0;
napi_handle_scope scope = nullptr;
napi_open_handle_scope(context->env, &scope);
napi_value argv[ARGC_MAX] = { nullptr };
if (context->getter) {
argc = ARGC_MAX;
context->getter(context->env, argc, argv);
}
napi_value undefined = nullptr;
if (napi_get_undefined(context->env, &undefined) != napi_ok) {
CLOGE("napi_get_undefined failed");
napi_close_handle_scope(context->env, scope);
return;
}
napi_value callback = nullptr;
if (napi_get_reference_value(context->env, context->method, &callback) != napi_ok) {
CLOGE("napi_get_reference_value failed");
napi_close_handle_scope(context->env, scope);
return;
}
napi_value callResult = nullptr;
if (napi_call_function(context->env, undefined, callback, argc, argv, &callResult) != napi_ok) {
CLOGE("napi_call_function failed");
}
napi_close_handle_scope(context->env, scope);
}
void NapiCallback::Call(napi_ref method, NapiArgsGetter getter)
{
CLOGD("Start to have JS call");
if (loop_ == nullptr) {
CLOGE("loop_ is nullptr");
return;
}
if (method == nullptr) {
CLOGE("method is nullptr");
return;
}
auto *work = new (std::nothrow) uv_work_t;
if (work == nullptr) {
CLOGE("no memory for uv_work_t");
return;
}
work->data = new DataContext { env_, method, std::move(getter) };
int res = uv_queue_work(
loop_, work, [](uv_work_t *work) {}, AfterWorkCallback);
if (res != 0) {
CLOGE("uv queue work failed");
delete work;
return;
}
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,663 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi interface realization for cast session.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#include <memory>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "oh_remote_control_event.h"
#include "i_cast_session.h"
#include "cast_session_manager.h"
#include "napi_castengine_utils.h"
#include "napi_cast_session_listener.h"
#include "napi_cast_session.h"
#include "napi_stream_player.h"
#include "napi_mirror_player.h"
#include "napi_async_work.h"
using namespace OHOS::CastEngine::CastEngineClient;
using namespace std;
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-Session");
thread_local napi_ref NapiCastSession::consRef_ = nullptr;
std::map<std::string, std::pair<NapiCastSession::OnEventHandlerType,
NapiCastSession::OffEventHandlerType>>
NapiCastSession::eventHandlers_ = {
{ "event", { OnInnerEvent, OffInnerEvent } },
{ "deviceState", { OnDeviceState, OffDeviceState } }
};
void NapiCastSession::DefineCastSessionJSClass(napi_env env)
{
napi_property_descriptor NapiCastSessionDesc[] = {
DECLARE_NAPI_FUNCTION("on", OnEvent),
DECLARE_NAPI_FUNCTION("off", OffEvent),
DECLARE_NAPI_FUNCTION("addDevice", AddDevice),
DECLARE_NAPI_FUNCTION("removeDevice", RemoveDevice),
DECLARE_NAPI_FUNCTION("getSessionId", GetSessionId),
DECLARE_NAPI_FUNCTION("setSessionProperty", SetSessionProperty),
DECLARE_NAPI_FUNCTION("createMirrorPlayer", CreateMirrorPlayer),
DECLARE_NAPI_FUNCTION("createStreamPlayer", CreateStreamPlayer),
DECLARE_NAPI_FUNCTION("setCastMode", SetCastMode),
DECLARE_NAPI_FUNCTION("release", Release)
};
napi_value castSession = nullptr;
constexpr int initialRefCount = 1;
napi_status status = napi_define_class(env, "castSession", NAPI_AUTO_LENGTH, NapiCastSessionConstructor, nullptr,
sizeof(NapiCastSessionDesc) / sizeof(NapiCastSessionDesc[0]), NapiCastSessionDesc, &castSession);
if (status != napi_ok) {
CLOGE("napi_define_class failed");
return;
}
status = napi_create_reference(env, castSession, initialRefCount, &consRef_);
if (status != napi_ok) {
CLOGE("DefineCastSessionJSClass napi_create_reference failed");
}
}
napi_value NapiCastSession::NapiCastSessionConstructor(napi_env env, napi_callback_info info)
{
CLOGD("NapiCastSession start to construct in");
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
CLOGD("NapiCastSession construct successfully");
return thisVar;
}
napi_status NapiCastSession::CreateNapiCastSession(napi_env env, shared_ptr<ICastSession> session, napi_value &out)
{
CLOGD("Start to create napiCastSession in");
napi_value result = nullptr;
napi_value constructor = nullptr;
if (consRef_ == nullptr || session == nullptr) {
CLOGE("CreateNapiCastSession input is null");
return napi_generic_failure;
}
napi_status status = napi_get_reference_value(env, consRef_, &constructor);
if (status != napi_ok || constructor == nullptr) {
CLOGE("CreateNapiCastSession napi_get_reference_value failed");
return napi_generic_failure;
}
constexpr size_t argc = 0;
status = napi_new_instance(env, constructor, argc, nullptr, &result);
if (status != napi_ok) {
CLOGE("CreateNapiCastSession napi_new_instance failed");
return napi_generic_failure;
}
NapiCastSession *napiCastSession = new NapiCastSession(session);
if (napiCastSession == nullptr) {
CLOGE("NapiCastSession is nullptr");
return napi_generic_failure;
}
auto finalize = [](napi_env env, void *data, void *hint) {
NapiCastSession *session = reinterpret_cast<NapiCastSession *>(data);
if (session != nullptr) {
CLOGI("Session deconstructed");
delete session;
session = nullptr;
}
};
if (napi_wrap(env, result, napiCastSession, finalize, nullptr, nullptr) != napi_ok) {
CLOGE("CreateNapiCastSession napi_wrap failed");
delete napiCastSession;
napiCastSession = nullptr;
return napi_generic_failure;
}
out = result;
CLOGD("Create napiCastSession successfully");
return napi_ok;
}
NapiCastSession *NapiCastSession::GetNapiCastSession(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL_BASE(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr), nullptr);
NapiCastSession *napiCastSession = nullptr;
NAPI_CALL_BASE(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiCastSession)), nullptr);
if (napiCastSession == nullptr) {
CLOGE("napi_unwrap napiStreamPlayer is null");
return nullptr;
}
return napiCastSession;
}
napi_value NapiCastSession::OnEvent(napi_env env, napi_callback_info info)
{
constexpr size_t expectedArgc = 2;
napi_value argv[expectedArgc] = { 0 };
napi_valuetype expectedTypes[expectedArgc] = { napi_string, napi_function };
if (!GetJSFuncParams(env, info, argv, expectedArgc, expectedTypes)) {
return GetUndefinedValue(env);
}
std::string eventName = ParseString(env, argv[0]);
NapiCastSession *napiSession = GetNapiCastSession(env, info);
if (napiSession == nullptr) {
CLOGE("napiSession is null");
return GetUndefinedValue(env);
}
auto it = eventHandlers_.find(eventName);
if (it == eventHandlers_.end()) {
CLOGE("event name invalid");
return GetUndefinedValue(env);
}
if (RegisterNativeSessionListener(napiSession) == napi_generic_failure) {
return GetUndefinedValue(env);
}
if (it->second.first(env, argv[1], napiSession) != napi_ok) {
CLOGE("event name invalid");
}
return GetUndefinedValue(env);
}
napi_value NapiCastSession::OffEvent(napi_env env, napi_callback_info info)
{
constexpr size_t expectedArgc = 2;
napi_value argv[expectedArgc] = { 0 };
napi_valuetype expectedTypes[expectedArgc] = { napi_string, napi_function};
if (!GetJSFuncParams(env, info, argv, expectedArgc, expectedTypes)) {
return GetUndefinedValue(env);
}
std::string eventName = ParseString(env, argv[0]);
auto it = eventHandlers_.find(eventName);
if (it == eventHandlers_.end()) {
CLOGE("event name invalid");
return GetUndefinedValue(env);
}
NapiCastSession *napiSession = GetNapiCastSession(env, info);
if (napiSession == nullptr) {
CLOGE("napiSession is null");
return GetUndefinedValue(env);
}
if (it->second.second(env, argv[1], napiSession) != napi_ok) {
CLOGE("event name invalid");
}
return GetUndefinedValue(env);
}
napi_status NapiCastSession::RegisterNativeSessionListener(NapiCastSession *napiSession)
{
if (napiSession == nullptr) {
CLOGE("napiSession is null");
return napi_generic_failure;
}
if (napiSession->NapiListenerGetter()) {
return napi_ok;
}
auto session = napiSession->GetCastSession();
if (!session) {
CLOGE("Session is null");
return napi_generic_failure;
}
auto listener = std::make_shared<NapiCastSessionListener>();
if (!listener) {
CLOGE("Failed to malloc session listener");
return napi_generic_failure;
}
int32_t ret = session->RegisterListener(listener);
if (ret != CAST_ENGINE_SUCCESS) {
CLOGE("native register session listener failed");
return napi_generic_failure;
}
napiSession->NapiListenerSetter(listener);
return napi_ok;
}
napi_status NapiCastSession::OnInnerEvent(napi_env env, napi_value callback, NapiCastSession *napiSession)
{
if (napiSession == nullptr) {
CLOGE("napiSession is null");
return napi_generic_failure;
}
if (!napiSession->NapiListenerGetter()) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (napiSession->NapiListenerGetter()->AddCallback(env, NapiCastSessionListener::EVENT_ON_EVENT,
callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSession::OnDeviceState(napi_env env, napi_value callback, NapiCastSession *napiSession)
{
if (napiSession == nullptr) {
CLOGE("napiSession is null");
return napi_generic_failure;
}
if (!napiSession->NapiListenerGetter()) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (napiSession->NapiListenerGetter()->AddCallback(env, NapiCastSessionListener::EVENT_DEVICE_STATE,
callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSession::OffInnerEvent(napi_env env, napi_value callback, NapiCastSession *napiSession)
{
if (napiSession == nullptr) {
CLOGE("napiSession is null");
return napi_generic_failure;
}
if (!napiSession->NapiListenerGetter()) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (napiSession->NapiListenerGetter()->RemoveCallback(env, NapiCastSessionListener::EVENT_ON_EVENT,
callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSession::OffDeviceState(napi_env env, napi_value callback, NapiCastSession *napiSession)
{
if (napiSession == nullptr) {
CLOGE("napiSession is null");
return napi_generic_failure;
}
if (!napiSession->NapiListenerGetter()) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (napiSession->NapiListenerGetter()->RemoveCallback(env, NapiCastSessionListener::EVENT_DEVICE_STATE,
callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_value NapiCastSession::AddDevice(napi_env env, napi_callback_info info)
{
CLOGD("Start to add device in");
struct ConcreteTask : public NapiAsyncTask {
CastRemoteDevice castRemoteDevice_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_object };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->castRemoteDevice_ = GetCastRemoteDeviceFromJS(env, argv[0]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = castSession->AddDevice(napiAsyntask->castRemoteDevice_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "AddDevice failed : no permission";
} else if (ret == ERR_INVALID_PARAM) {
napiAsyntask->errMessage = "AddDevice failed : invalid parameters";
} else {
napiAsyntask->errMessage = "AddDevice failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "AddDevice", executor, complete);
}
napi_value NapiCastSession::RemoveDevice(napi_env env, napi_callback_info info)
{
CLOGD("Start to remove device in");
struct ConcreteTask : public NapiAsyncTask {
string deviceId_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_string };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->deviceId_ = ParseString(env, argv[0]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = castSession->RemoveDevice(napiAsyntask->deviceId_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "RemoveDevice failed : no permission";
} else if (ret == ERR_INVALID_PARAM) {
napiAsyntask->errMessage = "RemoveDevice failed : invalid parameters";
} else {
napiAsyntask->errMessage = "RemoveDevice failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "RemoveDevice", executor, complete);
}
napi_value NapiCastSession::GetSessionId(napi_env env, napi_callback_info info)
{
CLOGD("Start to get sessionId in");
struct ConcreteTask : public NapiAsyncTask {
string sessionId_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
napiAsyntask->GetJSInfo(env, info);
auto executor = [napiAsyntask]() {
auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = castSession->GetSessionId(napiAsyntask->sessionId_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "GetSessionId failed : no permission";
} else {
napiAsyntask->errMessage = "GetSessionId failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env, napiAsyntask](napi_value &output) {
napiAsyntask->status =
napi_create_string_utf8(env, napiAsyntask->sessionId_.c_str(), NAPI_AUTO_LENGTH, &output);
CHECK_STATUS_RETURN_VOID(napiAsyntask, "napi_create_string_utf8 failed",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
};
return NapiAsyncWork::Enqueue(env, napiAsyntask, "GetSessionId", executor, complete);
}
napi_value NapiCastSession::SetSessionProperty(napi_env env, napi_callback_info info)
{
CLOGD("Start to set sessionProperty in");
struct ConcreteTask : public NapiAsyncTask {
CastSessionProperty castSessionProperty_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_object };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->castSessionProperty_ = GetCastSessionPropertyFromJS(env, argv[0]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = castSession->SetSessionProperty(napiAsyntask->castSessionProperty_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "SetSessionProperty failed : no permission";
} else if (ret == ERR_INVALID_PARAM) {
napiAsyntask->errMessage = "SetSessionProperty failed : invalid parameters";
} else {
napiAsyntask->errMessage = "SetSessionProperty failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetSessionProperty", executor, complete);
}
napi_value NapiCastSession::CreateMirrorPlayer(napi_env env, napi_callback_info info)
{
CLOGD("Start to create mirror Player");
struct ConcreteTask : public NapiAsyncTask {
shared_ptr<IMirrorPlayer> player_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
napiAsyntask->GetJSInfo(env, info);
auto executor = [napiAsyntask]() {
auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = castSession->CreateMirrorPlayer(napiAsyntask->player_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "CreateMirrorPlayer failed : no permission";
} else {
napiAsyntask->errMessage = "CreateMirrorPlayer failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [napiAsyntask](napi_value &output) {
napiAsyntask->status =
NapiMirrorPlayer::CreateNapiMirrorPlayer(napiAsyntask->env, napiAsyntask->player_, output);
CHECK_STATUS_RETURN_VOID(napiAsyntask, "convert native object to javascript object failed",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
};
return NapiAsyncWork::Enqueue(env, napiAsyntask, "CreateMirrorPlayer", executor, complete);
}
napi_value NapiCastSession::CreateStreamPlayer(napi_env env, napi_callback_info info)
{
CLOGD("Start to create Stream Player");
struct ConcreteTask : public NapiAsyncTask {
shared_ptr<IStreamPlayer> player_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
napiAsyntask->GetJSInfo(env, info);
auto executor = [napiAsyntask]() {
auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = castSession->CreateStreamPlayer(napiAsyntask->player_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "CreateStreamPlayer failed : no permission";
} else {
napiAsyntask->errMessage = "CreateStreamPlayer failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [napiAsyntask](napi_value &output) {
napiAsyntask->status =
NapiStreamPlayer::CreateNapiStreamPlayer(napiAsyntask->env, napiAsyntask->player_, output);
CHECK_STATUS_RETURN_VOID(napiAsyntask, "convert native object to javascript object failed",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
};
return NapiAsyncWork::Enqueue(env, napiAsyntask, "CreateStreamPlayer", executor, complete);
}
napi_value NapiCastSession::SetCastMode(napi_env env, napi_callback_info info)
{
CLOGD("Start to set cast mode in");
struct ConcreteTask : public NapiAsyncTask {
CastMode castMode_;
string jsonParam_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 2;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_number, napi_string };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->castMode_ = static_cast<CastMode>(ParseInt32(env, argv[0]));
napiAsyntask->jsonParam_ = ParseString(env, argv[1]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = castSession->SetCastMode(napiAsyntask->castMode_, napiAsyntask->jsonParam_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "SetCastMode failed : no permission";
} else if (ret == ERR_INVALID_PARAM) {
napiAsyntask->errMessage = "SetCastMode failed : invalid parameters";
} else {
napiAsyntask->errMessage = "SetCastMode failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetCastMode", executor, complete);
}
napi_value NapiCastSession::Release(napi_env env, napi_callback_info info)
{
CLOGD("Start to release in");
auto napiAsyntask = std::make_shared<NapiAsyncTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
napiAsyntask->GetJSInfo(env, info);
auto executor = [napiAsyntask]() {
auto *napiSession = reinterpret_cast<NapiCastSession *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiSession != nullptr, "napiSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<ICastSession> castSession = napiSession->GetCastSession();
CHECK_ARGS_RETURN_VOID(napiAsyntask, castSession, "ICastSession is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = castSession->Release();
if (ret == CAST_ENGINE_SUCCESS) {
napiSession->Reset();
} else if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "Release failed : no permission";
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
} else {
napiAsyntask->errMessage = "Release failed : native server exception";
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "Release", executor, complete);
}
std::shared_ptr<NapiCastSessionListener> NapiCastSession::NapiListenerGetter()
{
return listener_;
}
void NapiCastSession::NapiListenerSetter(std::shared_ptr<NapiCastSessionListener> listener)
{
listener_ = listener;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session listener realization for napi interface.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#include <uv.h>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "napi_castengine_utils.h"
#include "napi_cast_session_listener.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-SessionListener");
NapiCastSessionListener::~NapiCastSessionListener()
{
CLOGD("destrcutor in");
ClearCallback(callback_->GetEnv());
}
void NapiCastSessionListener::HandleEvent(int32_t event, NapiArgsGetter getter)
{
std::lock_guard<std::mutex> lockGuard(lock_);
if (callbacks_[event].empty()) {
CLOGE("not register callback event=%{public}d", event);
return;
}
for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
callback_->Call(*ref, getter);
}
}
void NapiCastSessionListener::OnDeviceState(const DeviceStateInfo &stateEvent)
{
CLOGD("OnDeviceState start");
NapiArgsGetter napiArgsGetter = [stateEvent](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
argv[0] = ConvertDeviceStateInfoToJS(env, stateEvent);
};
HandleEvent(EVENT_DEVICE_STATE, napiArgsGetter);
CLOGD("OnDeviceState finish");
}
void NapiCastSessionListener::OnEvent(const EventId &eventId, const std::string &jsonParam)
{
CLOGD("OnEvent start");
NapiArgsGetter napiArgsGetter = [eventId, jsonParam](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_TWO;
auto status = napi_create_int32(env, static_cast<int32_t>(eventId), &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
status = napi_create_string_utf8(env, jsonParam.c_str(), NAPI_AUTO_LENGTH, &argv[1]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_string_utf8 failed");
};
HandleEvent(EVENT_ON_EVENT, napiArgsGetter);
CLOGD("OnEvent finish");
}
napi_status NapiCastSessionListener::AddCallback(napi_env env, int32_t event, napi_value callback)
{
CLOGI("Add callback %{public}d", event);
constexpr int initialRefCount = 1;
napi_ref ref = nullptr;
if (GetRefByCallback(env, callbacks_[event], callback, ref) != napi_ok) {
CLOGE("get callback reference failed");
return napi_generic_failure;
}
if (ref != nullptr) {
CLOGD("callback has been registered");
return napi_ok;
}
napi_status status = napi_create_reference(env, callback, initialRefCount, &ref);
if (status != napi_ok) {
CLOGE("napi_create_reference failed");
return status;
}
if (callback_ == nullptr) {
callback_ = std::make_shared<NapiCallback>(env);
if (callback_ == nullptr) {
CLOGE("no memory");
return napi_generic_failure;
}
}
callbacks_[event].push_back(ref);
return napi_ok;
}
napi_status NapiCastSessionListener::RemoveCallback(napi_env env, int32_t event, napi_value callback)
{
if (callback == nullptr) {
for (auto &callbackRef : callbacks_[event]) {
napi_status ret = napi_delete_reference(env, callbackRef);
if (ret != napi_ok) {
CLOGE("delete callback reference failed");
return ret;
}
}
callbacks_[event].clear();
return napi_ok;
}
napi_ref ref = nullptr;
if (GetRefByCallback(env, callbacks_[event], callback, ref) != napi_ok) {
CLOGE("get callback reference failed");
return napi_generic_failure;
}
if (ref != nullptr) {
CLOGD("callback has been remove");
return napi_ok;
}
callbacks_[event].remove(ref);
return napi_delete_reference(env, ref);
}
napi_status NapiCastSessionListener::ClearCallback(napi_env env)
{
for (auto &callback : callbacks_) {
for (auto &callbackRef : callback) {
napi_status ret = napi_delete_reference(env, callbackRef);
if (ret != napi_ok) {
CLOGE("delete callback reference failed");
return ret;
}
}
callback.clear();
}
return napi_ok;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,392 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi interface realization for cast session manager.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#include <memory>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "cast_session_manager.h"
#include "napi_cast_session_manager_listener.h"
#include "napi_cast_session.h"
#include "napi_castengine_utils.h"
#include "napi_cast_session_manager.h"
#include "napi_async_work.h"
using namespace OHOS::CastEngine::CastEngineClient;
using namespace std;
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-SessionManager");
std::shared_ptr<NapiCastSessionManagerListener> NapiCastSessionManager::listener_;
std::map<std::string, std::pair<NapiCastSessionManager::OnEventHandlerType,
NapiCastSessionManager::OffEventHandlerType>>
NapiCastSessionManager::eventHandlers_ = {
{ "serviceDie", { OnServiceDied, OffServiceDie } },
{ "deviceFound", { OnDeviceFound, OffDeviceFound } },
{ "sessionCreate", { OnSessionCreated, OffSessionCreated } }
};
napi_value NapiCastSessionManager::Init(napi_env env, napi_value exports)
{
napi_property_descriptor NapiCastSessionManagerDesc[] = {
DECLARE_NAPI_FUNCTION("on", OnEvent),
DECLARE_NAPI_FUNCTION("off", OffEvent),
DECLARE_NAPI_FUNCTION("startDiscovery", StartDiscovery),
DECLARE_NAPI_FUNCTION("stopDiscovery", StopDiscovery),
DECLARE_NAPI_FUNCTION("setDiscoverable", SetDiscoverable),
DECLARE_NAPI_FUNCTION("createCastSession", CreateCastSession),
DECLARE_NAPI_FUNCTION("release", Release)
};
napi_status status = napi_define_properties(env, exports,
sizeof(NapiCastSessionManagerDesc) / sizeof(napi_property_descriptor), NapiCastSessionManagerDesc);
if (status != napi_ok) {
CLOGE("define manager properties failed");
return GetUndefinedValue(env);
}
return exports;
}
napi_value NapiCastSessionManager::StartDiscovery(napi_env env, napi_callback_info info)
{
CLOGD("Start to discovery in");
struct ConcreteTask : public NapiAsyncTask {
int protocolType_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_object };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
int32_t protocolTypeInt;
bool isProtocolTypesValid = GetProtocolTypesFromJS(env, argv[0], protocolTypeInt);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isProtocolTypesValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->protocolType_ = protocolTypeInt;
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
int32_t ret = CastSessionManager::GetInstance().StartDiscovery(napiAsyntask->protocolType_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "StartDiscovery failed : no permission";
} else if (ret == ERR_INVALID_PARAM) {
napiAsyntask->errMessage = "StartDiscovery failed : invalid parameters";
} else {
napiAsyntask->errMessage = "StartDiscovery failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "StartDiscovery", executor, complete);
}
napi_value NapiCastSessionManager::StopDiscovery(napi_env env, napi_callback_info info)
{
CLOGD("Start to stop discovery in");
auto napiAsyntask = std::make_shared<NapiAsyncTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
napiAsyntask->GetJSInfo(env, info);
auto executor = [napiAsyntask]() {
int32_t ret = CastSessionManager::GetInstance().StopDiscovery();
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "StopDiscovery failed : no permission";
} else {
napiAsyntask->errMessage = "StopDiscovery failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "StopDiscovery", executor, complete);
}
napi_value NapiCastSessionManager::SetDiscoverable(napi_env env, napi_callback_info info)
{
CLOGD("Start to set discoverable in");
struct ConcreteTask : public NapiAsyncTask {
bool isEnable_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_boolean };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->isEnable_ = ParseBool(env, argv[0]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
int32_t ret = CastSessionManager::GetInstance().SetDiscoverable(napiAsyntask->isEnable_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "SetDiscoverable failed : no permission";
} else {
napiAsyntask->errMessage = "SetDiscoverable failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetDiscoverable", executor, complete);
}
napi_value NapiCastSessionManager::CreateCastSession(napi_env env, napi_callback_info info)
{
CLOGD("Start to create castSession in");
struct ConcreteTask : public NapiAsyncTask {
CastSessionProperty property_;
std::shared_ptr<ICastSession> session_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_object };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->property_ = GetCastSessionPropertyFromJS(env, argv[0]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
int32_t ret =
CastSessionManager::GetInstance().CreateCastSession(napiAsyntask->property_, napiAsyntask->session_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "CreateCastSession failed : no permission";
} else if (ret == ERR_INVALID_PARAM) {
napiAsyntask->errMessage = "CreateCastSession failed : invalid parameters";
} else {
napiAsyntask->errMessage = "CreateCastSession failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [napiAsyntask](napi_value &output) {
napiAsyntask->status =
NapiCastSession::CreateNapiCastSession(napiAsyntask->env, napiAsyntask->session_, output);
CHECK_STATUS_RETURN_VOID(napiAsyntask, "convert native object to javascript object failed",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
};
return NapiAsyncWork::Enqueue(env, napiAsyntask, "CreateCastSession", executor, complete);
}
napi_value NapiCastSessionManager::Release(napi_env env, napi_callback_info info)
{
CLOGD("Start to release in");
auto napiAsyntask = std::make_shared<NapiAsyncTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
napiAsyntask->GetJSInfo(env, info);
auto executor = [napiAsyntask]() {
int32_t ret = CastSessionManager::GetInstance().Release();
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "Release failed : no permission";
} else {
napiAsyntask->errMessage = "Release failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "Release", executor, complete);
}
napi_value NapiCastSessionManager::OnEvent(napi_env env, napi_callback_info info)
{
constexpr size_t expectedArgc = 2;
napi_value argv[expectedArgc] = { 0 };
napi_valuetype expectedTypes[expectedArgc] = { napi_string, napi_function };
if (!GetJSFuncParams(env, info, argv, expectedArgc, expectedTypes)) {
return GetUndefinedValue(env);
}
std::string eventName = ParseString(env, argv[0]);
auto it = eventHandlers_.find(eventName);
if (it == eventHandlers_.end()) {
CLOGE("event name invalid");
return GetUndefinedValue(env);
}
if (RegisterNativeSessionManagerListener() == napi_generic_failure) {
return GetUndefinedValue(env);
}
if (it->second.first(env, argv[1]) != napi_ok) {
CLOGE("event name invalid");
}
return GetUndefinedValue(env);
}
napi_value NapiCastSessionManager::OffEvent(napi_env env, napi_callback_info info)
{
constexpr size_t expectedArgc = 2;
napi_value argv[expectedArgc] = { 0 };
napi_valuetype expectedTypes[expectedArgc] = { napi_string, napi_function};
if (!GetJSFuncParams(env, info, argv, expectedArgc, expectedTypes)) {
return GetUndefinedValue(env);
}
std::string eventName = ParseString(env, argv[0]);
auto it = eventHandlers_.find(eventName);
if (it == eventHandlers_.end()) {
CLOGE("event name invalid");
return GetUndefinedValue(env);
}
if (it->second.second(env, argv[1]) != napi_ok) {
CLOGE("event name invalid");
}
return GetUndefinedValue(env);
}
napi_status NapiCastSessionManager::OnServiceDied(napi_env env, napi_value callback)
{
if (!listener_) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (listener_->AddCallback(env, NapiCastSessionManagerListener::EVENT_SERVICE_DIED, callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSessionManager::OnDeviceFound(napi_env env, napi_value callback)
{
if (!listener_) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (listener_->AddCallback(env, NapiCastSessionManagerListener::EVENT_DEVICE_FOUND, callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSessionManager::OnSessionCreated(napi_env env, napi_value callback)
{
if (!listener_) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (listener_->AddCallback(env, NapiCastSessionManagerListener::EVENT_SESSION_CREATE, callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSessionManager::OffServiceDie(napi_env env, napi_value callback)
{
if (!listener_) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (listener_->RemoveCallback(env, NapiCastSessionManagerListener::EVENT_SERVICE_DIED, callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSessionManager::OffDeviceFound(napi_env env, napi_value callback)
{
if (!listener_) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (listener_->RemoveCallback(env, NapiCastSessionManagerListener::EVENT_DEVICE_FOUND, callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSessionManager::OffSessionCreated(napi_env env, napi_value callback)
{
if (!listener_) {
CLOGE("cast session manager callback is null");
return napi_generic_failure;
}
if (listener_->RemoveCallback(env, NapiCastSessionManagerListener::EVENT_SESSION_CREATE, callback) != napi_ok) {
return napi_generic_failure;
}
return napi_ok;
}
napi_status NapiCastSessionManager::RegisterNativeSessionManagerListener()
{
if (listener_) {
return napi_ok;
}
listener_ = std::make_shared<NapiCastSessionManagerListener>();
if (!listener_) {
CLOGE("Failed to malloc session manager listener");
return napi_generic_failure;
}
int32_t ret = CastSessionManager::GetInstance().RegisterListener(listener_);
if (ret != CAST_ENGINE_SUCCESS) {
CLOGE("native register session manager listener failed");
return napi_generic_failure;
}
return napi_ok;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager listener realization for napi interface.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#include <uv.h>
#include <memory>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "cast_session_manager.h"
#include "napi_cast_session.h"
#include "napi_castengine_utils.h"
#include "napi_cast_session_manager_listener.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-SessionManagerListener");
NapiCastSessionManagerListener::~NapiCastSessionManagerListener()
{
CLOGD("destrcutor in");
ClearCallback(callback_->GetEnv());
}
void NapiCastSessionManagerListener::HandleEvent(int32_t event, NapiArgsGetter getter)
{
std::lock_guard<std::mutex> lockGuard(lock_);
if (callbacks_[event].empty()) {
CLOGE("not register callback event=%{public}d", event);
return;
}
for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
callback_->Call(*ref, getter);
}
}
void NapiCastSessionManagerListener::OnDeviceFound(const std::vector<CastRemoteDevice> &deviceList)
{
CLOGD("OnDeviceFound start");
NapiArgsGetter napiArgsGetter = [deviceList](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
argv[0] = ConvertDeviceListToJS(env, deviceList);
};
HandleEvent(EVENT_DEVICE_FOUND, napiArgsGetter);
CLOGD("OnDeviceFound finish");
}
void NapiCastSessionManagerListener::OnDeviceOffline(const std::string &deviceId)
{
CLOGD("OnDeviceOffline start");
}
void NapiCastSessionManagerListener::OnSessionCreated(const std::shared_ptr<ICastSession> &castSession)
{
CLOGD("OnSessionCreated start");
NapiArgsGetter napiArgsGetter = [castSession](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
argv[0] = ConvertCastSessionToJS(env, castSession);
};
HandleEvent(EVENT_SESSION_CREATE, napiArgsGetter);
CLOGD("OnSessionCreated finish");
}
void NapiCastSessionManagerListener::OnServiceDied()
{
CLOGD("OnServiceDied start");
NapiArgsGetter napiArgsGetter = [](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ZERO;
argv[0] = { nullptr };
};
HandleEvent(EVENT_SERVICE_DIED, napiArgsGetter);
CLOGD("OnServiceDied finish");
}
napi_status NapiCastSessionManagerListener::AddCallback(napi_env env, int32_t event, napi_value callback)
{
CLOGI("Add callback %{public}d", event);
constexpr int initialRefCount = 1;
napi_ref ref = nullptr;
if (GetRefByCallback(env, callbacks_[event], callback, ref) != napi_ok) {
CLOGE("get callback reference failed");
return napi_generic_failure;
}
if (ref != nullptr) {
CLOGD("callback has been registered");
return napi_ok;
}
napi_status status = napi_create_reference(env, callback, initialRefCount, &ref);
if (status != napi_ok) {
CLOGE("napi_create_reference failed");
return status;
}
if (callback_ == nullptr) {
callback_ = std::make_shared<NapiCallback>(env);
if (callback_ == nullptr) {
CLOGE("no memory");
return napi_generic_failure;
}
}
callbacks_[event].push_back(ref);
return napi_ok;
}
napi_status NapiCastSessionManagerListener::RemoveCallback(napi_env env, int32_t event, napi_value callback)
{
if (callback == nullptr) {
for (auto &callbackRef : callbacks_[event]) {
napi_status ret = napi_delete_reference(env, callbackRef);
if (ret != napi_ok) {
CLOGE("delete callback reference failed");
return ret;
}
}
callbacks_[event].clear();
return napi_ok;
}
napi_ref ref = nullptr;
if (GetRefByCallback(env, callbacks_[event], callback, ref) != napi_ok) {
CLOGE("get callback reference failed");
return napi_generic_failure;
}
if (ref != nullptr) {
CLOGD("callback has been remove");
return napi_ok;
}
callbacks_[event].remove(ref);
return napi_delete_reference(env, ref);
}
napi_status NapiCastSessionManagerListener::ClearCallback(napi_env env)
{
for (auto &callback : callbacks_) {
for (auto &callbackRef : callback) {
napi_status ret = napi_delete_reference(env, callbackRef);
if (ret != napi_ok) {
CLOGE("delete callback reference failed");
return ret;
}
}
callback.clear();
}
return napi_ok;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,322 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi nums realization for interfaces.
* Author: zhangjingnan
* Create: 2023-4-11
*/
#include <string>
#include "napi/native_common.h"
#include "cast_engine_common.h"
#include "napi_castengine_enum.h"
#include "cast_engine_log.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-Enum");
static napi_status SetNamedProperty(napi_env env, napi_value &obj, const std::string &name, int32_t value)
{
napi_value property = nullptr;
napi_status status = napi_create_int32(env, value, &property);
if (status != napi_ok) {
CLOGE("napi_create_int32 failed");
return status;
}
status = napi_set_named_property(env, obj, name.c_str(), property);
if (status != napi_ok) {
CLOGD("napi_set_named_property failed");
return status;
}
return status;
}
static napi_value ExportPlayerStates(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "PLAYER_STATE_ERROR", static_cast<int32_t>(PlayerStates::PLAYER_STATE_ERROR));
(void)SetNamedProperty(env, result, "PLAYER_IDLE", static_cast<int32_t>(PlayerStates::PLAYER_IDLE));
(void)SetNamedProperty(env, result, "PLAYER_INITIALIZED", static_cast<int32_t>(PlayerStates::PLAYER_INITIALIZED));
(void)SetNamedProperty(env, result, "PLAYER_PREPARING", static_cast<int32_t>(PlayerStates::PLAYER_PREPARING));
(void)SetNamedProperty(env, result, "PLAYER_PREPARED", static_cast<int32_t>(PlayerStates::PLAYER_PREPARED));
(void)SetNamedProperty(env, result, "PLAYER_STARTED", static_cast<int32_t>(PlayerStates::PLAYER_STARTED));
(void)SetNamedProperty(env, result, "PLAYER_PAUSED", static_cast<int32_t>(PlayerStates::PLAYER_PAUSED));
(void)SetNamedProperty(env, result, "PLAYER_STOPPED", static_cast<int32_t>(PlayerStates::PLAYER_STOPPED));
(void)SetNamedProperty(env, result, "PLAYER_PLAYBACK_COMPLETE",
static_cast<int32_t>(PlayerStates::PLAYER_PLAYBACK_COMPLETE));
(void)SetNamedProperty(env, result, "PLAYER_RELEASED", static_cast<int32_t>(PlayerStates::PLAYER_RELEASED));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportPlaybackSpeed(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "SPEED_FORWARD_0_75_X",
static_cast<int32_t>(PlaybackSpeed::SPEED_FORWARD_0_75_X));
(void)SetNamedProperty(env, result, "SPEED_FORWARD_1_00_X",
static_cast<int32_t>(PlaybackSpeed::SPEED_FORWARD_1_00_X));
(void)SetNamedProperty(env, result, "SPEED_FORWARD_1_25_X",
static_cast<int32_t>(PlaybackSpeed::SPEED_FORWARD_1_25_X));
(void)SetNamedProperty(env, result, "SPEED_FORWARD_1_75_X",
static_cast<int32_t>(PlaybackSpeed::SPEED_FORWARD_1_75_X));
(void)SetNamedProperty(env, result, "SPEED_FORWARD_2_00_X",
static_cast<int32_t>(PlaybackSpeed::SPEED_FORWARD_2_00_X));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportLoopMode(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "LOOP_MODE_SEQUENCE", static_cast<int32_t>(LoopMode::LOOP_MODE_SEQUENCE));
(void)SetNamedProperty(env, result, "LOOP_MODE_SINGLE", static_cast<int32_t>(LoopMode::LOOP_MODE_SINGLE));
(void)SetNamedProperty(env, result, "LOOP_MODE_LIST", static_cast<int32_t>(LoopMode::LOOP_MODE_LIST));
(void)SetNamedProperty(env, result, "LOOP_MODE_SHUFFLE", static_cast<int32_t>(LoopMode::LOOP_MODE_SHUFFLE));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportDeviceType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "DEVICE_OTHERS", static_cast<int32_t>(DeviceType::DEVICE_OTHERS));
(void)SetNamedProperty(env, result, "DEVICE_SCREEN_PLAYER", static_cast<int32_t>(DeviceType::DEVICE_SCREEN_PLAYER));
(void)SetNamedProperty(env, result, "DEVICE_HW_TV", static_cast<int32_t>(DeviceType::DEVICE_HW_TV));
(void)SetNamedProperty(env, result, "DEVICE_SOUND_BOX", static_cast<int32_t>(DeviceType::DEVICE_SOUND_BOX));
(void)SetNamedProperty(env, result, "DEVICE_HICAR", static_cast<int32_t>(DeviceType::DEVICE_HICAR));
(void)SetNamedProperty(env, result, "DEVICE_MATEBOOK", static_cast<int32_t>(DeviceType::DEVICE_MATEBOOK));
(void)SetNamedProperty(env, result, "DEVICE_PAD", static_cast<int32_t>(DeviceType::DEVICE_PAD));
(void)SetNamedProperty(env, result, "DEVICE_CAST_PLUS", static_cast<int32_t>(DeviceType::DEVICE_CAST_PLUS));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportSubDeviceType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "SUB_DEVICE_DEFAULT", static_cast<int32_t>(SubDeviceType::SUB_DEVICE_DEFAULT));
(void)SetNamedProperty(env, result, "SUB_DEVICE_MATEBOOK_PAD",
static_cast<int32_t>(SubDeviceType::SUB_DEVICE_MATEBOOK_PAD));
(void)SetNamedProperty(env, result, "SUB_DEVICE_CAST_PLUS_WHITEBOARD",
static_cast<int32_t>(SubDeviceType::SUB_DEVICE_CAST_PLUS_WHITEBOARD));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportTriggerType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "UNSPEC_TAG", static_cast<int32_t>(TriggerType::UNSPEC_TAG));
(void)SetNamedProperty(env, result, "PASSIVE_MATCH_TAG", static_cast<int32_t>(TriggerType::PASSIVE_MATCH_TAG));
(void)SetNamedProperty(env, result, "ACTIVE_MATCH_TAG", static_cast<int32_t>(TriggerType::ACTIVE_MATCH_TAG));
(void)SetNamedProperty(env, result, "PASSIVE_BIND_TAG", static_cast<int32_t>(TriggerType::PASSIVE_BIND_TAG));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportDeviceState(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "CONNECTING", static_cast<int32_t>(DeviceState::CONNECTING));
(void)SetNamedProperty(env, result, "CONNECTED", static_cast<int32_t>(DeviceState::CONNECTED));
(void)SetNamedProperty(env, result, "PAUSED", static_cast<int32_t>(DeviceState::PAUSED));
(void)SetNamedProperty(env, result, "PLAYING", static_cast<int32_t>(DeviceState::PLAYING));
(void)SetNamedProperty(env, result, "DISCONNECTING", static_cast<int32_t>(DeviceState::DISCONNECTING));
(void)SetNamedProperty(env, result, "DISCONNECTED", static_cast<int32_t>(DeviceState::DISCONNECTED));
(void)SetNamedProperty(env, result, "STREAM", static_cast<int32_t>(DeviceState::STREAM));
(void)SetNamedProperty(env, result, "DEVICE_STATE_MAX", static_cast<int32_t>(DeviceState::DEVICE_STATE_MAX));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportServiceStatus(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "DISCONNECTED", static_cast<int32_t>(ServiceStatus::DISCONNECTED));
(void)SetNamedProperty(env, result, "DISCONNECTING", static_cast<int32_t>(ServiceStatus::DISCONNECTING));
(void)SetNamedProperty(env, result, "CONNECTING", static_cast<int32_t>(ServiceStatus::CONNECTING));
(void)SetNamedProperty(env, result, "CONNECTED", static_cast<int32_t>(ServiceStatus::CONNECTED));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportDeviceStatusState(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "DEVICE_AVAILABLE", static_cast<int32_t>(DeviceStatusState::DEVICE_AVAILABLE));
(void)SetNamedProperty(env, result, "DEVICE_CONNECTED", static_cast<int32_t>(DeviceStatusState::DEVICE_CONNECTED));
(void)SetNamedProperty(env, result, "DEVICE_DISCONNECTED",
static_cast<int32_t>(DeviceStatusState::DEVICE_DISCONNECTED));
(void)SetNamedProperty(env, result, "DEVICE_CONNECT_REQ",
static_cast<int32_t>(DeviceStatusState::DEVICE_CONNECT_REQ));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportPropertyType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "VIDEO_SIZE", static_cast<int32_t>(PropertyType::VIDEO_SIZE));
(void)SetNamedProperty(env, result, "VIDEO_FPS", static_cast<int32_t>(PropertyType::VIDEO_FPS));
(void)SetNamedProperty(env, result, "WINDOW_SIZE", static_cast<int32_t>(PropertyType::WINDOW_SIZE));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportChannelType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "SOFT_BUS", static_cast<int32_t>(ChannelType::SOFT_BUS));
(void)SetNamedProperty(env, result, "LEGACY_CHANNEL", static_cast<int32_t>(ChannelType::LEGACY_CHANNEL));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportProtocolType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "CAST_PLUS_MIRROR", static_cast<int32_t>(ProtocolType::CAST_PLUS_MIRROR));
(void)SetNamedProperty(env, result, "CAST_PLUS_STREAM", static_cast<int32_t>(ProtocolType::CAST_PLUS_STREAM));
(void)SetNamedProperty(env, result, "MIRACAST", static_cast<int32_t>(ProtocolType::MIRACAST));
(void)SetNamedProperty(env, result, "DLNA", static_cast<int32_t>(ProtocolType::DLNA));
(void)SetNamedProperty(env, result, "COOPERATION", static_cast<int32_t>(ProtocolType::COOPERATION));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportEndType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "CAST_SINK", static_cast<int32_t>(EndType::CAST_SINK));
(void)SetNamedProperty(env, result, "CAST_SOURCE", static_cast<int32_t>(EndType::CAST_SOURCE));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportEventId(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "EVENT_BEGIN", static_cast<int32_t>(EventId::EVENT_BEGIN));
(void)SetNamedProperty(env, result, "EVENT_END", static_cast<int32_t>(EventId::EVENT_END));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportColorStandard(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "BT709", static_cast<int32_t>(ColorStandard::BT709));
(void)SetNamedProperty(env, result, "BT601_PAL", static_cast<int32_t>(ColorStandard::BT601_PAL));
(void)SetNamedProperty(env, result, "BT601_NTSC", static_cast<int32_t>(ColorStandard::BT601_NTSC));
(void)SetNamedProperty(env, result, "BT2020", static_cast<int32_t>(ColorStandard::BT2020));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportVideoCodecType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "H264", static_cast<int32_t>(VideoCodecType::H264));
(void)SetNamedProperty(env, result, "H265", static_cast<int32_t>(VideoCodecType::H265));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
static napi_value ExportCastModeType(napi_env env)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
(void)SetNamedProperty(env, result, "MIRROR_CAST", static_cast<int32_t>(CastMode::MIRROR_CAST));
(void)SetNamedProperty(env, result, "APP_CAST", static_cast<int32_t>(CastMode::APP_CAST));
NAPI_CALL(env, napi_object_freeze(env, result));
return result;
}
napi_status InitEnums(napi_env env, napi_value exports)
{
const napi_property_descriptor properties[] = {
DECLARE_NAPI_PROPERTY("PlayerStates", ExportPlayerStates(env)),
DECLARE_NAPI_PROPERTY("PlaybackSpeed", ExportPlaybackSpeed(env)),
DECLARE_NAPI_PROPERTY("LoopMode", ExportLoopMode(env)),
DECLARE_NAPI_PROPERTY("DeviceType", ExportDeviceType(env)),
DECLARE_NAPI_PROPERTY("SubDeviceType", ExportSubDeviceType(env)),
DECLARE_NAPI_PROPERTY("TriggerType", ExportTriggerType(env)),
DECLARE_NAPI_PROPERTY("DeviceState", ExportDeviceState(env)),
DECLARE_NAPI_PROPERTY("ServiceStatus", ExportServiceStatus(env)),
DECLARE_NAPI_PROPERTY("DeviceStatusState", ExportDeviceStatusState(env)),
DECLARE_NAPI_PROPERTY("PropertyType", ExportPropertyType(env)),
DECLARE_NAPI_PROPERTY("ChannelType", ExportChannelType(env)),
DECLARE_NAPI_PROPERTY("ProtocolType", ExportProtocolType(env)),
DECLARE_NAPI_PROPERTY("EndType", ExportEndType(env)),
DECLARE_NAPI_PROPERTY("EventId", ExportEventId(env)),
DECLARE_NAPI_PROPERTY("ColorStandard", ExportColorStandard(env)),
DECLARE_NAPI_PROPERTY("VideoCodecType", ExportVideoCodecType(env)),
DECLARE_NAPI_PROPERTY("CastMode", ExportCastModeType(env))
};
size_t count = sizeof(properties) / sizeof(napi_property_descriptor);
return napi_define_properties(env, exports, count, properties);
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,767 @@
/*
* Copyright (c) 2023 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
*
* Description: supply untils realization for napi interface.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#include <uv.h>
#include <memory>
#include "securec.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "napi_cast_session.h"
#include "napi_castengine_utils.h"
using namespace std;
using namespace OHOS::CastEngine;
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-Utils");
napi_value GetUndefinedValue(napi_env env)
{
napi_value result {};
napi_get_undefined(env, &result);
return result;
}
string ParseString(napi_env env, napi_value args)
{
string result {};
if (args == nullptr) {
CLOGE("args is nullptr");
return result;
}
napi_valuetype valueType;
napi_status status = napi_typeof(env, args, &valueType);
CLOGD("param=%{public}d.", valueType);
if (status != napi_ok || valueType != napi_string) {
CLOGE("Wrong argument type. String expected.");
result = "";
return result;
}
size_t size = 0;
size_t bufSize = 0;
if (napi_get_value_string_utf8(env, args, nullptr, bufSize, &size) != napi_ok) {
CLOGE("can not get string size");
result = "";
return result;
}
result.reserve(size + 1);
result.resize(size);
if (napi_get_value_string_utf8(env, args, result.data(), (size + 1), &size) != napi_ok) {
CLOGE("can not get string value");
result = "";
return result;
}
return result;
}
int32_t ParseInt32(napi_env env, napi_value args)
{
int32_t param = 0;
if (args == nullptr) {
CLOGE("args is nullptr");
return param;
}
napi_valuetype valueType;
napi_status status = napi_typeof(env, args, &valueType);
if (status != napi_ok) {
CLOGE("napi_typeof failed.");
return param;
}
CLOGD("param=%{public}d.", valueType);
if (valueType != napi_number) {
CLOGE("Wrong argument type. Int32 expected.");
return param;
}
status = napi_get_value_int32(env, args, &param);
if (status != napi_ok) {
CLOGE("napi_get_value_int32 failed.");
return param;
}
return param;
}
bool ParseBool(napi_env env, napi_value args)
{
bool param = false;
if (args == nullptr) {
CLOGE("args is nullptr");
return param;
}
napi_valuetype valueType;
napi_status status = napi_typeof(env, args, &valueType);
if (status != napi_ok) {
CLOGE("napi_typeof failed.");
return param;
}
CLOGD("param=%{public}d.", valueType);
if (valueType != napi_boolean) {
CLOGE("Wrong argument type. bool expected.");
return param;
}
status = napi_get_value_bool(env, args, &param);
if (status != napi_ok) {
CLOGE("napi_get_value_bool failed.");
return param;
}
return param;
}
napi_value ConvertDeviceListToJS(napi_env env, const vector<CastRemoteDevice> &devices)
{
int count = 0;
napi_value devicesList = nullptr;
NAPI_CALL(env, napi_create_array(env, &devicesList));
for (CastRemoteDevice vec : devices) {
napi_value deviceResult = ConvertCastRemoteDeviceToJS(env, vec);
NAPI_CALL(env, napi_set_element(env, devicesList, count, deviceResult));
count++;
}
if (devicesList == nullptr) {
CLOGE("devicesList is null");
}
return devicesList;
}
napi_value ConvertCastSessionToJS(napi_env env, const shared_ptr<ICastSession> &castSession)
{
napi_value napiCastSession;
NapiCastSession::CreateNapiCastSession(env, castSession, napiCastSession);
if (napiCastSession == nullptr) {
CLOGE("napiCastSession is null");
}
return napiCastSession;
}
napi_value ConvertDeviceStateInfoToJS(napi_env env, const DeviceStateInfo &stateEvent)
{
napi_value stateEventCallback = nullptr;
napi_value deviceState = nullptr;
napi_value deviceId = nullptr;
NAPI_CALL(env, napi_create_object(env, &stateEventCallback));
NAPI_CALL(env, napi_create_string_utf8(env, stateEvent.deviceId.c_str(), NAPI_AUTO_LENGTH, &deviceId));
NAPI_CALL(env, napi_create_int32(env, static_cast<int32_t>(stateEvent.deviceState), &deviceState));
NAPI_CALL(env, napi_set_named_property(env, stateEventCallback, "deviceState", deviceState));
NAPI_CALL(env, napi_set_named_property(env, stateEventCallback, "deviceId", deviceId));
return stateEventCallback;
}
CastRemoteDevice GetCastRemoteDeviceFromJS(napi_env env, napi_value &object)
{
CastRemoteDevice castRemoteDevice = CastRemoteDevice();
castRemoteDevice.deviceId = JsObjectToString(env, object, "deviceId");
castRemoteDevice.deviceName = JsObjectToString(env, object, "deviceName");
int32_t deviceTypeCallback = JsObjectToInt32(env, object, "deviceType");
DeviceType deviceType = static_cast<DeviceType>(deviceTypeCallback);
int32_t subDeviceTypeCallback = JsObjectToInt32(env, object, "subDeviceType");
SubDeviceType subDeviceType = static_cast<SubDeviceType>(subDeviceTypeCallback);
castRemoteDevice.ipAddress = JsObjectToString(env, object, "ipAddress");
int32_t channelTypeInt = JsObjectToInt32(env, object, "channelType");
ChannelType channelType = static_cast<ChannelType>(channelTypeInt);
castRemoteDevice.deviceType = deviceType;
castRemoteDevice.subDeviceType = subDeviceType;
castRemoteDevice.channelType = channelType;
return castRemoteDevice;
}
WindowProperty GetWindowPropertyFromJS(napi_env env, napi_value &object)
{
WindowProperty windowProperty = WindowProperty();
napi_value windowPropertyCallback = nullptr;
bool hasProperty = false;
napi_status status = napi_has_named_property(env, object, "windowProperty", &hasProperty);
if (status == napi_ok && hasProperty) {
status = napi_get_named_property(env, object, "windowProperty", &windowPropertyCallback);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed.");
return windowProperty;
}
uint32_t width = JsObjectToUint32(env, windowPropertyCallback, "width");
uint32_t height = JsObjectToUint32(env, windowPropertyCallback, "height");
uint32_t startX = JsObjectToUint32(env, windowPropertyCallback, "startX");
uint32_t startY = JsObjectToUint32(env, windowPropertyCallback, "startY");
windowProperty.startX = startX;
windowProperty.startY = startY;
windowProperty.width = width;
windowProperty.height = height;
}
return windowProperty;
}
bool GetProtocolTypesFromJS(napi_env env, napi_value &object, int &protocolTypes)
{
bool isArray = false;
NAPI_CALL_BASE(env, napi_is_array(env, object, &isArray), false);
if (!isArray) {
CLOGE("protocolType is not array.");
return false;
}
uint32_t arrLen = 0;
NAPI_CALL_BASE(env, napi_get_array_length(env, object, &arrLen), false);
if (arrLen == 0) {
CLOGE("mediaInfoList len is invalid");
return false;
}
uint32_t ret = 0;
for (uint32_t i = 0; i < arrLen; i++) {
napi_value item = nullptr;
NAPI_CALL_BASE(env, napi_get_element(env, object, i, &item), false);
ret = ret | static_cast<uint32_t>(ParseInt32(env, item));
}
protocolTypes = static_cast<int>(ret);
CLOGI("GetProtocolTypesFromJS finished, protocolTypes: %{public}d", protocolTypes);
return true;
}
bool GetMediaInfoHolderFromJS(napi_env env, napi_value &object, MediaInfoHolder &mediaInfoHolder)
{
napi_value mediaInfoList = nullptr;
bool hasProperty = false;
mediaInfoHolder.currentIndex = JsObjectToUint32(env, object, "currentIndex");
mediaInfoHolder.progressRefreshInterval = JsObjectToUint32(env, object, "progressRefreshInterval");
NAPI_CALL_BASE(env, napi_has_named_property(env, object, "mediaInfoList", &hasProperty), false);
if (!hasProperty) {
CLOGE("mediaInfoList is not exit");
return false;
}
NAPI_CALL_BASE(env, napi_get_named_property(env, object, "mediaInfoList", &mediaInfoList), false);
bool isArray = false;
NAPI_CALL_BASE(env, napi_is_array(env, mediaInfoList, &isArray), false);
if (!isArray) {
CLOGE("mediaInfoList is not array.");
return false;
}
uint32_t arrLen = 0;
NAPI_CALL_BASE(env, napi_get_array_length(env, mediaInfoList, &arrLen), false);
if (arrLen == 0) {
CLOGE("mediaInfoList len is invalid");
return false;
}
for (uint32_t i = 0; i < arrLen; i++) {
napi_value item = nullptr;
NAPI_CALL_BASE(env, napi_get_element(env, mediaInfoList, i, &item), false);
MediaInfo mediaInfo = MediaInfo{};
GetMediaInfoFromJS(env, item, mediaInfo);
mediaInfoHolder.mediaInfoList.push_back(mediaInfo);
}
return true;
}
bool GetMediaInfoFromJS(napi_env env, napi_value &object, MediaInfo &mediaInfo)
{
mediaInfo.mediaId = JsObjectToString(env, object, "mediaId");
mediaInfo.mediaName = JsObjectToString(env, object, "mediaName");
mediaInfo.mediaUrl = JsObjectToString(env, object, "mediaUrl");
mediaInfo.mediaType = JsObjectToString(env, object, "mediaType");
mediaInfo.albumCoverUrl = JsObjectToString(env, object, "albumCoverUrl");
mediaInfo.albumTitle = JsObjectToString(env, object, "albumTitle");
mediaInfo.mediaArtist = JsObjectToString(env, object, "mediaArtist");
mediaInfo.lrcUrl = JsObjectToString(env, object, "lrcUrl");
mediaInfo.lrcContent = JsObjectToString(env, object, "lrcContent");
mediaInfo.appIconUrl = JsObjectToString(env, object, "appIconUrl");
mediaInfo.appName = JsObjectToString(env, object, "appName");
mediaInfo.mediaSize = JsObjectToUint32(env, object, "mediaSize");
mediaInfo.startPosition = JsObjectToUint32(env, object, "startPosition");
mediaInfo.duration = JsObjectToUint32(env, object, "duration");
mediaInfo.closingCreditsPosition = JsObjectToUint32(env, object, "closingCreditsPosition");
return true;
}
CastSessionProperty GetCastSessionPropertyFromJS(napi_env env, napi_value &object)
{
CastSessionProperty castSessionProperty = CastSessionProperty();
int32_t protocolTypeInt = JsObjectToInt32(env, object, "protocolType");
ProtocolType protocolType = static_cast<ProtocolType>(protocolTypeInt);
int32_t endTypeInt = JsObjectToInt32(env, object, "endType");
EndType endType = static_cast<EndType>(endTypeInt);
napi_value audioPropertyCallback = nullptr;
bool hasProperty = false;
napi_status status = napi_has_named_property(env, object, "audioProperty", &hasProperty);
if (status == napi_ok && hasProperty) {
status = napi_get_named_property(env, object, "audioProperty", &audioPropertyCallback);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed.");
return castSessionProperty;
}
AudioProperty audioProperty = GetAudioPropertyFromJS(env, audioPropertyCallback);
castSessionProperty.audioProperty = audioProperty;
}
napi_value videoPropertyCallback = nullptr;
hasProperty = false;
status = napi_has_named_property(env, object, "videoProperty", &hasProperty);
if (status == napi_ok && hasProperty) {
status = napi_get_named_property(env, object, "videoProperty", &videoPropertyCallback);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed.");
return castSessionProperty;
}
VideoProperty videoProperty = GetVideoPropertyFromJS(env, videoPropertyCallback);
castSessionProperty.videoProperty = videoProperty;
}
WindowProperty windowProperty = GetWindowPropertyFromJS(env, object);
castSessionProperty.protocolType = protocolType;
castSessionProperty.endType = endType;
castSessionProperty.windowProperty = windowProperty;
return castSessionProperty;
}
AudioProperty GetAudioPropertyFromJS(napi_env env, napi_value &object)
{
AudioProperty audioProperty = AudioProperty();
uint32_t sampleRate = JsObjectToUint32(env, object, "sampleRate");
uint32_t channelConfig = JsObjectToUint32(env, object, "channelConfig");
uint32_t bitrate = JsObjectToUint32(env, object, "bitrate");
uint32_t codec = JsObjectToUint32(env, object, "codec");
audioProperty.sampleRate = sampleRate;
audioProperty.channelConfig = channelConfig;
audioProperty.bitrate = bitrate;
audioProperty.codec = codec;
return audioProperty;
}
VideoProperty GetVideoPropertyFromJS(napi_env env, napi_value &object)
{
VideoProperty videoProperty = VideoProperty();
uint32_t videoWidth = JsObjectToUint32(env, object, "videoWidth");
uint32_t videoHeight = JsObjectToUint32(env, object, "videoHeight");
uint32_t fps = JsObjectToUint32(env, object, "fps");
int32_t codecTypeInt = JsObjectToInt32(env, object, "codecType");
VideoCodecType codecType = static_cast<VideoCodecType>(codecTypeInt);
uint32_t gop = JsObjectToUint32(env, object, "gop");
uint32_t bitrate = JsObjectToUint32(env, object, "bitrate");
uint32_t minBitrate = JsObjectToUint32(env, object, "minBitrate");
uint32_t maxBitrate = JsObjectToUint32(env, object, "maxBitrate");
uint32_t dpi = JsObjectToUint32(env, object, "dpi");
int32_t colorStandardInt = JsObjectToInt32(env, object, "colorStandard");
ColorStandard colorStandard = static_cast<ColorStandard>(colorStandardInt);
uint32_t screenWidth = JsObjectToUint32(env, object, "screenWidth");
uint32_t screenHeight = JsObjectToUint32(env, object, "screenHeight");
uint32_t profile = JsObjectToUint32(env, object, "profile");
uint32_t level = JsObjectToUint32(env, object, "level");
videoProperty.videoWidth = videoWidth;
videoProperty.videoHeight = videoHeight;
videoProperty.fps = fps;
videoProperty.codecType = codecType;
videoProperty.gop = gop;
videoProperty.bitrate = bitrate;
videoProperty.minBitrate = minBitrate;
videoProperty.maxBitrate = maxBitrate;
videoProperty.dpi = dpi;
videoProperty.colorStandard = colorStandard;
videoProperty.screenWidth = screenWidth;
videoProperty.screenHeight = screenHeight;
videoProperty.profile = profile;
videoProperty.level = level;
return videoProperty;
}
bool Equals(napi_env env, napi_value value, napi_ref copy)
{
if (copy == nullptr) {
return (value == nullptr);
}
napi_value copyValue = nullptr;
if (napi_get_reference_value(env, copy, &copyValue) != napi_ok) {
CLOGE("get ref value failed");
return false;
}
bool isEquals = false;
if (napi_strict_equals(env, value, copyValue, &isEquals) != napi_ok) {
CLOGE("get equals result failed");
return false;
}
return isEquals;
}
napi_status GetRefByCallback(napi_env env, std::list<napi_ref> callbackList, napi_value callback, napi_ref &callbackRef)
{
for (auto ref = callbackList.begin(); ref != callbackList.end(); ++ref) {
if (Equals(env, callback, *ref)) {
CLOGD("Callback has been matched");
callbackRef = *ref;
break;
}
}
return napi_ok;
}
napi_value ConvertCastRemoteDeviceToJS(napi_env env, const CastRemoteDevice &castRemoteDevice)
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
napi_value deviceId = nullptr;
NAPI_CALL(env, napi_create_string_utf8(env, castRemoteDevice.deviceId.c_str(), NAPI_AUTO_LENGTH, &deviceId));
NAPI_CALL(env, napi_set_named_property(env, result, "deviceId", deviceId));
napi_value deviceName = nullptr;
CLOGD("ConvertCastRemoteDeviceToJS deviceName %{public}s", castRemoteDevice.deviceName.c_str());
NAPI_CALL(env, napi_create_string_utf8(env, castRemoteDevice.deviceName.c_str(), NAPI_AUTO_LENGTH, &deviceName));
NAPI_CALL(env, napi_set_named_property(env, result, "deviceName", deviceName));
napi_value deviceType = nullptr;
NAPI_CALL(env, napi_create_int32(env, static_cast<int32_t>(castRemoteDevice.deviceType), &deviceType));
NAPI_CALL(env, napi_set_named_property(env, result, "deviceType", deviceType));
napi_value subDeviceType = nullptr;
NAPI_CALL(env, napi_create_int32(env, static_cast<int32_t>(castRemoteDevice.subDeviceType), &subDeviceType));
NAPI_CALL(env, napi_set_named_property(env, result, "subDeviceType", subDeviceType));
napi_value ipAddress = nullptr;
NAPI_CALL(env, napi_create_string_utf8(env, castRemoteDevice.ipAddress.c_str(), NAPI_AUTO_LENGTH, &ipAddress));
NAPI_CALL(env, napi_set_named_property(env, result, "ipAddress", ipAddress));
napi_value channelType = nullptr;
NAPI_CALL(env, napi_create_int32(env, static_cast<int32_t>(castRemoteDevice.channelType), &channelType));
NAPI_CALL(env, napi_set_named_property(env, result, "channelType", channelType));
return result;
}
string JsObjectToString(napi_env env, napi_value &object, const char *fieldStr)
{
string fieldRef {};
if (object == nullptr) {
CLOGE("args is nullptr");
return fieldRef;
}
napi_value field = nullptr;
bool hasProperty = false;
napi_status status = napi_has_named_property(env, object, fieldStr, &hasProperty);
if (status == napi_ok && hasProperty) {
status = napi_get_named_property(env, object, fieldStr, &field);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed.");
return fieldRef;
}
fieldRef = ParseString(env, field);
return fieldRef;
} else {
CLOGE("Js obj to str no property: %{public}s", fieldStr);
}
return fieldRef;
}
int32_t JsObjectToInt32(napi_env env, napi_value &object, const char *fieldStr)
{
int32_t fieldRef = 0;
if (object == nullptr) {
CLOGE("args is nullptr");
return fieldRef;
}
bool hasProperty = false;
napi_status status = napi_has_named_property(env, object, fieldStr, &hasProperty);
if (status == napi_ok && hasProperty) {
napi_value field;
napi_valuetype valueType;
status = napi_get_named_property(env, object, fieldStr, &field);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed.");
return fieldRef;
}
status = napi_typeof(env, field, &valueType);
if (status != napi_ok || valueType != napi_number) {
CLOGE("Wrong argument type. Number expected.");
return fieldRef;
}
status = napi_get_value_int32(env, field, &fieldRef);
if (status != napi_ok) {
CLOGE("napi_get_value_int32 failed");
return fieldRef;
}
return fieldRef;
} else {
CLOGE("Js to int32_t no property: %{public}s", fieldStr);
}
return fieldRef;
}
bool JsObjectToBool(napi_env env, napi_value &object, const char *fieldStr)
{
bool fieldRef = false;
if (object == nullptr) {
CLOGE("args is nullptr");
return fieldRef;
}
bool hasProperty = false;
napi_status status = napi_has_named_property(env, object, fieldStr, &hasProperty);
if (status == napi_ok && hasProperty) {
napi_value field;
napi_valuetype valueType;
status = napi_get_named_property(env, object, fieldStr, &field);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed.");
return fieldRef;
}
status = napi_typeof(env, field, &valueType);
if (status != napi_ok || valueType != napi_boolean) {
CLOGE("Wrong argument type. Bool expected.");
return fieldRef;
}
status = napi_get_value_bool(env, field, &fieldRef);
if (status != napi_ok) {
CLOGE("napi_get_value_bool failed");
return fieldRef;
}
return fieldRef;
} else {
CLOGE("Js to bool no property: %{public}s", fieldStr);
}
return fieldRef;
}
uint32_t JsObjectToUint32(napi_env env, napi_value &object, const char *fieldStr)
{
uint32_t fieldRef = 0;
if (object == nullptr) {
CLOGE("args is nullptr");
return fieldRef;
}
bool hasProperty = false;
napi_status status = napi_has_named_property(env, object, fieldStr, &hasProperty);
if (status == napi_ok && hasProperty) {
napi_value field;
napi_valuetype valueType;
status = napi_get_named_property(env, object, fieldStr, &field);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed.");
return fieldRef;
}
status = napi_typeof(env, field, &valueType);
if (status != napi_ok || valueType != napi_number) {
CLOGE("Wrong argument type. Number expected.");
return fieldRef;
}
status = napi_get_value_uint32(env, field, &fieldRef);
if (status != napi_ok) {
CLOGE("napi_get_value_uint32 failed");
return fieldRef;
}
return fieldRef;
} else {
CLOGE("Js to uint32_t no property: %{public}s", fieldStr);
}
return fieldRef;
}
double JsObjectToDouble(napi_env env, napi_value &object, const char *fieldStr)
{
double fieldRef = 0;
if (object == nullptr) {
CLOGE("args is nullptr");
return fieldRef;
}
bool hasProperty = false;
napi_status status = napi_has_named_property(env, object, fieldStr, &hasProperty);
if (status == napi_ok && hasProperty) {
napi_value field;
napi_valuetype valueType;
status = napi_get_named_property(env, object, fieldStr, &field);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed.");
return fieldRef;
}
status = napi_typeof(env, field, &valueType);
if (status != napi_ok || valueType != napi_number) {
CLOGE("Wrong argument type. Number expected.");
return fieldRef;
}
status = napi_get_value_double(env, field, &fieldRef);
if (status != napi_ok) {
CLOGE("napi_get_value_double failed");
return fieldRef;
}
return fieldRef;
} else {
CLOGE("Js to double no property: %{public}s", fieldStr);
}
return fieldRef;
}
int64_t JsObjectToInt64(napi_env env, napi_value &object, const char *fieldStr)
{
int64_t fieldRef = 0;
if (object == nullptr) {
CLOGE("args is nullptr");
return fieldRef;
}
bool hasProperty = false;
napi_status status = napi_has_named_property(env, object, fieldStr, &hasProperty);
if (status == napi_ok && hasProperty) {
napi_value field;
napi_valuetype valueType;
status = napi_get_named_property(env, object, fieldStr, &field);
if (status != napi_ok) {
CLOGE("napi_get_named_property failed");
return fieldRef;
}
status = napi_typeof(env, field, &valueType);
if (status != napi_ok || valueType != napi_number) {
CLOGE("Wrong argument type. Number expected.");
return fieldRef;
}
status = napi_get_value_int64(env, field, &fieldRef);
if (status != napi_ok) {
CLOGE("napi_get_value_int64 failed");
return fieldRef;
}
return fieldRef;
} else {
CLOGE("Js to int64_t no property: %{public}s", fieldStr);
}
return fieldRef;
}
napi_value ConvertMediaInfoToJS(napi_env env, const MediaInfo &mediaInfo)
{
CLOGD("ConvertMediaInfoToJS start");
napi_value result = nullptr;
napi_value value = nullptr;
NAPI_CALL(env, napi_create_object(env, &result));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.mediaId.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "mediaId", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.mediaName.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "mediaName", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.mediaUrl.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "mediaUrl", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.mediaType.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "mediaType", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.albumCoverUrl.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "albumCoverUrl", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.albumTitle.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "albumTitle", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.mediaArtist.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "mediaArtist", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.lrcUrl.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "lrcUrl", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.lrcContent.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "lrcContent", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.appIconUrl.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "appIconUrl", value));
NAPI_CALL(env, napi_create_string_utf8(env, mediaInfo.appName.c_str(), NAPI_AUTO_LENGTH, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "appName", value));
NAPI_CALL(env, napi_create_uint32(env, mediaInfo.mediaSize, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "mediaSize", value));
NAPI_CALL(env, napi_create_uint32(env, mediaInfo.startPosition, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "startPosition", value));
NAPI_CALL(env, napi_create_uint32(env, mediaInfo.duration, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "duration", value));
NAPI_CALL(env, napi_create_uint32(env, mediaInfo.closingCreditsPosition, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "closingCreditsPosition", value));
CLOGD("ConvertMediaInfoToJS end");
return result;
}
napi_value ConvertMediaInfoHolderToJS(napi_env env, const MediaInfoHolder &mediaInfoHolder)
{
CLOGD("ConvertMediaInfoHolderToJS start");
napi_value result = nullptr;
napi_value value = nullptr;
size_t len = mediaInfoHolder.mediaInfoList.size();
if (len == 0) {
CLOGE("mediaInfoList len is invalid");
return result;
}
NAPI_CALL(env, napi_create_object(env, &result));
NAPI_CALL(env, napi_create_uint32(env, mediaInfoHolder.currentIndex, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "currentIndex", value));
NAPI_CALL(env, napi_create_uint32(env, mediaInfoHolder.progressRefreshInterval, &value));
NAPI_CALL(env, napi_set_named_property(env, result, "progressRefreshInterval", value));
NAPI_CALL(env, napi_create_array_with_length(env, len, &value));
for (size_t i = 0; i < len; i++) {
napi_value mediaInfo = ConvertMediaInfoToJS(env, mediaInfoHolder.mediaInfoList[i]);
NAPI_CALL(env, napi_set_element(env, value, i, mediaInfo));
}
NAPI_CALL(env, napi_set_named_property(env, result, "mediaInfoList", value));
CLOGD("ConvertMediaInfoHolderToJS end");
return result;
}
void CallJSFunc(napi_env env, napi_ref func, size_t argc, napi_value argv[])
{
napi_value callback = nullptr;
napi_value undefined = nullptr;
napi_value callResult = nullptr;
if (napi_get_undefined(env, &undefined) != napi_ok) {
CLOGE("napi_get_undefined failed");
return;
}
if (napi_get_reference_value(env, func, &callback) != napi_ok) {
CLOGE("napi_get_reference_value failed");
return;
}
if (napi_call_function(env, undefined, callback, argc, argv, &callResult) != napi_ok) {
CLOGE("napi_call_function failed");
}
}
bool GetJSFuncParams(napi_env env, napi_callback_info info, napi_value argv[], size_t expectedArgc,
napi_valuetype expectedTypes[])
{
napi_value thisVar = nullptr;
size_t argc = expectedArgc;
napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
if (status != napi_ok || argc != expectedArgc) {
CLOGE("napi_get_cb_info failed");
return false;
}
for (size_t i = 0; i < expectedArgc; i++) {
napi_valuetype valueType = napi_undefined;
if (napi_typeof(env, argv[i], &valueType) != napi_ok) {
CLOGE("napi_typeof failed");
return false;
}
if (valueType != expectedTypes[i]) {
CLOGE("Wrong argument type. type:%d expected", expectedTypes[i]);
return false;
}
}
return true;
}
bool CheckJSParamsType(napi_env env, napi_value argv[], size_t expectedArgc, napi_valuetype expectedTypes[])
{
for (size_t i = 0; i < expectedArgc; i++) {
napi_valuetype valueType = napi_undefined;
if (napi_typeof(env, argv[i], &valueType) != napi_ok) {
CLOGE("napi_typeof failed");
return false;
}
if (valueType != expectedTypes[i]) {
CLOGE("Wrong argument type. type:%d expected", expectedTypes[i]);
return false;
}
}
return true;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,287 @@
/*
* Copyright (c) 2023 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
*
* Description: supply napi interface realization for cast mirror player.
* Author: zhangjingnan
* Create: 2023-5-27
*/
#include <memory>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "oh_remote_control_event.h"
#include "i_mirror_player.h"
#include "napi_castengine_utils.h"
#include "napi_mirror_player.h"
#include "napi_async_work.h"
using namespace OHOS::CastEngine::CastEngineClient;
using namespace std;
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-MirrorPlayer");
thread_local napi_ref NapiMirrorPlayer::consRef_ = nullptr;
void NapiMirrorPlayer::DefineMirrorPlayerJSClass(napi_env env)
{
napi_property_descriptor NapiMirrorPlayerDesc[] = {
DECLARE_NAPI_FUNCTION("play", Play),
DECLARE_NAPI_FUNCTION("pause", Pause),
DECLARE_NAPI_FUNCTION("setSurface", SetSurface),
DECLARE_NAPI_FUNCTION("release", Release)
};
napi_value mirrorPlayer = nullptr;
constexpr int initialRefCount = 1;
napi_status status = napi_define_class(env, "mirrorPlayer", NAPI_AUTO_LENGTH, NapiMirrorPlayerConstructor, nullptr,
sizeof(NapiMirrorPlayerDesc) / sizeof(NapiMirrorPlayerDesc[0]), NapiMirrorPlayerDesc, &mirrorPlayer);
if (status != napi_ok) {
CLOGE("napi_define_class failed");
return;
}
status = napi_create_reference(env, mirrorPlayer, initialRefCount, &consRef_);
if (status != napi_ok) {
CLOGE("DefineMirrorPlayerJSClass napi_create_reference failed");
}
}
napi_value NapiMirrorPlayer::NapiMirrorPlayerConstructor(napi_env env, napi_callback_info info)
{
CLOGD("NapiMirrorPlayer start to construct in");
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
CLOGD("NapiMirrorPlayer construct successfully");
return thisVar;
}
napi_status NapiMirrorPlayer::CreateNapiMirrorPlayer(napi_env env, shared_ptr<IMirrorPlayer> player, napi_value &out)
{
CLOGD("Start to create napiMirrorPlayer in");
napi_value result = nullptr;
napi_value constructor = nullptr;
if (consRef_ == nullptr || player == nullptr) {
CLOGE("CreateNapiMirrorPlayer input is null");
return napi_generic_failure;
}
napi_status status = napi_get_reference_value(env, consRef_, &constructor);
if (status != napi_ok || constructor == nullptr) {
CLOGE("CreateNapiMirrorPlayer napi_get_reference_value failed");
return napi_generic_failure;
}
constexpr size_t argc = 0;
status = napi_new_instance(env, constructor, argc, nullptr, &result);
if (status != napi_ok) {
CLOGE("CreateNapiMirrorPlayer napi_new_instance failed");
return napi_generic_failure;
}
NapiMirrorPlayer *napiMirrorPlayer = new NapiMirrorPlayer(player);
if (napiMirrorPlayer == nullptr) {
CLOGE("NapiMirrorPlayer is nullptr");
return napi_generic_failure;
}
auto finalize = [](napi_env env, void *data, void *hint) {
NapiMirrorPlayer *player = reinterpret_cast<NapiMirrorPlayer *>(data);
if (player != nullptr) {
CLOGI("Session deconstructed");
delete player;
player = nullptr;
}
};
if (napi_wrap(env, result, napiMirrorPlayer, finalize, nullptr, nullptr) != napi_ok) {
CLOGE("CreateNapiMirrorPlayer napi_wrap failed");
delete napiMirrorPlayer;
napiMirrorPlayer = nullptr;
return napi_generic_failure;
}
out = result;
CLOGD("Create napiMirrorPlayer successfully");
return napi_ok;
}
napi_value NapiMirrorPlayer::Play(napi_env env, napi_callback_info info)
{
CLOGD("Start to play in");
struct ConcreteTask : public NapiAsyncTask {
string deviceId_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_string };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->deviceId_ = ParseString(env, argv[0]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = mirrorPlayer->Play(napiAsyntask->deviceId_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "Play failed : no permission";
} else {
napiAsyntask->errMessage = "Play failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "Play", executor, complete);
}
napi_value NapiMirrorPlayer::Pause(napi_env env, napi_callback_info info)
{
CLOGD("Start to pause in");
struct ConcreteTask : public NapiAsyncTask {
string deviceId_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_string };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->deviceId_ = ParseString(env, argv[0]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = mirrorPlayer->Pause(napiAsyntask->deviceId_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "Pause failed : no permission";
} else {
napiAsyntask->errMessage = "Pause failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "Pause", executor, complete);
}
napi_value NapiMirrorPlayer::SetSurface(napi_env env, napi_callback_info info)
{
CLOGD("Start to set surface in");
struct ConcreteTask : public NapiAsyncTask {
string surfaceId_;
};
auto napiAsyntask = std::make_shared<ConcreteTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
auto inputParser = [env, napiAsyntask](size_t argc, napi_value *argv) {
constexpr size_t expectedArgc = 1;
CHECK_ARGS_RETURN_VOID(napiAsyntask, argc == expectedArgc, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napi_valuetype expectedTypes[expectedArgc] = { napi_string };
bool isParamsTypeValid = CheckJSParamsType(env, argv, expectedArgc, expectedTypes);
CHECK_ARGS_RETURN_VOID(napiAsyntask, isParamsTypeValid, "invalid arguments",
NapiErrors::errcode_[ERR_INVALID_PARAM]);
napiAsyntask->surfaceId_ = ParseString(env, argv[0]);
};
napiAsyntask->GetJSInfo(env, info, inputParser);
auto executor = [napiAsyntask]() {
auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = mirrorPlayer->SetSurface(napiAsyntask->surfaceId_);
if (ret != CAST_ENGINE_SUCCESS) {
if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "SetSurface failed : no permission";
} else {
napiAsyntask->errMessage = "SetSurface failed : native server exception";
}
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "SetSurface", executor, complete);
}
napi_value NapiMirrorPlayer::Release(napi_env env, napi_callback_info info)
{
CLOGD("Start to release in");
auto napiAsyntask = std::make_shared<NapiAsyncTask>();
if (napiAsyntask == nullptr) {
CLOGE("Create NapiAsyncTask failed");
return GetUndefinedValue(env);
}
napiAsyntask->GetJSInfo(env, info);
auto executor = [napiAsyntask]() {
auto *napiPlayer = reinterpret_cast<NapiMirrorPlayer *>(napiAsyntask->native);
CHECK_ARGS_RETURN_VOID(napiAsyntask, napiPlayer != nullptr, "napiPlayer is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
shared_ptr<IMirrorPlayer> mirrorPlayer = napiPlayer->GetMirrorPlayer();
CHECK_ARGS_RETURN_VOID(napiAsyntask, mirrorPlayer, "IMirrorPlayer is null",
NapiErrors::errcode_[CAST_ENGINE_ERROR]);
int32_t ret = mirrorPlayer->Release();
if (ret == CAST_ENGINE_SUCCESS) {
napiPlayer->Reset();
} else if (ret == ERR_NO_PERMISSION) {
napiAsyntask->errMessage = "Release failed : no permission";
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
} else {
napiAsyntask->errMessage = "Release failed : native server exception";
napiAsyntask->status = napi_generic_failure;
napiAsyntask->errCode = NapiErrors::errcode_[ret];
}
};
auto complete = [env](napi_value &output) { output = GetUndefinedValue(env); };
return NapiAsyncWork::Enqueue(env, napiAsyntask, "Release", executor, complete);
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,279 @@
/*
* Copyright (c) 2023 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
*
* Description: supply stream player listener realization for napi interface.
* Author: huangchanggui
* Create: 2023-1-11
*/
#include "napi_stream_player_listener.h"
#include <uv.h>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "cast_engine_log.h"
#include "cast_engine_common.h"
#include "napi_castengine_utils.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
DEFINE_CAST_ENGINE_LABEL("Cast-Napi-StreamPlayerListener");
NapiStreamPlayerListener::~NapiStreamPlayerListener()
{
CLOGD("destrcutor in");
ClearCallback(callback_->GetEnv());
}
void NapiStreamPlayerListener::HandleEvent(int32_t event, NapiArgsGetter getter)
{
std::lock_guard<std::mutex> lockGuard(lock_);
if (callbacks_[event].empty()) {
CLOGE("not register callback event=%{public}d", event);
return;
}
for (auto ref = callbacks_[event].begin(); ref != callbacks_[event].end(); ++ref) {
callback_->Call(*ref, getter);
}
}
void NapiStreamPlayerListener::OnStateChanged(const PlayerStates playbackState, bool isPlayWhenReady)
{
CLOGD("OnStateChanged start");
NapiArgsGetter napiArgsGetter = [playbackState, isPlayWhenReady](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_TWO;
auto status = napi_create_int32(env, static_cast<int>(playbackState), &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
status = napi_get_boolean(env, isPlayWhenReady, &argv[1]);
CHECK_RETURN_VOID(status == napi_ok, "napi_get_boolean failed");
};
HandleEvent(EVENT_PLAYER_STATUS_CHANGED, napiArgsGetter);
CLOGD("OnStateChanged finish");
}
void NapiStreamPlayerListener::OnPositionChanged(int position, int bufferPosition, int duration)
{
CLOGD("OnPositionChanged start");
std::chrono::steady_clock::duration timestampOrigin = std::chrono::steady_clock::now().time_since_epoch();
uint64_t timestamp =
static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(timestampOrigin).count());
NapiArgsGetter napiArgsGetter = [position, bufferPosition, duration, timestamp](napi_env env, int &argc,
napi_value *argv) {
argc = CALLBACK_ARGC_FOUR;
auto status = napi_create_int32(env, position, &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
status = napi_create_int32(env, bufferPosition, &argv[1]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
status = napi_create_int32(env, duration, &argv[2]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
status = napi_create_bigint_uint64(env, timestamp, &argv[3]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_bigint_uint64 failed");
};
HandleEvent(EVENT_POSITION_CHANGED, napiArgsGetter);
CLOGD("OnPositionChanged finish");
}
void NapiStreamPlayerListener::OnMediaItemChanged(const MediaInfo &mediaInfo)
{
CLOGD("OnMediaItemChanged start");
NapiArgsGetter napiArgsGetter = [mediaInfo](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
argv[0] = ConvertMediaInfoToJS(env, mediaInfo);
};
HandleEvent(EVENT_MEDIA_ITEM_CHANGED, napiArgsGetter);
CLOGD("OnMediaItemChanged finish");
}
void NapiStreamPlayerListener::OnVolumeChanged(int volume, int maxVolume)
{
CLOGD("OnVolumeChanged start");
NapiArgsGetter napiArgsGetter = [volume](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
auto status = napi_create_int32(env, volume, &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
};
HandleEvent(EVENT_VOLUME_CHANGED, napiArgsGetter);
CLOGD("OnVolumeChanged finish");
}
void NapiStreamPlayerListener::OnVideoSizeChanged(int width, int height)
{
CLOGD("OnVideoSizeChanged start");
NapiArgsGetter napiArgsGetter = [width, height](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_TWO;
auto status = napi_create_int32(env, width, &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
status = napi_create_int32(env, height, &argv[1]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
};
HandleEvent(EVENT_VIDEO_SIZE_CHANGED, napiArgsGetter);
CLOGD("OnVideoSizeChanged finish");
}
void NapiStreamPlayerListener::OnLoopModeChanged(const LoopMode loopMode)
{
CLOGD("OnLoopModeChanged start");
NapiArgsGetter napiArgsGetter = [loopMode](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
auto status = napi_create_int32(env, static_cast<int>(loopMode), &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
};
HandleEvent(EVENT_LOOP_MODE_CHANGED, napiArgsGetter);
CLOGD("OnLoopModeChanged finish");
}
void NapiStreamPlayerListener::OnPlaySpeedChanged(const PlaybackSpeed speed)
{
CLOGD("OnPlaySpeedChanged start");
NapiArgsGetter napiArgsGetter = [speed](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
auto status = napi_create_int32(env, static_cast<int>(speed), &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_double failed");
};
HandleEvent(EVENT_PLAY_SPEED_CHANGED, napiArgsGetter);
CLOGD("OnPlaySpeedChanged finish");
}
void NapiStreamPlayerListener::OnPlayerError(int errorCode, const std::string &errorMsg)
{
CLOGD("OnPlayerError start");
NapiArgsGetter napiArgsGetter = [errorCode, errorMsg](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_TWO;
auto status = napi_create_int32(env, errorCode, &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
status = napi_create_string_utf8(env, errorMsg.c_str(), NAPI_AUTO_LENGTH, &argv[1]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_string_utf8 failed");
};
HandleEvent(EVENT_PLAYER_ERROR, napiArgsGetter);
CLOGD("OnPlayerError finish");
}
void NapiStreamPlayerListener::OnNextRequest()
{
CLOGD("OnNextRequest start");
NapiArgsGetter napiArgsGetter = [](napi_env env, int &argc, napi_value *argv) {};
HandleEvent(EVENT_NEXT_REQUEST, napiArgsGetter);
CLOGD("OnNextRequest finish");
}
void NapiStreamPlayerListener::OnPreviousRequest()
{
CLOGD("OnPreviousRequest start");
NapiArgsGetter napiArgsGetter = [](napi_env env, int &argc, napi_value *argv) {};
HandleEvent(EVENT_PREVIOUS_REQUEST, napiArgsGetter);
CLOGD("OnPreviousRequest finish");
}
void NapiStreamPlayerListener::OnSeekDone(int position)
{
CLOGD("OnSeekDone start");
NapiArgsGetter napiArgsGetter = [position](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
auto status = napi_create_int32(env, position, &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
};
HandleEvent(EVENT_SEEK_DONE, napiArgsGetter);
CLOGD("OnSeekDone finish");
}
void NapiStreamPlayerListener::OnEndOfStream(int isLooping)
{
CLOGD("OnEndOfStream start");
NapiArgsGetter napiArgsGetter = [isLooping](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
auto status = napi_create_int32(env, isLooping, &argv[0]);
CHECK_RETURN_VOID(status == napi_ok, "napi_create_int32 failed");
};
HandleEvent(EVENT_END_OF_STREAM, napiArgsGetter);
CLOGD("OnEndOfStream finish");
}
void NapiStreamPlayerListener::OnPlayRequest(const MediaInfo &mediaInfo)
{
CLOGD("OnPlayRequest start");
NapiArgsGetter napiArgsGetter = [mediaInfo](napi_env env, int &argc, napi_value *argv) {
argc = CALLBACK_ARGC_ONE;
argv[0] = ConvertMediaInfoToJS(env, mediaInfo);
};
HandleEvent(EVENT_PLAY_REQUEST, napiArgsGetter);
CLOGD("OnPlayRequest finish");
}
napi_status NapiStreamPlayerListener::AddCallback(napi_env env, int32_t event, napi_value callback)
{
CLOGI("Add callback %{public}d", event);
constexpr int initialRefCount = 1;
napi_ref ref = nullptr;
if (GetRefByCallback(env, callbacks_[event], callback, ref) != napi_ok) {
CLOGE("get callback reference failed");
return napi_generic_failure;
}
if (ref != nullptr) {
CLOGD("callback has been registered");
return napi_ok;
}
napi_status status = napi_create_reference(env, callback, initialRefCount, &ref);
if (status != napi_ok) {
CLOGE("napi_create_reference failed");
return status;
}
if (callback_ == nullptr) {
callback_ = std::make_shared<NapiCallback>(env);
if (callback_ == nullptr) {
CLOGE("no memory");
return napi_generic_failure;
}
}
callbacks_[event].push_back(ref);
return napi_ok;
}
napi_status NapiStreamPlayerListener::RemoveCallback(napi_env env, int32_t event, napi_value callback)
{
if (callback == nullptr) {
for (auto &callbackRef : callbacks_[event]) {
napi_status ret = napi_delete_reference(env, callbackRef);
if (ret != napi_ok) {
CLOGE("delete callback reference failed");
return ret;
}
}
callbacks_[event].clear();
return napi_ok;
}
napi_ref ref = nullptr;
if (GetRefByCallback(env, callbacks_[event], callback, ref) != napi_ok) {
CLOGE("get callback reference failed");
return napi_generic_failure;
}
if (ref != nullptr) {
CLOGD("callback has been remove");
return napi_ok;
}
callbacks_[event].remove(ref);
return napi_delete_reference(env, ref);
}
napi_status NapiStreamPlayerListener::ClearCallback(napi_env env)
{
for (auto &callback : callbacks_) {
for (auto &callbackRef : callback) {
napi_status ret = napi_delete_reference(env, callbackRef);
if (ret != napi_ok) {
CLOGE("delete callback reference failed");
return ret;
}
}
callback.clear();
}
return napi_ok;
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2023 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
*
* Description: register napi module for napi interfaces.
* Author: zhangjingnan
* Create: 2022-7-11
*/
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "napi_cast_session_manager.h"
#include "napi_cast_session.h"
#include "napi_castengine_utils.h"
#include "napi_stream_player.h"
#include "napi_mirror_player.h"
#include "napi_castengine_enum.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineClient {
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
InitEnums(env, exports);
NapiCastSessionManager::Init(env, exports);
NapiCastSession::DefineCastSessionJSClass(env);
NapiStreamPlayer::DefineStreamPlayerJSClass(env);
NapiMirrorPlayer::DefineMirrorPlayerJSClass(env);
return exports;
}
EXTERN_C_END
// module description
static napi_module napiModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "cast",
.nm_priv = ((void *)0),
.reserved = { 0 }
};
// module registration
extern "C" __attribute__((constructor)) void RegisterModule()
{
napi_module_register(&napiModule);
}
} // namespace CastEngineClient
} // namespace CastEngine
} // namespace OHOS

24
patches/patches.json Normal file
View File

@ -0,0 +1,24 @@
{
"patches": [
{
"project":"vendor_hihope",
"path":"vendor/hihope",
"pr_url":"https://gitee.com/openharmony/vendor_hihope/pulls/970"
},
{
"project":"build",
"path":"build",
"pr_url":"https://gitee.com/openharmony/build/pulls/2546"
},
{
"project":"startup_init",
"path":"base/startup/init",
"pr_url":"https://gitee.com/openharmony/startup_init/pulls/2416"
},
{
"project":"security_selinux_adapter",
"path":"base/security/selinux_adapter",
"pr_url":"https://gitee.com/openharmony/security_selinux_adapter/pulls/3382"
}
]
}

12
sa_profile/5526.json Normal file
View File

@ -0,0 +1,12 @@
{
"process": "cast_engine_service",
"systemability": [
{
"name": 5526,
"libpath": "libcast_engine_service.z.so",
"run-on-create": false,
"distributed": false,
"dump_level": 1
}
]
}

14
sa_profile/BUILD.gn Normal file
View File

@ -0,0 +1,14 @@
# Copyright (c) 2023 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
#
import("//build/ohos/sa_profile/sa_profile.gni")
ohos_sa_profile("cast_engine_sa_profile") {
sources = [ "5526.json" ]
part_name = "cast_engine"
}

60
service/BUILD.gn Normal file
View File

@ -0,0 +1,60 @@
# Copyright (c) 2023 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.
import("//foundation/CastEngine/castengine_cast_framework/cast_engine.gni")
config("cast_service_config") {
include_dirs = [
"include",
"src/include",
]
}
ohos_shared_library("cast_engine_service") {
install_enable = true
sources = [
"src/cast_service_listener_impl_proxy.cpp",
"src/cast_session_manager_service.cpp",
"src/cast_session_manager_service_stub.cpp",
]
configs = [
":cast_service_config",
"${cast_engine_root}:cast_engine_default_config",
]
deps = [
"${cast_engine_client}:cast_client_inner",
"${cast_engine_common}:cast_engine_common_sources",
"src/device_manager:cast_discovery",
"${cast_session_stream_path}:cast_session",
"//third_party/openssl:libcrypto_shared",
]
external_deps = [
"c_utils:utils",
"device_manager:devicemanagersdk",
"dsoftbus:softbus_client",
"graphic_2d:surface",
"hilog:libhilog",
"hisysevent:libhisysevent",
"input:libmmi-client",
"ipc:ipc_core",
"player_framework:media_client",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
subsystem_name = "castplus"
part_name = "cast_engine"
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast service listener implement proxy class.
* Author: zhangge
* Create: 2022-6-15
*/
#ifndef CAST_SERVICE_LISTENER_IMPL_PROXY_H
#define CAST_SERVICE_LISTENER_IMPL_PROXY_H
#include "cast_engine_common.h"
#include "i_cast_service_listener_impl.h"
#include "i_cast_session_impl.h"
#include "iremote_proxy.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
class CastServiceListenerImplProxy : public IRemoteProxy<ICastServiceListenerImpl> {
public:
explicit CastServiceListenerImplProxy(const sptr<IRemoteObject> &impl)
: IRemoteProxy<ICastServiceListenerImpl>(impl)
{}
void OnDeviceFound(const std::vector<CastRemoteDevice> &deviceList) override;
void OnDeviceOffline(const std::string &deviceId) override;
void OnSessionCreated(const sptr<ICastSessionImpl> &castSession) override;
void OnServiceDied() override;
private:
static inline BrokerDelegator<CastServiceListenerImplProxy> delegator_;
};
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2023 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
*
* Description: cast session manager service class
* Author: zhangge
* Create: 2022-06-15
*/
#ifndef CAST_SESSION_MANAGER_SERVICE_H
#define CAST_SESSION_MANAGER_SERVICE_H
#include <atomic>
#include <map>
#include <mutex>
#include <shared_mutex>
#include "cast_session_manager_service_stub.h"
#include "session.h"
#include "system_ability.h"
using SharedRLock = std::shared_lock<std::shared_mutex>;
using SharedWLock = std::lock_guard<std::shared_mutex>;
namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
class CastSessionManagerService : public SystemAbility, public CastSessionManagerServiceStub {
DECLARE_SYSTEM_ABILITY(CastSessionManagerService);
public:
CastSessionManagerService(int32_t saId, bool runOnCreate);
~CastSessionManagerService() override;
void OnStart() override;
void OnStop() override;
int32_t RegisterListener(sptr<ICastServiceListenerImpl> listener) override;
int32_t UnregisterListener() override;
int32_t Release() override;
int32_t SetLocalDevice(const CastLocalDevice &localDevice) override;
int32_t CreateCastSession(const CastSessionProperty &property, sptr<ICastSessionImpl> &castSession) override;
int32_t SetSinkSessionCapacity(int sessionCapacity) override;
int32_t StartDiscovery(int protocols) override;
int32_t SetDiscoverable(bool enable) override;
int32_t StopDiscovery() override;
void ReleaseServiceResources(pid_t pid);
int32_t GetCastSession(std::string sessionId, sptr<ICastSessionImpl> &castSession) override;
bool DestroyCastSession(int32_t sessionId);
void ReportServiceDieLocked();
void ReportDeviceFound(const std::vector<CastRemoteDevice> &deviceList);
void ReportSessionCreate(const sptr<ICastSessionImpl> &castSession);
void ReportDeviceOffline(const std::string &deviceId);
private:
class CastEngineClientDeathRecipient : public IRemoteObject::DeathRecipient {
public:
CastEngineClientDeathRecipient(wptr<CastSessionManagerService> service, pid_t pid)
: service_(service), pid_(pid) {};
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
private:
wptr<CastSessionManagerService> service_;
pid_t pid_;
};
pid_t myPid_;
std::shared_mutex mutex_;
std::vector<std::pair<pid_t, sptr<ICastServiceListenerImpl>>> listeners_;
CastLocalDevice localDevice_{};
ServiceStatus serviceStatus_{ ServiceStatus::DISCONNECTED };
int sessionCapacity_{ 0 };
std::map<int32_t, sptr<ICastSessionImpl>> sessionMap_;
std::atomic<int> sessionIndex_{ 0 };
std::unordered_map<pid_t, sptr<IRemoteObject::DeathRecipient>> deathRecipientMap_;
void AddClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener);
void RemoveClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener);
bool AddListenerLocked(sptr<ICastServiceListenerImpl> listener);
int32_t ReleaseLocked();
int32_t RemoveListenerLocked(pid_t pid);
void ClearListenersLocked();
bool HasListenerLocked();
};
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2023 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
*
* Description: cast session manager service stub class.
* Author: zhangge
* Create: 2022-5-29
*/
#ifndef CAST_SESSION_MANAGER_SERVICE_STUB_H
#define CAST_SESSION_MANAGER_SERVICE_STUB_H
#include "cast_stub_helper.h"
#include "i_cast_session_manager_service.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
class CastSessionManagerServiceStub : public IRemoteStub<ICastSessionManagerService> {
public:
CastSessionManagerServiceStub();
~CastSessionManagerServiceStub() override;
int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
private:
DECLARE_STUB_TASK_MAP(CastSessionManagerServiceStub);
int32_t DoRegisterListenerTask(MessageParcel &data, MessageParcel &reply);
int32_t DoUnregisterListenerTask(MessageParcel &data, MessageParcel &reply);
int32_t DoReleaseTask(MessageParcel &data, MessageParcel &reply);
int32_t DoSetLocalDeviceTask(MessageParcel &data, MessageParcel &reply);
int32_t DoCreateCastSessionTask(MessageParcel &data, MessageParcel &reply);
int32_t DoSetSinkSessionCapacityTask(MessageParcel &data, MessageParcel &reply);
int32_t DoStartDiscoveryTask(MessageParcel &data, MessageParcel &reply);
int32_t DoSetDiscoverableTask(MessageParcel &data, MessageParcel &reply);
int32_t DoStopDiscoveryTask(MessageParcel &data, MessageParcel &reply);
int32_t DoGetCastSessionTask(MessageParcel &data, MessageParcel &reply);
};
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS
#endif // CAST_SESSION_MANAGER_SERVICE_STUB_H

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast service listener implement proxy class.
* Author: zhangge
* Create: 2022-6-15
*/
#include "cast_service_listener_impl_proxy.h"
#include <cast_engine_common_helper.h>
#include "cast_engine_log.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
DEFINE_CAST_ENGINE_LABEL("Cast-Service-ListenerImpl");
void CastServiceListenerImplProxy::OnServiceDied()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return;
}
if (Remote()->SendRequest(ON_SERVICE_DIE, data, reply, option) != ERR_NONE) {
CLOGE("Failed to send ipc request when reporting service die");
}
}
namespace {
bool FillCastRemoteDevices(MessageParcel &data, const std::vector<CastRemoteDevice> &devices)
{
auto size = devices.size();
if (size <= 0) {
CLOGE("devices size <= 0");
return false;
}
if (!data.WriteInt32(static_cast<int32_t>(size))) {
CLOGE("Failed to write the device size:%u", size);
return false;
}
for (auto &device : devices) {
if (!WriteCastRemoteDevice(data, device)) {
CLOGE("Failed to write the remote device item");
return false;
}
}
return true;
}
bool FillCastSession(MessageParcel &data, const sptr<ICastSessionImpl> &castSession)
{
if (!castSession) {
return false;
}
if (!data.WriteRemoteObject(castSession->AsObject())) {
CLOGE("Failed to write cast session");
return false;
}
return true;
}
} // namespace
void CastServiceListenerImplProxy::OnDeviceFound(const std::vector<CastRemoteDevice> &devices)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return;
}
if (!FillCastRemoteDevices(data, devices)) {
CLOGE("Failed to Write remote devices");
return;
}
Remote()->SendRequest(ON_DEVICE_FOUND, data, reply, option);
}
void CastServiceListenerImplProxy::OnSessionCreated(const sptr<ICastSessionImpl> &castSession)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return;
}
if (!FillCastSession(data, castSession)) {
CLOGE("Failed to Write cast session");
return;
}
Remote()->SendRequest(ON_SESSION_CREATE, data, reply, option);
}
void CastServiceListenerImplProxy::OnDeviceOffline(const std::string &deviceId)
{
MessageParcel data, reply;
MessageOption option;
CLOGD("OnDeviceOffline in");
if (!data.WriteInterfaceToken(GetDescriptor())) {
CLOGE("Failed to write the interface token");
return;
}
if (!data.WriteString(deviceId)) {
CLOGE("Failed to Write deviceId");
return;
}
CLOGD("send request");
Remote()->SendRequest(ON_DEVICE_OFFLINE, data, reply, option);
}
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,524 @@
/*
* Copyright (c) 2023 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
*
* Description: cast session manager service class
* Author: zhangge
* Create: 2022-06-15
*/
#include "cast_session_manager_service.h"
#include <algorithm>
#include <atomic>
#include <ipc_skeleton.h>
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
#include "cast_engine_dfx.h"
#include "cast_engine_errors.h"
#include "cast_engine_log.h"
#include "cast_session_impl.h"
#include "connection_manager.h"
#include "discovery_manager.h"
#include "hisysevent.h"
#include "permission.h"
#include "utils.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
DEFINE_CAST_ENGINE_LABEL("Cast-Service");
REGISTER_SYSTEM_ABILITY_BY_ID(CastSessionManagerService, CAST_ENGINE_SA_ID, false);
CastSessionManagerService::CastSessionManagerService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate)
{
CLOGD("construction in");
myPid_ = getpid();
};
CastSessionManagerService::~CastSessionManagerService()
{
CLOGD("destruction in");
}
void CastSessionManagerService::OnStart()
{
bool ret = Publish(this);
if (!ret) {
CLOGE("Failed to publish cast session manager service");
return;
}
AddSystemAbilityListener(CAST_ENGINE_SA_ID);
}
void CastSessionManagerService::OnStop() {}
namespace {
using namespace OHOS::DistributedHardware;
class DiscoveryManagerListener : public IDiscoveryManagerListener {
public:
DiscoveryManagerListener(sptr<CastSessionManagerService> service) : service_(service) {}
void OnDeviceFound(const std::vector<CastInnerRemoteDevice> &devices) override
{
auto service = service_.promote();
if (!service) {
CLOGE("service is null");
return;
}
std::vector<CastRemoteDevice> remoteDevices;
for (const auto &device : devices) {
remoteDevices.push_back(CastRemoteDevice{ device.deviceId, device.deviceName, device.deviceType,
device.subDeviceType, device.ipAddress, device.channelType });
}
service->ReportDeviceFound(remoteDevices);
}
private:
wptr<CastSessionManagerService> service_;
};
class ConnectionManagerListener : public IConnectionManagerListener {
public:
ConnectionManagerListener(sptr<CastSessionManagerService> service) : service_(service) {}
int NotifySessionIsReady() override
{
auto service = service_.promote();
if (!service) {
CLOGE("service is null");
return INVALID_ID;
}
sptr<ICastSessionImpl> session;
service->CreateCastSession({}, session);
if (session == nullptr) {
return INVALID_ID;
}
service->ReportSessionCreate(session);
std::string sessionId{};
session->GetSessionId(sessionId);
return Utils::StringToInt((sessionId));
}
bool NotifyRemoteDeviceIsReady(int castSessionId, const CastInnerRemoteDevice &device) override
{
auto service = service_.promote();
if (!service) {
CLOGE("service is null");
return INVALID_ID;
}
sptr<ICastSessionImpl> session;
service->GetCastSession(std::to_string(castSessionId), session);
if (session == nullptr) {
CLOGE("Session is null when consultation data comes!");
return false;
}
return session->AddDevice(device);
}
void NotifyDeviceIsOffline(const std::string &deviceId) override
{
auto service = service_.promote();
if (!service) {
CLOGE("service is null");
return;
}
service->ReportDeviceOffline(deviceId);
CLOGD("OnDeviceOffline out");
}
void OnError(const std::string &deviceId) override
{
auto service = service_.promote();
if (!service) {
CLOGE("service is null");
return;
}
int sessionId = CastDeviceDataManager::GetInstance().GetSessionIdByDeviceId(deviceId);
if (sessionId == INVALID_ID) {
CLOGE("The obtained sessionId is null");
return;
}
sptr<ICastSessionImpl> session;
service->GetCastSession(std::to_string(sessionId), session);
if (!session) {
CLOGE("The session is null. Failed to obtain the session.");
return;
}
session->RemoveDevice(deviceId);
}
private:
wptr<CastSessionManagerService> service_;
};
} // namespace
int32_t CastSessionManagerService::RegisterListener(sptr<ICastServiceListenerImpl> listener)
{
CLOGI("RegisterListener in");
HiSysEventWrite(CAST_ENGINE_DFX_DOMAIN_NAME, "CAST_ENGINE_EVE", HiviewDFX::HiSysEvent::EventType::STATISTIC,
"SEQUENTIAL_ID", CastEngineDfx::GetSequentialId(), "BIZ_PACKAGE_NAME", CastEngineDfx::GetBizPackageName());
SharedWLock lock(mutex_);
if (listener == nullptr) {
CLOGE("RegisterListener failed, listener is null");
return CAST_ENGINE_ERROR;
}
bool needInitMore = !HasListenerLocked();
if (!AddListenerLocked(listener)) {
return CAST_ENGINE_ERROR;
}
if (needInitMore) {
DiscoveryManager::GetInstance().Init(std::make_shared<DiscoveryManagerListener>(this));
ConnectionManager::GetInstance().Init(std::make_shared<ConnectionManagerListener>(this));
sessionMap_.clear();
}
serviceStatus_ = ServiceStatus::CONNECTED;
CLOGI("RegisterListener out");
return CAST_ENGINE_SUCCESS;
}
int32_t CastSessionManagerService::UnregisterListener()
{
SharedWLock lock(mutex_);
CLOGI("UnregisterListener in");
return RemoveListenerLocked(IPCSkeleton::GetCallingPid());
}
int32_t CastSessionManagerService::Release()
{
SharedWLock lock(mutex_);
CLOGI("Release in");
if (!Permission::CheckPidPermission()) {
return ERR_NO_PERMISSION;
}
return ReleaseLocked();
}
int32_t CastSessionManagerService::ReleaseLocked()
{
CLOGI("ReleaseLocked in");
serviceStatus_ = ServiceStatus::DISCONNECTED;
ReportServiceDieLocked();
ClearListenersLocked();
DiscoveryManager::GetInstance().Deinit();
ConnectionManager::GetInstance().Deinit();
sessionMap_.clear();
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (samgr == nullptr) {
CLOGE("get samgr failed");
return CAST_ENGINE_ERROR;
}
int32_t ret = samgr->UnloadSystemAbility(CAST_ENGINE_SA_ID);
if (ret != ERR_OK) {
CLOGE("remove system ability failed");
return CAST_ENGINE_ERROR;
}
CLOGI("Release success done");
return CAST_ENGINE_SUCCESS;
}
int32_t CastSessionManagerService::SetLocalDevice(const CastLocalDevice &localDevice)
{
CLOGD("SetLocalDevice in");
SharedWLock lock(mutex_);
if (!Permission::CheckPidPermission()) {
return ERR_NO_PERMISSION;
}
localDevice_ = localDevice;
return CAST_ENGINE_SUCCESS;
}
int32_t CastSessionManagerService::GetCastSession(std::string sessionId, sptr<ICastSessionImpl> &castSession)
{
auto innerSessionId = Utils::StringToInt(sessionId);
SharedRLock lock(mutex_);
if (!Permission::CheckPidPermission()) {
return ERR_NO_PERMISSION;
}
auto it = sessionMap_.find(innerSessionId);
if (it == sessionMap_.end()) {
CLOGE("No sessionId=%{public}d session.", innerSessionId);
return ERR_SESSION_NOT_EXIST;
}
castSession = it->second;
return CAST_ENGINE_SUCCESS;
}
int32_t CastSessionManagerService::CreateCastSession(const CastSessionProperty &property,
sptr<ICastSessionImpl> &castSession)
{
SharedWLock lock(mutex_);
if (!Permission::CheckPidPermission()) {
return ERR_NO_PERMISSION;
}
CLOGD("CreateCastSession in, protocol:%{public}d, endType:%{public}d.", property.protocolType, property.endType);
if (serviceStatus_ != ServiceStatus::CONNECTED) {
CLOGE("not connected");
return ERR_SERVICE_STATE_NOT_MATCH;
}
if (localDevice_.deviceId.empty()) {
auto local = ConnectionManager::GetInstance().GetLocalDeviceInfo();
if (local == nullptr) {
return CAST_ENGINE_ERROR;
}
localDevice_ = *local;
}
auto tmp = new (std::nothrow) CastSessionImpl(property, localDevice_);
if (tmp == nullptr) {
CLOGE("CastSessionImpl is null");
return ERR_NO_MEMORY;
}
sptr<ICastSessionImpl> session(static_cast<ICastSessionImpl *>(tmp));
tmp->Init();
tmp->SetServiceCallbackForRelease([this](int32_t sessionId) { DestroyCastSession(sessionId); });
sessionIndex_++;
std::string sessionId{};
session->GetSessionId(sessionId);
sessionMap_.insert({ Utils::StringToInt(sessionId), session });
CLOGD("CreateCastSession success, session(%{public}d) count:%{public}zu",
Utils::StringToInt(sessionId), sessionMap_.size());
castSession = session;
return CAST_ENGINE_SUCCESS;
}
bool CastSessionManagerService::DestroyCastSession(int32_t sessionId)
{
CLOGD("DestroyCastSession in");
sptr<ICastSessionImpl> session;
{
SharedWLock lock(mutex_);
auto it = sessionMap_.find(sessionId);
if (it == sessionMap_.end()) {
CLOGE("Cast session(%d) has gone.", sessionId);
return true;
}
session = it->second;
sessionMap_.erase(it);
}
session->Stop();
CLOGD("Session refcount is %d, session count:%zu", session->GetSptrRefCount(), sessionMap_.size());
return true;
}
int32_t CastSessionManagerService::SetSinkSessionCapacity(int sessionCapacity)
{
CLOGD("SetSinkSessionCapacity in, sessionCapacity = %d", sessionCapacity);
SharedRLock lock(mutex_);
if (!Permission::CheckPidPermission()) {
return ERR_NO_PERMISSION;
}
sessionCapacity_ = sessionCapacity;
return CAST_ENGINE_SUCCESS;
}
int32_t CastSessionManagerService::StartDiscovery(int protocols)
{
static_cast<void>(protocols);
CLOGD("StartDiscovery in, protocolType = %d", protocols);
SharedRLock lock(mutex_);
if (!Permission::CheckPidPermission()) {
return ERR_NO_PERMISSION;
}
DiscoveryManager::GetInstance().StartDiscovery();
return CAST_ENGINE_SUCCESS;
}
int32_t CastSessionManagerService::StopDiscovery()
{
CLOGD("StopDiscovery in");
SharedRLock lock(mutex_);
if (!Permission::CheckPidPermission()) {
return ERR_NO_PERMISSION;
}
DiscoveryManager::GetInstance().StopDiscovery();
return CAST_ENGINE_SUCCESS;
}
int32_t CastSessionManagerService::SetDiscoverable(bool enable)
{
CLOGD("SetDiscoverable in, enable = %{public}d", enable);
SharedRLock lock(mutex_);
if (!Permission::CheckPidPermission()) {
return ERR_NO_PERMISSION;
}
bool ret = false;
if (enable) {
ret = ConnectionManager::GetInstance().EnableDiscoverable();
} else {
ret = ConnectionManager::GetInstance().DisableDiscoverable();
}
return ret ? CAST_ENGINE_SUCCESS : CAST_ENGINE_ERROR;
}
void CastSessionManagerService::ReleaseServiceResources(pid_t pid)
{
{
SharedWLock lock(mutex_);
RemoveListenerLocked(pid);
for (auto it = sessionMap_.begin(); it != sessionMap_.end();) {
if (it->second->ReleaseSessionResources(pid)) {
sessionMap_.erase(it++);
continue;
}
it++;
}
if (HasListenerLocked()) {
return;
}
}
CLOGD("Release service resources");
if (Release() != CAST_ENGINE_SUCCESS) {
CLOGE("Release service resources failed");
}
}
void CastSessionManagerService::AddClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener)
{
sptr<CastEngineClientDeathRecipient> deathRecipient(
new (std::nothrow) CastEngineClientDeathRecipient(wptr<CastSessionManagerService>(this), pid));
if (deathRecipient == nullptr) {
CLOGE("Alloc death recipient filed");
return;
}
if (!listener->AsObject()->AddDeathRecipient(deathRecipient)) {
CLOGE("Add cast client death recipient failed");
return;
}
CLOGD("add death recipient pid:%d", pid);
deathRecipientMap_[pid] = deathRecipient;
}
void CastSessionManagerService::RemoveClientDeathRecipientLocked(pid_t pid, sptr<ICastServiceListenerImpl> listener)
{
auto it = deathRecipientMap_.find(pid);
if (it != deathRecipientMap_.end()) {
listener->AsObject()->RemoveDeathRecipient(it->second);
deathRecipientMap_.erase(it);
CLOGD("remove death recipient pid:%d", pid);
}
}
bool CastSessionManagerService::AddListenerLocked(sptr<ICastServiceListenerImpl> listener)
{
pid_t pid = IPCSkeleton::GetCallingPid();
Permission::SavePid(pid);
if (std::find_if(listeners_.begin(), listeners_.end(),
[pid](std::pair<pid_t, sptr<ICastServiceListenerImpl>> member) { return member.first == pid; }) ==
listeners_.end()) {
listeners_.push_back({ pid, listener });
AddClientDeathRecipientLocked(pid, listener);
return true;
}
CLOGE("The process(%u) has register the listener", pid);
return false;
}
int32_t CastSessionManagerService::RemoveListenerLocked(pid_t pid)
{
Permission::RemovePid(pid);
auto iter = std::find_if(listeners_.begin(), listeners_.end(),
[pid](std::pair<pid_t, sptr<ICastServiceListenerImpl>> element) { return element.first == pid; });
if (iter != listeners_.end()) {
RemoveClientDeathRecipientLocked(pid, (*iter).second);
listeners_.erase(iter);
if (listeners_.size() == 0) {
ReleaseLocked();
}
return CAST_ENGINE_SUCCESS;
}
return CAST_ENGINE_ERROR;
}
void CastSessionManagerService::ClearListenersLocked()
{
listeners_.clear();
Permission::ClearPids();
}
bool CastSessionManagerService::HasListenerLocked()
{
return listeners_.size() > 0;
}
void CastSessionManagerService::ReportServiceDieLocked()
{
pid_t pid = IPCSkeleton::GetCallingPid();
if (pid == myPid_) {
for (const auto &listener : listeners_) {
listener.second->OnServiceDied();
}
return;
}
auto it = std::find_if(listeners_.begin(), listeners_.end(),
[pid](std::pair<pid_t, sptr<ICastServiceListenerImpl>> element) { return element.first == pid; });
if (it != listeners_.end()) {
it->second->OnServiceDied();
return;
}
}
void CastSessionManagerService::ReportDeviceFound(const std::vector<CastRemoteDevice> &deviceList)
{
SharedRLock lock(mutex_);
for (const auto &listener : listeners_) {
listener.second->OnDeviceFound(deviceList);
}
}
void CastSessionManagerService::ReportSessionCreate(const sptr<ICastSessionImpl> &castSession)
{
SharedRLock lock(mutex_);
for (const auto &listener : listeners_) {
listener.second->OnSessionCreated(castSession);
}
}
void CastSessionManagerService::ReportDeviceOffline(const std::string &deviceId)
{
SharedRLock lock(mutex_);
for (const auto &listener : listeners_) {
listener.second->OnDeviceOffline(deviceId);
}
}
void CastSessionManagerService::CastEngineClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
CLOGD("Client died, need release resources, client pid_: %d", pid_);
sptr<CastSessionManagerService> service = service_.promote();
if (service == nullptr) {
CLOGE("ServiceStub is nullptr");
return;
}
service->ReleaseServiceResources(pid_);
}
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,232 @@
/*
* Copyright (c) 2023 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
*
* Description: supply cast session manager service stub class.
* Author: zhangge
* Create: 2022-5-29
*/
#include "cast_session_manager_service_stub.h"
#include "cast_engine_common_helper.h"
#include "cast_engine_log.h"
#include "cast_service_listener_impl_proxy.h"
#include "permission.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
DEFINE_CAST_ENGINE_LABEL("Cast-Service");
int CastSessionManagerServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
RETRUEN_IF_WRONG_TASK(code, data, reply, option);
return EXECUTE_SINGLE_STUB_TASK(code, data, reply);
}
CastSessionManagerServiceStub::CastSessionManagerServiceStub()
{
FILL_SINGLE_STUB_TASK(REGISTER_LISTENER, &CastSessionManagerServiceStub::DoRegisterListenerTask);
FILL_SINGLE_STUB_TASK(UNREGISTER_LISTENER, &CastSessionManagerServiceStub::DoUnregisterListenerTask);
FILL_SINGLE_STUB_TASK(RELEASE, &CastSessionManagerServiceStub::DoReleaseTask);
FILL_SINGLE_STUB_TASK(SET_LOCAL_DEVICE, &CastSessionManagerServiceStub::DoSetLocalDeviceTask);
FILL_SINGLE_STUB_TASK(CREATE_CAST_SESSION, &CastSessionManagerServiceStub::DoCreateCastSessionTask);
FILL_SINGLE_STUB_TASK(SET_SINK_SESSION_CAPACITY, &CastSessionManagerServiceStub::DoSetSinkSessionCapacityTask);
FILL_SINGLE_STUB_TASK(START_DISCOVERY, &CastSessionManagerServiceStub::DoStartDiscoveryTask);
FILL_SINGLE_STUB_TASK(SET_DISCOVERABLE, &CastSessionManagerServiceStub::DoSetDiscoverableTask);
FILL_SINGLE_STUB_TASK(STOP_DISCOVERY, &CastSessionManagerServiceStub::DoStopDiscoveryTask);
FILL_SINGLE_STUB_TASK(GET_CAST_SESSION, &CastSessionManagerServiceStub::DoGetCastSessionTask);
}
CastSessionManagerServiceStub::~CastSessionManagerServiceStub()
{
CLOGD("destructor in");
}
int32_t CastSessionManagerServiceStub::DoRegisterListenerTask(MessageParcel &data, MessageParcel &reply)
{
if (!Permission::CheckMirrorPermission() && !Permission::CheckStreamPermission() &&
!Permission::CheckPidPermission()) {
return ERR_UNKNOWN_TRANSACTION;
}
sptr<IRemoteObject> obj = data.ReadRemoteObject();
if (obj == nullptr) {
return ERR_NULL_OBJECT;
}
sptr<ICastServiceListenerImpl> listener{ new (std::nothrow) CastServiceListenerImplProxy(obj) };
if (listener == nullptr) {
CLOGE("RegisterListener failed, listener is null");
}
if (!reply.WriteInt32(RegisterListener(listener))) {
CLOGE("Failed to write int value");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoUnregisterListenerTask(MessageParcel &data, MessageParcel &reply)
{
if (!reply.WriteInt32(UnregisterListener())) {
CLOGE("Failed to write int value");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoReleaseTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(data);
if (!Permission::CheckMirrorPermission() && !Permission::CheckStreamPermission()) {
return ERR_UNKNOWN_TRANSACTION;
}
if (!reply.WriteInt32(Release())) {
CLOGE("Failed to write int value");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoSetLocalDeviceTask(MessageParcel &data, MessageParcel &reply)
{
if (!Permission::CheckMirrorPermission()) {
return ERR_UNKNOWN_TRANSACTION;
}
auto device = ReadCastLocalDevice(data);
if (device == nullptr) {
CLOGE("Invalid device object comes");
return ERR_INVALID_DATA;
}
if (!reply.WriteInt32(SetLocalDevice(*device))) {
CLOGE("Failed to write int value");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoCreateCastSessionTask(MessageParcel &data, MessageParcel &reply)
{
if (!Permission::CheckMirrorPermission() && !Permission::CheckStreamPermission()) {
return ERR_UNKNOWN_TRANSACTION;
}
auto property = ReadCastSessionProperty(data);
if (property == nullptr) {
CLOGE("Invalid property object comes");
return ERR_INVALID_DATA;
}
sptr<ICastSessionImpl> sessionStub;
int32_t ret = CreateCastSession(*property, sessionStub);
if (sessionStub == nullptr) {
return IPC_STUB_ERR;
}
if (!reply.WriteInt32(ret)) {
CLOGE("Failed to write ret:%d", ret);
return IPC_STUB_WRITE_PARCEL_ERR;
}
if (!reply.WriteRemoteObject(sessionStub->AsObject())) {
CLOGE("Failed to write cast session");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoSetSinkSessionCapacityTask(MessageParcel &data, MessageParcel &reply)
{
static_cast<void>(reply);
if (!Permission::CheckMirrorPermission()) {
return ERR_UNKNOWN_TRANSACTION;
}
int32_t capacity = data.ReadInt32();
int32_t ret = SetSinkSessionCapacity(capacity);
if (!reply.WriteInt32(ret)) {
CLOGE("Failed to write ret:%d", ret);
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoStartDiscoveryTask(MessageParcel &data, MessageParcel &reply)
{
if (!Permission::CheckMirrorPermission() && !Permission::CheckStreamPermission()) {
return ERR_UNKNOWN_TRANSACTION;
}
int32_t type = data.ReadInt32();
if (!IsProtocolType(type)) {
CLOGE("Invalid protocol type comes, %{public}d", type);
return ERR_INVALID_DATA;
}
if (!reply.WriteInt32(StartDiscovery(type))) {
CLOGE("Failed to write int value");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoSetDiscoverableTask(MessageParcel &data, MessageParcel &reply)
{
if (!Permission::CheckMirrorPermission() && !Permission::CheckStreamPermission()) {
return ERR_UNKNOWN_TRANSACTION;
}
bool enable = data.ReadBool();
if (!reply.WriteInt32(SetDiscoverable(enable))) {
CLOGE("Failed to write int value");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoStopDiscoveryTask(MessageParcel &data, MessageParcel &reply)
{
if (!Permission::CheckMirrorPermission() && !Permission::CheckStreamPermission()) {
return ERR_UNKNOWN_TRANSACTION;
}
if (!reply.WriteInt32(StopDiscovery())) {
CLOGE("Failed to write int value");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
int32_t CastSessionManagerServiceStub::DoGetCastSessionTask(MessageParcel &data, MessageParcel &reply)
{
sptr<ICastSessionImpl> sessionStub;
int32_t ret = GetCastSession(data.ReadString(), sessionStub);
if (sessionStub == nullptr) {
return IPC_STUB_ERR;
}
if (!reply.WriteInt32(ret)) {
CLOGE("Failed to write ret:%d", ret);
return IPC_STUB_WRITE_PARCEL_ERR;
}
if (!reply.WriteRemoteObject(sessionStub->AsObject())) {
CLOGE("Failed to write cast session");
return IPC_STUB_WRITE_PARCEL_ERR;
}
return ERR_NONE;
}
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS

View File

@ -0,0 +1,46 @@
# Copyright (c) 2023 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
#
import("//foundation/CastEngine/castengine_cast_framework/cast_engine.gni")
config("cast_discovery_config") {
include_dirs = [ "include" ]
}
ohos_static_library("cast_discovery") {
sources = [
"src/cast_device_data_manager.cpp",
"src/connection_manager.cpp",
"src/discovery_manager.cpp",
]
configs = [
":cast_discovery_config",
"${cast_engine_root}:cast_engine_default_config",
]
include_dirs = [
"${cast_engine_interfaces}/inner_api/include",
"//third_party/json/single_include/nlohmann",
]
public_configs = [ ":cast_discovery_config" ]
deps = [ "${cast_engine_common}:cast_engine_common_sources" ]
external_deps = [
"c_utils:utils",
"device_manager:devicemanagersdk",
"dsoftbus:softbus_client",
"hilog:libhilog",
"hisysevent:libhisysevent",
]
subsystem_name = "castplus"
part_name = "cast_engine"
}

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2023 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
*
* Description: cast device data management
* Author: zhangge
* Create: 2022-10-15
*/
#ifndef CAST_DEVICE_DATA_MANAGE_H
#define CAST_DEVICE_DATA_MANAGE_H
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <vector>
#include "cast_service_common.h"
#include "device_manager.h"
using OHOS::DistributedHardware::DmDeviceInfo;
namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
enum class RemoteDeviceState {
UNKNOWN,
FOUND,
CONNECTING,
CONNECTED,
};
class CastDeviceDataManager final {
public:
static CastDeviceDataManager &GetInstance();
~CastDeviceDataManager() = default;
bool AddDevice(const CastInnerRemoteDevice &device, const DmDeviceInfo &dmDeviceInfo);
bool HasDevice(const std::string &deviceId);
bool UpdateDevice(const CastInnerRemoteDevice &device);
void RemoveDevice(const std::string &deviceId);
std::optional<CastInnerRemoteDevice> GetDeviceByDeviceId(const std::string &deviceId);
std::optional<CastInnerRemoteDevice> GetDeviceByTransId(int sessionId);
std::optional<DmDeviceInfo> GetDmDevice(const std::string &deviceId);
bool SetDeviceTransId(const std::string &deviceId, int transportId);
int GetDeviceTransId(const std::string &deviceId);
int ResetDeviceTransId(const std::string &deviceId);
bool SetDeviceRole(const std::string &deviceId, bool isSink);
std::optional<bool> GetDeviceRole(const std::string &deviceId);
bool SetDeviceNetworkId(const std::string &deviceId, const std::string &networkId);
std::optional<std::string> GetDeviceNetworkId(const std::string &deviceId);
bool SetDeviceIsActiveAuth(const std::string &deviceId, bool isActiveAuth);
std::optional<bool> GetDeviceIsActiveAuth(const std::string &deviceId);
bool SetDeviceState(const std::string &deviceId, RemoteDeviceState state);
RemoteDeviceState GetDeviceState(const std::string &deviceId);
bool IsDeviceConnected(const std::string &deviceId);
bool IsDeviceConnecting(const std::string &deviceId);
bool IsDeviceUsed(const std::string &deviceId);
int GetSessionIdByDeviceId(const std::string &deviceId);
private:
struct DeviceInfoCollection {
CastInnerRemoteDevice device;
DmDeviceInfo dmDeviceInfo;
RemoteDeviceState state{ RemoteDeviceState::UNKNOWN };
std::string networkId;
int localSessionId{ INVALID_ID };
int transportId{ INVALID_ID };
bool isActiveAuth{ false };
bool isSink{ false };
};
CastDeviceDataManager() = default;
std::vector<DeviceInfoCollection>::iterator GetDeviceLocked(const std::string &deviceId);
void RemoveDeivceLocked(const std::string &deviceId);
RemoteDeviceState GetDeviceStateLocked(const std::string &deviceId);
bool HasDeviceLocked(const std::string &deviceId);
std::mutex mutex_;
std::vector<DeviceInfoCollection> devices_;
};
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS
#endif

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2023 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
*
* Description: implement the cast source connect
* Author: zhangge
* Create: 2022-08-23
*/
#ifndef CONNECTION_MANAGER_H
#define CONNECTION_MANAGER_H
#include <map>
#include <mutex>
#include <optional>
#include <string>
#include "cast_device_data_manager.h"
#include "cast_engine_common.h"
#include "cast_engine_log.h"
#include "cast_service_common.h"
#include "device_manager.h"
#include "session.h"
namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
using OHOS::DistributedHardware::AuthenticateCallback;
using OHOS::DistributedHardware::DeviceStateCallback;
using OHOS::DistributedHardware::DmDeviceInfo;
class CastAuthenticateCallback : public AuthenticateCallback {
public:
void OnAuthResult(const std::string &deviceId, const std::string &token, int32_t status, int32_t reason) override;
};
class IConnectionManagerListener {
public:
IConnectionManagerListener() = default;
virtual ~IConnectionManagerListener() = default;
virtual int NotifySessionIsReady() = 0;
virtual void NotifyDeviceIsOffline(const std::string &deviceId) = 0;
virtual bool NotifyRemoteDeviceIsReady(int castSessionId, const CastInnerRemoteDevice &device) = 0;
virtual void OnError(const std::string &deviceId) = 0;
};
class ConnectionManager {
public:
static ConnectionManager &GetInstance();
void Init(std::shared_ptr<IConnectionManagerListener> listener);
void Deinit();
bool IsDeviceTrusted(const std::string &deviceId, std::string &networkId);
bool EnableDiscoverable();
bool DisableDiscoverable();
bool OpenConsultSession(const std::string &deviceId);
void OnConsultDataReceived(int transportId, const void *data, unsigned int dataLen);
void OnConsultSessionOpened(int transportId, bool isSource);
bool ConnectDevice(const CastInnerRemoteDevice &dev);
void DisconnectDevice(const std::string &deviceId);
bool UpdateDeviceState(const std::string &deviceId, RemoteDeviceState state);
std::unique_ptr<CastLocalDevice> GetLocalDeviceInfo();
void NotifySessionIsReady(int transportId);
void NotifyDeviceIsOffline(const std::string &deviceId);
void ReportErrorByListener(const std::string &deviceId);
private:
bool AuthenticateDevice(const std::string &deviceId);
void SendConsultData(const CastInnerRemoteDevice &device);
void DestroyConsulationSession(const std::string &deviceId);
int GetCastSessionId(int transportId);
std::unique_ptr<CastInnerRemoteDevice> GetRemoteFromJsonData(const std::string &Data);
void SetListener(std::shared_ptr<IConnectionManagerListener> listener);
bool HasListener();
void ResetListener();
std::mutex mutex_;
std::shared_ptr<IConnectionManagerListener> listener_;
std::map<int, int> transIdToCastSessionIdMap_;
bool isDiscoverable_{ false };
};
class CastDeviceStateCallback : public DeviceStateCallback {
public:
void OnDeviceOnline(const DmDeviceInfo &deviceInfo) override;
void OnDeviceOffline(const DmDeviceInfo &deviceInfo) override;
void OnDeviceChanged(const DmDeviceInfo &deviceInfo) override;
void OnDeviceReady(const DmDeviceInfo &deviceInfo) override;
};
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS
#endif // CONNECTION_MANAGER_H

Some files were not shown because too many files have changed in this diff Show More