17c804472Sopenharmony_ci/* 27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 47c804472Sopenharmony_ci * you may not use this file except in compliance with the License. 57c804472Sopenharmony_ci * You may obtain a copy of the License at 67c804472Sopenharmony_ci * 77c804472Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 87c804472Sopenharmony_ci * 97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127c804472Sopenharmony_ci * See the License for the specific language governing permissions and 137c804472Sopenharmony_ci * limitations under the License. 147c804472Sopenharmony_ci */ 157c804472Sopenharmony_ci 167c804472Sopenharmony_ci 177c804472Sopenharmony_ci#include "CommandLineInterface.h" 187c804472Sopenharmony_ci 197c804472Sopenharmony_ci#include <chrono> 207c804472Sopenharmony_ci#include <regex> 217c804472Sopenharmony_ci 227c804472Sopenharmony_ci#include "CommandLine.h" 237c804472Sopenharmony_ci#include "CommandLineFactory.h" 247c804472Sopenharmony_ci#include "ModelManager.h" 257c804472Sopenharmony_ci#include "PreviewerEngineLog.h" 267c804472Sopenharmony_ci#include "VirtualScreen.h" 277c804472Sopenharmony_ci#include "CommandParser.h" 287c804472Sopenharmony_ci 297c804472Sopenharmony_ciconst std::string CommandLineInterface::COMMAND_VERSION = "1.0.1"; 307c804472Sopenharmony_cibool CommandLineInterface::isFirstWsSend = true; 317c804472Sopenharmony_cibool CommandLineInterface::isPipeConnected = false; 327c804472Sopenharmony_ciCommandLineInterface::CommandLineInterface() : socket(nullptr) {} 337c804472Sopenharmony_ci 347c804472Sopenharmony_ciCommandLineInterface::~CommandLineInterface() {} 357c804472Sopenharmony_ci 367c804472Sopenharmony_civoid CommandLineInterface::InitPipe(const std::string name) 377c804472Sopenharmony_ci{ 387c804472Sopenharmony_ci if (socket != nullptr) { 397c804472Sopenharmony_ci socket.reset(); 407c804472Sopenharmony_ci ELOG("CommandLineInterface::InitPipe socket is not null"); 417c804472Sopenharmony_ci } 427c804472Sopenharmony_ci 437c804472Sopenharmony_ci socket = std::make_unique<LocalSocket>(); 447c804472Sopenharmony_ci if (socket == nullptr) { 457c804472Sopenharmony_ci FLOG("CommandLineInterface::Connect socket memory allocation failed!"); 467c804472Sopenharmony_ci } 477c804472Sopenharmony_ci 487c804472Sopenharmony_ci if (!socket->ConnectToServer(socket->GetCommandPipeName(name), LocalSocket::READ_WRITE)) { 497c804472Sopenharmony_ci FLOG("CommandLineInterface command pipe connect failed"); 507c804472Sopenharmony_ci } 517c804472Sopenharmony_ci isPipeConnected = true; 527c804472Sopenharmony_ci} 537c804472Sopenharmony_ci 547c804472Sopenharmony_ciCommandLineInterface& CommandLineInterface::GetInstance() 557c804472Sopenharmony_ci{ 567c804472Sopenharmony_ci static CommandLineInterface instance; /* NOLINT */ 577c804472Sopenharmony_ci return instance; 587c804472Sopenharmony_ci} 597c804472Sopenharmony_ci 607c804472Sopenharmony_civoid CommandLineInterface::SendJsonData(const Json2::Value& value) 617c804472Sopenharmony_ci{ 627c804472Sopenharmony_ci *(GetInstance().socket) << value.ToStyledString(); 637c804472Sopenharmony_ci} 647c804472Sopenharmony_ci 657c804472Sopenharmony_civoid CommandLineInterface::SendJSHeapMemory(size_t total, size_t alloc, size_t peak) const 667c804472Sopenharmony_ci{ 677c804472Sopenharmony_ci Json2::Value result = JsonReader::CreateObject(); 687c804472Sopenharmony_ci result.Add("version", COMMAND_VERSION.c_str()); 697c804472Sopenharmony_ci result.Add("property", "memoryUsage"); 707c804472Sopenharmony_ci Json2::Value memory = JsonReader::CreateObject(); 717c804472Sopenharmony_ci memory.Add("totalBytes", static_cast<double>(total)); 727c804472Sopenharmony_ci memory.Add("allocBytes", static_cast<double>(alloc)); 737c804472Sopenharmony_ci memory.Add("peakAllocBytes", static_cast<double>(peak)); 747c804472Sopenharmony_ci result.Add("result", memory); 757c804472Sopenharmony_ci if (socket == nullptr) { 767c804472Sopenharmony_ci ELOG("CommandLineInterface::SendJSHeapMemory socket is null"); 777c804472Sopenharmony_ci return; 787c804472Sopenharmony_ci } 797c804472Sopenharmony_ci *socket << result.ToStyledString(); 807c804472Sopenharmony_ci} 817c804472Sopenharmony_ci 827c804472Sopenharmony_civoid CommandLineInterface::SendWebsocketStartupSignal() const 837c804472Sopenharmony_ci{ 847c804472Sopenharmony_ci Json2::Value result = JsonReader::CreateObject(); 857c804472Sopenharmony_ci Json2::Value args = JsonReader::CreateObject(); 867c804472Sopenharmony_ci result.Add("MessageType", "imageWebsocket"); 877c804472Sopenharmony_ci args.Add("port", VirtualScreen::webSocketPort.c_str()); 887c804472Sopenharmony_ci result.Add("args", args); 897c804472Sopenharmony_ci *socket << result.ToStyledString(); 907c804472Sopenharmony_ci} 917c804472Sopenharmony_ci 927c804472Sopenharmony_civoid CommandLineInterface::ProcessCommand() const 937c804472Sopenharmony_ci{ 947c804472Sopenharmony_ci std::string message; /* NOLINT */ 957c804472Sopenharmony_ci if (socket == nullptr) { 967c804472Sopenharmony_ci ELOG("CommandLineInterface::ProcessCommand socket is null"); 977c804472Sopenharmony_ci return; 987c804472Sopenharmony_ci } 997c804472Sopenharmony_ci if (isPipeConnected && VirtualScreen::isWebSocketListening && isFirstWsSend) { 1007c804472Sopenharmony_ci isFirstWsSend = false; 1017c804472Sopenharmony_ci SendWebsocketStartupSignal(); 1027c804472Sopenharmony_ci } 1037c804472Sopenharmony_ci *socket >> message; 1047c804472Sopenharmony_ci if (message.empty()) { 1057c804472Sopenharmony_ci return; 1067c804472Sopenharmony_ci } 1077c804472Sopenharmony_ci 1087c804472Sopenharmony_ci ProcessCommandMessage(message); 1097c804472Sopenharmony_ci} 1107c804472Sopenharmony_ci 1117c804472Sopenharmony_civoid CommandLineInterface::ProcessCommandMessage(std::string message) const 1127c804472Sopenharmony_ci{ 1137c804472Sopenharmony_ci ILOG("***cmd*** message:%s", message.c_str()); 1147c804472Sopenharmony_ci Json2::Value jsonData = JsonReader::ParseJsonData2(message); 1157c804472Sopenharmony_ci std::string errors; /* NOLINT */ 1167c804472Sopenharmony_ci bool parsingSuccessful = jsonData.IsNull() ? false : true; 1177c804472Sopenharmony_ci if (!parsingSuccessful) { 1187c804472Sopenharmony_ci errors = JsonReader::GetErrorPtr(); 1197c804472Sopenharmony_ci } 1207c804472Sopenharmony_ci 1217c804472Sopenharmony_ci if (!ProcessCommandValidate(parsingSuccessful, jsonData, errors)) { 1227c804472Sopenharmony_ci return; 1237c804472Sopenharmony_ci } 1247c804472Sopenharmony_ci 1257c804472Sopenharmony_ci CommandLine::CommandType type = GetCommandType(jsonData["type"].AsString()); 1267c804472Sopenharmony_ci if (type == CommandLine::CommandType::INVALID) { 1277c804472Sopenharmony_ci return; 1287c804472Sopenharmony_ci } 1297c804472Sopenharmony_ci 1307c804472Sopenharmony_ci std::string command = jsonData["command"].AsString(); 1317c804472Sopenharmony_ci if (CommandParser::GetInstance().IsStaticCard() && IsStaticIgnoreCmd(command)) { 1327c804472Sopenharmony_ci return; 1337c804472Sopenharmony_ci } 1347c804472Sopenharmony_ci Json2::Value val = jsonData["args"]; 1357c804472Sopenharmony_ci std::unique_ptr<CommandLine> commandLine = 1367c804472Sopenharmony_ci CommandLineFactory::CreateCommandLine(command, type, val, *socket); 1377c804472Sopenharmony_ci if (commandLine == nullptr) { 1387c804472Sopenharmony_ci ELOG("Unsupported command"); 1397c804472Sopenharmony_ci return; 1407c804472Sopenharmony_ci } 1417c804472Sopenharmony_ci commandLine->CheckAndRun(); 1427c804472Sopenharmony_ci} 1437c804472Sopenharmony_ci 1447c804472Sopenharmony_cibool CommandLineInterface::ProcessCommandValidate(bool parsingSuccessful, 1457c804472Sopenharmony_ci const Json2::Value& jsonData, 1467c804472Sopenharmony_ci const std::string& errors) const 1477c804472Sopenharmony_ci{ 1487c804472Sopenharmony_ci if (!parsingSuccessful) { 1497c804472Sopenharmony_ci ELOG("Failed to parse the JSON, errors: %s", errors.c_str()); 1507c804472Sopenharmony_ci return false; 1517c804472Sopenharmony_ci } 1527c804472Sopenharmony_ci 1537c804472Sopenharmony_ci if (!jsonData.IsObject()) { 1547c804472Sopenharmony_ci ELOG("Command is not a object!"); 1557c804472Sopenharmony_ci return false; 1567c804472Sopenharmony_ci } 1577c804472Sopenharmony_ci 1587c804472Sopenharmony_ci if (!jsonData.IsMember("type") || !jsonData.IsMember("command") || !jsonData.IsMember("version")) { 1597c804472Sopenharmony_ci ELOG("Command error!"); 1607c804472Sopenharmony_ci return false; 1617c804472Sopenharmony_ci } 1627c804472Sopenharmony_ci 1637c804472Sopenharmony_ci if (!regex_match(jsonData["version"].AsString(), 1647c804472Sopenharmony_ci std::regex("(([0-9]|([1-9]([0-9]*))).){2}([0-9]|([1-9]([0-9]*)))"))) { 1657c804472Sopenharmony_ci ELOG("Invalid command version!"); 1667c804472Sopenharmony_ci return false; 1677c804472Sopenharmony_ci } 1687c804472Sopenharmony_ci return true; 1697c804472Sopenharmony_ci} 1707c804472Sopenharmony_ci 1717c804472Sopenharmony_ciCommandLine::CommandType CommandLineInterface::GetCommandType(std::string name) const 1727c804472Sopenharmony_ci{ 1737c804472Sopenharmony_ci CommandLine::CommandType type = CommandLine::CommandType::INVALID; 1747c804472Sopenharmony_ci if (name == "set") { 1757c804472Sopenharmony_ci type = CommandLine::CommandType::SET; 1767c804472Sopenharmony_ci } else if (name == "get") { 1777c804472Sopenharmony_ci type = CommandLine::CommandType::GET; 1787c804472Sopenharmony_ci } else if (name == "action") { 1797c804472Sopenharmony_ci type = CommandLine::CommandType::ACTION; 1807c804472Sopenharmony_ci } else { 1817c804472Sopenharmony_ci ELOG("Command type invalid!"); 1827c804472Sopenharmony_ci } 1837c804472Sopenharmony_ci return type; 1847c804472Sopenharmony_ci} 1857c804472Sopenharmony_ci 1867c804472Sopenharmony_civoid CommandLineInterface::ApplyConfig(const Json2::Value& val) const 1877c804472Sopenharmony_ci{ 1887c804472Sopenharmony_ci const std::string set("setting"); 1897c804472Sopenharmony_ci if (val.IsMember(set.c_str())) { 1907c804472Sopenharmony_ci Json2::Value versionMembers = val[set]; 1917c804472Sopenharmony_ci if (!versionMembers.IsObject()) { 1927c804472Sopenharmony_ci return; 1937c804472Sopenharmony_ci } 1947c804472Sopenharmony_ci 1957c804472Sopenharmony_ci Json2::Value::Members versions = versionMembers.GetMemberNames(); 1967c804472Sopenharmony_ci 1977c804472Sopenharmony_ci for (Json2::Value::Members::iterator viter = versions.begin(); viter != versions.end(); viter++) { 1987c804472Sopenharmony_ci std::string version = *viter; 1997c804472Sopenharmony_ci Json2::Value commands = versionMembers[version]; 2007c804472Sopenharmony_ci if (!commands.IsObject()) { 2017c804472Sopenharmony_ci continue; 2027c804472Sopenharmony_ci } 2037c804472Sopenharmony_ci Json2::Value::Members members = commands.GetMemberNames(); 2047c804472Sopenharmony_ci 2057c804472Sopenharmony_ci ApplyConfigMembers(commands, members); 2067c804472Sopenharmony_ci } 2077c804472Sopenharmony_ci } 2087c804472Sopenharmony_ci} 2097c804472Sopenharmony_ci 2107c804472Sopenharmony_civoid CommandLineInterface::ApplyConfigMembers(const Json2::Value& commands, 2117c804472Sopenharmony_ci const Json2::Value::Members& members) const 2127c804472Sopenharmony_ci{ 2137c804472Sopenharmony_ci for (Json2::Value::Members::const_iterator iter = members.begin(); iter != members.end(); iter++) { 2147c804472Sopenharmony_ci std::string key = *iter; 2157c804472Sopenharmony_ci if (!commands[key].IsObject() || !commands[key].IsMember("args") || !commands[key]["args"].IsObject()) { 2167c804472Sopenharmony_ci ELOG("Invalid JSON: %s", commands[key].AsString().c_str()); 2177c804472Sopenharmony_ci continue; 2187c804472Sopenharmony_ci } 2197c804472Sopenharmony_ci Json2::Value val = commands[key]["args"]; 2207c804472Sopenharmony_ci std::unique_ptr<CommandLine> command = 2217c804472Sopenharmony_ci CommandLineFactory::CreateCommandLine(key, CommandLine::CommandType::SET, val, *socket); 2227c804472Sopenharmony_ci ApplyConfigCommands(key, command); 2237c804472Sopenharmony_ci } 2247c804472Sopenharmony_ci} 2257c804472Sopenharmony_ci 2267c804472Sopenharmony_civoid CommandLineInterface::ApplyConfigCommands(const std::string& key, 2277c804472Sopenharmony_ci const std::unique_ptr<CommandLine>& command) const 2287c804472Sopenharmony_ci{ 2297c804472Sopenharmony_ci if (command == nullptr) { 2307c804472Sopenharmony_ci ELOG("Unsupported configuration: %s", key.c_str()); 2317c804472Sopenharmony_ci return; 2327c804472Sopenharmony_ci } 2337c804472Sopenharmony_ci 2347c804472Sopenharmony_ci if (command->IsArgValid()) { 2357c804472Sopenharmony_ci command->RunSet(); 2367c804472Sopenharmony_ci } 2377c804472Sopenharmony_ci} 2387c804472Sopenharmony_ci 2397c804472Sopenharmony_civoid CommandLineInterface::Init(std::string pipeBaseName) 2407c804472Sopenharmony_ci{ 2417c804472Sopenharmony_ci CommandLineFactory::InitCommandMap(); 2427c804472Sopenharmony_ci InitPipe(pipeBaseName); 2437c804472Sopenharmony_ci} 2447c804472Sopenharmony_ci 2457c804472Sopenharmony_civoid CommandLineInterface::ReadAndApplyConfig(std::string path) const 2467c804472Sopenharmony_ci{ 2477c804472Sopenharmony_ci if (path.empty()) { 2487c804472Sopenharmony_ci return; 2497c804472Sopenharmony_ci } 2507c804472Sopenharmony_ci std::string jsonStr = JsonReader::ReadFile(path); 2517c804472Sopenharmony_ci Json2::Value val = JsonReader::ParseJsonData2(jsonStr); 2527c804472Sopenharmony_ci ApplyConfig(val); 2537c804472Sopenharmony_ci} 2547c804472Sopenharmony_ci 2557c804472Sopenharmony_civoid CommandLineInterface::CreatCommandToSendData(const std::string commandName, 2567c804472Sopenharmony_ci const Json2::Value& jsonData, 2577c804472Sopenharmony_ci const std::string type) const 2587c804472Sopenharmony_ci{ 2597c804472Sopenharmony_ci CommandLine::CommandType commandType = GetCommandType(type); 2607c804472Sopenharmony_ci std::unique_ptr<CommandLine> commandLine = 2617c804472Sopenharmony_ci CommandLineFactory::CreateCommandLine(commandName, commandType, jsonData, *socket); 2627c804472Sopenharmony_ci if (commandLine == nullptr) { 2637c804472Sopenharmony_ci ELOG("Unsupported CreatCommandToSendData: %s", commandName.c_str()); 2647c804472Sopenharmony_ci return; 2657c804472Sopenharmony_ci } 2667c804472Sopenharmony_ci commandLine->RunAndSendResultToManager(); 2677c804472Sopenharmony_ci} 2687c804472Sopenharmony_ci 2697c804472Sopenharmony_cibool CommandLineInterface::IsStaticIgnoreCmd(const std::string cmd) const 2707c804472Sopenharmony_ci{ 2717c804472Sopenharmony_ci auto it = std::find(staticIgnoreCmd.begin(), staticIgnoreCmd.end(), cmd); 2727c804472Sopenharmony_ci if (it != staticIgnoreCmd.end()) { 2737c804472Sopenharmony_ci return false; 2747c804472Sopenharmony_ci } else { 2757c804472Sopenharmony_ci return true; 2767c804472Sopenharmony_ci } 2777c804472Sopenharmony_ci} 278