diff --git a/services/applypatch/block_set.cpp b/services/applypatch/block_set.cpp index 7f70cf3dee0f977f31f4ddff7917ce66425672de..b1670a933cf21730069449cd4431a5ed674b67b4 100644 --- a/services/applypatch/block_set.cpp +++ b/services/applypatch/block_set.cpp @@ -330,23 +330,17 @@ int32_t BlockSet::WriteDiffToBlock(const Command &cmd, std::vector &src writer.reset(); UPDATER_ERROR_CHECK(ret == 0, "Fail to ApplyImagePatch", return -1); } else { - std::vector targetBuffer; - targetBuffer.resize(TotalBlockSize() * H_BLOCK_SIZE); LOG(DEBUG) << "Run bsdiff patch."; updatepatch::PatchBuffer patchInfo = {patchBuff, 0, length}; - auto ret = updatepatch::UpdatePatch::ApplyBlockPatch(patchInfo, {srcBuffer.data(), srcBuffSize}, targetBuffer); - if (ret != 0) { - LOG(ERROR) << "Failed to apply bspatch"; - return -1; - } - if (VerifySha256(targetBuffer, TotalBlockSize(), cmd.GetArgumentByPos(pos + 1)) != 0) { - LOG(ERROR) << "Not match sha256 after bspatch"; - return -1; - } - if (WriteDataToBlock(cmd.GetFileDescriptor(), targetBuffer) <= 0) { - LOG(ERROR) << "Error to write source to file"; - return -1; - } + std::unique_ptr writer = std::make_unique(cmd.GetFileDescriptor(), *this); + UPDATER_ERROR_CHECK(writer.get() != nullptr, "Cannot create block writer, pkgdiff patch abort!", return -1); + auto ret = updatepatch::UpdatePatch::ApplyBlockPatch(patchInfo, {srcBuffer.data(), srcBuffSize}, + [&](size_t start, const updatepatch::BlockBuffer &data, size_t size) -> int { + bool ret = writer->Write(data.buffer, size, WRITE_BLOCK, ""); + return ret ? 0 : -1; + }, cmd.GetArgumentByPos(pos + 1)); + writer.reset(); + UPDATER_ERROR_CHECK(ret == 0, "Fail to ApplyBlockPatch", return -1); } return 0; } diff --git a/services/applypatch/block_writer.cpp b/services/applypatch/block_writer.cpp index 2d4ac6ff28e3f2764560c21e8e4461d8f1d2383e..92eb931971ad069ac78af804338d2f6ae6fa1feb 100644 --- a/services/applypatch/block_writer.cpp +++ b/services/applypatch/block_writer.cpp @@ -84,12 +84,6 @@ bool BlockWriter::Write(const uint8_t *addr, size_t len, WriteMode mode, const s currentBlockLeft_ -= written; totalWritten_ += written; } - - if (fsync(fd_) == -1) { - LOG(ERROR) << "Failed to fsync"; - return false; - } - return true; } } // namespace updater diff --git a/services/applypatch/data_writer.cpp b/services/applypatch/data_writer.cpp index 602fdd749e5d6ccd1abf691d9bb310b8c0551b2f..28bc75785b77ba00418310de8da150aae1b7b230 100644 --- a/services/applypatch/data_writer.cpp +++ b/services/applypatch/data_writer.cpp @@ -25,6 +25,7 @@ #include "raw_writer.h" namespace updater { +UpdaterEnv *DataWriter::env_ = nullptr; int DataWriter::OpenPartition(const std::string &partitionName) { if (partitionName.empty()) { @@ -66,6 +67,18 @@ std::unique_ptr DataWriter::CreateDataWriter(WriteMode mode, const s return nullptr; } +UpdaterEnv *DataWriter::GetUpdaterEnv() +{ + return env_; +} + +std::unique_ptr DataWriter::CreateDataWriter(WriteMode mode, const std::string &partitionName, + UpdaterEnv *env) +{ + env_ = env; + return CreateDataWriter(mode, partitionName); +} + void DataWriter::ReleaseDataWriter(std::unique_ptr &writer) { writer.reset(); diff --git a/services/applypatch/store.cpp b/services/applypatch/store.cpp index 7bbc27d21da83604ec8d09c5dbeb2658582e46c8..f945e8ceb4cbdd944b45e05324d584e237260215 100644 --- a/services/applypatch/store.cpp +++ b/services/applypatch/store.cpp @@ -88,8 +88,7 @@ int32_t Store::WriteDataToStore(const std::string &dirPath, const std::string &f pathTmp = dirPath + "/"; } std::string path = pathTmp + fileName; - pathTmp = pathTmp + fileName + ".tmp"; - + pathTmp = pathTmp + fileName; int fd = open(pathTmp.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); UPDATER_ERROR_CHECK(fd != -1, "Failed to create store", return -1); UPDATER_ERROR_CHECK(fchown(fd, O_USER_GROUP_ID, O_USER_GROUP_ID) == 0, @@ -102,8 +101,6 @@ int32_t Store::WriteDataToStore(const std::string &dirPath, const std::string &f return -1; } UPDATER_ERROR_CHECK(fsync(fd) != -1, "Failed to fsync", close(fd); return -1); - UPDATER_ERROR_CHECK(rename(pathTmp.c_str(), path.c_str()) != -1, - "Failed rename store", close(fd); return -1); close(fd); int fdd = open(dirPath.c_str(), O_RDONLY | O_DIRECTORY); UPDATER_ERROR_CHECK(fdd != -1, "Failed to open", return -1); @@ -122,6 +119,7 @@ int32_t Store::LoadDataFromStore(const std::string &dirPath, const std::string & struct stat fileStat {}; UPDATER_WARING_CHECK(stat(path.c_str(), &fileStat) != -1, "Failed to stat", return -1); UPDATER_ERROR_CHECK((fileStat.st_size % H_BLOCK_SIZE) == 0, "Not multiple of block size 4096", return -1); + int fd = open(path.c_str(), O_RDONLY); UPDATER_ERROR_CHECK(fd != -1, "Failed to create", return -1); buffer.resize(fileStat.st_size); diff --git a/services/applypatch/transfer_manager.cpp b/services/applypatch/transfer_manager.cpp index 2051955b08f6a7063648bac7994cbc45cc691aee..f54507c7567fcde11a9273c1a90190c81f80580d 100644 --- a/services/applypatch/transfer_manager.cpp +++ b/services/applypatch/transfer_manager.cpp @@ -58,6 +58,7 @@ bool TransferManager::CommandsParser(int fd, const std::vector &con globalParams->blockCount = utils::String2Int(*ct++, utils::N_DEC); globalParams->maxEntries = utils::String2Int(*ct++, utils::N_DEC); globalParams->maxBlocks = utils::String2Int(*ct++, utils::N_DEC); + size_t totalSize = globalParams->maxBlocks * globalParams->blockCount; std::string retryCmd = ""; if (globalParams != nullptr && globalParams->env != nullptr && globalParams->env->IsRetry()) { retryCmd = ReloadForRetry(); @@ -65,7 +66,6 @@ bool TransferManager::CommandsParser(int fd, const std::vector &con std::unique_ptr cmd; while (ct != context.end()) { cmd = std::make_unique(); - // null pointer, return false UPDATER_ERROR_CHECK(cmd != nullptr, "Failed to parse command line.", return false); if (cmd->Init(*ct) && cmd->GetCommandType() != CommandType::LAST) { if (!retryCmd.empty() && globalParams->env->IsRetry()) { @@ -87,9 +87,16 @@ bool TransferManager::CommandsParser(int fd, const std::vector &con } CommandResult ret = cf->Execute(const_cast(*cmd.get())); CommandFunctionFactory::ReleaseCommandFunction(cf); - if (CheckResult(ret, cmd->GetCommandLine()) == false) { + if (CheckResult(ret, cmd->GetCommandLine(), cmd->GetCommandType()) == false) { return false; } + + bool typeResult = cmd->GetCommandType() == CommandType::NEW || + cmd->GetCommandType() == CommandType::IMGDIFF || + cmd->GetCommandType() == CommandType::BSDIFF; + if (totalSize != 0 && globalParams->env != nullptr && typeResult) { + globalParams->env->PostMessage("set_progress", std::to_string((float)globalParams->written/totalSize)); + } LOG(INFO) << "Running command : " << cmd->GetArgumentByPos(0) << " success"; } cmd.reset(); @@ -132,11 +139,13 @@ std::string TransferManager::ReloadForRetry() const return cmd; } -bool TransferManager::CheckResult(const CommandResult result, const std::string &cmd) +bool TransferManager::CheckResult(const CommandResult result, const std::string &cmd, const CommandType &type) { switch (result) { case SUCCESS: - RegisterForRetry(cmd); + if (type != CommandType::NEW) { + RegisterForRetry(cmd); + } break; case NEED_RETRY: LOG(INFO) << "Running command need retry!"; diff --git a/services/diffpatch/bzip2/bzip2_adapter.cpp b/services/diffpatch/bzip2/bzip2_adapter.cpp index f07cd19d1a44a3ab10a202e809e897a7e0391441..509f3eacffea9b714661714d64041cdfaa1349c4 100644 --- a/services/diffpatch/bzip2/bzip2_adapter.cpp +++ b/services/diffpatch/bzip2/bzip2_adapter.cpp @@ -80,7 +80,7 @@ int32_t BZipBuffer2Adapter::FlushData(size_t &dataSize) if (stream_.avail_out == 0) { dataSize_ += stream_.next_out - next; buffer_.resize(buffer_.size() + IGMDIFF_LIMIT_UNIT); - stream_.avail_out = buffer_.size() - offset_ + dataSize_; + stream_.avail_out = buffer_.size() - offset_ - dataSize_; next = reinterpret_cast(buffer_.data() + offset_ + dataSize_); stream_.next_out = next; } diff --git a/services/diffpatch/patch/update_patch.cpp b/services/diffpatch/patch/update_patch.cpp index f0393290755127fc200262d35a3d678c8b7d78bd..a5c30b5eaf14d8b789a977972a7bb1de51b97949 100644 --- a/services/diffpatch/patch/update_patch.cpp +++ b/services/diffpatch/patch/update_patch.cpp @@ -108,6 +108,30 @@ int32_t UpdatePatch::ApplyBlockPatch(const PatchBuffer &patchInfo, return ret; } +int32_t UpdatePatch::ApplyBlockPatch(const PatchBuffer &patchInfo, + const BlockBuffer &oldInfo, ImageProcessor writer, const std::string& expected) +{ + PATCH_CHECK(writer != nullptr, return -1, "processor is null"); + std::unique_ptr patchWriter = std::make_unique(writer, expected, ""); + PATCH_CHECK(patchWriter != nullptr, return -1, "Failed to create patch writer"); + int32_t ret = patchWriter->Init(); + PATCH_CHECK(ret == 0, return -1, "Failed to init patch writer"); + + PkgManager* pkgManager = hpackage::PkgManager::GetPackageInstance(); + PATCH_CHECK(pkgManager != nullptr, return -1, "Failed to get pkg manager"); + + hpackage::PkgManager::StreamPtr stream = nullptr; + ret = pkgManager->CreatePkgStream(stream, "", {oldInfo.buffer, oldInfo.length}); + PATCH_CHECK(stream != nullptr, pkgManager->ClosePkgStream(stream); return -1, "Failed to create stream"); + + std::unique_ptr patch = std::make_unique(patchInfo, stream, patchWriter.get()); + PATCH_CHECK(patch != nullptr, pkgManager->ClosePkgStream(stream); return -1, "Failed to creare patch "); + ret = patch->ApplyPatch(); + pkgManager->ClosePkgStream(stream); + PATCH_CHECK(ret == 0, return -1, "Failed to applay patch "); + return patchWriter->Finish(); +} + int32_t UpdatePatch::ApplyBlockPatch(const PatchBuffer &patchInfo, hpackage::PkgManager::StreamPtr stream, UpdatePatchWriterPtr writer) { diff --git a/services/include/applypatch/data_writer.h b/services/include/applypatch/data_writer.h index 7ab488a61d8945ee7faca81b4a3823af1dbafbb1..924387f41b60413fe8bb461c35cd7fd7f577afcb 100644 --- a/services/include/applypatch/data_writer.h +++ b/services/include/applypatch/data_writer.h @@ -20,6 +20,7 @@ #include #include #include +#include "updater_env.h" namespace updater { enum WriteMode : int { @@ -35,8 +36,13 @@ public: virtual bool Write(const uint8_t *addr, size_t len, WriteMode mode, const std::string &partitionName) = 0; virtual int OpenPartition(const std::string &partitionName); virtual ~DataWriter() {} + static std::unique_ptr CreateDataWriter(WriteMode mode, const std::string &partitionName, + UpdaterEnv *env); static std::unique_ptr CreateDataWriter(WriteMode mode, const std::string &partitionName); + static UpdaterEnv *GetUpdaterEnv(); static void ReleaseDataWriter(std::unique_ptr &writer); +private: + static UpdaterEnv *env_; }; // Maybe we should read sector size from flash. diff --git a/services/include/applypatch/transfer_manager.h b/services/include/applypatch/transfer_manager.h index cc40bda25d5825fa1c51ce359eed92606ba90e4d..4d63a04dc568f0f4a3ad7d2d0097577a520ba7a8 100644 --- a/services/include/applypatch/transfer_manager.h +++ b/services/include/applypatch/transfer_manager.h @@ -71,7 +71,7 @@ public: return globalParams.get(); } std::string ReloadForRetry() const; - bool CheckResult(const CommandResult result, const std::string &cmd); + bool CheckResult(const CommandResult result, const std::string &cmd, const CommandType &type); private: bool RegisterForRetry(const std::string &cmd); diff --git a/services/include/applypatch/updater_env.h b/services/include/applypatch/updater_env.h new file mode 100644 index 0000000000000000000000000000000000000000..4ce1b8f70ed1fbbc2fdbb96eecbfb32c353d3bb2 --- /dev/null +++ b/services/include/applypatch/updater_env.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UPDATE_ENV_H +#define UPDATE_ENV_H + +#include +#include +#include +#include +#include "package/pkg_manager.h" +#include "script_instruction.h" +#include "script_manager.h" + +using uscript::UScriptEnv; +using uscript::UScriptInstructionFactory; +using uscript::UScriptInstructionFactoryPtr; + +namespace updater { +class UpdaterEnv : public UScriptEnv { +public: + UpdaterEnv(hpackage::PkgManager::PkgManagerPtr pkgManager, FILE* pipeWrite, bool retry) : + UScriptEnv(pkgManager), pipeWrite_(pipeWrite), isRetry_(retry) {} + virtual ~UpdaterEnv(); + + virtual void PostMessage(const std::string &cmd, std::string content); + virtual UScriptInstructionFactoryPtr GetInstructionFactory(); + virtual const std::vector GetInstructionNames() const; + virtual bool IsRetry() const + { + return isRetry_; + } +private: + UScriptInstructionFactoryPtr factory_ = nullptr; + FILE* pipeWrite_ = nullptr; + bool isRetry_ = false; +}; +} +#endif /* UPDATE_ENV_H */ diff --git a/services/include/patch/update_patch.h b/services/include/patch/update_patch.h index c95ce6da1df4271dc81fd4baf5c30036d6749d61..6c46a5bc0c2dd1a344101aff0378e61f2e044b6c 100644 --- a/services/include/patch/update_patch.h +++ b/services/include/patch/update_patch.h @@ -59,6 +59,8 @@ public: static int32_t ApplyBlockPatch(const PatchBuffer &patchInfo, const BlockBuffer &oldInfo, UpdatePatchWriterPtr writer); + static int32_t ApplyBlockPatch(const PatchBuffer &patchInfo, + const BlockBuffer &oldInfo, ImageProcessor writer, const std::string& expected); static int32_t ApplyBlockPatch(const PatchBuffer &patchInfo, const BlockBuffer &oldInfo, std::vector &newData); static int32_t ApplyBlockPatch(const PatchBuffer &patchInfo, diff --git a/services/include/updater/updater_const.h b/services/include/updater/updater_const.h index 1214a0e41f31f4c512b3c7e26609c98ab8a61217..d6b862d498404300be1535b2426e4769d3fcd364 100644 --- a/services/include/updater/updater_const.h +++ b/services/include/updater/updater_const.h @@ -74,5 +74,7 @@ constexpr int PROGRESS_VALUE_CONST = 2; constexpr int SHOW_FULL_PROGRESS_TIME = 2000; constexpr unsigned int UI_SHOW_DURATION = 2000; constexpr unsigned int INTERVAL_TIME = 300; +constexpr float EPSINON = 0.00001; +constexpr float FULL_EPSINON = 1; } // namespace updater #endif diff --git a/services/package/pkg_algorithm/pkg_algo_deflate.cpp b/services/package/pkg_algorithm/pkg_algo_deflate.cpp index 85812b451718c8767bc136ed1bc40f64a434d9c7..e6147f26fbcd10caaf5f94427bf911f825df7d87 100644 --- a/services/package/pkg_algorithm/pkg_algo_deflate.cpp +++ b/services/package/pkg_algorithm/pkg_algo_deflate.cpp @@ -20,8 +20,8 @@ namespace hpackage { constexpr uint8_t INFLATE_ERROR_TIMES = 5; -constexpr uint32_t IN_BUFFER_SIZE = 1024 * 32; -constexpr uint32_t OUT_BUFFER_SIZE = 1024 * 4; +constexpr uint32_t IN_BUFFER_SIZE = 1024 * 64; +constexpr uint32_t OUT_BUFFER_SIZE = 1024 * 32; int32_t PkgAlgoDeflate::DeflateData(const PkgStreamPtr outStream, z_stream &zstream, int32_t flush, PkgBuffer &outBuffer, size_t &destOffset) const diff --git a/services/package/pkg_algorithm/pkg_algorithm.cpp b/services/package/pkg_algorithm/pkg_algorithm.cpp index 9a0aaee6fa2264e1ba36962da24060132cf13f9a..d1a02a6860f13cd5b19a448f28f85462a43cad65 100644 --- a/services/package/pkg_algorithm/pkg_algorithm.cpp +++ b/services/package/pkg_algorithm/pkg_algorithm.cpp @@ -20,7 +20,7 @@ #include "securec.h" namespace hpackage { -constexpr uint32_t MAX_BUFFER_SIZE = 1 << 10; +constexpr uint32_t MAX_BUFFER_SIZE = (4 *1024 * 1024); int32_t PkgAlgorithm::ReadData(const PkgStreamPtr inStream, size_t offset, PkgBuffer &buffer, size_t &remainSize, size_t &readLen) const diff --git a/services/package/pkg_package/pkg_upgradefile.cpp b/services/package/pkg_package/pkg_upgradefile.cpp index 33f6e4640d0af9eea3a0b8af520fd6488d4848cb..8487359d36379f56d0f7ea807a9d71e6be4352de 100644 --- a/services/package/pkg_package/pkg_upgradefile.cpp +++ b/services/package/pkg_package/pkg_upgradefile.cpp @@ -211,16 +211,18 @@ int32_t UpgradePkgFile::LoadPackage(std::vector &fileNames, VerifyF parsedLen += UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen(); // Calculate digest and verify - return Verify(parsedLen, {buffer.buffer, buffSize}, algorithm, verifier, signData); + return Verify(parsedLen, algorithm, verifier, signData); } -int32_t UpgradePkgFile::Verify(size_t start, const PkgBuffer &buffer, - DigestAlgorithm::DigestAlgorithmPtr algorithm, VerifyFunction verifier, const std::vector &signData) +int32_t UpgradePkgFile::Verify(size_t start, DigestAlgorithm::DigestAlgorithmPtr algorithm, + VerifyFunction verifier, const std::vector &signData) { int ret = 0; - size_t buffSize = buffer.length; + size_t buffSize = (4 * 1024 * 1024); size_t offset = start; size_t readBytes = 0; + PkgBuffer buffer(buffSize); + while (offset + readBytes < pkgStream_->GetFileLength()) { offset += readBytes; readBytes = 0; @@ -427,7 +429,7 @@ int32_t UpgradeFileEntry::DecodeHeader(const PkgBuffer &buffer, size_t headerOff fileInfo_.fileInfo.unpackedSize = fileInfo_.fileInfo.packedSize; fileInfo_.originalSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, originalSize)); fileInfo_.fileInfo.packMethod = PKG_COMPRESS_METHOD_NONE; - fileInfo_.fileInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; + fileInfo_.fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE; int32_t ret = memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), info->digest, sizeof(info->digest)); PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret:%d", ret); PkgFile::ConvertBufferToString(fileInfo_.fileInfo.identity, {info->address, sizeof(info->address)}); diff --git a/services/package/pkg_package/pkg_upgradefile.h b/services/package/pkg_package/pkg_upgradefile.h index b04d0486edd223b5cddefcb29988fbae7c38b9ec..93a8ec6135dd436b99fb7b5fbfc51cf18298f8d4 100644 --- a/services/package/pkg_package/pkg_upgradefile.h +++ b/services/package/pkg_package/pkg_upgradefile.h @@ -112,7 +112,7 @@ private: int32_t ReadUpgradePkgHeader(const PkgBuffer &buffer, size_t &realLen, DigestAlgorithm::DigestAlgorithmPtr &algorithm); - int32_t Verify(size_t start, const PkgBuffer &buffer, DigestAlgorithm::DigestAlgorithmPtr algorithm, + int32_t Verify(size_t start, DigestAlgorithm::DigestAlgorithmPtr algorithm, VerifyFunction verifier, const std::vector &signData); private: UpgradePkgInfo pkgInfo_ {}; diff --git a/services/ui/frame.cpp b/services/ui/frame.cpp index 25548cbaa2d06624b6e7905e41471545e820fba2..26d0d90cf0da7a416deb5efc8c56ff6fea4b9108 100644 --- a/services/ui/frame.cpp +++ b/services/ui/frame.cpp @@ -56,6 +56,7 @@ void Frame::FlushThreadLoop() }); } if (!IsVisiable()) { + flushFlag_ = false; continue; } SyncBuffer(); diff --git a/services/ui/text_label.h b/services/ui/text_label.h index 16abaf187406a8675dc7d197dc8813d7cf3cfd50..39f4d1b2000935c08b18b73745e0a92c2021d77b 100644 --- a/services/ui/text_label.h +++ b/services/ui/text_label.h @@ -24,6 +24,7 @@ namespace updater { constexpr int MAX_FONT_BUFFER_SIZE_HW = 4096; constexpr int MAX_TEXT_SIZE = 512; +constexpr int FONT_BUFFER_SIZE = 96; const std::string DEFAULT_FONT_NAME = "font"; class TextLabel : public View { @@ -71,7 +72,7 @@ private: bool boldBottomLine_ = false; FontType fontType_ { DEFAULT_FONT }; - char fontBuf_[MAX_FONT_BUFFER_SIZE_HW * MAX_FONT_BUFFER_SIZE_HW] {}; + char fontBuf_[MAX_FONT_BUFFER_SIZE_HW * FONT_BUFFER_SIZE] {}; unsigned int fontWidth_ = 0; unsigned int fontHeight_ = 0; }; diff --git a/services/ui/updater_ui.cpp b/services/ui/updater_ui.cpp index b12cf4c392ef1556dbf0383b275616e7c8448d23..f4a13ef1b44afa51564936ebafaf07a0f2aeef55 100644 --- a/services/ui/updater_ui.cpp +++ b/services/ui/updater_ui.cpp @@ -163,8 +163,6 @@ void OnKeyEvent(int viewId) ClearText(); if (viewId == g_textLabel0->GetViewId() && g_textLabel0->IsVisiable()) { HideDialog(); - LOG(INFO) << "g_textLabel0 clicked!"; - DeleteView(); PostUpdater(); utils::DoReboot(""); } else if (viewId == g_textLabel2->GetViewId() && g_textLabel2->IsVisiable()) { @@ -179,7 +177,6 @@ void OnKeyEvent(int viewId) ShowMenu(); return; } - DeleteView(); PostUpdater(); utils::DoReboot(""); } else if (viewId == g_dialogCancalBtn->GetViewId() && g_dialogCancalBtn->IsVisiable()) { diff --git a/services/updater.cpp b/services/updater.cpp index 57cfc55fd4bb7d5612a094dd4008619fb9d6a7b5..5e99ac4b3297b09b02af8fcb0d68d76e32f61cf4 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -45,11 +45,7 @@ extern ProgressBar *g_progressBar; int g_percentage; int g_tmpProgressValue; -static int GetTemprature() -{ - int temprature = FAKE_TEMPRATURE; - return temprature; -} +int g_tmpValue; static int32_t ExtractUpdaterBinary(PkgManager::PkgManagerPtr manager, const std::string &updaterBinary) { @@ -162,7 +158,6 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons UPDATER_ERROR_CHECK(pkgManager != nullptr, "Fail to GetPackageInstance", return UPDATE_CORRUPT); UPDATER_CHECK_ONLY_RETURN(SetupPartitions() == 0, ShowText(g_updateInfoLabel, "update failed"); return UPDATE_ERROR); - int beforeTemperature = GetTemprature(); LOG(INFO) << "Verify package..."; g_updateInfoLabel->SetText("Verify package..."); @@ -201,8 +196,6 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons g_updateInfoLabel->SetText("Install failed."); LOG(ERROR) << "Install package failed."; } - int afterTemprature = GetTemprature(); - LOG(INFO) << "Before install temprature: " << beforeTemperature << ",After install temprature: " << afterTemprature; return updateRet; } @@ -234,23 +227,24 @@ static void HandleChildOutput(const std::string &buffer, int32_t bufferLen, g_progressBar->Show(); g_updateInfoLabel->SetText("Start to install package."); frac = std::stof(progress[0]); - g_percentage = g_percentage + static_cast(frac * FULL_PERCENT_PROGRESS); - while (g_tmpProgressValue < g_percentage) { - g_progressBar->SetProgressValue(g_tmpProgressValue++); - std::this_thread::sleep_for(std::chrono::milliseconds(INTERVAL_TIME)); - if (g_tmpProgressValue >= FULL_PERCENT_PROGRESS - PROGRESS_VALUE_CONST) { - g_percentage = g_percentage - PROGRESS_VALUE_CONST; - break; - } - } - g_progressBar->SetProgressValue(g_percentage); + g_percentage = static_cast(frac * FULL_PERCENT_PROGRESS); } } else if (outputHeader == "set_progress") { UPDATER_ERROR_CHECK(output.size() >= DEFAULT_PROCESS_NUM, "check output fail", return); auto outputInfo = Trim(output[1]); float frac = 0.0; frac = std::stof(output[1]); - g_progressBar->SetProgressValue(FULL_PERCENT_PROGRESS); + if(frac >= -EPSINON && frac <= EPSINON) { + return; + } else { + g_tmpProgressValue = static_cast(frac * g_percentage); + } + if (frac >= FULL_EPSINON && g_tmpValue + g_percentage < FULL_PERCENT_PROGRESS) { + g_tmpValue += g_percentage; + return; + } + g_tmpProgressValue = g_tmpProgressValue + g_tmpValue; + g_progressBar->SetProgressValue(g_tmpProgressValue); } else { LOG(WARNING) << "Child process returns unexpected message."; } @@ -267,6 +261,10 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std:: UPDATER_ERROR_CHECK(ExtractUpdaterBinary(pkgManager, UPDATER_BINARY) == 0, "Updater: cannot extract updater binary from update package.", return UPDATE_CORRUPT); + g_tmpProgressValue = 0; + if (g_progressBar != nullptr) { + g_progressBar->SetProgressValue(0); + } pid_t pid = fork(); UPDATER_CHECK_ONLY_RETURN(pid >= 0, ERROR_CODE(CODE_FORK_FAIL); return UPDATE_ERROR); if (pid == 0) { // child @@ -295,10 +293,6 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std:: char buffer[MAX_BUFFER_SIZE]; bool retryUpdate = false; FILE* fromChild = fdopen(pipeRead, "r"); - g_tmpProgressValue = 0; - if (g_progressBar != nullptr) { - g_progressBar->SetProgressValue(0); - } while (fgets(buffer, MAX_BUFFER_SIZE, fromChild) != nullptr) { size_t n = strlen(buffer); if (buffer[n - 1] == '\n') { diff --git a/services/updater_binary/update_image_block.cpp b/services/updater_binary/update_image_block.cpp index 07c64c484fe3d0e7d8a47354a70a3ecface2d1de..088cb2e8ab5b135efcde6091b8db9692abc92531 100644 --- a/services/updater_binary/update_image_block.cpp +++ b/services/updater_binary/update_image_block.cpp @@ -23,6 +23,7 @@ #include "applypatch/block_set.h" #include "applypatch/store.h" #include "applypatch/transfer_manager.h" +#include "applypatch/partition_record.h" #include "fs_manager/mount.h" #include "log/log.h" #include "utils.h" @@ -246,6 +247,15 @@ static int32_t ExecuteUpdateBlock(uscript::UScriptEnv &env, uscript::UScriptCont UPDATER_CHECK_ONLY_RETURN(!GetUpdateBlockInfo(infos, env, context), return USCRIPT_ERROR_EXECUTE); UPDATER_ERROR_CHECK(env.GetPkgManager() != nullptr, "Error to get pkg manager", return USCRIPT_ERROR_EXECUTE); + if (env.IsRetry()) { + LOG(DEBUG) << "Retry updater, check if current partition updatered already during last time"; + bool isUpdated = PartitionRecord::GetInstance().IsPartitionUpdated(infos.partitionName); + if (isUpdated) { + LOG(INFO) << infos.partitionName << " already updated, skip"; + return USCRIPT_SUCCESS; + } + } + int32_t ret = ExtractDiffPackageAndLoad(infos, env, context); UPDATER_CHECK_ONLY_RETURN(ret == USCRIPT_SUCCESS, return USCRIPT_ERROR_EXECUTE); @@ -289,6 +299,9 @@ static int32_t ExecuteUpdateBlock(uscript::UScriptEnv &env, uscript::UScriptCont fd = -1; env.GetPkgManager()->ClosePkgStream(outStream); TransferManager::ReleaseTransferManagerInstance(tm); + if (ret == USCRIPT_SUCCESS) { + PartitionRecord::GetInstance().RecordPartitionUpdateStatus(infos.partitionName, true); + } return ret; } diff --git a/services/updater_binary/update_processor.cpp b/services/updater_binary/update_processor.cpp index cd3697b747b7448fcad625e642bd9f3d97a3b543..4cee4ae0905a306d7896b07d8a3a53a56073c565 100644 --- a/services/updater_binary/update_processor.cpp +++ b/services/updater_binary/update_processor.cpp @@ -31,6 +31,8 @@ using namespace hpackage; using namespace updater; namespace updater { +size_t UScriptInstructionRawImageWrite::totalSize_ = 0; +size_t UScriptInstructionRawImageWrite::readSize_ = 0; UpdaterEnv::~UpdaterEnv() { if (factory_ != nullptr) { @@ -102,6 +104,12 @@ int UScriptInstructionRawImageWrite::RawImageWriteProcessor(const PkgBuffer &buf LOG(ERROR) << "Write " << size << " byte(s) failed"; return PKG_INVALID_STREAM; } + + if (totalSize_ != 0) { + readSize_ += size; + writer->GetUpdaterEnv()->PostMessage("set_progress", std::to_string((float)readSize_/totalSize_)); + } + return PKG_SUCCESS; } @@ -122,12 +130,14 @@ int32_t UScriptInstructionRawImageWrite::Execute(uscript::UScriptEnv &env, uscri LOG(INFO) << "UScriptInstructionRawImageWrite::Execute " << partitionName; UPDATER_ERROR_CHECK(env.GetPkgManager() != nullptr, "Error to get pkg manager", return USCRIPT_ERROR_EXECUTE); - std::unique_ptr writer = DataWriter::CreateDataWriter(WRITE_RAW, partitionName); + std::unique_ptr writer = DataWriter::CreateDataWriter(WRITE_RAW, partitionName, + static_cast(&env)); UPDATER_ERROR_CHECK(writer != nullptr, "Error to create writer", return USCRIPT_ERROR_EXECUTE); // Extract partition information hpackage::PkgManager::StreamPtr outStream = nullptr; const FileInfo *info = env.GetPkgManager()->GetFileInfo(partitionName); + totalSize_ = info->unpackedSize; UPDATER_ERROR_CHECK(info != nullptr, "Error to get file info", DataWriter::ReleaseDataWriter(writer); return USCRIPT_ERROR_EXECUTE); @@ -145,6 +155,9 @@ int32_t UScriptInstructionRawImageWrite::Execute(uscript::UScriptEnv &env, uscri ret = USCRIPT_SUCCESS; env.GetPkgManager()->ClosePkgStream(outStream); DataWriter::ReleaseDataWriter(writer); + totalSize_ = 0; + readSize_ = 0; + LOG(INFO)<<"UScriptInstructionRawImageWrite finish"; return ret; } diff --git a/services/updater_binary/update_processor.h b/services/updater_binary/update_processor.h index e131a6e5bb638657d599724fb823ae6d1f8a38c9..3ed2a86fe7481673935e0fb891c62c94d3792ada 100644 --- a/services/updater_binary/update_processor.h +++ b/services/updater_binary/update_processor.h @@ -30,25 +30,6 @@ using uscript::UScriptInstructionFactoryPtr; using uscript::UScriptInstructionPtr; namespace updater { -class UpdaterEnv : public UScriptEnv { -public: - UpdaterEnv(hpackage::PkgManager::PkgManagerPtr pkgManager, FILE* pipeWrite, bool retry) : - UScriptEnv(pkgManager), pipeWrite_(pipeWrite), isRetry_(retry) {} - virtual ~UpdaterEnv(); - - virtual void PostMessage(const std::string &cmd, std::string content); - virtual UScriptInstructionFactoryPtr GetInstructionFactory(); - virtual const std::vector GetInstructionNames() const; - virtual bool IsRetry() const - { - return isRetry_; - } -private: - UScriptInstructionFactoryPtr factory_ = nullptr; - FILE* pipeWrite_ = nullptr; - bool isRetry_ = false; -}; - class UpdaterInstructionFactory : public UScriptInstructionFactory { public: virtual int32_t CreateInstructionInstance(UScriptInstructionPtr& instr, const std::string& name); @@ -71,6 +52,8 @@ public: private: static int RawImageWriteProcessor(const hpackage::PkgBuffer &buffer, size_t size, size_t start, bool isFinish, const void* context); + static size_t totalSize_; + static size_t readSize_; }; } // updater diff --git a/services/updater_main.cpp b/services/updater_main.cpp index 8de5e775c3b1e4c3b439ee5d523f2e16ee160b6f..73020ec4ba645bc56cdea0f9b60d318e3d77328f 100644 --- a/services/updater_main.cpp +++ b/services/updater_main.cpp @@ -379,9 +379,7 @@ int UpdaterMain(int argc, char **argv) return 0; } #endif - DeleteView(); PostUpdater(); - PkgManager::ReleasePackageInstance(manager); utils::DoReboot(""); return 0; } diff --git a/test/unittest/applypatch_test/applypatch_unittest.cpp b/test/unittest/applypatch_test/applypatch_unittest.cpp index 80153363f066e8f336c3dd95b5fb82d07d65d3e8..bd0c8d6ff9e0e20b5b4bf4902e09636f8b3e15e9 100755 --- a/test/unittest/applypatch_test/applypatch_unittest.cpp +++ b/test/unittest/applypatch_test/applypatch_unittest.cpp @@ -132,7 +132,7 @@ TEST_F(ApplyPatchUnitTest, updater_CreateDataWriter) EXPECT_EQ(writer, nullptr); continue; } - writer = DataWriter::CreateDataWriter(mode, ""); + writer = DataWriter::CreateDataWriter(mode, "", DataWriter::GetUpdaterEnv()); EXPECT_NE(writer, nullptr); DataWriter::ReleaseDataWriter(writer); writer = nullptr; diff --git a/test/unittest/applypatch_test/transfer_manager_unittest.cpp b/test/unittest/applypatch_test/transfer_manager_unittest.cpp index 79f8294042f0dedaa3fa634c414339b41a7e849c..7f64800d685b46f9db072d696bfac5759f6479e6 100755 --- a/test/unittest/applypatch_test/transfer_manager_unittest.cpp +++ b/test/unittest/applypatch_test/transfer_manager_unittest.cpp @@ -51,7 +51,7 @@ TEST_F(TransferManagerUnitTest, transfer_manager_test_001) { TransferManagerPtr tm = TransferManager::GetTransferManagerInstance(); std::string cmd = "zero 2,0,1"; - tm->CheckResult(CommandResult::NEED_RETRY, cmd); + tm->CheckResult(CommandResult::NEED_RETRY, cmd, CommandType::ZERO); TransferManager::ReleaseTransferManagerInstance(tm); } diff --git a/utils/utils.cpp b/utils/utils.cpp index 7ce2b17284153863ad62c6f41b0cde2c19789556..5c072f2dc3d51f2679a6a3fd462fe2820c368571 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -179,6 +179,7 @@ void DoReboot(const std::string& rebootTarget) LOG(INFO) << "DoReboot: WriteUpdaterMessage boot_updater error"; return; } + sync(); } else { UPDATER_ERROR_CHECK(!memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE), "Memset_s failed", return); bool ret = WriteUpdaterMessage(miscBlockDevice, msg); @@ -186,9 +187,13 @@ void DoReboot(const std::string& rebootTarget) LOG(INFO) << "DoReboot: WriteUpdaterMessage empty error"; return; } + sync(); } #ifndef UPDATER_UT syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, rebootTarget.c_str()); + while (true) { + pause(); + } #else return; #endif