1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <dlfcn.h>
16 #include <unordered_map>
17
18 #include "avsession_hianalytics_report.h"
19 #include "avsession_errors.h"
20 #include "avsession_log.h"
21 #include "device_manager.h"
22 #include "dm_device_info.h"
23
24
25 namespace OHOS::AVSession {
26 const int32_t CAST_CONNECT_STATE = 6;
27 const int32_t CAST_STREAM = 2;
28 const int32_t DLNA = 4;
29 const int32_t CAST_AND_STREAM = 6;
30 const int32_t CONNECT = 1;
31 const int32_t DISCONNECT = 2;
32 const char *HA_INSTANCE_TAG = "$SceneDataShare";
33 const char *HA_AVCAST_RECOMMEND_ID = "$APP_AVCAST_RECOMMEND";
34 const char *HA_AVCAST_EVENT_ID = "$APP_AVCAST_EVENT";
35 const char *HA_AVCAST_RECORD_ID = "$APP_AVCAST_RECORD";
36 const char *HA_KEY_AVCAST_STATE = "$Status";
37 const char *HA_KEY_PROTOCOL_TYPE = "$ProtocolType";
38 const char *HA_KEY_SRC_BUNDLE_NAME = "$BundleName";
39 const char *HA_KEY_SRC_NETWORK_ID = "$SrcNetworkId";
40 const char *HA_KEY_SRC_DEVICE_ID = "$SrcDeviceId";
41 const char *HA_KEY_SRC_DEVICE_TYPE = "$SrcDeviceType";
42 const char *HA_KEY_SRC_DEVICE_NAME = "$SrcDeviceName";
43 const char *HA_KEY_PEER_NETWORK_ID = "$PeerNetworkId";
44 const char *HA_KEY_PEER_DEVICE_ID = "$PeerDeviceId";
45 const char *HA_KEY_PEER_DEVICE_TYPE = "$PeerDeviceType";
46 const char *HA_KEY_PEER_DEVICE_NAME = "$PeerDeviceName";
47 const char *HA_KEY_AVSESSION_ID = "$SessionId";
48 const char *HA_KEY_AVSESSION_MEDIA_ID = "$MediaId";
49 const char *HA_KEY_AVSESSION_TYPE = "$SessionType";
50 const char *HA_KEY_RESOURCE_DURATION = "$Duration";
51 const char *ON_EVENT = "_ZN4OHOS7HaCloud15HaClientLiteApi7OnEventERKNSt3__h12basic_stringIcNS2_11char_traitsIcEENS2_"
52 "9allocatorIcEEEENS0_13EventTypeLiteESA_RKNS2_13unordered_mapIS8_S8_NS2_4hashIS8_EENS2_8equal_toIS8_EENS6_INS2"
53 "_4pairIS9_S8_EEEEEE";
54 const char *RELEASE = "_ZN4OHOS7HaCloud15HaClientLiteApi7ReleaseEv";
55
GetProtocol(int supportProtocol)56 std::string GetProtocol(int supportProtocol)
57 {
58 switch (supportProtocol) {
59 case CAST_STREAM:
60 case CAST_AND_STREAM:
61 return "CastStream";
62 case DLNA:
63 return "DLNA";
64 default:
65 return "LOCAL";
66 }
67 }
68
ConnectHAClient(std::string eventId,std::unordered_map<std::string,std::string> properties)69 void AVSessionHiAnalyticsReport::ConnectHAClient(std::string eventId,
70 std::unordered_map<std::string, std::string> properties)
71 {
72 SLOGI("ConnectHAClient start");
73 void *haClientHandle = dlopen("libha_client_lite.z.so", RTLD_NOW);
74 CHECK_AND_RETURN_LOG(haClientHandle != nullptr, "dlopen ha_client failed, reason:%{public}sn", dlerror());
75 // get release func
76 void *releaseFunc = dlsym(haClientHandle, RELEASE);
77 if (releaseFunc == nullptr) {
78 SLOGE("dlsm release func failed, reason:%{public}sn", dlerror());
79 dlclose(haClientHandle);
80 return;
81 }
82 void *onHAEventFunc = dlsym(haClientHandle, ON_EVENT);
83 if (onHAEventFunc == nullptr) {
84 SLOGE("dlsm onEvent failed, reason:%{public}sn", dlerror());
85 dlclose(haClientHandle);
86 return;
87 }
88 auto onHAEvent = reinterpret_cast<HaResponseLite(*)(
89 std::string, int32_t, std::string, std::unordered_map<std::string, std::string>)>(onHAEventFunc);
90 onHAEvent(HA_INSTANCE_TAG, 0, eventId, properties);
91 SLOGI("OnHaEvent eventId: %{public}s", eventId.c_str());
92 auto haRelease = reinterpret_cast<HaResponseLite(*)()>(releaseFunc);
93 haRelease();
94 dlclose(haClientHandle);
95 }
96
PublishRecommendInfo(const std::string & bundleName,const std::string & sessionId,const std::string & sessionType,const std::string & assetId,const int32_t duration)97 void AVSessionHiAnalyticsReport::PublishRecommendInfo(const std::string &bundleName, const std::string &sessionId,
98 const std::string &sessionType, const std::string &assetId, const int32_t duration)
99 {
100 std::unordered_map<std::string, std::string> properties;
101 properties.emplace(HA_KEY_SRC_BUNDLE_NAME, bundleName);
102 properties.emplace(HA_KEY_AVSESSION_ID, sessionId);
103 properties.emplace(HA_KEY_AVSESSION_TYPE, sessionType);
104 properties.emplace(HA_KEY_AVSESSION_MEDIA_ID, assetId);
105 properties.emplace(HA_KEY_RESOURCE_DURATION, std::to_string(duration));
106 SLOGI("PublishRecommendInfo: bundleName:%{public}s duration:%{public}d", bundleName.c_str(), duration);
107 ConnectHAClient(HA_AVCAST_RECOMMEND_ID, properties);
108 return;
109 }
110
PublishCastEvent(const std::string & bundleName,const int32_t castState,const DeviceInfo deviceInfo)111 void AVSessionHiAnalyticsReport::PublishCastEvent(const std::string &bundleName, const int32_t castState,
112 const DeviceInfo deviceInfo)
113 {
114 DistributedHardware::DmDeviceInfo dmDeviceInfo;
115 int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo("av_session", dmDeviceInfo);
116 CHECK_AND_RETURN_LOG(ret == 0, "get local deviceInfo failed");
117 std::string localNetworkId = dmDeviceInfo.networkId;
118 std::string localDeviceId = dmDeviceInfo.deviceId;
119 std::unordered_map<std::string, std::string> properties;
120 properties.emplace(HA_KEY_SRC_BUNDLE_NAME, bundleName);
121 properties.emplace(HA_KEY_AVCAST_STATE, std::to_string(castState == CAST_CONNECT_STATE ? CONNECT : DISCONNECT));
122 properties.emplace(HA_KEY_SRC_DEVICE_ID, localDeviceId);
123 properties.emplace(HA_KEY_SRC_NETWORK_ID, localNetworkId);
124 properties.emplace(HA_KEY_PEER_DEVICE_ID, deviceInfo.deviceId_);
125 properties.emplace(HA_KEY_PEER_NETWORK_ID, deviceInfo.networkId_);
126 SLOGI("PublishCastEvent: bundleName:%{public}s castState:%{public}d", bundleName.c_str(), castState);
127 ConnectHAClient(HA_AVCAST_EVENT_ID, properties);
128 return;
129 }
130
PublishCastRecord(const std::string & bundleName,const DeviceInfo deviceInfo)131 void AVSessionHiAnalyticsReport::PublishCastRecord(const std::string &bundleName, const DeviceInfo deviceInfo)
132 {
133 DistributedHardware::DmDeviceInfo dmDeviceInfo;
134 int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo("av_session", dmDeviceInfo);
135 CHECK_AND_RETURN_LOG(ret == 0, "get local deviceInfo failed");
136 std::string localNetworkId = dmDeviceInfo.networkId;
137 std::string localDeviceId = dmDeviceInfo.deviceId;
138 uint16_t localDeviceType = dmDeviceInfo.deviceTypeId;
139 std::string localDeviceName = dmDeviceInfo.deviceName;
140 std::unordered_map<std::string, std::string> properties;
141 properties.emplace(HA_KEY_SRC_BUNDLE_NAME, bundleName);
142 properties.emplace(HA_KEY_PROTOCOL_TYPE, GetProtocol(deviceInfo.supportedProtocols_));
143 properties.emplace(HA_KEY_SRC_DEVICE_ID, localDeviceId);
144 properties.emplace(HA_KEY_SRC_NETWORK_ID, localNetworkId);
145 properties.emplace(HA_KEY_SRC_DEVICE_TYPE, std::to_string(localDeviceType));
146 properties.emplace(HA_KEY_SRC_DEVICE_NAME, localDeviceName);
147 properties.emplace(HA_KEY_PEER_DEVICE_ID, deviceInfo.deviceId_);
148 properties.emplace(HA_KEY_PEER_NETWORK_ID, deviceInfo.networkId_);
149 properties.emplace(HA_KEY_PEER_DEVICE_TYPE, std::to_string(deviceInfo.deviceType_));
150 properties.emplace(HA_KEY_PEER_DEVICE_NAME, deviceInfo.deviceName_);
151 SLOGI("PublishCastRecord: bundleName:%{public}s Protocol:%{public}d",
152 bundleName.c_str(), deviceInfo.supportedProtocols_);
153 ConnectHAClient(HA_AVCAST_RECORD_ID, properties);
154 return;
155 }
156 }
157