1e0dac50fSopenharmony_ci/*
2e0dac50fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License.
5e0dac50fSopenharmony_ci * You may obtain a copy of the License at
6e0dac50fSopenharmony_ci *
7e0dac50fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0dac50fSopenharmony_ci *
9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and
13e0dac50fSopenharmony_ci * limitations under the License.
14e0dac50fSopenharmony_ci */
15e0dac50fSopenharmony_ci
16e0dac50fSopenharmony_ci#include <ctime>
17e0dac50fSopenharmony_ci#include <iostream>
18e0dac50fSopenharmony_ci#include <string>
19e0dac50fSopenharmony_ci
20e0dac50fSopenharmony_ci#include "display_manager_proxy.h"
21e0dac50fSopenharmony_ci#include "screen_manager.h"
22e0dac50fSopenharmony_ci#include "snapshot_utils.h"
23e0dac50fSopenharmony_ci#include "surface_reader.h"
24e0dac50fSopenharmony_ci#include "surface_reader_handler_impl.h"
25e0dac50fSopenharmony_ci
26e0dac50fSopenharmony_ciusing namespace OHOS;
27e0dac50fSopenharmony_ciusing namespace OHOS::Rosen;
28e0dac50fSopenharmony_ciusing namespace OHOS::Media;
29e0dac50fSopenharmony_ci
30e0dac50fSopenharmony_cinamespace {
31e0dac50fSopenharmony_ciconst int SLEEP_US = 10 * 1000; // 10ms
32e0dac50fSopenharmony_ciconst int MAX_SNAPSHOT_COUNT = 10;
33e0dac50fSopenharmony_ciconst int MAX_WAIT_COUNT = 200;
34e0dac50fSopenharmony_ciconst float DEFAULT_DENSITY = 2.0;
35e0dac50fSopenharmony_ciconst std::string FILE_NAME = "/data/local/tmp/snapshot_virtual_screen";
36e0dac50fSopenharmony_ci}
37e0dac50fSopenharmony_ci
38e0dac50fSopenharmony_cistatic ScreenId mainId;
39e0dac50fSopenharmony_cistatic ScreenId virtualScreenId;
40e0dac50fSopenharmony_ci
41e0dac50fSopenharmony_cistatic VirtualScreenOption InitOption(ScreenId mainId, SurfaceReader& surfaceReader)
42e0dac50fSopenharmony_ci{
43e0dac50fSopenharmony_ci    auto defaultScreen = ScreenManager::GetInstance().GetScreenById(mainId);
44e0dac50fSopenharmony_ci    VirtualScreenOption option = {
45e0dac50fSopenharmony_ci        .name_ = "virtualScreen",
46e0dac50fSopenharmony_ci        .width_ = defaultScreen->GetWidth(),
47e0dac50fSopenharmony_ci        .height_ = defaultScreen->GetHeight(),
48e0dac50fSopenharmony_ci        .density_ = DEFAULT_DENSITY,
49e0dac50fSopenharmony_ci        .surface_ = surfaceReader.GetSurface(),
50e0dac50fSopenharmony_ci        .flags_ = 0,
51e0dac50fSopenharmony_ci        .isForShot_ = true,
52e0dac50fSopenharmony_ci    };
53e0dac50fSopenharmony_ci    return option;
54e0dac50fSopenharmony_ci}
55e0dac50fSopenharmony_ci
56e0dac50fSopenharmony_cistatic bool InitMirror(SurfaceReader& surfaceReader)
57e0dac50fSopenharmony_ci{
58e0dac50fSopenharmony_ci    mainId = static_cast<ScreenId>(DisplayManager::GetInstance().GetDefaultDisplayId());
59e0dac50fSopenharmony_ci    if (mainId == SCREEN_ID_INVALID) {
60e0dac50fSopenharmony_ci        std::cout<< "get default display id failed!" << std::endl;
61e0dac50fSopenharmony_ci        return false;
62e0dac50fSopenharmony_ci    }
63e0dac50fSopenharmony_ci    VirtualScreenOption option = InitOption(mainId, surfaceReader);
64e0dac50fSopenharmony_ci    virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(option);
65e0dac50fSopenharmony_ci    std::vector<ScreenId> mirrorIds;
66e0dac50fSopenharmony_ci    mirrorIds.push_back(virtualScreenId);
67e0dac50fSopenharmony_ci    ScreenId screenGroupId = static_cast<ScreenId>(1);
68e0dac50fSopenharmony_ci    ScreenManager::GetInstance().MakeMirror(mainId, mirrorIds, screenGroupId);
69e0dac50fSopenharmony_ci    return true;
70e0dac50fSopenharmony_ci}
71e0dac50fSopenharmony_ci
72e0dac50fSopenharmony_ciint main(int argc, char *argv[])
73e0dac50fSopenharmony_ci{
74e0dac50fSopenharmony_ci    SurfaceReader surfaceReader;
75e0dac50fSopenharmony_ci    sptr<SurfaceReaderHandlerImpl> surfaceReaderHandler = new SurfaceReaderHandlerImpl();
76e0dac50fSopenharmony_ci    if (!surfaceReader.Init()) {
77e0dac50fSopenharmony_ci        std::cout << "surfaceReader init failed!" << std::endl;
78e0dac50fSopenharmony_ci        return 0;
79e0dac50fSopenharmony_ci    }
80e0dac50fSopenharmony_ci    surfaceReader.SetHandler(surfaceReaderHandler);
81e0dac50fSopenharmony_ci    if (!InitMirror(surfaceReader)) {
82e0dac50fSopenharmony_ci        return 0;
83e0dac50fSopenharmony_ci    }
84e0dac50fSopenharmony_ci    int fileIndex = 1;
85e0dac50fSopenharmony_ci    auto startTime = time(nullptr);
86e0dac50fSopenharmony_ci    if (startTime < 0) {
87e0dac50fSopenharmony_ci        std::cout << "startTime error!" << std::endl;
88e0dac50fSopenharmony_ci        return 0;
89e0dac50fSopenharmony_ci    }
90e0dac50fSopenharmony_ci    while (time(nullptr) - startTime < MAX_SNAPSHOT_COUNT) {
91e0dac50fSopenharmony_ci        int waitCount = 0;
92e0dac50fSopenharmony_ci        while (!surfaceReaderHandler->IsImageOk()) {
93e0dac50fSopenharmony_ci            waitCount++;
94e0dac50fSopenharmony_ci            if (waitCount >= MAX_WAIT_COUNT) {
95e0dac50fSopenharmony_ci                std::cout << "wait image overtime" << std::endl;
96e0dac50fSopenharmony_ci                break;
97e0dac50fSopenharmony_ci            }
98e0dac50fSopenharmony_ci            usleep(SLEEP_US);
99e0dac50fSopenharmony_ci        }
100e0dac50fSopenharmony_ci        if (waitCount >= MAX_WAIT_COUNT) {
101e0dac50fSopenharmony_ci            continue;
102e0dac50fSopenharmony_ci        }
103e0dac50fSopenharmony_ci        auto pixelMap = surfaceReaderHandler->GetPixelMap();
104e0dac50fSopenharmony_ci        bool ret = SnapShotUtils::WriteToJpegWithPixelMap(FILE_NAME + std::to_string(fileIndex) + ".jpeg", *pixelMap);
105e0dac50fSopenharmony_ci        if (ret) {
106e0dac50fSopenharmony_ci            std::cout << "snapshot "<< mainId << " write to " <<
107e0dac50fSopenharmony_ci                (FILE_NAME + std::to_string(fileIndex)).c_str() << " as jpeg" << std::endl;
108e0dac50fSopenharmony_ci        } else {
109e0dac50fSopenharmony_ci            std::cout << "snapshot "<< mainId << " write to " <<
110e0dac50fSopenharmony_ci                (FILE_NAME + std::to_string(fileIndex)).c_str() << " failed!" << std::endl;
111e0dac50fSopenharmony_ci        }
112e0dac50fSopenharmony_ci        surfaceReaderHandler->ResetFlag();
113e0dac50fSopenharmony_ci        fileIndex++;
114e0dac50fSopenharmony_ci    }
115e0dac50fSopenharmony_ci    ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId);
116e0dac50fSopenharmony_ci    std::cout << "DestroyVirtualScreen " << virtualScreenId << std::endl;
117e0dac50fSopenharmony_ci    return 0;
118e0dac50fSopenharmony_ci}
119