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 <cstdio>
17#include <image_type.h>
18#include <iosfwd>
19#include <iostream>
20#include <memory>
21#include <ostream>
22#include <refbase.h>
23
24#include "display_manager.h"
25#include "parameters.h"
26#include "snapshot_utils.h"
27
28using namespace OHOS;
29using namespace OHOS::Media;
30using namespace OHOS::Rosen;
31using OHOS::system::GetParameter;
32
33// developer mode
34static const std::string DEVELOPER_MODE_STATE_ON_DEFAULT = "false";
35static const std::string DEVELOPER_MODE_PARAMETER = "const.security.developermode.state";
36static const std::string IS_DEVELOPER_MODE = GetParameter(DEVELOPER_MODE_PARAMETER, DEVELOPER_MODE_STATE_ON_DEFAULT);
37
38static bool GetScreenshotByCmdArguments(CmdArguments& cmdArguments, sptr<Display> display,
39    std::shared_ptr<OHOS::Media::PixelMap>& pixelMap);
40
41int main(int argc, char *argv[])
42{
43    CmdArguments cmdArguments;
44    cmdArguments.fileName = "";
45
46    if (!SnapShotUtils::ProcessArgs(argc, argv, cmdArguments)) {
47        _exit(-1);
48    }
49
50    if (DEVELOPER_MODE_STATE_ON_DEFAULT == IS_DEVELOPER_MODE) {
51        std::cout << "current mode is not developer mode, just return." << std::endl;
52        _exit(-1);
53    }
54
55    auto display = DisplayManager::GetInstance().GetDisplayById(cmdArguments.displayId);
56    if (display == nullptr) {
57        std::cout << "error: GetDisplayById " << cmdArguments.displayId << " error!" << std::endl;
58        _exit(-1);
59    }
60    if (cmdArguments.fileType != "png") {
61        cmdArguments.fileType = "jpeg";
62    }
63
64    std::cout << "process: display " << cmdArguments.displayId << ", file type: " << cmdArguments.fileType <<
65        ", width: " << display->GetWidth() << ", height: " << display->GetHeight() << std::endl;
66
67    // get PixelMap from DisplayManager API
68    std::shared_ptr<OHOS::Media::PixelMap> pixelMap = nullptr;
69    if (!GetScreenshotByCmdArguments(cmdArguments, display, pixelMap)) {
70        _exit(-1);
71    }
72
73    bool ret = false;
74    if (pixelMap != nullptr) {
75        if (cmdArguments.fileType == "png") {
76            ret = SnapShotUtils::SaveSnapShot(cmdArguments.fileName, *pixelMap, cmdArguments.fileType);
77        } else {
78            ret = SnapShotUtils::WriteToJpegWithPixelMap(cmdArguments.fileName, *pixelMap);
79        }
80    }
81    if (!ret) {
82        std::cout << "\nerror: snapshot display " << cmdArguments.displayId <<
83            ", write to " << cmdArguments.fileName << " as jpeg failed!" << std::endl;
84        _exit(-1);
85    }
86
87    std::cout << "\nsuccess: snapshot display " << cmdArguments.displayId << " , write to " <<
88        cmdArguments.fileName << " as " << cmdArguments.fileType << ", width: " << pixelMap->GetWidth() <<
89        ", height: " << pixelMap->GetHeight() << std::endl;
90    _exit(0);
91}
92
93static bool GetScreenshotByCmdArguments(CmdArguments& cmdArguments, sptr<Display> display,
94    std::shared_ptr<OHOS::Media::PixelMap>& pixelMap)
95{
96    if (!cmdArguments.isWidthSet && !cmdArguments.isHeightSet) {
97        pixelMap = DisplayManager::GetInstance().GetScreenshot(cmdArguments.displayId);  // default width & height
98    } else {
99        if (!cmdArguments.isWidthSet) {
100            cmdArguments.width = display->GetWidth();
101            std::cout << "process: reset to display's width " << cmdArguments.width << std::endl;
102        }
103        if (!cmdArguments.isHeightSet) {
104            cmdArguments.height = display->GetHeight();
105            std::cout << "process: reset to display's height " << cmdArguments.height << std::endl;
106        }
107        if (!SnapShotUtils::CheckWidthAndHeightValid(cmdArguments.width, cmdArguments.height)) {
108            std::cout << "error: width " << cmdArguments.width << " height " <<
109            cmdArguments.height << " invalid!" << std::endl;
110            return false;
111        }
112        const Media::Rect rect = {0, 0, display->GetWidth(), display->GetHeight()};
113        const Media::Size size = {cmdArguments.width, cmdArguments.height};
114        constexpr int rotation = 0;
115        pixelMap = DisplayManager::GetInstance().GetScreenshot(cmdArguments.displayId, rect, size, rotation);
116    }
117    return true;
118}