1/*
2 * Copyright (c) 2021-2022 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 <ctime>
17#include <iostream>
18#include <string>
19
20#include "display_manager_proxy.h"
21#include "screen_manager.h"
22#include "snapshot_utils.h"
23#include "surface_reader.h"
24#include "surface_reader_handler_impl.h"
25
26using namespace OHOS;
27using namespace OHOS::Rosen;
28using namespace OHOS::Media;
29
30namespace {
31const int SLEEP_US = 10 * 1000; // 10ms
32const int MAX_SNAPSHOT_COUNT = 10;
33const int MAX_WAIT_COUNT = 200;
34const float DEFAULT_DENSITY = 2.0;
35const std::string FILE_NAME = "/data/local/tmp/snapshot_virtual_screen";
36}
37
38static ScreenId mainId;
39static ScreenId virtualScreenId;
40
41static VirtualScreenOption InitOption(ScreenId mainId, SurfaceReader& surfaceReader)
42{
43    auto defaultScreen = ScreenManager::GetInstance().GetScreenById(mainId);
44    VirtualScreenOption option = {
45        .name_ = "virtualScreen",
46        .width_ = defaultScreen->GetWidth(),
47        .height_ = defaultScreen->GetHeight(),
48        .density_ = DEFAULT_DENSITY,
49        .surface_ = surfaceReader.GetSurface(),
50        .flags_ = 0,
51        .isForShot_ = true,
52    };
53    return option;
54}
55
56static bool InitMirror(SurfaceReader& surfaceReader)
57{
58    mainId = static_cast<ScreenId>(DisplayManager::GetInstance().GetDefaultDisplayId());
59    if (mainId == SCREEN_ID_INVALID) {
60        std::cout<< "get default display id failed!" << std::endl;
61        return false;
62    }
63    VirtualScreenOption option = InitOption(mainId, surfaceReader);
64    virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(option);
65    std::vector<ScreenId> mirrorIds;
66    mirrorIds.push_back(virtualScreenId);
67    ScreenId screenGroupId = static_cast<ScreenId>(1);
68    ScreenManager::GetInstance().MakeMirror(mainId, mirrorIds, screenGroupId);
69    return true;
70}
71
72int main(int argc, char *argv[])
73{
74    SurfaceReader surfaceReader;
75    sptr<SurfaceReaderHandlerImpl> surfaceReaderHandler = new SurfaceReaderHandlerImpl();
76    if (!surfaceReader.Init()) {
77        std::cout << "surfaceReader init failed!" << std::endl;
78        return 0;
79    }
80    surfaceReader.SetHandler(surfaceReaderHandler);
81    if (!InitMirror(surfaceReader)) {
82        return 0;
83    }
84    int fileIndex = 1;
85    auto startTime = time(nullptr);
86    if (startTime < 0) {
87        std::cout << "startTime error!" << std::endl;
88        return 0;
89    }
90    while (time(nullptr) - startTime < MAX_SNAPSHOT_COUNT) {
91        int waitCount = 0;
92        while (!surfaceReaderHandler->IsImageOk()) {
93            waitCount++;
94            if (waitCount >= MAX_WAIT_COUNT) {
95                std::cout << "wait image overtime" << std::endl;
96                break;
97            }
98            usleep(SLEEP_US);
99        }
100        if (waitCount >= MAX_WAIT_COUNT) {
101            continue;
102        }
103        auto pixelMap = surfaceReaderHandler->GetPixelMap();
104        bool ret = SnapShotUtils::WriteToJpegWithPixelMap(FILE_NAME + std::to_string(fileIndex) + ".jpeg", *pixelMap);
105        if (ret) {
106            std::cout << "snapshot "<< mainId << " write to " <<
107                (FILE_NAME + std::to_string(fileIndex)).c_str() << " as jpeg" << std::endl;
108        } else {
109            std::cout << "snapshot "<< mainId << " write to " <<
110                (FILE_NAME + std::to_string(fileIndex)).c_str() << " failed!" << std::endl;
111        }
112        surfaceReaderHandler->ResetFlag();
113        fileIndex++;
114    }
115    ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId);
116    std::cout << "DestroyVirtualScreen " << virtualScreenId << std::endl;
117    return 0;
118}
119