1/*
2 * Copyright (c) 2022-2024 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
18#include "accesstoken_kit.h"
19#include "display.h"
20#include "display_manager.h"
21#include "dscreen_source_handler.h"
22#include "dscreen_sink_handler.h"
23#include "dscreen_util.h"
24#include "idistributed_hardware_sink.h"
25#include "idistributed_hardware_source.h"
26#include "screen.h"
27#include "screen_client.h"
28#include "screen_client_common.h"
29#include "screen_manager.h"
30#include "wm_common.h"
31#include "window.h"
32#include "window_scene.h"
33#include "window_option.h"
34#include "nativetoken_kit.h"
35#include "token_setproc.h"
36
37#include "decoder_demo.h"
38#include "softbus_bus_center.h"
39#include "softbus_common.h"
40
41using namespace std;
42using namespace OHOS;
43using namespace OHOS::DistributedHardware;
44using namespace OHOS::Rosen;
45using namespace OHOS::MediaAVCodec;
46using namespace OHOS::Security::AccessToken;
47
48namespace {
49    static char const *DSOFTBUS_TOOL_PKG_NAME = "ohos.dsoftbus.tool";
50    const uint32_t MAX_WINDOW_WIDTH = 2560;
51    const uint32_t MAX_WINDOW_HEIGHT = 2772;
52    const uint32_t DCODE_WIDTH = 1920;
53    const uint32_t DCODE_HEIGHT = 1080;
54}
55
56static vector<sptr<Screen>> QueryRemoteScreenInfo()
57{
58    vector<sptr<Screen>> allScreens;
59    ScreenManager::GetInstance().GetAllScreens(allScreens);
60    sptr<Display> defaultDisplay = DisplayManager::GetInstance().GetDefaultDisplay();
61    vector<sptr<Screen>> remoteScreens;
62    for (const auto &screen : allScreens) {
63        if (screen == nullptr) {
64            continue;
65        }
66        if (!screen->IsReal() && screen->GetWidth() > 0) {
67            remoteScreens.push_back(screen);
68        }
69    }
70    cout << "-------------remote screen info---------------" << endl;
71    cout << "remote screen Num: " << remoteScreens.size() << endl;
72    for (const auto &screen : remoteScreens) {
73        if (screen == nullptr) {
74            continue;
75        }
76        cout << endl;
77        cout << "--------screen id " << screen->GetId() << "---------" << endl;
78        cout << "screen name: " << GetAnonyString(screen->GetName()).c_str() << endl;
79        cout << "width: " << screen->GetWidth() << endl;
80        cout << "height: " << screen->GetHeight() << endl;
81        cout << "-------------------------------------------" << endl;
82    }
83    return remoteScreens;
84}
85
86static void StartMirror()
87{
88    vector<sptr<Screen>> remoteScreens = QueryRemoteScreenInfo();
89    if (remoteScreens.size() == 0) {
90        cout << "Error: no remote screens enabled" << endl;
91        return;
92    }
93
94    cout << "select remote screen id to mirror: " << endl;
95    uint64_t mirrorId;
96    cin >> mirrorId;
97
98    bool isMirrorIdValid = false;
99    for (const auto &screen : remoteScreens) {
100        if (screen == nullptr) {
101            continue;
102        }
103        if (screen->GetId() == mirrorId) {
104            isMirrorIdValid = true;
105            break;
106        }
107    }
108
109    if (!isMirrorIdValid) {
110        cout << "input mirrorId is not valid!" << endl;
111        return;
112    }
113
114    sptr<Display> defaultDisplay = DisplayManager::GetInstance().GetDefaultDisplay();
115    cout << "------------start mirror----------" << endl;
116    cout << "mirror screen Id is " << mirrorId << endl;
117    vector<uint64_t> mirrorIds;
118    mirrorIds.push_back(mirrorId);
119    ScreenId screenGroupId;
120    ScreenManager::GetInstance().MakeMirror(defaultDisplay->GetScreenId(), mirrorIds, screenGroupId);
121}
122
123static void StopMirror()
124{
125    vector<sptr<Screen>> remoteScreens = QueryRemoteScreenInfo();
126    if (remoteScreens.size() == 0) {
127        cout << "no remote screens enabled, no need stop mirror" << endl;
128        return;
129    }
130
131    bool isStopMirrorIdValid = false;
132    cout << "select remote screen id to stop mirror: " << endl;
133    uint64_t stopMirrorId;
134    cin >> stopMirrorId;
135
136    for (const auto &screen : remoteScreens) {
137        if (screen == nullptr) {
138            continue;
139        }
140        if (screen->GetId() == stopMirrorId) {
141            isStopMirrorIdValid = true;
142            break;
143        }
144    }
145    if (!isStopMirrorIdValid) {
146        cout << "input screenId is not valid!" << endl;
147        return;
148    }
149
150    cout << "-------------- stop mirror ------------" << endl;
151    cout << "stop mirror screen id is " << stopMirrorId << endl;
152    vector<uint64_t> stopMirrorIds;
153    stopMirrorIds.push_back(stopMirrorId);
154    ScreenManager::GetInstance().RemoveVirtualScreenFromGroup(stopMirrorIds);
155}
156
157static void StartExpand()
158{
159    vector<sptr<Screen>> remoteScreens = QueryRemoteScreenInfo();
160    if (remoteScreens.size() == 0) {
161        cout << "Error: no remote screens enabled" << endl;
162        return;
163    }
164
165    cout << "select remote screen id to expand: " << endl;
166    uint64_t expandId;
167    cin >> expandId;
168
169    bool isExpandIdValid = false;
170    for (const auto &screen : remoteScreens) {
171        if (screen == nullptr) {
172            continue;
173        }
174        if (screen->GetId() == expandId) {
175            isExpandIdValid = true;
176            break;
177        }
178    }
179
180    if (!isExpandIdValid) {
181        cout << "input expandId is not valid!" << endl;
182        return;
183    }
184
185    sptr<Display> defaultDisplay = DisplayManager::GetInstance().GetDefaultDisplay();
186    cout << endl << "------------start expand----------" << endl;
187    cout << "expand screen Id is " << expandId << endl;
188    vector<ExpandOption> options = {{defaultDisplay->GetScreenId(), 0, 0}, {expandId, defaultDisplay->GetWidth(), 0}};
189    ScreenId screenGroupId;
190    ScreenManager::GetInstance().MakeExpand(options, screenGroupId);
191}
192
193static void StopExpand()
194{
195    vector<sptr<Screen>> remoteScreens = QueryRemoteScreenInfo();
196    if (remoteScreens.size() == 0) {
197        cout << "no remote screens enabled, no need stop expand" << endl;
198        return;
199    }
200
201    bool isStopExpandIdValid = false;
202    cout << "select remote screen id to stop expand: " << endl;
203    uint64_t stopExpandId;
204    cin >> stopExpandId;
205
206    for (const auto &screen : remoteScreens) {
207        if (screen == nullptr) {
208            continue;
209        }
210        if (screen->GetId() == stopExpandId) {
211            isStopExpandIdValid = true;
212            break;
213        }
214    }
215    if (!isStopExpandIdValid) {
216        cout << "input screenId is not valid!" << endl;
217        return;
218    }
219
220    cout << "-------------- stop expand ------------" << endl;
221    cout << "stop expand screen id is " << stopExpandId << endl;
222    vector<uint64_t> stopExpandIds;
223    stopExpandIds.push_back(stopExpandId);
224    ScreenManager::GetInstance().RemoveVirtualScreenFromGroup(stopExpandIds);
225}
226
227static void PrintNodeProperty(NodeBasicInfo *nodeInfo)
228{
229    if (nodeInfo == nullptr) {
230        cout << "nodeInfo is nullptr" << endl;
231        return;
232    }
233
234    printf("DeviceName = %s\n", nodeInfo->deviceName);
235    printf("NetworkId = %s\n", GetAnonyString(nodeInfo->networkId).c_str());
236    NodeDeviceInfoKey key = NODE_KEY_UDID;
237    unsigned char udid[UDID_BUF_LEN] = {0};
238    if (GetNodeKeyInfo(DSOFTBUS_TOOL_PKG_NAME, nodeInfo->networkId, key, udid, UDID_BUF_LEN) != 0) {
239        printf("GetNodeKeyInfo Fail!\n");
240    } else {
241        printf("Udid = %s\n", GetAnonyString(reinterpret_cast<char *>(udid)).c_str());
242    }
243    key = NODE_KEY_UUID;
244    unsigned char uuid[UUID_BUF_LEN] = {0};
245    if (GetNodeKeyInfo(DSOFTBUS_TOOL_PKG_NAME, nodeInfo->networkId, key, uuid, UUID_BUF_LEN) != 0) {
246        printf("GetNodeKeyInfo Fail!\n");
247    } else {
248        printf("Uuid = %s\n", GetAnonyString(reinterpret_cast<char *>(udid)).c_str());
249    }
250}
251
252static void QueryRemoteDeviceInfo()
253{
254    uint64_t tokenId;
255    const char *perms[2];
256    perms[0] = OHOS_PERMISSION_DISTRIBUTED_SOFTBUS_CENTER;
257    perms[1] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;
258    NativeTokenInfoParams infoInstance = {
259        .dcapsNum = 0,
260        .permsNum = 2,
261        .aclsNum = 0,
262        .dcaps = NULL,
263        .perms = perms,
264        .acls = NULL,
265        .processName = "dscreen_test_demo",
266        .aplStr = "system_core",
267    };
268    tokenId = GetAccessTokenId(&infoInstance);
269    SetSelfTokenID(tokenId);
270    OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
271
272    NodeBasicInfo localNodeinfo;
273    NodeBasicInfo *remoteNodeInfo = nullptr;
274    int32_t infoNum = 0;
275    printf("-----------Local Device Info------\n");
276    if (GetLocalNodeDeviceInfo(DSOFTBUS_TOOL_PKG_NAME, &localNodeinfo) != 0) {
277        printf("LnnGetLocalNodeInfo Fail!\n");
278        return;
279    }
280    PrintNodeProperty(&localNodeinfo);
281    printf("-------Remote Device info---------\n");
282    if (GetAllNodeDeviceInfo(DSOFTBUS_TOOL_PKG_NAME, &remoteNodeInfo, &infoNum) != 0) {
283        printf("GetAllNodeDeviceInfo Fail!\n");
284        return;
285    }
286    printf("Device Num = %" PRId32 "\n", infoNum);
287    for (int i = 0; i < infoNum; ++i) {
288        printf("\n[No.%" PRId32 "]", i + 1);
289        PrintNodeProperty(remoteNodeInfo + i);
290    }
291    FreeNodeInfo(remoteNodeInfo);
292    printf("SoftBusDumpDeviceInfo complete!\n");
293}
294
295static void CreateWindow()
296{
297    cout << "create window, please input window size" << endl;
298    cout << "width: ";
299    uint32_t windowWidth;
300    cin >> windowWidth;
301    cout << "height: ";
302    uint32_t windowHeight;
303    cin >> windowHeight;
304
305    if (windowWidth == 0 || windowWidth >= MAX_WINDOW_WIDTH ||
306        windowHeight == 0 || windowHeight >= MAX_WINDOW_HEIGHT) {
307        cout << "Invalid window size." << endl;
308        return;
309    }
310
311    sptr<Display> defaultDisplay = DisplayManager::GetInstance().GetDefaultDisplay();
312    shared_ptr<WindowProperty> windowProperty = make_shared<WindowProperty>();
313    windowProperty->displayId = defaultDisplay->GetId();
314    windowProperty->startX = 0;
315    windowProperty->startY = 0;
316    windowProperty->width = windowWidth;
317    windowProperty->height = windowHeight;
318    int32_t windowId = ScreenClient::GetInstance().AddWindow(windowProperty);
319    ScreenClient::GetInstance().ShowWindow(windowId);
320    sptr<Surface> surface = ScreenClient::GetInstance().GetSurface(windowId);
321    cout << "create window success." << endl;
322
323    auto vdec = make_shared<VDecDemo>();
324
325    vdec->SetWindowSize(DCODE_WIDTH, DCODE_HEIGHT);
326    vdec->SetOutputSurface(surface);
327    cout << "start run decoder" << endl;
328    vdec->RunCase();
329    cout << "create window success, window id: " << windowId
330         << ", width: " << windowWidth
331         << ", height: " << windowHeight << endl;
332    ScreenClient::GetInstance().RemoveWindow(windowId);
333    _Exit(0);
334}
335
336int main()
337{
338    cout << "Please select a test scenario number(default StartMirror): " << endl;
339    cout << "0:StartMirror" << endl;
340    cout << "1:StopMirror" << endl;
341    cout << "2:StartExpand" << endl;
342    cout << "3:StopExpand" << endl;
343    cout << "4:CreateWindow" << endl;
344    cout << "5:QueryRemoteDeviceInfo" << endl;
345    cout << "6:QueryRemoteScreenInfo" << endl;
346    string mode;
347    (void)getline(cin, mode);
348    if (mode == "" || mode == "0") {
349        (void)StartMirror();
350    } else if (mode == "1") {
351        (void)StopMirror();
352    } else if (mode == "2") {
353        (void)StartExpand();
354    } else if (mode == "3") {
355        (void)StopExpand();
356    } else if (mode == "4") {
357        (void)CreateWindow();
358    } else if (mode == "5") {
359        (void)QueryRemoteDeviceInfo();
360    } else if (mode == "6") {
361        (void)QueryRemoteScreenInfo();
362    } else {
363        cout << "no that selection" << endl;
364    }
365    return 0;
366}
367