• 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 "host_app.h"
16 
17 namespace Hdc {
HdcHostApp(HTaskInfo hTaskInfo)18 HdcHostApp::HdcHostApp(HTaskInfo hTaskInfo)
19     : HdcTransferBase(hTaskInfo)
20 {
21     commandBegin = CMD_APP_BEGIN;
22     commandData = CMD_APP_DATA;
23 }
24 
~HdcHostApp()25 HdcHostApp::~HdcHostApp()
26 {
27 }
28 
BeginInstall(CtxFile * context,const char * command)29 bool HdcHostApp::BeginInstall(CtxFile *context, const char *command)
30 {
31     int argc = 0;
32     bool ret = false;
33     string options;
34     char **argv = Base::SplitCommandToArgs(command, &argc);
35     if (argc < 1) {
36         goto Finish;
37     }
38 
39     for (int i = 0; i < argc; ++i) {
40         if (!strcmp(argv[i], CMD_OPTION_CLIENTCWD.c_str())) {
41             if (i + 1 < argc) {
42                 context->transferConfig.clientCwd = argv[i + 1];
43                 i += 1;  // add content index
44             }
45         } else if (!strncmp(argv[i], "-", 1)) {
46             if (options.size()) {
47                 options += " ";
48             }
49             options += argv[i];
50         } else {
51             string path = argv[i];
52             ExtractRelativePath(context->transferConfig.clientCwd, path);
53             if (MatchPackageExtendName(path, ".hap") || MatchPackageExtendName(path, ".hsp")) {
54                 context->taskQueue.push_back(path);
55             } else {
56                 GetSubFiles(argv[i], ".hap", &context->taskQueue);
57                 GetSubFiles(argv[i], ".hsp", &context->taskQueue);
58             }
59         }
60     }
61     if (!context->taskQueue.size()) {
62         LogMsg(MSG_FAIL, "Not any installation package was found");
63         goto Finish;
64     }
65     // remove repeate
66     sort(context->taskQueue.begin(), context->taskQueue.end());
67     context->taskQueue.erase(unique(context->taskQueue.begin(), context->taskQueue.end()), context->taskQueue.end());
68 
69     context->transferConfig.options = options;
70     context->transferConfig.functionName = CMDSTR_APP_INSTALL;
71     RunQueue(context);
72     ret = true;
73 Finish:
74     if (argv) {
75         delete[](reinterpret_cast<char *>(argv));
76     }
77     return ret;
78 }
79 
BeginSideload(CtxFile * context,const char * localPath)80 bool HdcHostApp::BeginSideload(CtxFile *context, const char *localPath)
81 {
82     bool ret = false;
83     context->transferConfig.functionName = CMDSTR_APP_SIDELOAD;
84     context->taskQueue.push_back(localPath);
85     RunQueue(context);
86     ret = true;
87     return ret;
88 }
89 
RunQueue(CtxFile * context)90 void HdcHostApp::RunQueue(CtxFile *context)
91 {
92     ++refCount;
93     context->localPath = context->taskQueue.back();
94     uv_fs_open(loopTask, &context->fsOpenReq, context->localPath.c_str(), O_RDONLY, 0, OnFileOpen);
95     context->master = true;
96 }
97 
CheckMaster(CtxFile * context)98 void HdcHostApp::CheckMaster(CtxFile *context)
99 {
100     uv_fs_t fs = {};
101     uv_fs_fstat(nullptr, &fs, context->fsOpenReq.result, nullptr);
102     context->transferConfig.fileSize = fs.statbuf.st_size;
103     uv_fs_req_cleanup(&fs);
104 
105     context->transferConfig.optionalName
106         = Base::GetRandomString(EXPECTED_LEN);  // Prevent the name of illegal APP leads to pm unable to install
107     if (context->localPath.find(".hap") != static_cast<size_t>(-1)) {
108         context->transferConfig.optionalName += ".hap";
109     } else if (context->localPath.find(".hsp") != static_cast<size_t>(-1)) {
110         context->transferConfig.optionalName += ".hsp";
111     } else {
112         context->transferConfig.optionalName += ".bundle";
113     }
114     string bufString = SerialStruct::SerializeToString(context->transferConfig);
115     SendToAnother(CMD_APP_CHECK, const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(bufString.c_str())),
116                   bufString.size());
117 }
118 
CheckInstallContinue(AppModType mode,bool lastResult,const char * msg)119 bool HdcHostApp::CheckInstallContinue(AppModType mode, bool lastResult, const char *msg)
120 {
121     string modeDesc;
122     switch (mode) {
123         case APPMOD_INSTALL:
124             modeDesc = "App install";
125             break;
126         case APPMOD_UNINSTALL:
127             modeDesc = "App uninstall";
128             break;
129         case APPMOD_SIDELOAD:
130             modeDesc = "Side load";
131             break;
132         default:
133             modeDesc = "Unknown";
134             break;
135     }
136     if (ctxNow.taskQueue.size() > 0) {
137         ctxNow.taskQueue.pop_back();
138     }
139     LogMsg(MSG_INFO, "%s path:%s, queuesize:%d, msg:%s", modeDesc.c_str(), ctxNow.localPath.c_str(),
140            ctxNow.taskQueue.size(), msg + printedMsgLen);
141     printedMsgLen = strlen(msg);
142     if (singalStop || !ctxNow.taskQueue.size()) {
143         LogMsg(MSG_OK, "AppMod finish");
144         return false;
145     }
146     RunQueue(&ctxNow);
147     return true;
148 }
149 
CommandDispatch(const uint16_t command,uint8_t * payload,const int payloadSize)150 bool HdcHostApp::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize)
151 {
152     if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) {
153         return false;
154     }
155     bool ret = true;
156     constexpr int cmdOffset = 2;
157     switch (command) {
158         case CMD_APP_INIT: {
159             ret = BeginInstall(&ctxNow, (const char *)payload);
160             break;
161         }
162         case CMD_APP_FINISH: {
163             AppModType mode = static_cast<AppModType>(payload[0]);
164             bool result = static_cast<bool>(payload[1]);
165             string s(reinterpret_cast<char *>(payload + cmdOffset), payloadSize - cmdOffset);
166             ret = CheckInstallContinue(mode, result, s.c_str());
167             break;
168         }
169         case CMD_APP_UNINSTALL: {
170             SendToAnother(CMD_APP_UNINSTALL, payload, payloadSize);
171             ctxNow.taskQueue.push_back(reinterpret_cast<char *>(payload));  // just compatible
172             break;
173         }
174         case CMD_APP_SIDELOAD: {
175             BeginSideload(&ctxNow, (const char *)payload);
176             break;
177         }
178         default:
179             break;
180     }
181     return ret;
182 };
183 }
184