• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "wfd_sink_demo.h"
17 #include <cstdint>
18 #include <iostream>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 #include "common/sharing_log.h"
23 #include "extend/magic_enum/magic_enum.hpp"
24 #include "impl/scene/wfd/wfd_def.h"
25 #include "interaction/interprocess/client_factory.h"
26 #include "surface_utils.h"
27 #include "utils/utils.h"
28 #include "windowmgr/include/window_manager.h"
29 
30 using namespace OHOS::Sharing;
31 
32 VideoFormat DEFAULT_VIDEO_FORMAT = VideoFormat::VIDEO_1920X1080_30;
33 AudioFormat DEFAULT_AUDIO_FORMAT = AudioFormat::AUDIO_48000_16_2;
34 std::vector<std::pair<int32_t, int32_t>> position{{0, 0}, {960, 0}, {0, 540}, {960, 540}};
35 
36 constexpr uint32_t DEFAULT_WIDTH = 1280;
37 constexpr uint32_t DEFAULT_HEIGHT = 720;
38 
WfdSinkDemo()39 WfdSinkDemo::WfdSinkDemo()
40 {
41     listener_ = std::make_shared<WfdSinkDemoListener>();
42     if (!listener_)
43         printf("create WfdSinkDemoListener failed");
44 }
45 
GetClient()46 std::shared_ptr<WfdSink> WfdSinkDemo::GetClient()
47 {
48     return client_;
49 }
50 
CreateClient()51 bool WfdSinkDemo::CreateClient()
52 {
53     client_ = WfdSinkFactory::CreateSink(0, "wfd_sink_demo");
54     if (!client_) {
55         printf("create wfdsink client error");
56         return false;
57     }
58     if (listener_) {
59         listener_->SetListener(shared_from_this());
60         client_->SetListener(listener_);
61         return true;
62     } else {
63         printf("Listener is nullptr");
64         return false;
65     }
66 }
67 
SetDiscoverable(bool enable)68 bool WfdSinkDemo::SetDiscoverable(bool enable)
69 {
70     if (!client_) {
71         int ret = 0;
72         if (enable) {
73             ret = client_->Start();
74         } else {
75             ret = client_->Stop();
76         }
77         if (ret == 0) {
78             printf("start or stop p2p success");
79             return true;
80         }
81     }
82     printf("start or stop failed");
83     return false;
84 }
85 
GetConfig()86 bool WfdSinkDemo::GetConfig()
87 {
88     return true;
89 }
90 
Start()91 bool WfdSinkDemo::Start()
92 {
93     printf("enter start");
94     if (!client_) {
95         printf("client is nullptr");
96         return false;
97     }
98     if (client_->Start() == -1) {
99         printf("sink start error");
100         return false;
101     }
102     return true;
103 }
104 
Stop()105 bool WfdSinkDemo::Stop()
106 {
107     if (client_->Stop() == -1) {
108         printf("sink stop error");
109         return false;
110     }
111     return true;
112 }
113 
AppendSurface(std::string deviceId)114 bool WfdSinkDemo::AppendSurface(std::string deviceId)
115 {
116     uint64_t surfaceId = 0;
117     for (auto item : surfaceUsing_) {
118         if (!item.second) {
119             surfaceId = item.first;
120             surfaceUsing_[surfaceId] = true;
121         }
122     }
123     if (surfaceId == 0 && wdnum_ < 4) {
124         // window1
125         printf("create window enter");
126         WindowProperty::Ptr windowPropertyPtr = std::make_shared<WindowProperty>();
127         windowPropertyPtr->height = DEFAULT_HEIGHT;
128         windowPropertyPtr->width = DEFAULT_WIDTH;
129         windowPropertyPtr->startX = position[wdnum_].first;
130         windowPropertyPtr->startY = position[wdnum_].second;
131         windowPropertyPtr->isFull = false;
132         windowPropertyPtr->isShow = true;
133         ++wdnum_;
134         int32_t windowId = WindowManager::GetInstance().CreateWindow(windowPropertyPtr);
135         sptr<Surface> surface = WindowManager::GetInstance().GetSurface(windowId);
136         surfaceId = surface->GetUniqueId();
137         int ret = SurfaceUtils::GetInstance()->Add(surfaceId, surface);
138         if (ret != 0)
139             printf("add failed");
140         surfaceUsing_.emplace(surfaceId, true);
141         surfaces_.push_back(surface);
142     }
143     printf("surfaceId: %llu", surfaceId);
144     if (client_->AppendSurface(deviceId, surfaceId) == -1) {
145         printf("SetSurface error");
146         return false;
147     }
148     surfaceDevMap_[surfaceId] = deviceId;
149     return true;
150 }
151 
RemoveSurface(std::string deviceId,std::string surfaceId)152 bool WfdSinkDemo::RemoveSurface(std::string deviceId, std::string surfaceId)
153 {
154     uint64_t surfaceUintId = std::stoull(surfaceId);
155     if (client_->RemoveSurface(deviceId, surfaceUintId) != 0) {
156         printf("delete surface:%llu failed", surfaceUintId);
157         return false;
158     }
159     return true;
160 }
161 
SetMediaFormat(std::string deviceId,VideoFormat videoFormatId,AudioFormat audioFormatId)162 bool WfdSinkDemo::SetMediaFormat(std::string deviceId, VideoFormat videoFormatId, AudioFormat audioFormatId)
163 {
164     CodecAttr videoAttr;
165     videoAttr.codecType = CodecId::CODEC_H264;
166     videoAttr.formatId = videoFormatId;
167     CodecAttr audioAttr;
168     audioAttr.codecType = CodecId::CODEC_AAC;
169     audioAttr.formatId = audioFormatId;
170 
171     if (client_->SetMediaFormat(deviceId, videoAttr, audioAttr) == -1) {
172         printf("SetVideoFormat error, surfaceId: %s", deviceId.c_str());
173         return false;
174     }
175     return true;
176 }
177 
SetSceneType(std::string deviceId,std::string surfaceId,SceneType sceneType)178 bool WfdSinkDemo::SetSceneType(std::string deviceId, std::string surfaceId, SceneType sceneType)
179 {
180     uint64_t stringUintId = std::stoull(surfaceId);
181     if (client_->SetSceneType(deviceId, stringUintId, sceneType) == -1) {
182         printf("SetSceneType error, surfaceId: %s", deviceId.c_str());
183         return false;
184     }
185     return true;
186 }
187 
Mute(std::string deviceId)188 bool WfdSinkDemo::Mute(std::string deviceId)
189 {
190     if (client_->Mute(deviceId) == -1) {
191         printf("Mute error, deviceId: %s", deviceId.c_str());
192         return false;
193     }
194     return true;
195 }
196 
UnMute(std::string deviceId)197 int32_t WfdSinkDemo::UnMute(std::string deviceId)
198 {
199     if (client_->UnMute(deviceId) == -1) {
200         printf("UnMute error, deviceId: %s", deviceId.c_str());
201         return false;
202     }
203     return true;
204 }
205 
AddDevice(const std::string deviceId)206 void WfdSinkDemo::AddDevice(const std::string deviceId)
207 {
208     devices_.push_back(deviceId);
209 }
210 
RemoveDevice(const std::string deviceId)211 void WfdSinkDemo::RemoveDevice(const std::string deviceId)
212 {
213     printf("remove device: %s", deviceId.c_str());
214     for (uint32_t i = 0; i < devices_.size(); i++)
215         if (devices_[i] == deviceId) {
216             devices_.erase(devices_.begin() + i);
217         }
218     for (auto item : surfaceDevMap_) {
219         if (item.second == deviceId) {
220             printf("free surfacId: %llu", item.first);
221             surfaceUsing_[item.first] = false;
222         }
223     }
224 }
225 
ListDevices()226 void WfdSinkDemo::ListDevices()
227 {
228     printf("The connected devices:");
229     for (auto str : devices_) {
230         printf("device : %s", str.c_str());
231     }
232 }
233 
Play(std::string deviceId)234 bool WfdSinkDemo::Play(std::string deviceId)
235 {
236     if (client_->Play(deviceId) == -1) {
237         printf("play error, deviceId: %s", deviceId.c_str());
238         return false;
239     }
240     return true;
241 }
242 
Pause(std::string deviceId)243 bool WfdSinkDemo::Pause(std::string deviceId)
244 {
245     if (client_->Pause(deviceId) == -1) {
246         printf("Pause error, deviceId: %s", deviceId.c_str());
247         return false;
248     }
249     return true;
250 }
251 
Close(std::string deviceId)252 bool WfdSinkDemo::Close(std::string deviceId)
253 {
254     RemoveDevice(deviceId);
255     if (client_->Close(deviceId) == -1) {
256         printf("close error, deviceId: %s", deviceId.c_str());
257         return false;
258     }
259     return true;
260 }
261 
DoCmd(std::string cmd)262 void WfdSinkDemo::DoCmd(std::string cmd)
263 {
264     const std::map<std::string, int> cmd2index = {
265         {"GetConfig", 1},   {"Start", 2},          {"Stop", 3},          {"SetMediaFormat", 4}, {"Play", 5},
266         {"Pause", 6},       {"Close", 7},          {"Mute", 8},          {"UnMute", 9},         {"SetSceneType", 10},
267         {"ListDevice", 11}, {"AppendSurface", 12}, {"RemoveSurface", 13}};
268 
269     if (cmd2index.count(cmd) == 0) {
270         printf("command: %s not found", cmd.c_str());
271         return;
272     }
273     printf("enter commond, the commond is %s, the id is %d", cmd.c_str(), cmd2index.at(cmd));
274     std::string input;
275     std::string deviceId;
276     std::string surfaceId;
277     VideoFormat videoFormatId = VIDEO_1920X1080_30;
278     AudioFormat audioFormatId = AUDIO_48000_16_2;
279     SceneType sceneType = FOREGROUND;
280     // input params
281     switch (cmd2index.at(cmd)) {
282         case 5:  // play
283         case 6:  // pause
284         case 7:  // close
285         case 8:  // mute
286         case 9:  // unmute
287         case 12: // AppendSurface
288             printf("please input deviceId:");
289             getline(std::cin, input);
290             if (input != "") {
291                 deviceId = input;
292             }
293             break;
294         case 10: // SetSceneType
295             printf("please input deviceId:");
296             getline(std::cin, input);
297             if (input != "") {
298                 deviceId = input;
299             }
300             printf("please input surfaceId:");
301             getline(std::cin, input);
302             if (input != "") {
303                 surfaceId = input;
304             }
305             printf("please input scenetype: default for 0, (0: FOREGROUND, 1: BACKGROUND)");
306             getline(std::cin, input);
307             if (input != "") {
308                 sceneType = static_cast<SceneType>(atoi(input.c_str()));
309             }
310             break;
311         case 4: // SetMediaFormat
312             printf("please input deviceId:");
313             getline(std::cin, input);
314             if (input != "") {
315                 deviceId = input;
316             }
317             getline(std::cin, input);
318             if (input != "") {
319                 videoFormatId = static_cast<VideoFormat>(atoi(input.c_str()));
320             }
321             getline(std::cin, input);
322             if (input != "") {
323                 audioFormatId = static_cast<AudioFormat>(atoi(input.c_str()));
324             }
325             break;
326         case 13: // delsurface
327             printf("please input deviceId:");
328             getline(std::cin, input);
329             if (input != "") {
330                 deviceId = input;
331             }
332             printf("please input surfaceId:");
333             getline(std::cin, input);
334             if (input != "") {
335                 surfaceId = input;
336             }
337             break;
338         default:
339             break;
340     }
341     // execute command
342     switch (cmd2index.at(cmd)) {
343         case 1: // GetConfig
344             if (GetConfig()) {
345                 printf("GetConfig success");
346             }
347             break;
348         case 2: // start
349             if (Start()) {
350                 printf("p2p start success");
351             }
352             break;
353         case 3: // Stop
354             if (Stop()) {
355                 printf("p2p stop success");
356             }
357             break;
358         case 4: // SetMediaFormat
359             if (SetMediaFormat(deviceId, videoFormatId, audioFormatId)) {
360                 printf("Start success");
361             }
362             break;
363         case 5: // Play
364             if (Play(deviceId)) {
365                 printf("Play success");
366             }
367             break;
368         case 6: // Close
369             if (Pause(deviceId)) {
370                 printf("Pause success");
371             }
372             break;
373         case 7: // Close
374             if (Close(deviceId)) {
375                 printf("Close success");
376             }
377             break;
378         case 8: // Mute
379             if (Mute(deviceId)) {
380                 printf("Mute success");
381             }
382             break;
383         case 9: // UnMute
384             if (UnMute(deviceId)) {
385                 printf("UnMute success");
386             }
387             break;
388         case 10: // SetSceneType
389             if (SetSceneType(deviceId, surfaceId, sceneType)) {
390                 printf("UnMute success");
391             }
392             break;
393         case 11: // ListDevice
394             ListDevices();
395             break;
396         case 12:
397             AppendSurface(deviceId);
398             break;
399         case 13:
400             RemoveSurface(deviceId, surfaceId);
401             break;
402         default:
403             break;
404     }
405 }
406 
OnError(uint32_t regionId,uint32_t agentId,SharingErrorCode errorCode)407 void WfdSinkDemoListener::OnError(uint32_t regionId, uint32_t agentId, SharingErrorCode errorCode)
408 {
409     printf("on error. errorCode: %s, %d", std::string(magic_enum::enum_name(errorCode)).c_str(), errorCode);
410 }
411 
OnInfo(std::shared_ptr<BaseMsg> & msg)412 void WfdSinkDemoListener::OnInfo(std::shared_ptr<BaseMsg> &msg)
413 {
414     printf("on Info. msgId: %d", msg->GetMsgId());
415     switch (msg->GetMsgId()) {
416         case WfdConnectionChangedMsg::MSG_ID: {
417             auto data = std::static_pointer_cast<WfdConnectionChangedMsg>(msg);
418             ConnectionInfo info;
419             info.ip = data->ip;
420             info.mac = data->mac;
421             info.state = static_cast<ConnectionState>(data->state);
422             info.surfaceId = data->surfaceId;
423             info.deviceName = data->deviceName;
424             info.primaryDeviceType = data->primaryDeviceType;
425             info.secondaryDeviceType = data->secondaryDeviceType;
426             OnConnectionChanged(info);
427             break;
428         }
429         default:
430             break;
431     }
432 }
433 
OnConnectionChanged(const ConnectionInfo & info)434 void WfdSinkDemoListener::OnConnectionChanged(const ConnectionInfo &info)
435 {
436     auto listener = listener_.lock();
437     if (!listener) {
438         printf("no listener");
439     }
440     switch (info.state) {
441         case ConnectionState::CONNECTED: {
442             listener->AddDevice(info.mac);
443             listener->AppendSurface(info.mac);
444             listener->SetMediaFormat(info.mac, DEFAULT_VIDEO_FORMAT, DEFAULT_AUDIO_FORMAT);
445             listener->Play(info.mac);
446             break;
447         }
448         case ConnectionState::DISCONNECTED: {
449             listener->RemoveDevice(info.mac);
450             break;
451         }
452         default:
453             break;
454     }
455     printf("on OnConnectionChanged. ip: %s, mac: %s, surfaceId: %llu", info.ip.c_str(), info.mac.c_str(),
456            info.surfaceId);
457 }
458 
TestOneByOne()459 int TestOneByOne()
460 {
461     printf("ENTER TEST");
462     std::map<std::string, std::string> cmdMap = {
463         {"1", "GetConfig"}, {"2", "AppendSurface"}, {"3", "SetMediaFormat"}, {"4", "Start"},
464         {"5", "Stop"},      {"6", "ListDevice"},    {"7", "Play"},           {"8", "Pause"},
465         {"9", "Close"},     {"10", "SetSceneType"}, {"11", "Mute"},          {"12", "UnMute"}};
466 
467     std::string helpNotice = "select steps:     0-quit;"
468                              "1-GetConfig;      2-AppendSurface;"
469                              "3-SetMediaFormat; 4-Start;"
470                              "5-Stop;           6-ListDevice;"
471                              "7-Play;           8-Pause;"
472                              "9-Close;          10-SetSceneType;"
473                              "11-Mute;          12-UnMute";
474 
475     std::shared_ptr<WfdSinkDemo> demo = std::make_shared<WfdSinkDemo>();
476     if (!demo->CreateClient()) {
477         printf("create client failed");
478         return -1;
479     }
480     std::string inputCmd;
481     while (1) {
482         printf("%s", helpNotice.c_str());
483         getline(std::cin, inputCmd);
484         if (inputCmd == "") {
485             continue;
486         } else if (inputCmd == "0") {
487             break;
488         } else {
489             if (cmdMap.count(inputCmd) == 0) {
490                 printf("no cmd: %s, input again", inputCmd.c_str());
491                 continue;
492             } else {
493                 demo->DoCmd(cmdMap[inputCmd]);
494             }
495         }
496     }
497 
498     return 0;
499 }
500 
main()501 int main()
502 {
503     printf("wfd sink test start!");
504     TestOneByOne();
505     return 0;
506 }