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