• 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     printf("enter stop");
108     if (!client_) {
109         printf("client is nullptr");
110         return false;
111     }
112     if (client_->Stop() == -1) {
113         printf("sink stop error");
114         return false;
115     }
116     return true;
117 }
118 
AppendSurface(std::string deviceId)119 bool WfdSinkDemo::AppendSurface(std::string deviceId)
120 {
121     if (!client_) {
122         printf("client is nullptr");
123         return false;
124     }
125     uint64_t surfaceId = 0;
126     for (auto item : surfaceUsing_) {
127         if (!item.second) {
128             surfaceId = item.first;
129             surfaceUsing_[surfaceId] = true;
130         }
131     }
132     if (surfaceId == 0 && wdnum_ < 4) {
133         // window1
134         printf("create window enter");
135         WindowProperty::Ptr windowPropertyPtr = std::make_shared<WindowProperty>();
136         windowPropertyPtr->height = DEFAULT_HEIGHT;
137         windowPropertyPtr->width = DEFAULT_WIDTH;
138         windowPropertyPtr->startX = position[wdnum_].first;
139         windowPropertyPtr->startY = position[wdnum_].second;
140         windowPropertyPtr->isFull = false;
141         windowPropertyPtr->isShow = true;
142         ++wdnum_;
143         int32_t windowId = WindowManager::GetInstance().CreateWindow(windowPropertyPtr);
144         sptr<Surface> surface = WindowManager::GetInstance().GetSurface(windowId);
145         surfaceId = surface->GetUniqueId();
146         int ret = SurfaceUtils::GetInstance()->Add(surfaceId, surface);
147         if (ret != 0)
148             printf("add failed");
149         surfaceUsing_.emplace(surfaceId, true);
150         surfaces_.push_back(surface);
151     }
152     printf("surfaceId: %llu", surfaceId);
153     if (client_->AppendSurface(deviceId, surfaceId) == -1) {
154         printf("SetSurface error");
155         return false;
156     }
157     surfaceDevMap_[surfaceId] = deviceId;
158     return true;
159 }
160 
RemoveSurface(std::string deviceId,std::string surfaceId)161 bool WfdSinkDemo::RemoveSurface(std::string deviceId, std::string surfaceId)
162 {
163     if (!client_) {
164         printf("client is nullptr");
165         return false;
166     }
167     uint64_t surfaceUintId = std::stoull(surfaceId);
168     if (client_->RemoveSurface(deviceId, surfaceUintId) != 0) {
169         printf("delete surface:%llu failed", surfaceUintId);
170         return false;
171     }
172     return true;
173 }
174 
SetMediaFormat(std::string deviceId,VideoFormat videoFormatId,AudioFormat audioFormatId)175 bool WfdSinkDemo::SetMediaFormat(std::string deviceId, VideoFormat videoFormatId, AudioFormat audioFormatId)
176 {
177     if (!client_) {
178         printf("client is nullptr");
179         return false;
180     }
181     CodecAttr videoAttr;
182     videoAttr.codecType = CodecId::CODEC_H264;
183     videoAttr.formatId = videoFormatId;
184     CodecAttr audioAttr;
185     audioAttr.codecType = CodecId::CODEC_AAC;
186     audioAttr.formatId = audioFormatId;
187 
188     if (client_->SetMediaFormat(deviceId, videoAttr, audioAttr) == -1) {
189         printf("SetVideoFormat error, surfaceId: %s", deviceId.c_str());
190         return false;
191     }
192     return true;
193 }
194 
SetSceneType(std::string deviceId,std::string surfaceId,SceneType sceneType)195 bool WfdSinkDemo::SetSceneType(std::string deviceId, std::string surfaceId, SceneType sceneType)
196 {
197     if (!client_) {
198         printf("client is nullptr");
199         return false;
200     }
201     uint64_t stringUintId = std::stoull(surfaceId);
202     if (client_->SetSceneType(deviceId, stringUintId, sceneType) == -1) {
203         printf("SetSceneType error, surfaceId: %s", deviceId.c_str());
204         return false;
205     }
206     return true;
207 }
208 
Mute(std::string deviceId)209 bool WfdSinkDemo::Mute(std::string deviceId)
210 {
211     if (!client_) {
212         printf("client is nullptr");
213         return false;
214     }
215     if (client_->Mute(deviceId) == -1) {
216         printf("Mute error, deviceId: %s", deviceId.c_str());
217         return false;
218     }
219     return true;
220 }
221 
UnMute(std::string deviceId)222 int32_t WfdSinkDemo::UnMute(std::string deviceId)
223 {
224     if (!client_) {
225         printf("client is nullptr");
226         return false;
227     }
228     if (client_->UnMute(deviceId) == -1) {
229         printf("UnMute error, deviceId: %s", deviceId.c_str());
230         return false;
231     }
232     return true;
233 }
234 
AddDevice(const std::string deviceId)235 void WfdSinkDemo::AddDevice(const std::string deviceId)
236 {
237     devices_.push_back(deviceId);
238 }
239 
RemoveDevice(const std::string deviceId)240 void WfdSinkDemo::RemoveDevice(const std::string deviceId)
241 {
242     printf("remove device: %s", deviceId.c_str());
243     for (uint32_t i = 0; i < devices_.size(); i++)
244         if (devices_[i] == deviceId) {
245             devices_.erase(devices_.begin() + i);
246         }
247     for (auto item : surfaceDevMap_) {
248         if (item.second == deviceId) {
249             printf("free surfacId: %llu", item.first);
250             surfaceUsing_[item.first] = false;
251         }
252     }
253 }
254 
ListDevices()255 void WfdSinkDemo::ListDevices()
256 {
257     printf("The connected devices:");
258     for (auto str : devices_) {
259         printf("device : %s", str.c_str());
260     }
261 }
262 
Play(std::string deviceId)263 bool WfdSinkDemo::Play(std::string deviceId)
264 {
265     if (!client_) {
266         printf("client is nullptr");
267         return false;
268     }
269     if (client_->Play(deviceId) == -1) {
270         printf("play error, deviceId: %s", deviceId.c_str());
271         return false;
272     }
273     return true;
274 }
275 
Pause(std::string deviceId)276 bool WfdSinkDemo::Pause(std::string deviceId)
277 {
278     if (!client_) {
279         printf("client is nullptr");
280         return false;
281     }
282     if (client_->Pause(deviceId) == -1) {
283         printf("Pause error, deviceId: %s", deviceId.c_str());
284         return false;
285     }
286     return true;
287 }
288 
Close(std::string deviceId)289 bool WfdSinkDemo::Close(std::string deviceId)
290 {
291     if (!client_) {
292         printf("client is nullptr");
293         return false;
294     }
295     RemoveDevice(deviceId);
296     if (client_->Close(deviceId) == -1) {
297         printf("close error, deviceId: %s", deviceId.c_str());
298         return false;
299     }
300     return true;
301 }
302 
DoCmd(std::string cmd)303 void WfdSinkDemo::DoCmd(std::string cmd)
304 {
305     const std::map<std::string, int> cmd2index = {
306         {"GetConfig", 1},   {"Start", 2},          {"Stop", 3},          {"SetMediaFormat", 4}, {"Play", 5},
307         {"Pause", 6},       {"Close", 7},          {"Mute", 8},          {"UnMute", 9},         {"SetSceneType", 10},
308         {"ListDevice", 11}, {"AppendSurface", 12}, {"RemoveSurface", 13}};
309 
310     if (cmd2index.count(cmd) == 0) {
311         printf("command: %s not found", cmd.c_str());
312         return;
313     }
314     printf("enter commond, the commond is %s, the id is %d", cmd.c_str(), cmd2index.at(cmd));
315     std::string input;
316     std::string deviceId;
317     std::string surfaceId;
318     VideoFormat videoFormatId = VIDEO_1920X1080_30;
319     AudioFormat audioFormatId = AUDIO_48000_16_2;
320     SceneType sceneType = FOREGROUND;
321     // input params
322     switch (cmd2index.at(cmd)) {
323         case 5:  // play
324         case 6:  // pause
325         case 7:  // close
326         case 8:  // mute
327         case 9:  // unmute
328         case 12: // AppendSurface
329             printf("please input deviceId:");
330             getline(std::cin, input);
331             if (input != "") {
332                 deviceId = input;
333             }
334             break;
335         case 10: // SetSceneType
336             printf("please input deviceId:");
337             getline(std::cin, input);
338             if (input != "") {
339                 deviceId = input;
340             }
341             printf("please input surfaceId:");
342             getline(std::cin, input);
343             if (input != "") {
344                 surfaceId = input;
345             }
346             printf("please input scenetype: default for 0, (0: FOREGROUND, 1: BACKGROUND)");
347             getline(std::cin, input);
348             if (input != "") {
349                 sceneType = static_cast<SceneType>(atoi(input.c_str()));
350             }
351             break;
352         case 4: // SetMediaFormat
353             printf("please input deviceId:");
354             getline(std::cin, input);
355             if (input != "") {
356                 deviceId = input;
357             }
358             getline(std::cin, input);
359             if (input != "") {
360                 videoFormatId = static_cast<VideoFormat>(atoi(input.c_str()));
361             }
362             getline(std::cin, input);
363             if (input != "") {
364                 audioFormatId = static_cast<AudioFormat>(atoi(input.c_str()));
365             }
366             break;
367         case 13: // delsurface
368             printf("please input deviceId:");
369             getline(std::cin, input);
370             if (input != "") {
371                 deviceId = input;
372             }
373             printf("please input surfaceId:");
374             getline(std::cin, input);
375             if (input != "") {
376                 surfaceId = input;
377             }
378             break;
379         default:
380             break;
381     }
382     // execute command
383     switch (cmd2index.at(cmd)) {
384         case 1: // GetConfig
385             if (GetConfig()) {
386                 printf("GetConfig success");
387             }
388             break;
389         case 2: // start
390             if (Start()) {
391                 printf("p2p start success");
392             }
393             break;
394         case 3: // Stop
395             if (Stop()) {
396                 printf("p2p stop success");
397             }
398             break;
399         case 4: // SetMediaFormat
400             if (SetMediaFormat(deviceId, videoFormatId, audioFormatId)) {
401                 printf("Start success");
402             }
403             break;
404         case 5: // Play
405             if (Play(deviceId)) {
406                 printf("Play success");
407             }
408             break;
409         case 6: // Close
410             if (Pause(deviceId)) {
411                 printf("Pause success");
412             }
413             break;
414         case 7: // Close
415             if (Close(deviceId)) {
416                 printf("Close success");
417             }
418             break;
419         case 8: // Mute
420             if (Mute(deviceId)) {
421                 printf("Mute success");
422             }
423             break;
424         case 9: // UnMute
425             if (UnMute(deviceId)) {
426                 printf("UnMute success");
427             }
428             break;
429         case 10: // SetSceneType
430             if (SetSceneType(deviceId, surfaceId, sceneType)) {
431                 printf("UnMute success");
432             }
433             break;
434         case 11: // ListDevice
435             ListDevices();
436             break;
437         case 12:
438             AppendSurface(deviceId);
439             break;
440         case 13:
441             RemoveSurface(deviceId, surfaceId);
442             break;
443         default:
444             break;
445     }
446 }
447 
OnError(uint32_t regionId,uint32_t agentId,SharingErrorCode errorCode)448 void WfdSinkDemoListener::OnError(uint32_t regionId, uint32_t agentId, SharingErrorCode errorCode)
449 {
450     printf("on error. errorCode: %s, %d", std::string(magic_enum::enum_name(errorCode)).c_str(), errorCode);
451 }
452 
OnInfo(std::shared_ptr<BaseMsg> & msg)453 void WfdSinkDemoListener::OnInfo(std::shared_ptr<BaseMsg> &msg)
454 {
455     printf("on Info. msgId: %d", msg->GetMsgId());
456     switch (msg->GetMsgId()) {
457         case WfdConnectionChangedMsg::MSG_ID: {
458             auto data = std::static_pointer_cast<WfdConnectionChangedMsg>(msg);
459             ConnectionInfo info;
460             info.ip = data->ip;
461             info.mac = data->mac;
462             info.state = static_cast<ConnectionState>(data->state);
463             info.surfaceId = data->surfaceId;
464             info.deviceName = data->deviceName;
465             info.primaryDeviceType = data->primaryDeviceType;
466             info.secondaryDeviceType = data->secondaryDeviceType;
467             OnConnectionChanged(info);
468             break;
469         }
470         default:
471             break;
472     }
473 }
474 
OnConnectionChanged(const ConnectionInfo & info)475 void WfdSinkDemoListener::OnConnectionChanged(const ConnectionInfo &info)
476 {
477     auto listener = listener_.lock();
478     if (!listener) {
479         printf("no listener");
480         return;
481     }
482     switch (info.state) {
483         case ConnectionState::CONNECTED: {
484             listener->AddDevice(info.mac);
485             listener->AppendSurface(info.mac);
486             listener->SetMediaFormat(info.mac, DEFAULT_VIDEO_FORMAT, DEFAULT_AUDIO_FORMAT);
487             listener->Play(info.mac);
488             break;
489         }
490         case ConnectionState::DISCONNECTED: {
491             listener->RemoveDevice(info.mac);
492             break;
493         }
494         default:
495             break;
496     }
497     printf("on OnConnectionChanged. ip: %s, mac: %s, surfaceId: %llu", info.ip.c_str(), info.mac.c_str(),
498            info.surfaceId);
499 }
500 
TestOneByOne()501 int TestOneByOne()
502 {
503     printf("ENTER TEST");
504     std::map<std::string, std::string> cmdMap = {
505         {"1", "GetConfig"}, {"2", "AppendSurface"}, {"3", "SetMediaFormat"}, {"4", "Start"},
506         {"5", "Stop"},      {"6", "ListDevice"},    {"7", "Play"},           {"8", "Pause"},
507         {"9", "Close"},     {"10", "SetSceneType"}, {"11", "Mute"},          {"12", "UnMute"}};
508 
509     std::string helpNotice = "select steps:     0-quit;"
510                              "1-GetConfig;      2-AppendSurface;"
511                              "3-SetMediaFormat; 4-Start;"
512                              "5-Stop;           6-ListDevice;"
513                              "7-Play;           8-Pause;"
514                              "9-Close;          10-SetSceneType;"
515                              "11-Mute;          12-UnMute";
516 
517     std::shared_ptr<WfdSinkDemo> demo = std::make_shared<WfdSinkDemo>();
518     if (!demo->CreateClient()) {
519         printf("create client failed");
520         return -1;
521     }
522     std::string inputCmd;
523     while (1) {
524         printf("%s", helpNotice.c_str());
525         getline(std::cin, inputCmd);
526         if (inputCmd == "") {
527             continue;
528         } else if (inputCmd == "0") {
529             break;
530         } else {
531             if (cmdMap.count(inputCmd) == 0) {
532                 printf("no cmd: %s, input again", inputCmd.c_str());
533                 continue;
534             } else {
535                 demo->DoCmd(cmdMap[inputCmd]);
536             }
537         }
538     }
539 
540     return 0;
541 }
542 
main()543 int main()
544 {
545     printf("wfd sink test start!");
546     TestOneByOne();
547     return 0;
548 }