1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <iostream>
17 #include <ctime>
18 
19 #include "avsession_errors.h"
20 #include "avsession_dumper.h"
21 
22 namespace OHOS::AVSession {
23 const int32_t TIME_MAX = 64;
24 const std::string ARGS_HELP = "-h";
25 const std::string ILLEGAL_INFORMATION = "AVSession service, enter '-h' for usage.\n";
26 const std::string ARGS_SHOW_METADATA = "-show_metadata";
27 const std::string ARGS_SHOW_SESSION_INFO = "-show_session_info";
28 const std::string ARGS_SHOW_CONTROLLER_INFO = "-show_controller_info";
29 const std::string ARGS_SHOW_ERROR_INFO = "-show_error_info";
30 const std::string ARGS_TRUSTED_DEVICES_INFO = "-show_trusted_devices_Info";
31 
32 std::map<std::string, AVSessionDumper::DumpActionType> AVSessionDumper::funcMap_ = {
33     { ARGS_SHOW_METADATA, AVSessionDumper::ShowMetaData },
34     { ARGS_SHOW_SESSION_INFO, AVSessionDumper::ShowSessionInfo },
35     { ARGS_SHOW_CONTROLLER_INFO, AVSessionDumper::ShowControllerInfo },
36     { ARGS_SHOW_ERROR_INFO, AVSessionDumper::ShowErrorInfo },
37     { ARGS_TRUSTED_DEVICES_INFO, AVSessionDumper::ShowTrustedDevicesInfo },
38 };
39 
40 std::map<int32_t, std::string> AVSessionDumper::playBackStates_ = {
41     { AVPlaybackState::PLAYBACK_STATE_INITIAL, "initial" },
42     { AVPlaybackState::PLAYBACK_STATE_PREPARE, "preparing" },
43     { AVPlaybackState::PLAYBACK_STATE_PLAY, "playing" },
44     { AVPlaybackState::PLAYBACK_STATE_PAUSE, "paused" },
45     { AVPlaybackState::PLAYBACK_STATE_FAST_FORWARD, "fast_forward" },
46     { AVPlaybackState::PLAYBACK_STATE_REWIND, "rewind" },
47     { AVPlaybackState::PLAYBACK_STATE_STOP, "stop" },
48     { AVPlaybackState::PLAYBACK_STATE_COMPLETED, "complete" },
49     { AVPlaybackState::PLAYBACK_STATE_RELEASED, "released" },
50     { AVPlaybackState::PLAYBACK_STATE_ERROR, "error" },
51     { AVPlaybackState::PLAYBACK_STATE_IDLE, "idle" },
52     { AVPlaybackState::PLAYBACK_STATE_BUFFERING, "buffering" },
53 };
54 
55 std::map<int32_t, std::string> AVSessionDumper::deviceTypeId_ = {
56     {DistributedHardware::DEVICE_TYPE_UNKNOWN, "unknown" },
57     {DistributedHardware::DEVICE_TYPE_WIFI_CAMERA, "camera" },
58     {DistributedHardware::DEVICE_TYPE_AUDIO, "audio" },
59     {DistributedHardware::DEVICE_TYPE_PC, "pc" },
60     {DistributedHardware::DEVICE_TYPE_PHONE, "phone" },
61     {DistributedHardware::DEVICE_TYPE_PAD, "pad" },
62     {DistributedHardware::DEVICE_TYPE_WATCH, "watch" },
63     {DistributedHardware::DEVICE_TYPE_CAR, "car" },
64     {DistributedHardware::DEVICE_TYPE_TV, "tv" },
65 };
66 
67 std::map<int32_t, std::string> AVSessionDumper::loopMode_ = {
68     { AVPlaybackState::LOOP_MODE_SEQUENCE, "sequence" },
69     { AVPlaybackState::LOOP_MODE_SINGLE, "single" },
70     { AVPlaybackState::LOOP_MODE_LIST, "list" },
71     { AVPlaybackState::LOOP_MODE_SHUFFLE, "shuffle" },
72     { AVPlaybackState::LOOP_MODE_CUSTOM, "custom" },
73 };
74 
75 std::vector<std::string> AVSessionDumper::errMessage_ = {};
76 
ShowHelp(std::string & result) const77 void AVSessionDumper::ShowHelp(std::string& result) const
78 {
79     result.append("Usage:dump <command> [options]\n")
80         .append("Description:\n")
81         .append("-show_metadata               :show all avsession metadata in the system\n")
82         .append("-show_session_info           :show information of all sessions\n")
83         .append("-show_controller_info        :show information of all controllers \n")
84         .append("-show_error_info             :show error information about avsession\n")
85         .append("-show_trusted_devices_Info   :show trusted devices Info\n");
86 }
87 
ShowMetaData(std::string & result,const AVSessionService & sessionService)88 void AVSessionDumper::ShowMetaData(std::string& result, const AVSessionService& sessionService)
89 {
90     int32_t controllerIndex = 0;
91     int32_t itemIndex = 0;
92     for (const auto& it : sessionService.controllers_) {
93         result.append("ControllerIndex: " + std::to_string(++controllerIndex) + "\n");
94         for (const auto& item : it.second) {
95             result.append("ItemIndex: " + std::to_string(++itemIndex)+ "\n");
96             AVMetaData metaData;
97             item->GetAVMetaData(metaData);
98 
99             result.append("Metadata:\n");
100             result.append("        assetid              : " + metaData.GetAssetId() + "\n");
101             result.append("        title                : " + metaData.GetTitle() + "\n");
102             result.append("        artist               : " + metaData.GetArtist() + "\n");
103             result.append("        author               : " + metaData.GetAuthor() + "\n");
104             result.append("        avqueue name         : " + metaData.GetAVQueueName() + "\n");
105             result.append("        avqueue id           : " + metaData.GetAVQueueId() + "\n");
106             result.append("        avqueue url          : " + metaData.GetAVQueueImageUri() + "\n");
107             result.append("        album                : " + metaData.GetAlbum() + "\n");
108             result.append("        writer               : " + metaData.GetWriter() + "\n");
109             result.append("        composer             : " + metaData.GetComposer() + "\n");
110             result.append("        duration             : " + std::to_string(metaData.GetDuration()) + "\n");
111             result.append("        media image url      : " + metaData.GetMediaImageUri() + "\n");
112             result.append("        publish date         : " + std::to_string(metaData.GetPublishDate()) + "\n");
113             result.append("        subtitle             : " + metaData.GetSubTitle() + "\n");
114             result.append("        description          : " + metaData.GetDescription() + "\n");
115             result.append("        lyric                : " + metaData.GetLyric() + "\n");
116             result.append("        previous assetid     : " + metaData.GetPreviousAssetId() + "\n");
117             result.append("        next assetid         : " + metaData.GetNextAssetId() + "\n");
118             result.append("        skip intervals       : " + std::to_string(metaData.GetSkipIntervals()) + "\n");
119             result.append("        filter               : " + std::to_string(metaData.GetFilter()) + "\n");
120         }
121     }
122 }
123 
ShowTrustedDevicesInfo(std::string & result,const AVSessionService & sessionService)124 void AVSessionDumper::ShowTrustedDevicesInfo(std::string& result, const AVSessionService& sessionService)
125 {
126     std::vector<OHOS::DistributedHardware::DmDeviceInfo> deviceList;
127     DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList("av_session", "", deviceList);
128 
129     std::string buff;
130     result.append("Trusted Devices Info:\n\n")
131         .append("Count                          : " + std::to_string(deviceList.size()) + "\n");
132     for (const auto& device : deviceList) {
133         buff=device.deviceId;
134         result.append("         device id             : ");
135         result.append(buff + "  ");
136 
137         buff=device.deviceName;
138         result.append("\n        device name            : ");
139         result.append(buff + "  ");
140 
141         result.append("\n        device type id         : " + deviceTypeId_.find(device.deviceTypeId)->second);
142 
143         buff=device.networkId;
144         result.append("\n        network  id            : ");
145         result.append(buff + "  ");
146 
147         result.append("\n        range                  : " + std::to_string(device.range));
148         result.append("\n");
149     }
150 }
151 
ShowSessionInfo(std::string & result,const AVSessionService & sessionService)152 void AVSessionDumper::ShowSessionInfo(std::string& result, const AVSessionService& sessionService)
153 {
154     std::vector<sptr<AVSessionItem>> sessions = sessionService.GetContainer().GetAllSessions();
155     result.append("Session Information:\n\n")
156         .append("Count                        : " + std::to_string(sessions.size()));
157 
158     AVSessionDescriptor descriptor;
159     for (const auto& session : sessions) {
160         descriptor = session->GetDescriptor();
161         std::string isActive = descriptor.isActive_ ? "true" : "false";
162         std::string isTopSession = descriptor.isTopSession_ ? "true" : "false";
163         result.append("\n\ncurrent session id           : " + descriptor.sessionId_ + "\n")
164             .append("State:\n")
165             .append("is active                    : " + isActive + "\n")
166             .append("is the topsession            : " + isTopSession)
167             .append("\n\nConfiguration:\n")
168             .append("pid                          : " + std::to_string(session->GetPid()) + "\n")
169             .append("uid                          : " + std::to_string(session->GetUid()) + "\n");
170         if (descriptor.sessionType_ == AVSession::SESSION_TYPE_AUDIO) {
171             result.append("session type                 : audio\n");
172         } else if (descriptor.sessionType_ == AVSession::SESSION_TYPE_VIDEO) {
173             result.append("session type                 : video\n");
174         } else if (descriptor.sessionType_ == AVSession::SESSION_TYPE_VOICE_CALL) {
175             result.append("session type                 : voice_call\n");
176         } else if (descriptor.sessionType_ == AVSession::SESSION_TYPE_VIDEO_CALL) {
177             result.append("session type                 : video_call\n");
178         } else {
179             result.append("session type is invalid.\n");
180         }
181 
182         result.append("session tag                  : " + descriptor.sessionTag_ + "\n")
183             .append("bundle name                  : " + descriptor.elementName_.GetBundleName() + "\n")
184             .append("ability name                 : " + descriptor.elementName_.GetAbilityName() + "\n");
185 
186         result.append("outputdevice\n")
187             .append("        the count of devices         : " +
188             std::to_string(descriptor.outputDeviceInfo_.deviceInfos_.size()) +
189             "\n        device id                    : ");
190         for (const auto& deviceInfo : descriptor.outputDeviceInfo_.deviceInfos_) {
191             result.append(deviceInfo.deviceId_ + "  ");
192         }
193         result.append("\n        device name                  : ");
194         for (const auto& deviceInfo : descriptor.outputDeviceInfo_.deviceInfos_) {
195             result.append(deviceInfo.deviceName_ + "  ");
196         }
197         result.append("\n\nRelated Controllers:\n")
198             .append("the count of controllers     : " + std::to_string(session->controllers_.size()) + "\n")
199             .append("pid of controllers           : ");
200         for (const auto& it : session->controllers_) {
201             result.append(std::to_string(it.first) + "  ");
202         }
203     }
204 }
205 
ShowControllerInfo(std::string & result,const AVSessionService & sessionService)206 void AVSessionDumper::ShowControllerInfo(std::string& result, const AVSessionService& sessionService)
207 {
208     AVPlaybackState playbackState;
209     std::string temp;
210     int32_t controllerCount = 0;
211     for (const auto& it : sessionService.controllers_) {
212         for (const auto& controller : it.second) {
213             controllerCount++;
214             controller->GetAVPlaybackState(playbackState);
215 
216             int32_t state = playbackState.GetState();
217             double speed = playbackState.GetSpeed();
218             AVPlaybackState::Position position = playbackState.GetPosition();
219             int64_t bufferedTime = playbackState.GetBufferedTime();
220             int32_t loopMode = playbackState.GetLoopMode();
221             std::string isFavorite = playbackState.GetFavorite() ? "true" : "false";
222 
223             temp.append("\n\ncurretn controller pid       : " + std::to_string(controller->GetPid()) + "\n")
224                 .append("State:\n")
225                 .append("state                        : " + playBackStates_.find(state)->second + "\n")
226                 .append("speed                        : " + std::to_string(speed) + "\n")
227                 .append("position\n")
228                 .append("        elapsed time                 : " + std::to_string(position.elapsedTime_) + "\n")
229                 .append("        update time                  : " + std::to_string(position.updateTime_) + "\n")
230                 .append("buffered time                : " + std::to_string(bufferedTime) + "\n")
231                 .append("loopmode                     : " + loopMode_.find(loopMode)->second + "\n")
232                 .append("is favorite                  : " + isFavorite + "\n")
233                 .append("\nRelated Sessionid            : " + controller->GetSessionId());
234         }
235     }
236     result.append("Controller Information:\n\n")
237         .append("Count                        : " + std::to_string(controllerCount))
238         .append(temp);
239 }
240 
SetErrorInfo(const std::string & inErrMsg)241 void AVSessionDumper::SetErrorInfo(const std::string& inErrMsg)
242 {
243     time_t now = time(nullptr);
244     if (now == -1) {
245         SLOGE("get time failed");
246         return;
247     }
248     struct tm *locTime = localtime(&now);
249     if (locTime == nullptr) {
250         SLOGE("get localtime failed");
251         return;
252     }
253     char tempTime [TIME_MAX];
254     auto ret = strftime(tempTime, sizeof(tempTime), "%Y-%m-%d %H:%M:%S", locTime);
255     if (ret == 0) {
256         SLOGE("strftime failed");
257         return;
258     }
259     auto time  = tempTime;
260     std::string msgInfo;
261     msgInfo.append(time + inErrMsg);
262     errMessage_.push_back(msgInfo);
263 }
264 
ShowErrorInfo(std::string & result,const AVSessionService & sessionService)265 void AVSessionDumper::ShowErrorInfo(std::string& result, const AVSessionService& sessionService)
266 {
267     if (errMessage_.empty()) {
268         result.append("No Error Information!\n");
269         return;
270     }
271 
272     int32_t errMsgCount = 0;
273     result.append("Error Information:\n\n");
274     for (auto iter = errMessage_.begin(); iter != errMessage_.end(); iter++) {
275         result.append(errMessage_.at(errMsgCount++) + "\n");
276     }
277 }
278 
ProcessParameter(const std::string & arg,std::string & result,const AVSessionService & sessionService) const279 void AVSessionDumper::ProcessParameter(const std::string& arg, std::string& result,
280                                        const AVSessionService& sessionService) const
281 {
282     if (arg == ARGS_HELP) {
283         ShowHelp(result);
284     } else {
285         auto it = funcMap_.find(arg);
286         if (it != funcMap_.end()) {
287             it->second(result, sessionService);
288         } else {
289             ShowIllegalInfo(result);
290         }
291     }
292 }
293 
ShowIllegalInfo(std::string & result) const294 void AVSessionDumper::ShowIllegalInfo(std::string& result) const
295 {
296     result.append(ILLEGAL_INFORMATION);
297 }
298 
Dump(const std::vector<std::string> & args,std::string & result,const AVSessionService & sessionService) const299 void AVSessionDumper::Dump(const std::vector<std::string>& args, std::string& result,
300     const AVSessionService& sessionService) const
301 {
302     result.clear();
303     auto argsSize = args.size();
304     if (argsSize == 1) {
305         ProcessParameter(args[0], result, sessionService);
306     } else {
307         ShowIllegalInfo(result);
308     }
309 }
310 } // namespace OHOS::AVSession