• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include "daemon_app.h"
16 
17 namespace Hdc {
HdcDaemonApp(HTaskInfo hTaskInfo)18 HdcDaemonApp::HdcDaemonApp(HTaskInfo hTaskInfo)
19     : HdcTransferBase(hTaskInfo)
20 {
21     commandBegin = CMD_APP_BEGIN;
22     commandData = CMD_APP_DATA;
23     funcAppModFinish = nullptr;
24 }
25 
~HdcDaemonApp()26 HdcDaemonApp::~HdcDaemonApp()
27 {
28     WRITE_LOG(LOG_DEBUG, "~HdcDaemonApp");
29 }
30 
ReadyForRelease()31 bool HdcDaemonApp::ReadyForRelease()
32 {
33     if (!HdcTaskBase::ReadyForRelease()) {
34         return false;
35     }
36     if (!asyncCommand.ReadyForRelease()) {
37         return false;
38     }
39     WRITE_LOG(LOG_DEBUG, "HdcDaemonApp ready for release");
40     return true;
41 }
42 
CommandDispatch(const uint16_t command,uint8_t * payload,const int payloadSize)43 bool HdcDaemonApp::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize)
44 {
45     if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) {
46         return false;
47     }
48     bool ret = true;
49     switch (command) {
50         case CMD_APP_CHECK: {
51             string tmpData = "/data/local/tmp/";
52             string tmpSD = "/sdcard/tmp/";
53             string dstPath = tmpData;
54             string bufString(reinterpret_cast<char *>(payload), payloadSize);
55             SerialStruct::ParseFromString(ctxNow.transferConfig, bufString);
56             // update transferconfig to main context
57             ctxNow.master = false;
58             ctxNow.fsOpenReq.data = &ctxNow;
59             // -lrtsdpg, -l -r -t -s..,
60             if (ctxNow.transferConfig.functionName == CMDSTR_APP_INSTALL
61                 && ctxNow.transferConfig.options.find("s") != std::string::npos) {
62                 dstPath = tmpSD;
63             }
64 #ifdef HDC_PCDEBUG
65             char tmpPath[256] = "";
66             size_t size = 256;
67             uv_os_tmpdir(tmpPath, &size);
68             dstPath = tmpPath;
69             dstPath += Base::GetPathSep();
70 #endif
71             dstPath += ctxNow.transferConfig.optionalName;
72             ctxNow.localPath = dstPath;
73             ctxNow.transferBegin = Base::GetRuntimeMSec();
74             ctxNow.fileSize = ctxNow.transferConfig.fileSize;
75             ++refCount;
76             uv_fs_open(loopTask, &ctxNow.fsOpenReq, ctxNow.localPath.c_str(),
77                        UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH,
78                        OnFileOpen);
79             break;
80         }
81         case CMD_APP_UNINSTALL: {
82             // This maybe has a command implanting risk, since it is a controllable device, it can be ignored
83             string bufString(reinterpret_cast<char *>(payload), payloadSize);
84             PackageShell(false, "", bufString);
85             break;
86         }
87         default:
88             break;
89     }
90     return ret;
91 };
92 
AsyncInstallFinish(bool finish,int64_t exitStatus,const string result)93 bool HdcDaemonApp::AsyncInstallFinish(bool finish, int64_t exitStatus, const string result)
94 {
95     if (mode == APPMOD_INSTALL) {
96         unlink(ctxNow.localPath.c_str());
97     }
98     asyncCommand.DoRelease();
99     string echo = result;
100     echo = Base::ReplaceAll(echo, "\n", " ");
101     vector<uint8_t> vecBuf;
102     vecBuf.push_back(mode);
103     vecBuf.push_back(exitStatus == 0);
104     vecBuf.insert(vecBuf.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size());
105     SendToAnother(CMD_APP_FINISH, vecBuf.data(), vecBuf.size());
106     --refCount;
107 #ifdef UNIT_TEST
108     Base::WriteBinFile((UT_TMP_PATH + "/appinstall.result").c_str(), (uint8_t *)MESSAGE_SUCCESS.c_str(),
109                        MESSAGE_SUCCESS.size(), true);
110 #endif
111     return true;
112 }
113 
PackageShell(bool installOrUninstall,const char * options,const string package)114 void HdcDaemonApp::PackageShell(bool installOrUninstall, const char *options, const string package)
115 {
116     ++refCount;
117     // asynccmd Other processes, no RunningProtect protection
118     chmod(package.c_str(), 0644);  // 0644 : permission
119     string doBuf;
120     if (installOrUninstall) {
121         doBuf = Base::StringFormat("bm install %s -p %s", options, package.c_str());
122     } else {
123         doBuf = Base::StringFormat("bm uninstall %s -n %s", options, package.c_str());
124     }
125     funcAppModFinish = std::bind(&HdcDaemonApp::AsyncInstallFinish, this, std::placeholders::_1, std::placeholders::_2,
126                                  std::placeholders::_3);
127     if (installOrUninstall) {
128         mode = APPMOD_INSTALL;
129     } else {
130         mode = APPMOD_UNINSTALL;
131     }
132     asyncCommand.Initial(loopTask, funcAppModFinish, AsyncCmd::OPTION_COMMAND_ONETIME);
133     asyncCommand.ExecuteCommand(doBuf);
134 }
135 
Sideload(const char * pathOTA)136 void HdcDaemonApp::Sideload(const char *pathOTA)
137 {
138     mode = APPMOD_SIDELOAD;
139     LogMsg(MSG_OK, "[placeholders] sideload %s", pathOTA);
140     TaskFinish();
141     unlink(pathOTA);
142 }
143 
WhenTransferFinish(CtxFile * context)144 void HdcDaemonApp::WhenTransferFinish(CtxFile *context)
145 {
146     if (context->lastErrno > 0) {
147         constexpr int bufSize = 1024;
148         char buf[bufSize] = { 0 };
149         uv_strerror_r(static_cast<int>(-context->lastErrno), buf, bufSize);
150         WRITE_LOG(LOG_DEBUG, "HdcDaemonApp WhenTransferFinish with errno:%d", context->lastErrno);
151         LogMsg(MSG_FAIL, "Transfer App at:%lld/%lld(Bytes), Reason: %s",
152                context->indexIO, context->fileSize, buf);
153         return;
154     }
155     if (ctxNow.transferConfig.functionName == CMDSTR_APP_SIDELOAD) {
156         Sideload(context->localPath.c_str());
157     } else if (ctxNow.transferConfig.functionName == CMDSTR_APP_INSTALL) {
158         PackageShell(true, context->transferConfig.options.c_str(), context->localPath.c_str());
159     } else {
160     }
161 };
162 }
163