diff --git a/interfaces/kits/include/misc_info/misc_info.h b/interfaces/kits/include/misc_info/misc_info.h index d866253a61494fca87160a6c347feb6102396fc0..8b260fcaa90b53737c65521daf8b234490981b10 100755 --- a/interfaces/kits/include/misc_info/misc_info.h +++ b/interfaces/kits/include/misc_info/misc_info.h @@ -24,10 +24,18 @@ namespace updater { constexpr int MAX_COMMAND_SIZE = 20; constexpr int MAX_UPDATE_SIZE = 100; -// misc partition offset definition. + +// misc partition offset definition. max size of misc is 1MB, do not overflow. constexpr off_t MISC_BASE_OFFSET = 0; + constexpr off_t MISC_UPDATE_MESSAGE_OFFSET = MISC_BASE_OFFSET; -constexpr off_t MISC_PARTITION_RECORD_OFFSET = MISC_UPDATE_MESSAGE_OFFSET + MAX_COMMAND_SIZE + MAX_UPDATE_SIZE; +constexpr off_t MISC_UPDATE_MESSAGE_SIZE = 120; + +constexpr off_t MISC_PARTITION_RECORD_OFFSET = MISC_UPDATE_MESSAGE_OFFSET + MISC_UPDATE_MESSAGE_SIZE; +constexpr off_t MISC_PARTITION_RECORD_SIZE = 1024; + +constexpr off_t MISC_RECORD_UPDATE_PARTITIONS_OFFSET = MISC_PARTITION_RECORD_OFFSET + MISC_PARTITION_RECORD_SIZE; +constexpr off_t MISC_RECORD_UPDATE_PARTITIONS_SIZE = 256; struct UpdateMessage { char command[MAX_COMMAND_SIZE]; diff --git a/interfaces/kits/include/package/package.h b/interfaces/kits/include/package/package.h index b08942cae85723fe5d224ac90742c8eef74c7b5f..94baf70a79012c3c41b1cf96dab2c3719592ce67 100755 --- a/interfaces/kits/include/package/package.h +++ b/interfaces/kits/include/package/package.h @@ -82,6 +82,7 @@ struct UpgradePkgInfoExt { char *softwareVersion; char *date; char *time; + char *descriptPackageId = nullptr; }; struct ComponentInfoExt { diff --git a/interfaces/kits/packages/package.cpp b/interfaces/kits/packages/package.cpp index fcba7a4e5854e3c186fbaa936ff35df3679aac5e..ad8dae29762a838c688d03bffd2d2b4a4256d8ae 100755 --- a/interfaces/kits/packages/package.cpp +++ b/interfaces/kits/packages/package.cpp @@ -31,10 +31,21 @@ static int32_t GetUpgradePkgInfo(UpgradePkgInfo *upgradePackageInfo, ComponentInfoExt compInfo[]) { upgradePackageInfo->updateFileVersion = pkgInfoExt->updateFileVersion; - upgradePackageInfo->softwareVersion = pkgInfoExt->softwareVersion; - upgradePackageInfo->productUpdateId = pkgInfoExt->productUpdateId; - upgradePackageInfo->time = pkgInfoExt->time; - upgradePackageInfo->date = pkgInfoExt->date; + if (pkgInfoExt->softwareVersion != nullptr) { + upgradePackageInfo->softwareVersion = pkgInfoExt->softwareVersion; + } + if (pkgInfoExt->productUpdateId != nullptr) { + upgradePackageInfo->productUpdateId = pkgInfoExt->productUpdateId; + } + if (pkgInfoExt->descriptPackageId != nullptr) { + upgradePackageInfo->descriptPackageId = pkgInfoExt->descriptPackageId; + } + if (pkgInfoExt->time != nullptr) { + upgradePackageInfo->time = pkgInfoExt->time; + } + if (pkgInfoExt->date != nullptr) { + upgradePackageInfo->date = pkgInfoExt->date; + } upgradePackageInfo->pkgInfo.digestMethod = pkgInfoExt->digestMethod; upgradePackageInfo->pkgInfo.signMethod = pkgInfoExt->signMethod; upgradePackageInfo->pkgInfo.entryCount = pkgInfoExt->entryCount; diff --git a/services/applypatch/block_set.cpp b/services/applypatch/block_set.cpp index 0b1e2d7417bc9123b4d4ab96101d93c9ef153517..51cef91ad4f9dbf1e624928760610110d6728add 100644 --- a/services/applypatch/block_set.cpp +++ b/services/applypatch/block_set.cpp @@ -320,7 +320,7 @@ int32_t BlockSet::WriteDiffToBlock(const Command &cmd, std::vector &src reinterpret_cast(srcBuffer.data()), srcBuffSize, reinterpret_cast(patchBuff), length }; std::unique_ptr writer = std::make_unique(cmd.GetFileDescriptor(), *this); - UPDATER_ERROR_CHECK(writer.get() != nullptr, "Cannot create block writer, imgdiff patch abort!", return -1); + UPDATER_ERROR_CHECK(writer.get() != nullptr, "Cannot create block writer, pkgdiff patch abort!", return -1); int32_t ret = updatepatch::UpdatePatch::ApplyImagePatch(patchParam, empty, [&](size_t start, const updatepatch::BlockBuffer &data, size_t size) -> int { bool ret = writer->Write(data.buffer, size, WRITE_BLOCK, ""); diff --git a/services/applypatch/command.cpp b/services/applypatch/command.cpp index d6041088ec0524191ffe5f552118ea857e31024b..9d8cdb745e47d68b54eaf843fa3098d23ecfee1c 100644 --- a/services/applypatch/command.cpp +++ b/services/applypatch/command.cpp @@ -72,7 +72,7 @@ CommandType Command::ParseCommandType(const std::string &firstCmd) return CommandType::ERASE; } else if (firstCmd == "free") { return CommandType::FREE; - } else if (firstCmd == "imgdiff") { + } else if (firstCmd == "pkgdiff") { return CommandType::IMGDIFF; } else if (firstCmd == "move") { return CommandType::MOVE; diff --git a/services/applypatch/partition_record.cpp b/services/applypatch/partition_record.cpp index cdaeea12e6f06348b84fd00653cc1361b92db502..02ea8459ba24f3d8e2ae455845b0c6f7c5a5d682 100644 --- a/services/applypatch/partition_record.cpp +++ b/services/applypatch/partition_record.cpp @@ -61,7 +61,7 @@ bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionNa int fd = open(miscBlockDevice.c_str(), O_RDWR | O_EXCL | O_CLOEXEC | O_BINARY); UPDATER_FILE_CHECK(fd >= 0, "PartitionRecord: Open misc to recording partition failed", return false); off_t newOffset = 0; - UPDATER_CHECK_FILE_OP(lseek(fd, MISC_PARTITION_RECORD_OFFSET, SEEK_SET) >= 0, + UPDATER_CHECK_FILE_OP(lseek(fd, PARTITION_RECORD_OFFSET, SEEK_SET) >= 0, "PartitionRecord: Seek misc to record offset failed", fd, return false); UPDATER_CHECK_FILE_OP(read(fd, &newOffset, sizeof(off_t)) == sizeof(off_t), "PartitionRecord: Read offset failed", fd, return false); @@ -76,7 +76,7 @@ bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionNa UPDATER_CHECK_FILE_OP(write(fd, &info_, sizeof(PartitionRecordInfo)) == sizeof(PartitionRecordInfo), "PartitionRecord: write failed", fd, return false); offset_ += sizeof(PartitionRecordInfo); - UPDATER_CHECK_FILE_OP(lseek(fd, MISC_PARTITION_RECORD_OFFSET, SEEK_SET) >= 0, + UPDATER_CHECK_FILE_OP(lseek(fd, PARTITION_RECORD_OFFSET, SEEK_SET) >= 0, "PartitionRecord: Seek misc to record offset failed", fd, return false); UPDATER_CHECK_FILE_OP(write(fd, &offset_, sizeof(off_t)) == sizeof(off_t), "PartitionRecord: Seek misc to record offset failed", fd, return false); @@ -99,7 +99,7 @@ bool PartitionRecord::ClearRecordPartitionOffset() if (!miscBlockDevice.empty()) { int fd = open(miscBlockDevice.c_str(), O_RDWR | O_EXCL | O_CLOEXEC | O_BINARY); UPDATER_FILE_CHECK(fd >= 0, "Open misc to recording partition failed", return false); - UPDATER_CHECK_FILE_OP(lseek(fd, MISC_PARTITION_RECORD_OFFSET, SEEK_SET) >= 0, + UPDATER_CHECK_FILE_OP(lseek(fd, PARTITION_RECORD_OFFSET, SEEK_SET) >= 0, "Seek misc to specific offset failed", fd, return false); off_t initOffset = 0; diff --git a/services/applypatch/store.cpp b/services/applypatch/store.cpp index a906eebac92372d80530fc84620d48d7ca9d18ac..7bbc27d21da83604ec8d09c5dbeb2658582e46c8 100644 --- a/services/applypatch/store.cpp +++ b/services/applypatch/store.cpp @@ -59,13 +59,13 @@ int32_t Store::CreateNewSpace(const std::string &path, bool needClear) LOG(INFO) << "Create dir " << dirPath; if (stat(dirPath.c_str(), &fileStat) == -1) { UPDATER_ERROR_CHECK(errno == ENOENT, "Create new space, failed to stat", return -1); - UPDATER_ERROR_CHECK(MkdirRecursive(dirPath, S_DIR_PERMISSION) == 0, "Failed to make store", return -1); - UPDATER_ERROR_CHECK(chown(dirPath.c_str(), S_USER_PERMISSION, S_USER_PERMISSION) == 0, + UPDATER_ERROR_CHECK(MkdirRecursive(dirPath, S_IRWXU) == 0, "Failed to make store", return -1); + UPDATER_ERROR_CHECK(chown(dirPath.c_str(), O_USER_GROUP_ID, O_USER_GROUP_ID) == 0, "Failed to chown store", return -1); } else { UPDATER_CHECK_ONLY_RETURN(needClear, return 0); - std::vector files; - UPDATER_CHECK_ONLY_RETURN(GetFilesFromDirectory(dirPath, files) > 0, return -1); + std::vector files {}; + UPDATER_CHECK_ONLY_RETURN(GetFilesFromDirectory(dirPath, files) >= 0, return -1); UPDATER_CHECK_ONLY_RETURN(!files.empty(), return 0); std::vector::iterator iter = files.begin(); while (iter != files.end()) { @@ -90,9 +90,9 @@ int32_t Store::WriteDataToStore(const std::string &dirPath, const std::string &f std::string path = pathTmp + fileName; pathTmp = pathTmp + fileName + ".tmp"; - int fd = open(pathTmp.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_OPEN_PERMISSION); + 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, S_USER_PERMISSION, S_USER_PERMISSION) == 0, + UPDATER_ERROR_CHECK(fchown(fd, O_USER_GROUP_ID, O_USER_GROUP_ID) == 0, "Failed to chown", close(fd); return -1); LOG(INFO) << "Writing " << size << " blocks to " << path; if (!WriteFully(fd, const_cast(buffer.data()), size)) { diff --git a/services/applypatch/transfer_manager.cpp b/services/applypatch/transfer_manager.cpp index 32cfeb5399293880a98d9f1aa9789612a3c69f48..2051955b08f6a7063648bac7994cbc45cc691aee 100644 --- a/services/applypatch/transfer_manager.cpp +++ b/services/applypatch/transfer_manager.cpp @@ -108,9 +108,9 @@ void TransferManager::Init() bool TransferManager::RegisterForRetry(const std::string &cmd) { std::string path = globalParams->storeBase + "/" + "retry_flag"; - int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_OPEN_PERMISSION); + int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); UPDATER_ERROR_CHECK(fd != -1, "Failed to create", return false); - UPDATER_ERROR_CHECK(fchown(fd, S_USER_PERMISSION, S_USER_PERMISSION) == 0, + UPDATER_ERROR_CHECK(fchown(fd, O_USER_GROUP_ID, O_USER_GROUP_ID) == 0, "Failed to chown", close(fd); return -1); bool ret = utils::WriteStringToFile(fd, cmd); UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Write retry flag error"); diff --git a/services/diffpatch/bzip2/bzip2_adapter.cpp b/services/diffpatch/bzip2/bzip2_adapter.cpp index f305126ba1395e9fa46da28f7ecf9ff8069416d8..f07cd19d1a44a3ab10a202e809e897a7e0391441 100644 --- a/services/diffpatch/bzip2/bzip2_adapter.cpp +++ b/services/diffpatch/bzip2/bzip2_adapter.cpp @@ -41,15 +41,17 @@ int32_t BZip2Adapter::Close() return ret; } -int32_t BZip2Adapter::WriteData(const BlockBuffer &srcData) +int32_t BZipBuffer2Adapter::WriteData(const BlockBuffer &srcData) { stream_.next_in = reinterpret_cast(srcData.buffer); - if (offset_ + srcData.length > buffer_.size()) { + stream_.avail_in = srcData.length; + + if (offset_ + dataSize_ + srcData.length > buffer_.size()) { buffer_.resize(buffer_.size() + srcData.length); } - stream_.avail_in = srcData.length; - stream_.avail_out = buffer_.size() - offset_; - stream_.next_out = reinterpret_cast(buffer_.data() + offset_); + char *next = reinterpret_cast(buffer_.data() + offset_ + dataSize_); + stream_.avail_out = buffer_.size() - offset_ - dataSize_; + stream_.next_out = next; int32_t ret = BZ_RUN_OK; do { ret = BZ2_bzCompress(&stream_, BZ_RUN); @@ -59,31 +61,96 @@ int32_t BZip2Adapter::WriteData(const BlockBuffer &srcData) } while (ret == BZ_RUN_OK); PATCH_CHECK(ret == BZ_RUN_OK, return ret, "Failed to write data ret %d", ret); PATCH_CHECK(stream_.avail_in == 0, return ret, "Failed to write data"); - offset_ = stream_.next_out - reinterpret_cast(buffer_.data()); + dataSize_ += stream_.next_out - next; return PATCH_SUCCESS; } -int32_t BZip2Adapter::FlushData(size_t &offset) +int32_t BZipBuffer2Adapter::FlushData(size_t &dataSize) { - PATCH_DEBUG("FlushData offset_ %d offset %zu ", offset_, offset); - stream_.next_in = nullptr; + dataSize = 0; + PATCH_DEBUG("FlushData dataSize_ %d ", dataSize_); + stream_.next_in = 0; stream_.avail_in = 0; - stream_.avail_out = buffer_.size() - offset_; - stream_.next_out = reinterpret_cast(buffer_.data() + offset_); + stream_.avail_out = buffer_.size() - offset_ - dataSize_; + char *next = reinterpret_cast(buffer_.data() + offset_ + dataSize_); + stream_.next_out = next; int ret = BZ_FINISH_OK; while (ret == BZ_FINISH_OK) { ret = BZ2_bzCompress(&stream_, BZ_FINISH); if (stream_.avail_out == 0) { - offset_ = stream_.next_out - reinterpret_cast(buffer_.data()); + dataSize_ += stream_.next_out - next; buffer_.resize(buffer_.size() + IGMDIFF_LIMIT_UNIT); - stream_.avail_out = buffer_.size() - offset_; - stream_.next_out = reinterpret_cast(buffer_.data() + offset_); + stream_.avail_out = buffer_.size() - offset_ + dataSize_; + next = reinterpret_cast(buffer_.data() + offset_ + dataSize_); + stream_.next_out = next; } } PATCH_CHECK(ret == BZ_RUN_OK || ret == BZ_STREAM_END, return ret, "Failed to write data %d", ret); - offset_ = stream_.next_out - reinterpret_cast(buffer_.data()); - PATCH_DEBUG("FlushData offset_ %zu ", offset_); - offset = offset_; + dataSize_ += stream_.next_out - next; + PATCH_DEBUG("FlushData offset_ %zu dataSize_ %zu ", offset_, dataSize_); + dataSize = dataSize_; + return 0; +} + +int32_t BZip2StreamAdapter::Open() +{ + buffer_.resize(IGMDIFF_LIMIT_UNIT); + return BZip2Adapter::Open(); +} + +int32_t BZip2StreamAdapter::WriteData(const BlockBuffer &srcData) +{ + stream_.next_in = reinterpret_cast(srcData.buffer); + stream_.avail_in = srcData.length; + + stream_.avail_out = buffer_.size(); + stream_.next_out = reinterpret_cast(buffer_.data()); + int32_t ret = BZ_RUN_OK; + do { + ret = BZ2_bzCompress(&stream_, BZ_RUN); + if (stream_.avail_out == 0) { + outStream_.write(buffer_.data(), buffer_.size()); + dataSize_ += stream_.next_out - reinterpret_cast(buffer_.data()); + stream_.avail_out = buffer_.size(); + stream_.next_out = reinterpret_cast(buffer_.data()); + } + if (stream_.avail_in == 0) { + break; + } + } while (ret == BZ_RUN_OK); + PATCH_CHECK(ret == BZ_RUN_OK, return ret, "Failed to write data ret %d", ret); + PATCH_CHECK(stream_.avail_in == 0, return ret, "Failed to write data"); + if (stream_.avail_out != buffer_.size()) { + outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast(buffer_.data())); + } + dataSize_ += stream_.next_out - reinterpret_cast(buffer_.data()); + return PATCH_SUCCESS; +} +int32_t BZip2StreamAdapter::FlushData(size_t &dataSize) +{ + dataSize = 0; + PATCH_DEBUG("FlushData dataSize_ %d ", dataSize_); + stream_.next_in = 0; + stream_.avail_in = 0; + stream_.avail_out = buffer_.size(); + stream_.next_out = reinterpret_cast(buffer_.data()); + int ret = BZ_FINISH_OK; + while (ret == BZ_FINISH_OK) { + ret = BZ2_bzCompress(&stream_, BZ_FINISH); + if (stream_.avail_out == 0) { + outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast(buffer_.data())); + dataSize_ += stream_.next_out - reinterpret_cast(buffer_.data()); + stream_.avail_out = buffer_.size(); + stream_.next_out = reinterpret_cast(buffer_.data()); + } + } + PATCH_CHECK(ret == BZ_RUN_OK || ret == BZ_STREAM_END, return ret, "Failed to write data %d", ret); + if (stream_.avail_out != buffer_.size()) { + outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast(buffer_.data())); + } + dataSize_ += stream_.next_out - reinterpret_cast(buffer_.data()); + PATCH_DEBUG("FlushData dataSize %zu %zu", dataSize_, static_cast(outStream_.tellp())); + dataSize = dataSize_; return 0; } diff --git a/services/diffpatch/bzip2/bzip2_adapter.h b/services/diffpatch/bzip2/bzip2_adapter.h index 7abc9102b75550e75c9420052bc190321d19fe17..1a5dbfdaa15c66e9d8e50d54cfcdddb4868b4e6d 100644 --- a/services/diffpatch/bzip2/bzip2_adapter.h +++ b/services/diffpatch/bzip2/bzip2_adapter.h @@ -26,20 +26,50 @@ namespace updatepatch { class BZip2Adapter : public DeflateAdapter { public: - BZip2Adapter(std::vector &buffer, size_t offset) - : DeflateAdapter(), buffer_(buffer), offset_(offset) {} + BZip2Adapter() : DeflateAdapter() {} ~BZip2Adapter() override {} int32_t Open() override; int32_t Close() override; + int32_t WriteData(const BlockBuffer &srcData) override + { + return 0; + } + int32_t FlushData(size_t &offset) override + { + return 0; + } +protected: + static constexpr int32_t BLOCK_SIZE_BEST = 9; + bz_stream stream_ {}; +}; + +class BZipBuffer2Adapter : public BZip2Adapter { +public: + BZipBuffer2Adapter(std::vector &buffer, size_t offset) + : BZip2Adapter(), offset_(offset), buffer_(buffer) {} + ~BZipBuffer2Adapter() override {} int32_t WriteData(const BlockBuffer &srcData) override; - int32_t FlushData(size_t &offset) override; + int32_t FlushData(size_t &dataSize) override; private: - static constexpr int32_t BLOCK_SIZE_BEST = 9; + size_t offset_ { 0 }; + size_t dataSize_ { 0 }; std::vector &buffer_; - size_t offset_; - bz_stream stream_ {}; +}; + +class BZip2StreamAdapter : public BZip2Adapter { +public: + explicit BZip2StreamAdapter(std::fstream &stream) : BZip2Adapter(), outStream_(stream) {} + ~BZip2StreamAdapter() override {} + + int32_t Open() override; + int32_t WriteData(const BlockBuffer &srcData) override; + int32_t FlushData(size_t &dataSize) override; +private: + std::vector buffer_ { 0 }; + size_t dataSize_ { 0 }; + std::fstream &outStream_; }; class BZip2ReadAdapter { diff --git a/services/diffpatch/bzip2/lz4_adapter.cpp b/services/diffpatch/bzip2/lz4_adapter.cpp index 196ed10f9064400c32e39e41fdfec9581e226a24..c2ab338284155d6a7d53895a689b1bdf98d28587 100644 --- a/services/diffpatch/bzip2/lz4_adapter.cpp +++ b/services/diffpatch/bzip2/lz4_adapter.cpp @@ -83,9 +83,9 @@ int32_t Lz4FrameAdapter::Open() PATCH_CHECK(outBuffSize > 0, return -1, "BufferSize must > 0"); buffer_.resize(outBuffSize); - PATCH_LOGI("frameInfo blockSizeID %d compressionLevel_: %d blockIndependence_:%d %d blockSize %zu %zu %zu", + PATCH_LOGI("frameInfo blockSizeID %d compressionLevel_: %d blockIndependence_:%d %d %d blockSize %zu %zu %zu", static_cast(blockSizeID_), static_cast(compressionLevel_), - static_cast(blockIndependence_), static_cast(contentChecksumFlag_), + static_cast(blockIndependence_), static_cast(contentChecksumFlag_), autoFlush_, blockSize, LZ4_BLOCK_SIZE(blockSizeID_), outBuffSize); /* write package header */ diff --git a/services/diffpatch/diff/blocks_diff.cpp b/services/diffpatch/diff/blocks_diff.cpp index e472875abae2fda9fc523ae9010f5b536b2c0c41..7a97f9177e65132e211ecee507a35d8f14077970 100644 --- a/services/diffpatch/diff/blocks_diff.cpp +++ b/services/diffpatch/diff/blocks_diff.cpp @@ -29,7 +29,6 @@ namespace updatepatch { (buffer)[index] = (y) % 256; (y) -= (buffer)[index]; (y) = (y) / 256 constexpr uint32_t BUCKET_SIZE = 256; -constexpr uint32_t PATCH_BUFFER = 10240; constexpr uint32_t MULTIPLE_TWO = 2; constexpr int64_t BLOCK_SCORE = 8; constexpr int64_t MIN_LENGTH = 16; @@ -62,23 +61,54 @@ int32_t BlocksDiff::MakePatch(const std::string &oldFileName, const std::string const std::string &patchFileName) { PATCH_LOGI("BlocksDiff::MakePatch %s ", patchFileName.c_str()); + std::fstream patchFile(patchFileName, std::ios::out | std::ios::trunc | std::ios::binary); + PATCH_CHECK(!patchFile.fail(), return -1, "Failed to open %s", strerror(errno)); + MemMapInfo oldBuffer {}; MemMapInfo newBuffer {}; int32_t ret = PatchMapFile(oldFileName, oldBuffer); ret |= PatchMapFile(newFileName, newBuffer); - if (ret == PATCH_SUCCESS) { - BlockBuffer newInfo = {newBuffer.memory, newBuffer.length}; - BlockBuffer oldInfo = {oldBuffer.memory, oldBuffer.length}; - std::vector patchData; - ret = MakePatch(newInfo, oldInfo, patchData); - PATCH_CHECK(ret == PATCH_SUCCESS, return ret, "Failed to generate patch"); - ret = WriteDataToFile(patchFileName, patchData, patchData.size()); + PATCH_CHECK(ret == 0, return -1, "Failed to open %s", newFileName.c_str()); + BlockBuffer newInfo = {newBuffer.memory, newBuffer.length}; + BlockBuffer oldInfo = {oldBuffer.memory, oldBuffer.length}; + std::unique_ptr blockdiff = std::make_unique(patchFile, 0); + size_t patchSize = 0; + ret = blockdiff->MakePatch(newInfo, oldInfo, patchSize); + PATCH_CHECK(ret == PATCH_SUCCESS, return ret, "Failed to generate patch"); + PATCH_DEBUG("MakePatch %zu", static_cast(patchFile.tellp())); + patchFile.close(); + PATCH_LOGI("BlocksDiff::MakePatch success %zu", patchSize); + return ret; +} + +int32_t BlocksDiff::MakePatch(const BlockBuffer &newInfo, + const BlockBuffer &oldInfo, std::vector &patchData, size_t offset, size_t &patchSize) +{ + if (patchData.empty()) { + patchData.resize(IGMDIFF_LIMIT_UNIT); } + std::unique_ptr blockdiff = std::make_unique(patchData, offset); + int32_t ret = blockdiff->MakePatch(newInfo, oldInfo, patchSize); + PATCH_CHECK(ret == PATCH_SUCCESS, return ret, "Failed to generate patch"); + PATCH_CHECK(patchData.size() >= patchSize, return -1, "Failed to make block patch"); + patchData.resize(patchSize); + PATCH_LOGI("BlocksDiff::MakePatch success %zu", patchSize); + return ret; +} + +int32_t BlocksDiff::MakePatch(const BlockBuffer &newInfo, + const BlockBuffer &oldInfo, std::fstream &patchFile, size_t &patchSize) +{ + std::unique_ptr blockdiff = std::make_unique( + patchFile, static_cast(patchFile.tellp())); + int32_t ret = blockdiff->MakePatch(newInfo, oldInfo, patchSize); + PATCH_CHECK(ret == PATCH_SUCCESS, return ret, "Failed to generate patch"); + PATCH_LOGI("BlocksDiff::MakePatch success %zu patchFile %zu", + patchSize, static_cast(patchFile.tellp())); return ret; } -int32_t BlocksDiff::MakePatch(const BlockBuffer &newInfo, const BlockBuffer &oldInfo, - std::vector &patchData) +int32_t BlocksDiff::MakePatch(const BlockBuffer &newInfo, const BlockBuffer &oldInfo, size_t &patchSize) { if (suffixArray_ == nullptr) { suffixArray_.reset(new SuffixArray()); @@ -86,43 +116,93 @@ int32_t BlocksDiff::MakePatch(const BlockBuffer &newInfo, const BlockBuffer &old suffixArray_->Init(oldInfo); } - patchData.resize(PATCH_BUFFER); std::vector controlDatas; int32_t ret = GetCtrlDatas(newInfo, oldInfo, controlDatas); - PATCH_CHECK(ret == PATCH_SUCCESS, return ret, "Failed to get control data"); + PATCH_CHECK(ret == 0, return ret, "Failed to get control data"); - // 生成补丁数据,使用bzip进行压缩 - ret = memcpy_s(patchData.data(), patchData.size(), BSDIFF_MAGIC.c_str(), BSDIFF_MAGIC.size()); - PATCH_CHECK(ret == 0, return ret, "Failed to copy magic"); - size_t patchSize = BSDIFF_MAGIC.size() + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t); + patchSize = 0; + ret = WritePatchHeader(0, 0, 0, patchSize); + PATCH_CHECK(ret == 0, return ret, "Failed to write patch header"); size_t controlSize = patchSize; - ret = WriteControlData(controlDatas, patchData, patchSize); + ret = WriteControlData(controlDatas, patchSize); PATCH_CHECK(ret == BZ_OK, return ret, "Failed to write diff data"); controlSize = patchSize - controlSize; // 写diff数据 size_t diffDataSize = patchSize; - ret = WriteDiffData(controlDatas, patchData, patchSize); + ret = WriteDiffData(controlDatas, patchSize); PATCH_CHECK(ret == BZ_OK, return ret, "Failed to write diff data"); diffDataSize = patchSize - diffDataSize; size_t extraDataSize = patchSize; - ret = WriteExtraData(controlDatas, patchData, patchSize); + ret = WriteExtraData(controlDatas, patchSize); PATCH_CHECK(ret == BZ_OK, return ret, "Failed to write extra data"); extraDataSize = patchSize - extraDataSize; - PATCH_DEBUG("MakePatch patchSize:%zu controlSize:%zu diffDataSize:%zu, extraDataSize:%zu", + // write real data + size_t headerLen = 0; + ret = WritePatchHeader(controlSize, diffDataSize, newInfo.length, headerLen); + PATCH_CHECK(ret == 0, return ret, "Failed to write patch header"); + + PATCH_DEBUG("MakePatch success patchSize:%zu controlSize:%zu diffDataSize:%zu, extraDataSize:%zu", patchSize, controlSize, diffDataSize, extraDataSize); + return 0; +} - // 修改为实际的长度 - patchData.resize(patchSize); - BlockBuffer data = {patchData.data() + BSDIFF_MAGIC.size(), patchSize}; +std::unique_ptr BlocksBufferDiff::CreateBZip2Adapter(size_t patchOffset) +{ + std::unique_ptr bzip2Adapter = std::make_unique(patchData_, + offset_ + patchOffset); + PATCH_CHECK(bzip2Adapter != nullptr, return nullptr, "Failed to create bzip2Adapter"); + bzip2Adapter->Open(); + return bzip2Adapter; +} + +std::unique_ptr BlocksStreamDiff::CreateBZip2Adapter(size_t patchOffset) +{ + std::unique_ptr bzip2Adapter = std::make_unique(stream_); + PATCH_CHECK(bzip2Adapter != nullptr, return nullptr, "Failed to create bzip2Adapter"); + bzip2Adapter->Open(); + return bzip2Adapter; +} + +int32_t BlocksBufferDiff::WritePatchHeader(int64_t controlSize, + int64_t diffDataSize, int64_t newSize, size_t &headerLen) +{ + headerLen = BSDIFF_MAGIC.size() + sizeof(int64_t) + sizeof(int64_t) + sizeof(int64_t); + PATCH_CHECK(patchData_.size() > headerLen + offset_, return -1, "Invalid patch size"); + + int32_t ret = memcpy_s(patchData_.data() + offset_, patchData_.size(), BSDIFF_MAGIC.c_str(), BSDIFF_MAGIC.size()); + PATCH_CHECK(ret == 0, return ret, "Failed to copy magic"); + headerLen = BSDIFF_MAGIC.size(); + BlockBuffer data = {patchData_.data() + offset_ + headerLen, patchData_.size()}; WriteLE64(data, controlSize); - BlockBuffer diffData = {patchData.data() + BSDIFF_MAGIC.size() + sizeof(uint64_t), patchSize}; + headerLen += sizeof(int64_t); + BlockBuffer diffData = {patchData_.data() + offset_ + headerLen, patchData_.size()}; WriteLE64(diffData, diffDataSize); - BlockBuffer newData = {patchData.data() + BSDIFF_MAGIC.size() + sizeof(uint64_t) + sizeof(uint64_t), patchSize}; - WriteLE64(newData, newInfo.length); + headerLen += sizeof(int64_t); + BlockBuffer newData = {patchData_.data() + offset_ + headerLen, patchData_.size()}; + WriteLE64(newData, newSize); + headerLen += sizeof(int64_t); + return 0; +} + +int32_t BlocksStreamDiff::WritePatchHeader(int64_t controlSize, + int64_t diffDataSize, int64_t newSize, size_t &headerLen) +{ + PATCH_DEBUG("WritePatchHeader %zu", static_cast(stream_.tellp())); + stream_.seekp(offset_, std::ios::beg); + stream_.write(BSDIFF_MAGIC.c_str(), BSDIFF_MAGIC.size()); + PkgBuffer buffer(sizeof(int64_t)); + WriteLE64(buffer, controlSize); + stream_.write(reinterpret_cast(buffer.buffer), sizeof(int64_t)); + WriteLE64(buffer, diffDataSize); + stream_.write(reinterpret_cast(buffer.buffer), sizeof(int64_t)); + WriteLE64(buffer, newSize); + stream_.write(reinterpret_cast(buffer.buffer), sizeof(int64_t)); + headerLen = BSDIFF_MAGIC.size() + sizeof(int64_t) + sizeof(int64_t) + sizeof(int64_t); + stream_.seekp(0, std::ios::end); return 0; } @@ -234,10 +314,9 @@ int32_t BlocksDiff::GetCtrlDatas(const BlockBuffer &newInfo, return 0; } -int32_t BlocksDiff::WriteControlData(const std::vector controlDatas, - std::vector &patchData, size_t &patchSize) const +int32_t BlocksDiff::WriteControlData(const std::vector controlDatas, size_t &patchSize) { - std::unique_ptr bzip2Adapter = std::make_unique(patchData, patchSize); + std::unique_ptr bzip2Adapter = CreateBZip2Adapter(patchSize); PATCH_CHECK(bzip2Adapter != nullptr, return -1, "Failed to create bzip2Adapter"); bzip2Adapter->Open(); int32_t ret = 0; @@ -256,51 +335,54 @@ int32_t BlocksDiff::WriteControlData(const std::vector controlDatas ret = bzip2Adapter->WriteData(srcData); PATCH_CHECK(ret == 0, return ret, "Failed to write data"); } - ret = bzip2Adapter->FlushData(patchSize); + size_t dataSize = 0; + ret = bzip2Adapter->FlushData(dataSize); bzip2Adapter->Close(); + patchSize += dataSize; PATCH_DEBUG("WriteControlData exit patchSize %zu", patchSize); return 0; } -int32_t BlocksDiff::WriteDiffData(const std::vector controlDatas, - std::vector &patchData, size_t &patchSize) const +int32_t BlocksDiff::WriteDiffData(const std::vector controlDatas, size_t &patchSize) { PATCH_DEBUG("WriteDiffData patchSize %zu", patchSize); - shared_ptr bzip2Adapter = make_shared(patchData, patchSize); + std::unique_ptr bzip2Adapter = CreateBZip2Adapter(patchSize); PATCH_CHECK(bzip2Adapter != nullptr, return -1, "Failed to create bzip2Adapter"); bzip2Adapter->Open(); - std::vector diffData; + std::vector diffData(IGMDIFF_LIMIT_UNIT, 0); int32_t ret = 0; for (size_t i = 0; i < controlDatas.size(); i++) { if (controlDatas[i].diffLength <= 0) { continue; } - if (diffData.size() < static_cast(controlDatas[i].diffLength)) { - diffData.resize(controlDatas[i].diffLength); - } - for (int64_t k = 0; k < controlDatas[i].diffLength; k++) { - diffData[k] = controlDatas[i].diffNewStart[k] - controlDatas[i].diffOldStart[k]; - } + int64_t offset = 0; + while (offset < controlDatas[i].diffLength) { + int64_t cpyLen = static_cast(IGMDIFF_LIMIT_UNIT); + cpyLen = (offset + cpyLen > controlDatas[i].diffLength) ? (controlDatas[i].diffLength - offset) : cpyLen; + for (int64_t k = 0; k < cpyLen; k++) { + diffData[k] = controlDatas[i].diffNewStart[offset + k] - controlDatas[i].diffOldStart[offset + k]; + } - BlockBuffer srcData = { - reinterpret_cast(diffData.data()), static_cast(controlDatas[i].diffLength) - }; - ret = bzip2Adapter->WriteData(srcData); - PATCH_CHECK(ret == 0, return ret, "Failed to write data"); + BlockBuffer srcData = {reinterpret_cast(diffData.data()), static_cast(cpyLen)}; + ret = bzip2Adapter->WriteData(srcData); + PATCH_CHECK(ret == 0, return ret, "Failed to write data"); + offset += cpyLen; + } } - ret = bzip2Adapter->FlushData(patchSize); + size_t dataSize = 0; + ret = bzip2Adapter->FlushData(dataSize); bzip2Adapter->Close(); - PATCH_DEBUG("WriteDiffData exit patchSize %zu ", patchSize); + patchSize += dataSize; + PATCH_DEBUG("WriteDiffData exit patchSize %zu dataSize %zu ", patchSize, dataSize); return 0; } -int32_t BlocksDiff::WriteExtraData(const std::vector controlDatas, - std::vector &patchData, size_t &patchSize) const +int32_t BlocksDiff::WriteExtraData(const std::vector controlDatas, size_t &patchSize) { PATCH_DEBUG("WriteExtraData patchSize %zu ", patchSize); - shared_ptr bzip2Adapter = make_shared(patchData, patchSize); + std::unique_ptr bzip2Adapter = CreateBZip2Adapter(patchSize); PATCH_CHECK(bzip2Adapter != nullptr, return -1, "Failed to create bzip2Adapter"); bzip2Adapter->Open(); int32_t ret = 0; @@ -312,8 +394,10 @@ int32_t BlocksDiff::WriteExtraData(const std::vector controlDatas, ret = bzip2Adapter->WriteData(srcData); PATCH_CHECK(ret == 0, return ret, "Failed to write data"); } - ret = bzip2Adapter->FlushData(patchSize); + size_t dataSize = 0; + ret = bzip2Adapter->FlushData(dataSize); bzip2Adapter->Close(); + patchSize += dataSize; PATCH_DEBUG("WriteExtraData exit patchSize %zu", patchSize); return 0; } diff --git a/services/diffpatch/diff/blocks_diff.h b/services/diffpatch/diff/blocks_diff.h index 1bdead30911993b81db3c8ac4cdf708c86182bb9..dc682eac4d3b7e9e10d9b894577d8b098b4b323b 100644 --- a/services/diffpatch/diff/blocks_diff.h +++ b/services/diffpatch/diff/blocks_diff.h @@ -49,19 +49,24 @@ public: BlocksDiff() = default; virtual ~BlocksDiff() {} - int32_t MakePatch(const std::string &oldFileName, + static int32_t MakePatch(const std::string &oldFileName, const std::string &newFileName, const std::string &patchFileName); - int32_t MakePatch(const BlockBuffer &newInfo, - const BlockBuffer &oldInfo, std::vector &patchData); + static int32_t MakePatch(const BlockBuffer &newInfo, + const BlockBuffer &oldInfo, std::vector &patchData, size_t offset, size_t &patchSize); + static int32_t MakePatch(const BlockBuffer &newInfo, + const BlockBuffer &oldInfo, std::fstream &patchFile, size_t &patchSize); + + int32_t MakePatch(const BlockBuffer &newInfo, const BlockBuffer &oldInfo, size_t &patchSize); private: + virtual std::unique_ptr CreateBZip2Adapter(size_t patchOffset) = 0; + virtual int32_t WritePatchHeader(int64_t controlSize, + int64_t diffDataSize, int64_t newSize, size_t &patchOffset) = 0; + int32_t GetCtrlDatas(const BlockBuffer &newInfo, const BlockBuffer &oldInfo, std::vector &controlDatas); - int32_t WriteControlData(const std::vector controlDatas, - std::vector &patchData, size_t &patchSize) const; - int32_t WriteDiffData(const std::vector controlDatas, - std::vector &patchData, size_t &patchSize) const; - int32_t WriteExtraData(const std::vector controlDatas, - std::vector &patchData, size_t &patchSize) const; + int32_t WriteControlData(const std::vector controlDatas, size_t &patchSize); + int32_t WriteDiffData(const std::vector controlDatas, size_t &patchSize); + int32_t WriteExtraData(const std::vector controlDatas, size_t &patchSize); void ComputeOldScore(const BlockBuffer &newInfo, const BlockBuffer &oldInfo, int64_t &oldScore, int64_t &matchLen); @@ -76,5 +81,30 @@ private: int64_t lastScan_ { 0 }; int64_t lastPos_ { 0 }; }; + +class BlocksStreamDiff : public BlocksDiff { +public: + BlocksStreamDiff(std::fstream &stream, size_t offset) : BlocksDiff(), stream_(stream), offset_(offset) {} + ~BlocksStreamDiff() override {} +private: + std::unique_ptr CreateBZip2Adapter(size_t patchOffset) override; + int32_t WritePatchHeader(int64_t controlSize, + int64_t diffDataSize, int64_t newSize, size_t &patchOffset) override; + std::fstream &stream_; + size_t offset_ { 0 }; +}; + +class BlocksBufferDiff : public BlocksDiff { +public: + BlocksBufferDiff(std::vector &patchData, size_t offset) + : BlocksDiff(), patchData_(patchData), offset_(offset) {} + ~BlocksBufferDiff() override {} +private: + std::unique_ptr CreateBZip2Adapter(size_t patchOffset) override; + int32_t WritePatchHeader(int64_t controlSize, + int64_t diffDataSize, int64_t newSize, size_t &patchOffset) override; + std::vector &patchData_; + size_t offset_ { 0 }; +}; } // namespace updatepatch #endif // BLOCKS_DIFF_H \ No newline at end of file diff --git a/services/diffpatch/diff/image_diff.cpp b/services/diffpatch/diff/image_diff.cpp index 41dae87c4e1a8654cf7b7ec66dd6959717714407..0415e920625901f4bf48f3f915a37d19c40d33e5 100644 --- a/services/diffpatch/diff/image_diff.cpp +++ b/services/diffpatch/diff/image_diff.cpp @@ -24,6 +24,7 @@ namespace updatepatch { #define GET_REAL_DATA_LEN(info) (info) ->packedSize + (info)->dataOffset - (info)->headerOffset constexpr int32_t LZ4F_MAX_BLOCKID = 7; constexpr int32_t ZIP_MAX_LEVEL = 9; +constexpr int32_t MAX_NEW_LENGTH = 1 << 20; template static void WriteToFile(std::ofstream &patchFile, DataType data, size_t dataSize) @@ -100,30 +101,25 @@ int32_t ImageDiff::SplitImage(const PatchBuffer &oldInfo, const PatchBuffer &new return 0; } -int32_t ImageDiff::WriteHeader(std::ofstream &patchFile, size_t &dataOffset, ImageBlock &block) const +int32_t ImageDiff::WriteHeader(std::ofstream &patchFile, + std::fstream &blockPatchFile, size_t &dataOffset, ImageBlock &block) const { int32_t ret = 0; switch (block.type) { case BLOCK_NORMAL: { - std::vector patchData; - BlocksDiff diff; + size_t patchSize = 0; BlockBuffer newInfo = { block.newInfo.buffer + block.newInfo.start, block.newInfo.length }; BlockBuffer oldInfo = { block.oldInfo.buffer + block.oldInfo.start, block.oldInfo.length }; - ret = diff.MakePatch(newInfo, oldInfo, patchData); + ret = MakeBlockPatch(block, blockPatchFile, newInfo, oldInfo, patchSize); PATCH_CHECK(ret == 0, return -1, "Failed to make block patch"); - - block.patchData = std::move(patchData); - PATCH_LOGI("WriteHeader BLOCK_NORMAL patchOffset %zu oldInfo %ld %ld newInfo:%zu %zu", + PATCH_LOGI("WriteHeader BLOCK_NORMAL patchOffset %zu oldInfo %ld %ld newInfo:%zu %zu patch %zu %zu", static_cast(patchFile.tellp()), - block.oldInfo.start, block.oldInfo.length, block.newInfo.start, block.newInfo.length); - BlockBuffer patchBuffer = {block.patchData.data(), block.patchData.size()}; - PATCH_LOGI("WriteHeader BLOCK_NORMAL dataOffset:%zu hash %zu %s", dataOffset, - block.patchData.size(), GeneraterBufferHash(patchBuffer).c_str()); - + block.oldInfo.start, block.oldInfo.length, block.newInfo.start, block.newInfo.length, + dataOffset, patchSize); WriteToFile(patchFile, static_cast(block.oldInfo.start), sizeof(int64_t)); WriteToFile(patchFile, static_cast(block.oldInfo.length), sizeof(int64_t)); WriteToFile(patchFile, static_cast(dataOffset), sizeof(int64_t)); - dataOffset += block.patchData.size(); + dataOffset += patchSize; break; } case BLOCK_RAW: { @@ -143,37 +139,89 @@ int32_t ImageDiff::WriteHeader(std::ofstream &patchFile, size_t &dataOffset, Ima return ret; } +int32_t ImageDiff::MakeBlockPatch(ImageBlock &block, std::fstream &blockPatchFile, + const BlockBuffer &newInfo, const BlockBuffer &oldInfo, size_t &patchSize) const +{ + if (!usePatchFile_) { + std::vector patchData; + int32_t ret = BlocksDiff::MakePatch(newInfo, oldInfo, patchData, 0, patchSize); + PATCH_CHECK(ret == 0, return -1, "Failed to make block patch"); + BlockBuffer patchBuffer = {patchData.data(), patchSize}; + PATCH_DEBUG("MakeBlockPatch hash %zu %s", patchSize, GeneraterBufferHash(patchBuffer).c_str()); + block.patchData = std::move(patchData); + } else { + int32_t ret = BlocksDiff::MakePatch(newInfo, oldInfo, blockPatchFile, patchSize); + PATCH_CHECK(ret == 0, return -1, "Failed to make block patch"); + PATCH_LOGI("MakeBlockPatch patch %zu patch %zu", + patchSize, static_cast(blockPatchFile.tellp())); + } + return 0; +} + +int32_t ImageDiff::WritePatch(std::ofstream &patchFile, std::fstream &blockPatchFile) +{ + if (usePatchFile_) { // copy to patch + size_t bsPatchSize = static_cast(blockPatchFile.tellp()); + PATCH_LOGI("WritePatch patch block patch %zu img patch offset %zu", + bsPatchSize, static_cast(patchFile.tellp())); + blockPatchFile.seekg(0, std::ios::beg); + std::vector buffer(IGMDIFF_LIMIT_UNIT); + while (bsPatchSize > 0) { + size_t readLen = (bsPatchSize > IGMDIFF_LIMIT_UNIT) ? IGMDIFF_LIMIT_UNIT : bsPatchSize; + blockPatchFile.read(buffer.data(), readLen); + patchFile.write(buffer.data(), readLen); + bsPatchSize -= readLen; + } + PATCH_LOGI("WritePatch patch %zu", static_cast(patchFile.tellp())); + } else { + for (size_t index = 0; index < updateBlocks_.size(); index++) { + if (updateBlocks_[index].type == BLOCK_RAW) { + continue; + } + PATCH_LOGI("WritePatch [%zu] write patch patchOffset %zu length %zu", + index, static_cast(patchFile.tellp()), updateBlocks_[index].patchData.size()); + patchFile.write(reinterpret_cast(updateBlocks_[index].patchData.data()), + updateBlocks_[index].patchData.size()); + } + } + return 0; +} + int32_t ImageDiff::DiffImage(const std::string &patchName) { - std::ofstream patchFile(patchName, std::ios::out | std::ios::binary); + std::fstream blockPatchFile; + std::ofstream patchFile(patchName, std::ios::out | std::ios::trunc | std::ios::binary); PATCH_CHECK(!patchFile.fail(), return -1, "Failed to open %s", patchName.c_str()); - patchFile.write(IMGDIFF_MAGIC.c_str(), IMGDIFF_MAGIC.size()); - size_t dataOffset = IMGDIFF_MAGIC.size(); + patchFile.write(PKGDIFF_MAGIC.c_str(), PKGDIFF_MAGIC.size()); + size_t dataOffset = PKGDIFF_MAGIC.size(); uint32_t size = static_cast(updateBlocks_.size()); patchFile.write(reinterpret_cast(&size), sizeof(uint32_t)); dataOffset += sizeof(uint32_t); for (size_t index = 0; index < updateBlocks_.size(); index++) { dataOffset += GetHeaderSize(updateBlocks_[index]); + if (updateBlocks_[index].destOriginalLength >= MAX_NEW_LENGTH || + updateBlocks_[index].newInfo.length >= MAX_NEW_LENGTH) { + usePatchFile_ = true; + } + } + + if (usePatchFile_) { + blockPatchFile.open(patchName + ".bspatch", std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary); + PATCH_CHECK(!blockPatchFile.fail(), return -1, "Failed to open bspatch %s", patchName.c_str()); } for (size_t index = 0; index < updateBlocks_.size(); index++) { PATCH_LOGI("DiffImage [%zu] write header patchOffset %zu dataOffset %zu", index, static_cast(patchFile.tellp()), dataOffset); patchFile.write(reinterpret_cast(&updateBlocks_[index].type), sizeof(uint32_t)); - int32_t ret = WriteHeader(patchFile, dataOffset, updateBlocks_[index]); + int32_t ret = WriteHeader(patchFile, blockPatchFile, dataOffset, updateBlocks_[index]); PATCH_CHECK(ret == 0, return -1, "Failed to write header"); } - for (size_t index = 0; index < updateBlocks_.size(); index++) { - if (updateBlocks_[index].type != BLOCK_RAW) { - PATCH_LOGI("DiffImage [%zu] write patch patchOffset %zu length %zu", - index, static_cast(patchFile.tellp()), updateBlocks_[index].patchData.size()); - patchFile.write(reinterpret_cast(updateBlocks_[index].patchData.data()), - updateBlocks_[index].patchData.size()); - } - } + int32_t ret = WritePatch(patchFile, blockPatchFile); + PATCH_CHECK(ret == 0, return -1, "Failed to write patch"); PATCH_LOGI("DiffImage success patchOffset %zu %s", static_cast(patchFile.tellp()), patchName.c_str()); patchFile.close(); return 0; @@ -279,26 +327,23 @@ int32_t CompressedImageDiff::DiffFile(const std::string &fileName, size_t &oldOf return 0; } -int32_t ZipImageDiff::WriteHeader(std::ofstream &patchFile, size_t &dataOffset, ImageBlock &block) const +int32_t ZipImageDiff::WriteHeader(std::ofstream &patchFile, + std::fstream &blockPatchFile, size_t &dataOffset, ImageBlock &block) const { int32_t ret = 0; if (block.type == BLOCK_DEFLATE) { - std::vector patchData; - BlocksDiff diff; + size_t patchSize = 0; BlockBuffer oldInfo = { block.srcOriginalData.data(), block.srcOriginalLength }; BlockBuffer newInfo = { block.destOriginalData.data(), block.destOriginalLength }; - ret = diff.MakePatch(newInfo, oldInfo, patchData); + ret = MakeBlockPatch(block, blockPatchFile, newInfo, oldInfo, patchSize); PATCH_CHECK(ret == 0, return -1, "Failed to make block patch"); - block.patchData = std::move(patchData); PATCH_LOGI("WriteHeader BLOCK_DEFLATE patchoffset %zu dataOffset:%zu patchData:%zu", - static_cast(patchFile.tellp()), dataOffset, block.patchData.size()); + static_cast(patchFile.tellp()), dataOffset, patchSize); PATCH_LOGI("WriteHeader oldInfo start:%zu length:%zu", block.oldInfo.start, block.oldInfo.length); PATCH_LOGI("WriteHeader uncompressedLength:%zu %zu", block.srcOriginalLength, block.destOriginalLength); PATCH_LOGI("WriteHeader level_:%d method_:%d windowBits_:%d memLevel_:%d strategy_:%d", level_, method_, windowBits_, memLevel_, strategy_); - PATCH_LOGI("WriteHeader BLOCK_DEFLATE decompressed hash %zu %s", - newInfo.length, GeneraterBufferHash(newInfo).c_str()); WriteToFile(patchFile, static_cast(block.oldInfo.start), sizeof(int64_t)); WriteToFile(patchFile, static_cast(block.oldInfo.length), sizeof(int64_t)); @@ -311,9 +356,9 @@ int32_t ZipImageDiff::WriteHeader(std::ofstream &patchFile, size_t &dataOffset, WriteToFile(patchFile, windowBits_, sizeof(int32_t)); WriteToFile(patchFile, memLevel_, sizeof(int32_t)); WriteToFile(patchFile, strategy_, sizeof(int32_t)); - dataOffset += block.patchData.size(); + dataOffset += patchSize; } else { - ret = ImageDiff::WriteHeader(patchFile, dataOffset, block); + ret = ImageDiff::WriteHeader(patchFile, blockPatchFile, dataOffset, block); } return ret; } @@ -363,20 +408,19 @@ int32_t ZipImageDiff::TestAndSetConfig(const BlockBuffer &buffer, const std::str return -1; } -int32_t Lz4ImageDiff::WriteHeader(std::ofstream &patchFile, size_t &dataOffset, ImageBlock &block) const +int32_t Lz4ImageDiff::WriteHeader(std::ofstream &patchFile, + std::fstream &blockPatchFile, size_t &dataOffset, ImageBlock &block) const { int32_t ret = 0; if (block.type == BLOCK_LZ4) { - std::vector patchData; - BlocksDiff diff; + size_t patchSize = 0; BlockBuffer oldInfo = { block.srcOriginalData.data(), block.srcOriginalLength }; BlockBuffer newInfo = { block.destOriginalData.data(), block.destOriginalLength }; - ret = diff.MakePatch(newInfo, oldInfo, patchData); + ret = MakeBlockPatch(block, blockPatchFile, newInfo, oldInfo, patchSize); PATCH_CHECK(ret == 0, return -1, "Failed to make block patch"); - block.patchData = std::move(patchData); - PATCH_LOGI("WriteHeader BLOCK_LZ4 patchoffset %zu dataOffset:%zu patchData:%zu", - static_cast(patchFile.tellp()), dataOffset, block.patchData.size()); + PATCH_LOGI("WriteHeader BLOCK_LZ4 patchoffset %zu dataOffset:%zu %zu", + static_cast(patchFile.tellp()), dataOffset, patchSize); PATCH_LOGI("WriteHeader oldInfo start:%zu length:%zu", block.oldInfo.start, block.oldInfo.length); PATCH_LOGI("WriteHeader uncompressedLength:%zu %zu", block.srcOriginalLength, block.destOriginalLength); PATCH_LOGI("WriteHeader level_:%d method_:%d blockIndependence_:%d contentChecksumFlag_:%d blockSizeID_:%d %d", @@ -396,9 +440,9 @@ int32_t Lz4ImageDiff::WriteHeader(std::ofstream &patchFile, size_t &dataOffset, WriteToFile(patchFile, contentChecksumFlag_, sizeof(int32_t)); WriteToFile(patchFile, blockSizeID_, sizeof(int32_t)); WriteToFile(patchFile, autoFlush_, sizeof(int32_t)); - dataOffset += block.patchData.size(); + dataOffset += patchSize; } else { - ret = ImageDiff::WriteHeader(patchFile, dataOffset, block); + ret = ImageDiff::WriteHeader(patchFile, blockPatchFile, dataOffset, block); } return ret; } diff --git a/services/diffpatch/diff/image_diff.h b/services/diffpatch/diff/image_diff.h index 52a66e9adaf7e42a1ba17601f1d9439c5bb788c5..965249e7af5ecaad95924f468d5cbb9b72ef14f2 100644 --- a/services/diffpatch/diff/image_diff.h +++ b/services/diffpatch/diff/image_diff.h @@ -44,15 +44,20 @@ public: } virtual int32_t MakePatch(const std::string &patchName); - virtual int32_t WriteHeader(std::ofstream &patchFile, size_t &offset, ImageBlock &block) const; + virtual int32_t WriteHeader(std::ofstream &patchFile, + std::fstream &blockPatchFile, size_t &offset, ImageBlock &block) const; protected: int32_t SplitImage(const PatchBuffer &oldInfo, const PatchBuffer &newInfo); int32_t DiffImage(const std::string &patchName); + int32_t MakeBlockPatch(ImageBlock &block, std::fstream &blockPatchFile, + const BlockBuffer &newInfo, const BlockBuffer &oldInfo, size_t &patchSize) const; + int32_t WritePatch(std::ofstream &patchFile, std::fstream &blockPatchFile); size_t limit_; std::vector updateBlocks_ {}; UpdateDiff::ImageParserPtr newParser_ {nullptr}; UpdateDiff::ImageParserPtr oldParser_ {nullptr}; + bool usePatchFile_ { false }; }; class CompressedImageDiff : public ImageDiff { @@ -77,7 +82,8 @@ public: : CompressedImageDiff(limit, newParser, oldParser, BLOCK_DEFLATE) {} ~ZipImageDiff() override {} - int32_t WriteHeader(std::ofstream &patchFile, size_t &offset, ImageBlock &block) const override; + int32_t WriteHeader(std::ofstream &patchFile, + std::fstream &blockPatchFile, size_t &offset, ImageBlock &block) const override; protected: int32_t TestAndSetConfig(const BlockBuffer &buffer, const std::string &fileName) override; @@ -94,7 +100,8 @@ public: : CompressedImageDiff(limit, newParser, oldParser, BLOCK_LZ4) {} ~Lz4ImageDiff() override {} - int32_t WriteHeader(std::ofstream &patchFile, size_t &offset, ImageBlock &block) const override; + int32_t WriteHeader(std::ofstream &patchFile, + std::fstream &blockPatchFile, size_t &offset, ImageBlock &block) const override; protected: int32_t TestAndSetConfig(const BlockBuffer &buffer, const std::string &fileName) override; private: diff --git a/services/diffpatch/diff/update_diff.cpp b/services/diffpatch/diff/update_diff.cpp index 01b716e76cb838d2da05587ed00adb144347c37f..870a4e8ce58515faabde44067bfacc828469a682 100644 --- a/services/diffpatch/diff/update_diff.cpp +++ b/services/diffpatch/diff/update_diff.cpp @@ -81,6 +81,7 @@ int32_t ImageParser::Parse(const std::string &packageName) int32_t ImageParser::Extract(const std::string &fileName, std::vector &buffer) { + PATCH_DEBUG("ImageParser::Extract %s", fileName.c_str()); PATCH_CHECK(pkgManager_ != nullptr, return PATCH_INVALID_PARAM, "Failed to get pkg manager"); size_t bufferSize = 0; hpackage::PkgManager::StreamPtr outStream = nullptr; @@ -112,9 +113,7 @@ int32_t UpdateDiff::MakePatch(const std::string &oldFileName, const std::string &newFileName, const std::string &patchFileName) { if (blockDiff_) { - std::unique_ptr blockDiff(new BlocksDiff()); - PATCH_CHECK(blockDiff != nullptr, return -1, "Failed to create block diff"); - return blockDiff->MakePatch(oldFileName, newFileName, patchFileName); + return BlocksDiff::MakePatch(oldFileName, newFileName, patchFileName); } newParser_.reset(new ImageParser()); diff --git a/services/diffpatch/diffpatch.h b/services/diffpatch/diffpatch.h index 3e2e2890ed8b847dbc2a6d4577bd5ad78b51d774..896c27a8a0ac695d5b1b823a56da302e66999cfa 100644 --- a/services/diffpatch/diffpatch.h +++ b/services/diffpatch/diffpatch.h @@ -55,53 +55,40 @@ enum { }; /* - * The imgdiff patch header looks like this: + * The pkgdiff patch header looks like this: * - * "IMGDIFF2" (8) [magic number and version] - * chunk count (4) - * for each chunk: - * chunk type (4) [CHUNK_{NORMAL, GZIP, DEFLATE, RAW}] - * if chunk type == CHUNK_NORMAL: + * "pkgdiff0" (8) [magic number and version] + * block count (4) + * for each block: + * block type (4) [BLOCK_{NORMAL, DEFLATE, RAW, Lz4}] + * if block type == BLOCK_NORMAL: * source start (8) * source len (8) * bsdiff patch offset (8) [from start of patch file] - * if chunk type == CHUNK_GZIP: (version 1 only) + * if block type == BLOCK_DEFLATE: * source start (8) * source len (8) * bsdiff patch offset (8) [from start of patch file] * source expanded len (8) [size of uncompressed source] * target expected len (8) [size of uncompressed target] - * gzip level (4) + * zip level (4) * method (4) * windowBits (4) * memLevel (4) * strategy (4) - * gzip header len (4) - * gzip header (gzip header len) - * gzip footer (8) - * if chunk type == CHUNK_DEFLATE: (version 2 only) + * if block type == BLOCK_LZ4: * source start (8) * source len (8) * bsdiff patch offset (8) [from start of patch file] * source expanded len (8) [size of uncompressed source] * target expected len (8) [size of uncompressed target] - * gzip level (4) - * method (4) - * windowBits (4) - * memLevel (4) - * strategy (4) - * if chunk type == CHUNK_LZ4: (version 3 only) - * source start (8) - * source len (8) - * bsdiff patch offset (8) [from start of patch file] - * source expanded len (8) [size of uncompressed source] - * target expected len (8) [size of uncompressed target] - * gzip level (4) + * lz4 level (4) * method (4) * blockIndependence (4) * contentChecksumFlag (4) * blockSizeID (4) - * if chunk type == RAW: (version 2 only) + * autoFlush (4) + * if block type == RAW: * target len (4) * data (target len) * @@ -120,17 +107,13 @@ enum { 48 56 Bzip2ed extra block */ -// Image patch block types +// patch block types #define BLOCK_NORMAL 0 -#define BLOCK_GZIP 1 // version 1 only -#define BLOCK_DEFLATE 2 // version 2 only -#define BLOCK_RAW 3 // version 2 only -#define BLOCK_LZ4 4 // version 3 only - -// The gzip header size is actually variable, but we currently don't -// support gzipped data with any of the optional fields, so for now it -// will always be ten bytes. See RFC 1952 for the definition of the -// gzip format. +#define BLOCK_GZIP 1 +#define BLOCK_DEFLATE 2 +#define BLOCK_RAW 3 +#define BLOCK_LZ4 4 + static constexpr size_t GZIP_HEADER_LEN = 10; static constexpr size_t VERSION = 2; static constexpr unsigned short HEADER_CRC = 0x02; /* bit 1 set: CRC16 for the gzip header */ @@ -154,7 +137,7 @@ static constexpr int PATCH_DEFLATE_MIN_HEADER_LEN = 60; static constexpr int PATCH_LZ4_MIN_HEADER_LEN = 64; static const std::string BSDIFF_MAGIC = "BSDIFF40"; -static const std::string IMGDIFF_MAGIC = "IMGDIFF2"; +static const std::string PKGDIFF_MAGIC = "PKGDIFF0"; struct PatchHeader { size_t srcStart = 0; diff --git a/services/diffpatch/patch/image_patch.cpp b/services/diffpatch/patch/image_patch.cpp index c05d4e86d22774765cd7db52cf0440b1d88cf378..6fef437d513151a342398936df9203b81165d4ea 100644 --- a/services/diffpatch/patch/image_patch.cpp +++ b/services/diffpatch/patch/image_patch.cpp @@ -219,17 +219,17 @@ int32_t Lz4ImagePatch::ReadHeader(const PatchParam ¶m, PatchHeader &header, header.targetSize = static_cast(ReadLE(param.patch + offset)); offset += sizeof(uint64_t); - compressionLevel_ = static_cast(ReadLE(param.patch + offset)); + compressionLevel_ = static_cast(ReadLE(param.patch + offset)); offset += sizeof(int32_t); - method_ = static_cast(ReadLE(param.patch + offset)); + method_ = static_cast(ReadLE(param.patch + offset)); offset += sizeof(int32_t); - blockIndependence_ = static_cast(ReadLE(param.patch + offset)); + blockIndependence_ = static_cast(ReadLE(param.patch + offset)); offset += sizeof(int32_t); - contentChecksumFlag_ = static_cast(ReadLE(param.patch + offset)); + contentChecksumFlag_ = static_cast(ReadLE(param.patch + offset)); offset += sizeof(int32_t); - blockSizeID_ = static_cast(ReadLE(param.patch + offset)); + blockSizeID_ = static_cast(ReadLE(param.patch + offset)); offset += sizeof(int32_t); - autoFlush_ = static_cast(ReadLE(param.patch + offset)); + autoFlush_ = static_cast(ReadLE(param.patch + offset)); offset += sizeof(int32_t); PATCH_LOGI("ReadHeader BLOCK_LZ4 level_:%d method_:%d %d contentChecksumFlag_:%d blockSizeID_:%d %d", compressionLevel_, method_, blockIndependence_, contentChecksumFlag_, blockSizeID_, autoFlush_); @@ -288,7 +288,7 @@ int32_t CompressedFileRestore::CompressData(size_t &originalSize, size_t &compre SHA256_Final(digest.data(), &sha256Ctx_); BlockBuffer buffer = { digest.data(), digest.size() }; std::string hexDigest = ConvertSha256Hex(buffer); - PATCH_DEBUG("CompressedFileRestore hash %zu %s ", dataSize_, hexDigest.c_str()); + PATCH_LOGI("CompressedFileRestore hash %zu %s ", dataSize_, hexDigest.c_str()); return 0; } } // namespace updater diff --git a/services/diffpatch/patch/update_patch.cpp b/services/diffpatch/patch/update_patch.cpp index 07414e111d36fd366d0ae01d8f06c67ca8c5c8b3..f0393290755127fc200262d35a3d678c8b7d78bd 100644 --- a/services/diffpatch/patch/update_patch.cpp +++ b/services/diffpatch/patch/update_patch.cpp @@ -41,11 +41,11 @@ int32_t UpdatePatch::ApplyImagePatch(const PatchParam ¶m, UpdatePatchWriterPtr writer, const std::vector &bonusData) { PATCH_CHECK(writer != nullptr, return -1, "check param fail "); - PATCH_CHECK(param.patchSize >= (IMGDIFF_MAGIC.size() + sizeof(int32_t)), + PATCH_CHECK(param.patchSize >= (PKGDIFF_MAGIC.size() + sizeof(int32_t)), return -1, "patch too short to contain header "); - PATCH_CHECK(memcmp(param.patch, IMGDIFF_MAGIC.c_str(), IMGDIFF_MAGIC.size()) == 0, + PATCH_CHECK(memcmp(param.patch, PKGDIFF_MAGIC.c_str(), PKGDIFF_MAGIC.size()) == 0, return -1, "corrupt patch file header (magic number) "); - size_t offset = IMGDIFF_MAGIC.size(); + size_t offset = PKGDIFF_MAGIC.size(); int32_t numChunks = ImagePatch::ReadLE(param.patch + offset); offset += sizeof(int32_t); @@ -132,7 +132,7 @@ int32_t UpdatePatch::ApplyPatch(const std::string &patchName, const std::string writer->Init(); // check if image patch - if (memcmp(patchData.memory, IMGDIFF_MAGIC.c_str(), IMGDIFF_MAGIC.size()) == 0) { + if (memcmp(patchData.memory, PKGDIFF_MAGIC.c_str(), PKGDIFF_MAGIC.size()) == 0) { PatchParam param {}; param.patch = patchData.memory; param.patchSize = patchData.length; @@ -179,7 +179,7 @@ int32_t ImagePatchWriter::Finish() SHA256_Final(digest.data(), &sha256Ctx_); BlockBuffer data = { digest.data(), digest.size() }; std::string hexDigest = ConvertSha256Hex(data); - PATCH_DEBUG("VerifySha256 SHA256 : %s expected SHA256 : %s", hexDigest.c_str(), expected_.c_str()); + PATCH_LOGI("VerifySha256 SHA256 : %s expected SHA256 : %s", hexDigest.c_str(), expected_.c_str()); init_ = false; return hexDigest.compare(expected_); } diff --git a/services/fs_manager/BUILD.gn b/services/fs_manager/BUILD.gn index bcf2fe4a6b66388020d9d4ae2212899dec7b6142..3ce65a7c5343e9292f98f2f8d870afff8b48a98e 100644 --- a/services/fs_manager/BUILD.gn +++ b/services/fs_manager/BUILD.gn @@ -24,6 +24,7 @@ ohos_static_library("libfsmanager") { include_dirs = [ "//base/update/updater/services/include", + "//base/update/updater/interfaces/kits/include", "//base/update/updater/utils/include", "//third_party/bounds_checking_function/include", ] diff --git a/services/fs_manager/do_partition.cpp b/services/fs_manager/do_partition.cpp index aeb90a318d96d0ed051703ee8f96a55083f65567..daee219d5b774a877c9c7159d19e2c93747f94ac 100644 --- a/services/fs_manager/do_partition.cpp +++ b/services/fs_manager/do_partition.cpp @@ -25,6 +25,7 @@ #include "fs_manager/mount.h" #include "fs_manager/partitions.h" #include "log/log.h" +#include "misc_info/misc_info.h" #include "partition_const.h" #include "securec.h" @@ -175,7 +176,7 @@ static void DestroyDiskDevices(const Disk &disk) static bool WriteDiskPartitionToMisc(PartitonList &nlist) { UPDATER_CHECK_ONLY_RETURN(nlist.empty()==0, return false); - char blkdevparts[BUFFER_SIZE] = "mmcblk0:"; + char blkdevparts[MISC_RECORD_UPDATE_PARTITIONS_SIZE] = "mmcblk0:"; std::sort(nlist.begin(), nlist.end(), [](const struct Partition *a, const struct Partition *b) { return (a->start < b->start); }); // Sort in ascending order @@ -191,7 +192,7 @@ static bool WriteDiskPartitionToMisc(PartitonList &nlist) UPDATER_CHECK_ONLY_RETURN(snprintf_s(tmp, sizeof(tmp), sizeof(tmp) - 1, "%luM(%s),", size, p->partName.c_str()) != -1, return false); } - int ncatRet = strncat_s(blkdevparts, BUFFER_SIZE - 1, tmp, strlen(tmp)); + int ncatRet = strncat_s(blkdevparts, MISC_RECORD_UPDATE_PARTITIONS_SIZE - 1, tmp, strlen(tmp)); UPDATER_ERROR_CHECK(ncatRet == EOK, "Block device name overflow", return false); } @@ -202,7 +203,7 @@ static bool WriteDiskPartitionToMisc(PartitonList &nlist) FILE *fp = fopen(miscDevPath.c_str(), "rb+"); UPDATER_ERROR_CHECK(fp, "fopen error " << errno, return false); - fseek(fp, DEFAULT_SIZE_2KB, SEEK_SET); + fseek(fp, MISC_RECORD_UPDATE_PARTITIONS_OFFSET, SEEK_SET); size_t ret = fwrite(blkdevparts, sizeof(blkdevparts), 1, fp); UPDATER_ERROR_CHECK(ret >= 0, "fwrite error " << errno, fclose(fp); return false); diff --git a/services/fs_manager/partition_const.h b/services/fs_manager/partition_const.h index 73beb5027fa05813fec758f7d5eea2116f331922..d3bb809f06be56c93c9b2dd8b8b73cdc95d4908e 100644 --- a/services/fs_manager/partition_const.h +++ b/services/fs_manager/partition_const.h @@ -24,7 +24,6 @@ constexpr int SMALL_BUFFER_SIZE = 64; constexpr int DEVPATH_SIZE = 128; constexpr int DEFAULT_PARTSUM = 16; constexpr size_t SECTOR_SIZE_DEFAULT = 512; -constexpr int DEFAULT_SIZE_2KB = 2048; constexpr size_t DEFAULT_SIZE_1MB = 1048576; const std::string SDA_PATH = "/dev/sda"; diff --git a/services/include/applypatch/partition_record.h b/services/include/applypatch/partition_record.h index 34211e008fa6f06097c2a4ce6c20a9e40fe4a5ec..916863f45de28cf357cdddb2aa830e24ba7cc3ca 100644 --- a/services/include/applypatch/partition_record.h +++ b/services/include/applypatch/partition_record.h @@ -33,11 +33,11 @@ constexpr int MAX_PARTITION_NUM = 8; // Refer to updater package format restriction. constexpr int PARTITION_NAME_LEN = 125; constexpr int PARTITION_RECORD_INFO_LEN = 126; -constexpr size_t PARTITION_UPDATER_RECORD_SIZE = 1024; -constexpr size_t PARTITION_RECORD_OFFSET_SIZE = 16; -constexpr size_t PARTITION_UPDATER_RECORD_MSG_SIZE = PARTITION_UPDATER_RECORD_SIZE - PARTITION_RECORD_OFFSET_SIZE; -constexpr size_t PARTITION_RECORD_START = MISC_PARTITION_RECORD_OFFSET + PARTITION_RECORD_OFFSET_SIZE; - +constexpr off_t PARTITION_RECORD_OFFSET = MISC_PARTITION_RECORD_OFFSET; +constexpr off_t PARTITION_UPDATER_RECORD_SIZE = MISC_PARTITION_RECORD_SIZE; +constexpr off_t PARTITION_RECORD_OFFSET_SIZE = 16; +constexpr off_t PARTITION_UPDATER_RECORD_MSG_SIZE = PARTITION_UPDATER_RECORD_SIZE - PARTITION_RECORD_OFFSET_SIZE; +constexpr off_t PARTITION_RECORD_START = MISC_PARTITION_RECORD_OFFSET + PARTITION_RECORD_OFFSET_SIZE; struct PartitionRecordInfo { char partitionName[PARTITION_NAME_LEN]; // true: this partition is updated already. diff --git a/services/include/package/pkg_manager.h b/services/include/package/pkg_manager.h index c86ac8a26e4e881b1b0cd54273f93cdf98e309df..9cf37201c23978115e9d841ab1949d53efe46af0 100644 --- a/services/include/package/pkg_manager.h +++ b/services/include/package/pkg_manager.h @@ -83,6 +83,7 @@ struct UpgradePkgInfo { std::string softwareVersion; std::string date; std::string time; + std::string descriptPackageId; }; /** diff --git a/services/include/updater/updater.h b/services/include/updater/updater.h index a3e670de43d80900219b4fa148eb6001586da176..e71b1b9ca55b1fc9039bb5516f5c05ea971a2c56 100644 --- a/services/include/updater/updater.h +++ b/services/include/updater/updater.h @@ -26,8 +26,7 @@ enum UpdaterStatus { UPDATE_CORRUPT, /* package or verify failed, something is broken. */ UPDATE_SKIP, /* skip update because of condition is not satisfied, e.g, battery is low */ UPDATE_RETRY, - UPDATE_NORMAL, - UPDATE_FINISH + UPDATE_UNKNOWN }; UpdaterStatus DoInstallUpdaterPackage(hpackage::PkgManager::PkgManagerPtr pkgManager, diff --git a/services/include/updater/updater_const.h b/services/include/updater/updater_const.h index ff0284b6dcb88279294e73d1213b9cc691b847fa..1214a0e41f31f4c512b3c7e26609c98ab8a61217 100644 --- a/services/include/updater/updater_const.h +++ b/services/include/updater/updater_const.h @@ -29,6 +29,7 @@ const std::string UPDATER_STAGE_LOG = "/data/updater/log/updater_stage_log"; const std::string UPDATER_PATH = "/data/updater"; const std::string MISC_FILE = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/misc"; const std::string UPDATER_BINARY = "updater_binary"; +const std::string SDCARD_PATH = "/sdcard"; #ifndef UPDATER_UT const std::string SDCARD_CARD_PATH = "/sdcard/updater"; const std::string SDCARD_CARD_PKG_PATH = "/sdcard/updater/updater.zip"; @@ -72,5 +73,6 @@ constexpr int FULL_PERCENT_PROGRESS = 100; 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; } // namespace updater #endif diff --git a/services/package/pkg_algorithm/pkg_algorithm.cpp b/services/package/pkg_algorithm/pkg_algorithm.cpp index 9af4e5ef848e2ee52b765051ce6fc48352060b8a..9a0aaee6fa2264e1ba36962da24060132cf13f9a 100644 --- a/services/package/pkg_algorithm/pkg_algorithm.cpp +++ b/services/package/pkg_algorithm/pkg_algorithm.cpp @@ -42,10 +42,10 @@ int32_t PkgAlgorithm::FinalDigest(DigestAlgorithm::DigestAlgorithmPtr algorithm, if (context.digestMethod == PKG_DIGEST_TYPE_SHA256) { PkgBuffer digest(DIGEST_MAX_LEN); algorithm->Final(digest); - if (check && memcmp(digest.buffer, context.digest, sizeof(digest)) != 0) { + if (check && memcmp(digest.buffer, context.digest, DIGEST_MAX_LEN) != 0) { return PKG_INVALID_DIGEST; } - PKG_CHECK(!memcpy_s(context.digest, sizeof(context.digest), digest.buffer, sizeof(digest)), + PKG_CHECK(!memcpy_s(context.digest, sizeof(context.digest), digest.buffer, DIGEST_MAX_LEN), return PKG_NONE_MEMORY, "FinalDigest memcpy failed"); } return PKG_SUCCESS; @@ -76,8 +76,8 @@ int32_t PkgAlgorithm::Pack(const PkgStreamPtr inStream, const PkgStreamPtr outSt destOffset += readLen; } - FinalDigest(algorithm, context, true); - + ret = FinalDigest(algorithm, context, true); + PKG_CHECK(ret == 0, return ret, "Check digest fail"); PKG_CHECK(srcOffset - context.srcOffset == context.unpackedSize, return ret, "original size error %zu %zu", srcOffset, context.unpackedSize); context.packedSize = destOffset - context.destOffset; @@ -108,7 +108,8 @@ int32_t PkgAlgorithm::Unpack(const PkgStreamPtr inStream, const PkgStreamPtr out destOffset += readLen; } - FinalDigest(algorithm, context, true); + ret = FinalDigest(algorithm, context, true); + PKG_CHECK(ret == 0, return ret, "Check digest fail"); PKG_CHECK(destOffset - context.destOffset == context.packedSize, return ret, "original size error %zu %zu", destOffset, context.packedSize); context.unpackedSize = srcOffset - context.srcOffset; diff --git a/services/package/pkg_manager/pkg_managerImpl.cpp b/services/package/pkg_manager/pkg_managerImpl.cpp index dcb40eaf7d1aee3309af1ce0dc305a33ab5b7af5..a3f8088d39ce4b26354cc5a8534186a7ec510669 100644 --- a/services/package/pkg_manager/pkg_managerImpl.cpp +++ b/services/package/pkg_manager/pkg_managerImpl.cpp @@ -153,11 +153,13 @@ int32_t PkgManagerImpl::CreatePackage(const std::string &path, PkgInfoPtr header digestInfos[DIGEST_INFO_HAS_SIGN].resize(digestLen); ret = GenerateFileDigest(pkgFile->GetPkgStream(), header->digestMethod, DIGEST_FLAGS_HAS_SIGN, digestInfos, offset); + offset = (header->digestMethod == PKG_DIGEST_TYPE_SHA384) ? (offset + SIGN_SHA256_LEN) : offset; PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to generate signature %s", pkgFile->GetPkgStream()->GetFileName().c_str()); hashValue = ConvertShaHex(digestInfos[DIGEST_INFO_HAS_SIGN]); PKG_LOGI("PkgManagerImpl::CreatePackage sign offset %zu ", offset); } else { + offset = (header->digestMethod == PKG_DIGEST_TYPE_SHA384) ? (offset + SIGN_SHA256_LEN) : offset; ret = Sign(pkgFile->GetPkgStream(), offset, header); } delete pkgFile; diff --git a/services/package/pkg_manager/pkg_utils.cpp b/services/package/pkg_manager/pkg_utils.cpp index 6eabc22ac41fe5fbe782a7b9b336ae9c26d3f119..9eedcdb65ffb14e74a78e4ad79e62641935b4af1 100644 --- a/services/package/pkg_manager/pkg_utils.cpp +++ b/services/package/pkg_manager/pkg_utils.cpp @@ -72,7 +72,7 @@ int32_t CheckFile(const std::string &fileName) return PKG_SUCCESS; } if (access(path.c_str(), F_OK) == -1) { - mkdir(path.c_str(), S_READ_WRITE_PERMISSION); + mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); } // If the path writable int ret = access(path.c_str(), R_OK | W_OK); diff --git a/services/package/pkg_package/pkg_pkgfile.cpp b/services/package/pkg_package/pkg_pkgfile.cpp index a61391b08de18ebc550fe0daed539397448161d8..afa0724da87b1f1b325ebeb2da26e352fe8347ae 100644 --- a/services/package/pkg_package/pkg_pkgfile.cpp +++ b/services/package/pkg_package/pkg_pkgfile.cpp @@ -154,8 +154,6 @@ void PkgFile::AddSignData(uint8_t digestMethod, size_t currOffset, size_t &signO signOffset = currOffset; if (digestMethod == PKG_DIGEST_TYPE_NONE) { return; - } else if (digestMethod == PKG_DIGEST_TYPE_SHA384) { - signOffset += SIGN_SHA256_LEN; } std::vector buffer(SIGN_SHA256_LEN + SIGN_SHA384_LEN, 0); int32_t ret = pkgStream_->Write(buffer, buffer.size(), currOffset); diff --git a/services/package/pkg_package/pkg_upgradefile.cpp b/services/package/pkg_package/pkg_upgradefile.cpp index 8c316b786e7ec624eb00890b38f2cde8d37b72fb..33f6e4640d0af9eea3a0b8af520fd6488d4848cb 100644 --- a/services/package/pkg_package/pkg_upgradefile.cpp +++ b/services/package/pkg_package/pkg_upgradefile.cpp @@ -153,10 +153,12 @@ int32_t UpgradePkgFile::SavePackage(size_t &signOffset) // Clear buffer and save signature information offset += pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo); - signOffset = (pkgInfo_.pkgInfo.digestMethod == PKG_DIGEST_TYPE_SHA384) ? - (offset + UPGRADE_RESERVE_LEN + SIGN_SHA256_LEN) : (offset + UPGRADE_RESERVE_LEN); + signOffset = offset + UPGRADE_RESERVE_LEN; buffer.assign(buffer.capacity(), 0); + size_t nameLen = 0; + ret = PkgFile::ConvertStringToBuffer(pkgInfo_.descriptPackageId, {buffer.data(), UPGRADE_RESERVE_LEN}, nameLen); + PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail write descriptPackageId"); ret = pkgStream_->Write(buffer, GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN, offset); PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail write sign for %s", pkgStream_->GetFileName().c_str()); PKG_LOGI("SavePackage success file length: %zu signOffset %zu", pkgStream_->GetFileLength(), signOffset); @@ -190,24 +192,34 @@ int32_t UpgradePkgFile::LoadPackage(std::vector &fileNames, VerifyF return ret, "Decode components fail %d", ret); // Read signature information - std::vector reversedData(UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen(), 0); - PkgBuffer signBuffer(reversedData); - algorithm->Update(signBuffer, UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen()); - size_t readLen = 0; + size_t readBytes = 0; + ret = pkgStream_->Read(buffer, parsedLen, GetUpgradeSignatureLen() + UPGRADE_RESERVE_LEN, readBytes); + PKG_CHECK(ret == PKG_SUCCESS, return ret, "read sign data fail"); + PkgFile::ConvertBufferToString(pkgInfo_.descriptPackageId, {buffer.buffer, UPGRADE_RESERVE_LEN}); + std::vector signData; if (pkgInfo_.pkgInfo.digestMethod == PKG_DIGEST_TYPE_SHA384) { - reversedData.resize(SIGN_SHA384_LEN); - ret = pkgStream_->Read(reversedData, - parsedLen + UPGRADE_RESERVE_LEN + SIGN_SHA256_LEN, SIGN_SHA384_LEN, readLen); + signData.resize(SIGN_SHA384_LEN); + ret = memcpy_s(signData.data(), signData.size(), + buffer.buffer + UPGRADE_RESERVE_LEN + SIGN_SHA256_LEN, SIGN_SHA384_LEN); } else { - reversedData.resize(SIGN_SHA256_LEN); - ret = pkgStream_->Read(reversedData, parsedLen + UPGRADE_RESERVE_LEN, SIGN_SHA256_LEN, readLen); + signData.resize(SIGN_SHA256_LEN); + ret = memcpy_s(signData.data(), signData.size(), buffer.buffer + UPGRADE_RESERVE_LEN, SIGN_SHA256_LEN); } - PKG_LOGI("signOffset %zu", parsedLen + UPGRADE_RESERVE_LEN); - PKG_CHECK(ret == PKG_SUCCESS, return ret, "read header struct fail"); + PKG_CHECK(ret == PKG_SUCCESS, return ret, "memcpy sign data fail"); + memset_s(buffer.buffer + UPGRADE_RESERVE_LEN, buffer.length, 0, GetUpgradeSignatureLen()); + algorithm->Update(buffer, UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen()); parsedLen += UPGRADE_RESERVE_LEN + GetUpgradeSignatureLen(); - // Calculate digest - size_t offset = parsedLen; + // Calculate digest and verify + return Verify(parsedLen, {buffer.buffer, buffSize}, algorithm, verifier, signData); +} + +int32_t UpgradePkgFile::Verify(size_t start, const PkgBuffer &buffer, + DigestAlgorithm::DigestAlgorithmPtr algorithm, VerifyFunction verifier, const std::vector &signData) +{ + int ret = 0; + size_t buffSize = buffer.length; + size_t offset = start; size_t readBytes = 0; while (offset + readBytes < pkgStream_->GetFileLength()) { offset += readBytes; @@ -221,9 +233,9 @@ int32_t UpgradePkgFile::LoadPackage(std::vector &fileNames, VerifyF PkgBuffer digest(GetDigestLen()); algorithm->Final(digest); - ret = verifier(&pkgInfo_.pkgInfo, digest.data, reversedData); + ret = verifier(&pkgInfo_.pkgInfo, digest.data, signData); PKG_CHECK(ret == 0, return PKG_INVALID_SIGNATURE, "Fail to verifier signature"); - return PKG_SUCCESS; + return 0; } int32_t UpgradePkgFile::ReadComponents(const PkgBuffer &buffer, size_t &parsedLen, @@ -289,15 +301,13 @@ int32_t UpgradePkgFile::ReadUpgradePkgHeader(const PkgBuffer &buffer, size_t &re int32_t ret = pkgStream_->Read(buffer, 0, buffer.length, readLen); PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to read header"); pkgInfo_.pkgInfo.pkgType = PkgFile::PKG_TYPE_UPGRADE; + pkgInfo_.pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; + pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; PkgTlv tlv; tlv.type = ReadLE16(buffer.buffer); tlv.length = ReadLE16(buffer.buffer + sizeof(uint16_t)); - if (tlv.type == TLV_TYPE_FOR_SHA256) { - pkgInfo_.pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; - pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; - } else if (tlv.type == TLV_TYPE_FOR_SHA384) { - pkgInfo_.pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; + if (tlv.type == TLV_TYPE_FOR_SHA384) { pkgInfo_.pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA384; } @@ -360,7 +370,7 @@ int32_t UpgradeFileEntry::EncodeHeader(PkgStreamPtr inStream, size_t startOffset PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret:%d", ret); WriteLE32(reinterpret_cast(&comp.size), fileInfo_.fileInfo.unpackedSize); WriteLE16(reinterpret_cast(&comp.id), fileInfo_.id); - WriteLE32(reinterpret_cast(&comp.originalSize), fileInfo_.fileInfo.unpackedSize); + WriteLE32(reinterpret_cast(&comp.originalSize), fileInfo_.originalSize); comp.resType = fileInfo_.resType; comp.flags = fileInfo_.compFlags; comp.type = fileInfo_.type; @@ -414,7 +424,8 @@ int32_t UpgradeFileEntry::DecodeHeader(const PkgBuffer &buffer, size_t headerOff UpgradeCompInfo *info = reinterpret_cast(buffer.buffer); fileInfo_.fileInfo.packedSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, size)); - fileInfo_.fileInfo.unpackedSize = ReadLE32(buffer.buffer + offsetof(UpgradeCompInfo, originalSize)); + 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; int32_t ret = memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), info->digest, sizeof(info->digest)); @@ -426,7 +437,6 @@ int32_t UpgradeFileEntry::DecodeHeader(const PkgBuffer &buffer, size_t headerOff fileInfo_.resType = info->resType; fileInfo_.compFlags = info->flags; fileInfo_.type = info->type; - fileInfo_.originalSize = fileInfo_.fileInfo.unpackedSize; headerOffset_ = headerOffset; dataOffset_ = dataOffset; diff --git a/services/package/pkg_package/pkg_upgradefile.h b/services/package/pkg_package/pkg_upgradefile.h index 3322ade8dc8e4d1d511bbf8d031e1c1347404dd4..b04d0486edd223b5cddefcb29988fbae7c38b9ec 100644 --- a/services/package/pkg_package/pkg_upgradefile.h +++ b/services/package/pkg_package/pkg_upgradefile.h @@ -112,6 +112,8 @@ 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, + VerifyFunction verifier, const std::vector &signData); private: UpgradePkgInfo pkgInfo_ {}; size_t packedFileSize_ {0}; diff --git a/services/ui/BUILD.gn b/services/ui/BUILD.gn index 287c492714645f5daa22b4011a0ef0e1f0946392..fd2b2f517c04eaf3c3b35dd4455a9fd939a7bca5 100644 --- a/services/ui/BUILD.gn +++ b/services/ui/BUILD.gn @@ -16,12 +16,13 @@ ohos_static_library("libui") { sources = [ "animation_label.cpp", "frame.cpp", - "updater_ui.cpp", "input_event.cpp", "progress_bar.cpp", "surface_dev.cpp", "text_label.cpp", + "updater_ui.cpp", "view.cpp", + "drm_driver.cpp", ] include_dirs = [ diff --git a/services/ui/animation_label.cpp b/services/ui/animation_label.cpp index e7033cacf2c2d21f41fd5101aa2e95d7d96dbe1e..f49f2a0bad46e46be7ed798485a49338aca16f96 100644 --- a/services/ui/animation_label.cpp +++ b/services/ui/animation_label.cpp @@ -39,12 +39,13 @@ AnimationLable::AnimationLable(int startX, int startY, int w, int h, Frame *mPar AnimationLable::~AnimationLable() { + startFlag_ = false; needStop_ = true; - FreeBuffer(); - int imgSize = imgList_.size(); - - for (int i = 0; i < imgSize; i++) { - free(imgList_[i]); + for (std::vector::iterator it = imgList_.begin(); it != imgList_.end(); it++) { + if (*it != nullptr) { + free(*it); + *it = nullptr; + } } imgList_.clear(); } @@ -83,7 +84,7 @@ void AnimationLable::UpdateLoop() usleep(intervalMs_ * SECOND_PER_MS); } if (imgList_.size() <= 0) { - continue; + return; } if (!startFlag_ && IsVisiable()) { continue; @@ -115,7 +116,9 @@ void AnimationLable::AddImg(const std::string &imgFileName) { mutex_.lock(); void *buf = LoadPng(imgFileName); - imgList_.push_back(buf); + if (buf != nullptr) { + imgList_.push_back(buf); + } mutex_.unlock(); } diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bed53b9482ca28253df12660484a882f53df72f8 --- /dev/null +++ b/services/ui/drm_driver.cpp @@ -0,0 +1,132 @@ +/* + * 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. + */ +#include "drm_driver.h" +#include +#include +#include "log/log.h" +#include "securec.h" + +namespace updater { +void DrmDriver::FlipBuffer(void *buf) +{ + if (!buf) { + LOG(ERROR) << "buf is null"; + return; + } + UPDATER_CHECK_ONLY_RETURN(!memcpy_s(buff_.vaddr, buff_.size, buf, buff_.size), return); +} + +int DrmDriver::ModesetCreateFb(struct BufferObject *bo) +{ + struct drm_mode_create_dumb create = {}; + struct drm_mode_map_dumb map = {}; + const int offsetNumber = 4; + uint32_t handles[offsetNumber] = {0}; + uint32_t pitches[offsetNumber] = {0}; + uint32_t offsets[offsetNumber] = {0}; + + /* create a dumb-buffer, the pixel format is XRGB888 */ + const int pixelDepth = 32; + create.width = bo->width; + create.height = bo->height; + create.bpp = pixelDepth; + drmIoctl(fd_, DRM_IOCTL_MODE_CREATE_DUMB, &create); + + /* bind the dumb-buffer to an FB object */ + bo->pitch = create.pitch; + bo->size = create.size; + bo->handle = create.handle; + + handles[0] = bo->handle; + pitches[0] = bo->pitch; + offsets[0] = 0; + int ret = drmModeAddFB2(fd_, bo->width, bo->height, DRM_FORMAT_ARGB8888, handles, pitches, offsets, &bo->fbId, 0); + if (ret) { + LOG(ERROR) << "[fbtest]failed to add fb (" << bo->width << "x" << bo->height << "): " << strerror(errno); + return -1; + } + + /* map the dumb-buffer to userspace */ + map.handle = create.handle; + drmIoctl(fd_, DRM_IOCTL_MODE_MAP_DUMB, &map); + bo->vaddr = static_cast(mmap(0, create.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, map.offset)); + const int newColor = 0xff000000; + uint32_t i = 0; + uint32_t color = newColor; + while (i < bo->size) { + UPDATER_CHECK_ONLY_RETURN(!memcpy_s(&bo->vaddr[i], bo->size, &color, sizeof(color)), return -1); + i += sizeof(color); + } + return 0; +} + +int DrmDriver::DrmInit(void) +{ + fd_ = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); + if (fd_ < 0) { + LOG(ERROR) << "open failed"; + return -1; + } + + res_ = drmModeGetResources(fd_); + if (res_ == nullptr) { + LOG(ERROR) << "drmModeGetResources"; + return -1; + } + + uint32_t crtcId = res_->crtcs[0]; + uint32_t connId = res_->connectors[1]; + conn_ = drmModeGetConnector(fd_, connId); + if (conn_ == nullptr) { + LOG(ERROR) << "drmModeGetConnector"; + return -1; + } + buff_.width = conn_->modes[0].hdisplay; + buff_.height = conn_->modes[0].vdisplay; + + ModesetCreateFb(&buff_); + drmModeSetCrtc(fd_, crtcId, buff_.fbId, 0, 0, &connId, 1, &conn_->modes[0]); + LOG(INFO) << " drm init success."; + return 0; +} + +DrmDriver::DrmDriver() : fd_(-1), conn_(nullptr), res_(nullptr) +{ +} + +void DrmDriver::LoadDrmDriver() +{ + if (DrmInit() == -1) { + LOG(ERROR) << "load drm driver fail"; + } +} + +void DrmDriver::ModesetDestroyFb(struct BufferObject *bo) +{ + struct drm_mode_destroy_dumb destroy = {}; + drmModeRmFB(fd_, bo->fbId); + munmap(bo->vaddr, bo->size); + destroy.handle = bo->handle; + drmIoctl(fd_, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy); + drmModeFreeConnector(conn_); + drmModeFreeResources(res_); + close(fd_); +} + +DrmDriver::~DrmDriver() +{ + ModesetDestroyFb(&buff_); +} +} // namespace updater diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h new file mode 100644 index 0000000000000000000000000000000000000000..47f209ed33e1d326c2ef381f30b385c49c37b648 --- /dev/null +++ b/services/ui/drm_driver.h @@ -0,0 +1,57 @@ +/* + * 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 UPDATER_UI_DRM_DRIVER_H +#define UPDATER_UI_DRM_DRIVER_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace updater { +struct BufferObject { + uint32_t width; + uint32_t height; + uint32_t pitch; + uint32_t handle; + uint32_t size; + uint8_t *vaddr; + uint32_t fbId; +}; + +class DrmDriver { +protected: + DrmDriver(); + virtual ~DrmDriver(); + void FlipBuffer(void* buf); + void LoadDrmDriver(); +private: + int ModesetCreateFb(struct BufferObject *bo); + void ModesetDestroyFb(struct BufferObject *bo); + int DrmInit(); + int fd_; + drmModeConnector *conn_; + drmModeRes *res_; + struct BufferObject buff_; +}; +} // namespace updater +#endif diff --git a/services/ui/frame.cpp b/services/ui/frame.cpp index da8fbdfad7c41942623eafab2ed7234f70d0fea4..25548cbaa2d06624b6e7905e41471545e820fba2 100644 --- a/services/ui/frame.cpp +++ b/services/ui/frame.cpp @@ -16,13 +16,15 @@ #include "frame.h" #include #include "log/log.h" +#include "updater_ui_const.h" #include "view.h" namespace updater { using namespace std; extern int g_textLabelNum; +extern Frame *g_menuFrame; -Frame::Frame(unsigned int w, unsigned int h, View::PixelFormat pixType, SurfaceDev *sfDev) +Frame::Frame(unsigned int w, unsigned int h, View::PixelFormat pixType, SurfaceDev *sfDev) { this->CreateBuffer(w, h, pixType); this->startX_ = 0; @@ -32,15 +34,16 @@ Frame::Frame(unsigned int w, unsigned int h, View::PixelFormat pixType, SurfaceD flushFlag_ = false; flushLoop_ = std::thread(&Frame::FlushThreadLoop, this); flushLoop_.detach(); +#ifdef CONVERT_RL_SLIDE_TO_CLICK keyProcessLoop_ = std::thread(&Frame::ProcessKeyLoop, this); keyProcessLoop_.detach(); +#endif currentActionIndex_ = 0; } Frame::~Frame() { needStop_ = true; - FreeBuffer(); } void Frame::FlushThreadLoop() @@ -147,7 +150,7 @@ void Frame::DownFoucs() frameMutex_.lock(); std::map::iterator iter; currentActionIndex_++; - View *view; + View *view = nullptr; for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) { View *tmpView = (*iter).first; if (tmpView->IsVisiable() && tmpView->IsFocusAble()) { @@ -241,4 +244,72 @@ void Frame::DispatchKeyEvent(int key) keyEventNotify_ = true; mCondKey_.notify_all(); } + +void Frame::DispatchKeyEvent(int id, int event) +{ + bool isClicked = (keyEvent_ == event); + keyEvent_ = event; + if (isClicked) { + return; + } + if (!g_menuFrame->IsVisiable()) { + event = -1; + } + switch (event) { + case INVALID_EVENT: + LOG(INFO) << "DispatchKeyEvent invalid"; + break; + case PRESS_EVENT: + btnId_ = id; + PressEvent(); + LOG(INFO) << "DispatchKeyEvent press"; + break; + case RELEASE_EVENT: + btnId_ = id; + ReleaseEvent(); + LOG(INFO) << "DispatchKeyEvent release"; + break; + default: + break; + } +} + +void Frame::ReleaseEvent() +{ + frameMutex_.lock(); + std::map::iterator iter; + for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) { + View* tmpView = (*iter).first; + if (tmpView->IsVisiable() && btnId_ == tmpView->GetViewId()) { + if (!g_menuFrame->IsVisiable()) { + return; + } + frameMutex_.unlock(); + tmpView->OnKeyEvent(KEY_POWER); + tmpView->OnFocus(false); + frameMutex_.lock(); + break; + } + } + frameMutex_.unlock(); +} + +void Frame::PressEvent() +{ + frameMutex_.lock(); + std::map::iterator iter; + for (iter = viewMapList_.begin(); iter != viewMapList_.end(); ++iter) { + View* tmpView = (*iter).first; + if (tmpView->IsVisiable() && btnId_ == tmpView->GetViewId()) { + if (!g_menuFrame->IsVisiable()) { + return; + } + frameMutex_.unlock(); + tmpView->OnFocus(true); + frameMutex_.lock(); + break; + } + } + frameMutex_.unlock(); +} } // namespace updater \ No newline at end of file diff --git a/services/ui/frame.h b/services/ui/frame.h index 139e28a373f042a923d7beeed3dec77cb346f34c..9712086afded493751d4e8ad9c8f89af8feedb42 100644 --- a/services/ui/frame.h +++ b/services/ui/frame.h @@ -40,6 +40,8 @@ public: void ViewRegister(View *view); void DispatchKeyEvent(int key); + + void DispatchKeyEvent(int id, int event); private: void FlushThreadLoop(); @@ -53,6 +55,10 @@ private: void DoEvent(int key); + void ReleaseEvent(); + + void PressEvent(); + int currentActionIndex_ = 0; int maxActionIndex_ = 0; int listIndex_ = 0; @@ -69,6 +75,8 @@ private: std::condition_variable_any mCondKey_; std::list keyFifo_; std::map viewMapList_; + int keyEvent_ = -1; + int btnId_ = -1; }; } // namespace updater #endif // UPDATER_UI_FRAME_H diff --git a/services/ui/input_event.cpp b/services/ui/input_event.cpp index a6790c4d6862097c1c4c0e71f497d975b35d1bca..5867bb6eb06252d5998a7361df04b42021ded55a 100644 --- a/services/ui/input_event.cpp +++ b/services/ui/input_event.cpp @@ -16,11 +16,16 @@ #include #include #include "log/log.h" +#include "updater_ui_const.h" namespace updater { constexpr int TOUCH_LOW_TH = 50; constexpr int TOUCH_HIGH_TH = 90; constexpr int INIT_DEFAULT_VALUE = 255; +constexpr int LABEL_HEIGHT = 64; +constexpr int LABEL_OFFSET_2 = 2; +constexpr int LABEL_OFFSET_3 = 3; +constexpr int DIALOG_START_Y = 550; IInputInterface *g_inputInterface; InputEventCb g_callback; @@ -31,7 +36,7 @@ int g_touchX; int g_touchY; int g_touchStartX; int g_touchStartY; -extern Frame *g_hosFrame; +extern Frame *g_menuFrame; enum SwipeDirection { UP, @@ -40,6 +45,28 @@ enum SwipeDirection { LEFT }; +void TouchToClickEvent(const int dx, const int dy, int event) +{ + if (!g_menuFrame->IsVisiable()) { + LOG(INFO) << "menu page is not top"; + return; + } + if (abs(dy) >= 0 && abs(dy) <= LABEL_HEIGHT) { + g_menuFrame->DispatchKeyEvent(LABEL_ID_0, event); + } else if (abs(dy) > LABEL_HEIGHT && abs(dy) <= LABEL_HEIGHT * LABEL_OFFSET_2) { + g_menuFrame->DispatchKeyEvent(LABEL_ID_1, event); + } else if (abs(dy) > LABEL_HEIGHT * LABEL_OFFSET_2 && abs(dy) <= LABEL_HEIGHT * LABEL_OFFSET_3) { + g_menuFrame->DispatchKeyEvent(LABEL_ID_2, event); + } else if (abs(dy) > WIDTH1 && abs(dy) <= DIALOG_START_Y) { + if (abs(dx) > 0 && abs(dx) <= DIALOG_OK_WIDTH) { + g_menuFrame->DispatchKeyEvent(DIALOG_OK_ID, event); + } else if (abs(dx) > DIALOG_CANCEL_X && abs(dx) <= WIDTH1) { + g_menuFrame->DispatchKeyEvent(DIALOG_CANCEL_ID, event); + } + } + return; +} + void TouchToKey(const int dx, const int dy) { enum SwipeDirection direction; @@ -52,14 +79,14 @@ void TouchToKey(const int dx, const int dy) } switch (direction) { case SwipeDirection::UP: - g_hosFrame->DispatchKeyEvent(KEY_UP); + g_menuFrame->DispatchKeyEvent(KEY_UP); break; case SwipeDirection::DOWN: - g_hosFrame->DispatchKeyEvent(KEY_DOWN); + g_menuFrame->DispatchKeyEvent(KEY_DOWN); break; case SwipeDirection::LEFT: case SwipeDirection::RIGHT: - g_hosFrame->DispatchKeyEvent(KEY_POWER); + g_menuFrame->DispatchKeyEvent(KEY_POWER); break; default: break; @@ -67,6 +94,32 @@ void TouchToKey(const int dx, const int dy) return; } +void SwipEvent() +{ + if (g_touchFingerDown && !g_touchSwiping) { + g_touchStartX = g_touchX; + g_touchStartY = g_touchY; + g_touchSwiping = true; + } else if (!g_touchFingerDown && g_touchSwiping) { + g_touchSwiping = false; + TouchToKey(g_touchX - g_touchStartX, g_touchY - g_touchStartY); + } +} + +void ClickEvent() +{ + if (!g_menuFrame->IsVisiable()) { + LOG(INFO) << "click event"; + TouchToClickEvent(g_touchX, g_touchY, -1); + return; + } + if (g_touchFingerDown) { + TouchToClickEvent(g_touchX, g_touchY, PRESS_EVENT); + } else if (!g_touchFingerDown) { + TouchToClickEvent(g_touchX, g_touchY, RELEASE_EVENT); + } +} + int HandleInputEvent(const struct input_event *iev) { struct input_event ev {}; @@ -77,14 +130,11 @@ int HandleInputEvent(const struct input_event *iev) if (ev.code == SYN_REPORT) { // There might be multiple SYN_REPORT events. We should only detect // a swipe after lifting the contact. - if (g_touchFingerDown && !g_touchSwiping) { - g_touchStartX = g_touchX; - g_touchStartY = g_touchY; - g_touchSwiping = true; - } else if (!g_touchFingerDown && g_touchSwiping) { - g_touchSwiping = false; - TouchToKey(g_touchX - g_touchStartX, g_touchY - g_touchStartY); - } +#ifdef CONVERT_RL_SLIDE_TO_CLICK + SwipEvent(); +#else + ClickEvent(); +#endif } return 0; } @@ -122,7 +172,7 @@ int HandleInputEvent(const struct input_event *iev) void ReportEventPkgCallback(const EventPackage **pkgs, const uint32_t count, uint32_t devIndex) { - if (pkgs == nullptr || *pkgs == nullptr) { + if (pkgs == nullptr || *pkgs == nullptr || !g_menuFrame->IsVisiable()) { return; } for (uint32_t i = 0; i < count; i++) { diff --git a/services/ui/progress_bar.cpp b/services/ui/progress_bar.cpp index 4b61e1bf46e04a8aff7f197a99c7306b34993c98..37109d840f4116732626f98a6af706b5ddafc16a 100644 --- a/services/ui/progress_bar.cpp +++ b/services/ui/progress_bar.cpp @@ -23,6 +23,7 @@ namespace updater { constexpr int DEFAULT_PROGRESS_COLOR_A = 0xCC; constexpr int DEFAULT_NORMAL_COLOR = 0xFF; constexpr int MAX_PROGRESS_VALUE = 100; +constexpr uint32_t DEFAULT_PROGRESS_COLOR = 0x00; ProgressBar::ProgressBar(const int mStartX, const int mStartY, const int w, const int h, Frame *mParent) { @@ -32,14 +33,14 @@ ProgressBar::ProgressBar(const int mStartX, const int mStartY, const int w, cons parent_ = mParent; SetFocusAble(false); parent_->ViewRegister(this); - progressColor_.r = 0x00; - progressColor_.g = 0x00; - progressColor_.b = 0x00; - progressColor_.a = DEFAULT_PROGRESS_COLOR_A; - normalColor_.r = DEFAULT_NORMAL_COLOR; - normalColor_.g = DEFAULT_NORMAL_COLOR; - normalColor_.b = DEFAULT_NORMAL_COLOR; - normalColor_.a = DEFAULT_NORMAL_COLOR; + progressColor_.r = DEFAULT_NORMAL_COLOR; + progressColor_.g = DEFAULT_NORMAL_COLOR; + progressColor_.b = DEFAULT_NORMAL_COLOR; + progressColor_.a = DEFAULT_NORMAL_COLOR; + normalColor_.r = DEFAULT_PROGRESS_COLOR; + normalColor_.g = DEFAULT_PROGRESS_COLOR; + normalColor_.b = DEFAULT_PROGRESS_COLOR; + normalColor_.a = DEFAULT_PROGRESS_COLOR_A; } void ProgressBar::SetProgressValue(int value) diff --git a/services/ui/surface_dev.cpp b/services/ui/surface_dev.cpp index 147748d1c2fe4205a0d9614daf0cd74ba4350250..73de0f69f16fb5f9de6cb6cff153b2c101b52cdc 100644 --- a/services/ui/surface_dev.cpp +++ b/services/ui/surface_dev.cpp @@ -13,123 +13,25 @@ * limitations under the License. */ #include "surface_dev.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "log/log.h" -#include "securec.h" +#include "updater_ui_const.h" namespace updater { -struct BufferObject { - uint32_t width; - uint32_t height; - uint32_t pitch; - uint32_t handle; - uint32_t size; - uint8_t *vaddr; - uint32_t fbId; -}; - -struct BufferObject g_buff; - void SurfaceDev::Flip(void *buf) { if (!buf) { LOG(ERROR) << "buf is null"; return; } - UPDATER_CHECK_ONLY_RETURN(!memcpy_s(g_buff.vaddr, g_buff.size, buf, g_buff.size), return); -} - -static int ModesetCreateFb(int fd, struct BufferObject *bo) -{ - struct drm_mode_create_dumb create = {}; - struct drm_mode_map_dumb map = {}; - const int offsetNumber = 4; - uint32_t handles[offsetNumber] = {0}; - uint32_t pitches[offsetNumber] = {0}; - uint32_t offsets[offsetNumber] = {0}; - int ret; - - /* create a dumb-buffer, the pixel format is XRGB888 */ - const int pixelDepth = 32; - create.width = bo->width; - create.height = bo->height; - create.bpp = pixelDepth; - drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create); - - /* bind the dumb-buffer to an FB object */ - bo->pitch = create.pitch; - bo->size = create.size; - bo->handle = create.handle; - - handles[0] = bo->handle; - pitches[0] = bo->pitch; - offsets[0] = 0; - ret = drmModeAddFB2(fd, bo->width, bo->height, DRM_FORMAT_ARGB8888, handles, pitches, offsets, &bo->fbId, 0); - if (ret) { - LOG(ERROR) << "[fbtest]failed to add fb (" << bo->width << "x" << bo->height << "): " << strerror(errno); - return -1; - } - - /* map the dumb-buffer to userspace */ - map.handle = create.handle; - drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map); - bo->vaddr = static_cast(mmap(0, create.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map.offset)); - const int newColor = 0xff00ff00; - uint32_t i = 0; - uint32_t color = newColor; - while (i < bo->size) { - UPDATER_CHECK_ONLY_RETURN(!memcpy_s(&bo->vaddr[i], bo->size, &color, sizeof(color)), return -1); - i += sizeof(color); - } - return 0; -} - -int DrmInit(void) -{ - int fd = -1; - drmModeConnector *conn; - uint32_t connId; - uint32_t crtcId; - fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); - if (fd < 0) { - LOG(ERROR) << "open failed"; - return -1; - } - - drmModeRes *res = drmModeGetResources(fd); - if (res == nullptr) { - LOG(ERROR) << "drmModeGetResources"; - return -1; - } - - crtcId = res->crtcs[0]; - connId = res->connectors[1]; - conn = drmModeGetConnector(fd, connId); - if (conn == nullptr) { - LOG(ERROR) << "drmModeGetConnector"; - return -1; - } - g_buff.width = conn->modes[0].hdisplay; - g_buff.height = conn->modes[0].vdisplay; - - ModesetCreateFb(fd, &g_buff); - drmModeSetCrtc(fd, crtcId, g_buff.fbId, 0, 0, &connId, 1, &conn->modes[0]); - LOG(INFO) << " drm init success."; - return 0; + this->FlipBuffer(buf); } SurfaceDev::SurfaceDev(SurfaceDev::DevType devType) { + screenSizeW_ = SCREEN_WIDTH; + screenSizeH_ = SCREEN_HEIGHT; if (devType == SurfaceDev::DevType::DRM_DEVICE) { - DrmInit(); + this->LoadDrmDriver(); } else { LOG(ERROR) << " Only Support drm driver."; } @@ -137,9 +39,12 @@ SurfaceDev::SurfaceDev(SurfaceDev::DevType devType) void SurfaceDev::GetScreenSize(int &w, int &h) { - const int screenSizeW = 480; - const int screenSizeH = 960; - w = screenSizeW; - h = screenSizeH; + w = screenSizeW_; + h = screenSizeH_; +} + +SurfaceDev::~SurfaceDev() +{ + LOG(INFO)<<"SurfaceDev end"; } } // namespace updater \ No newline at end of file diff --git a/services/ui/surface_dev.h b/services/ui/surface_dev.h index 6dc072ccb814d2e30ce36dae7ec0c429d8cc825b..cc7c47ac098eb65bbf91720568e499c9e7372cc0 100644 --- a/services/ui/surface_dev.h +++ b/services/ui/surface_dev.h @@ -15,12 +15,10 @@ #ifndef UPDATER_UI_SURFACE_DEV_H #define UPDATER_UI_SURFACE_DEV_H -#include -#include -#include +#include "drm_driver.h" namespace updater { -class SurfaceDev { +class SurfaceDev : public DrmDriver { public: enum DevType { FB_DEVICE = 0, @@ -28,11 +26,12 @@ public: }; explicit SurfaceDev(SurfaceDev::DevType deviceType); - ~SurfaceDev(); + ~SurfaceDev() override; void Flip(void* buf); void GetScreenSize(int &w, int &h); private: - std::mutex mMutex; + int screenSizeW_ = 0; + int screenSizeH_ = 0; }; } // namespace updater #endif diff --git a/services/ui/text_label.cpp b/services/ui/text_label.cpp index d17b31bdcbf09104e7a6743a0f2d45c10c523b1c..0b8cb2aef1328a08cbc16c7c3eed4271c28e4f9b 100644 --- a/services/ui/text_label.cpp +++ b/services/ui/text_label.cpp @@ -22,7 +22,7 @@ #include "securec.h" namespace updater { -TextLable::TextLable(int mStartX, int mStartY, int w, int h, Frame *mparent) +TextLabel::TextLabel(int mStartX, int mStartY, int w, int h, Frame *mparent) { startX_ = mStartX; startY_ = mStartY; @@ -60,7 +60,7 @@ TextLable::TextLable(int mStartX, int mStartY, int w, int h, Frame *mparent) InitFont(); } -void TextLable::SetFont(FontType fType) +void TextLabel::SetFont(FontType fType) { fontType_ = fType; InitFont(); @@ -88,7 +88,7 @@ static void PNGReadRow(png_uint_32 fontWidth, png_uint_32 fontHeight, png_struct return; } -void TextLable::InitFont() +void TextLabel::InitFont() { char resPath[MAX_TEXT_SIZE + 1]; png_infop fontInfoPtr = nullptr; @@ -140,7 +140,7 @@ void TextLable::InitFont() PNGReadRow(fontWidth_, fontHeight_, fontPngPtr, fontBuf_); } -void TextLable::SetText(const char *str) +void TextLabel::SetText(const char *str) { UPDATER_CHECK_ONLY_RETURN(!memset_s(textBuf_, MAX_TEXT_SIZE + 1, 0, MAX_TEXT_SIZE), return); OnDraw(); @@ -148,7 +148,7 @@ void TextLable::SetText(const char *str) OnDraw(); } -void TextLable::OnDraw() +void TextLabel::OnDraw() { std::unique_lock locker(mutex_); SyncBuffer(); @@ -162,14 +162,14 @@ void TextLable::OnDraw() } } -void TextLable::SetOutLineBold(bool topBold, bool bottomBold) +void TextLabel::SetOutLineBold(bool topBold, bool bottomBold) { boldTopLine_ = topBold; boldBottomLine_ = bottomBold; OnDraw(); } -void TextLable::DrawOutline() +void TextLabel::DrawOutline() { void *tmpBuf = GetBuffer(); auto *pixelBuf = static_cast(tmpBuf); @@ -200,7 +200,7 @@ void TextLable::DrawOutline() } } -void TextLable::SetTextColor(BRGA888Pixel color) +void TextLabel::SetTextColor(BRGA888Pixel color) { textColor_.r = color.r; textColor_.g = color.g; @@ -208,18 +208,18 @@ void TextLable::SetTextColor(BRGA888Pixel color) textColor_.a = color.a; } -void TextLable::SetTextAlignmentMethod(AlignmentMethod methodH, AlignmentMethod methodV) +void TextLabel::SetTextAlignmentMethod(AlignmentMethod methodH, AlignmentMethod methodV) { fontAligMethodLevel_ = methodH; fontAligMethodUpright_ = methodV; } -void TextLable::SetOnClickCallback(ClickCallback cb) +void TextLabel::SetOnClickCallback(ClickCallback cb) { callBack_ = cb; } -void TextLable::DrawText() +void TextLabel::DrawText() { void *tmpBuf = GetBuffer(); int textSx = 0; @@ -272,7 +272,7 @@ void TextLable::DrawText() } } -void TextLable::DrawFocus() +void TextLabel::DrawFocus() { BRGA888Pixel pixBuf[viewWidth_]; for (int a =0; a< viewWidth_; a++) { @@ -289,7 +289,7 @@ void TextLable::DrawFocus() } } -void TextLable::OnKeyEvent(int key) +void TextLabel::OnKeyEvent(int key) { LOG(INFO) << "OnKeyEvent !"; switch (key) { diff --git a/services/ui/text_label.h b/services/ui/text_label.h index ff99ebbcfb927beee2834e1e582ca3f1b94cc5b3..16abaf187406a8675dc7d197dc8813d7cf3cfd50 100644 --- a/services/ui/text_label.h +++ b/services/ui/text_label.h @@ -26,20 +26,21 @@ constexpr int MAX_FONT_BUFFER_SIZE_HW = 4096; constexpr int MAX_TEXT_SIZE = 512; const std::string DEFAULT_FONT_NAME = "font"; -class TextLable : public View { +class TextLabel : public View { using ClickCallback = std::function; enum FontType { DEFAULT_FONT, }; -enum AlignmentMethod { - ALIGN_CENTER, - ALIGN_TO_LEFT, - ALIGN_TO_TOP, -}; public: - TextLable(int startX, int startY, int w, int h, Frame *parent); - ~TextLable() override {}; + enum AlignmentMethod { + ALIGN_CENTER, + ALIGN_TO_LEFT, + ALIGN_TO_TOP, + }; + + TextLabel(int startX, int startY, int w, int h, Frame *parent); + ~TextLabel() override {}; void SetText(const char *str); void SetTextColor(BRGA888Pixel color); void SetFont(FontType fType); diff --git a/services/ui/updater_ui.cpp b/services/ui/updater_ui.cpp index 81a19c23e010c18bf284a5f8155e17b15d30e55d..b12cf4c392ef1556dbf0383b275616e7c8448d23 100644 --- a/services/ui/updater_ui.cpp +++ b/services/ui/updater_ui.cpp @@ -14,7 +14,6 @@ */ #include "updater_ui.h" #include -#include #include "animation_label.h" #include "frame.h" #include "input_event.h" @@ -22,7 +21,6 @@ #include "progress_bar.h" #include "securec.h" #include "surface_dev.h" -#include "text_label.h" #include "updater_main.h" #include "updater_ui_const.h" #include "utils.h" @@ -31,92 +29,209 @@ namespace updater { using utils::String2Int; -constexpr int LABEL_HEIGHT = 15; -constexpr int LABEL0_OFFSET = 0; -constexpr int LABEL2_OFFSET = 1; -constexpr int LABEL3_OFFSET = 2; -constexpr int MAX_IMGS_NAME_SIZE = 255; +constexpr int LABEL_HEIGHT = 13; constexpr int MAX_IMGS = 62; +constexpr int DIALIG_COLOR_A = 0xAA; +constexpr int DIALOG_COLOR = 0x00; +constexpr int DISPLAY_TIME = 1000 * 1000; int g_updateFlag = 0; int g_textLabelNum = 0; -int g_updateErrFlag = 0; -Frame *g_hosFrame; +Frame *g_menuFrame; Frame *g_updateFrame; -TextLable *g_textLabel0; -TextLable *g_textLabel2; -TextLable *g_textLabel3; -TextLable *g_logLabel; -TextLable *g_logResultLabel; -TextLable *g_updateStateLable; -TextLable *g_updateInfoLabel; +TextLabel *g_textLabel0; +TextLabel *g_textLabel2; +TextLabel *g_textLabel3; +TextLabel *g_logLabel; +TextLabel *g_logResultLabel; +TextLabel *g_updateInfoLabel; AnimationLable *g_anmimationLabel; ProgressBar *g_progressBar; +TextLabel *g_dialogTitle; +TextLabel *g_dialogNote; +TextLabel *g_dialogNoteNext; +TextLabel *g_dialogCancalBtn; +TextLabel *g_dialogOkBtn; +SurfaceDev *g_sfDev; + +static void ClearText() +{ + if (g_logLabel != nullptr) { + g_logLabel->SetText(""); + } + if (g_logResultLabel != nullptr) { + g_logResultLabel->SetText(""); + } + if (g_updateInfoLabel != nullptr) { + g_updateInfoLabel->SetText(""); + } +} + +void ShowText(TextLabel *label, std::string text) +{ + if (label != nullptr) { + ClearText(); + label->SetText(text.c_str()); + } +} + +static void HideDialog() +{ + if (!g_menuFrame->IsVisiable()) { + return; + } + if (g_dialogTitle != nullptr) { + g_dialogTitle->Hide(); + } + if (g_dialogNote != nullptr) { + g_dialogNote->Hide(); + } + if (g_dialogNoteNext != nullptr) { + g_dialogNoteNext->Hide(); + } + if (g_dialogCancalBtn != nullptr) { + g_dialogCancalBtn->Hide(); + } + if (g_dialogOkBtn != nullptr) { + g_dialogOkBtn->Hide(); + } +} + +static void ShowDialog() +{ + if (!g_menuFrame->IsVisiable()) { + return; + } + if (g_dialogTitle != nullptr) { + g_dialogTitle->Show(); + } + if (g_dialogNote != nullptr) { + g_dialogNote->Show(); + } + if (g_dialogNoteNext != nullptr) { + g_dialogNoteNext->Show(); + } + if (g_dialogCancalBtn != nullptr) { + g_dialogCancalBtn->Show(); + } + if (g_dialogOkBtn != nullptr) { + g_dialogOkBtn->Show(); + } +} + +static void ShowMenu() +{ + if (g_menuFrame == nullptr) { + return; + } + if (g_textLabel0 != nullptr) { + g_textLabel0->Show(); + } + if (g_textLabel2 != nullptr) { + g_textLabel2->Show(); + } + if (g_textLabel3 != nullptr) { + g_textLabel3->Show(); + } + g_menuFrame->Show(); +} + +static void HideMenu() +{ + if (g_menuFrame == nullptr) { + return; + } + if (g_textLabel0 != nullptr) { + g_textLabel0->Hide(); + } + if (g_textLabel2 != nullptr) { + g_textLabel2->Hide(); + } + if (g_textLabel3 != nullptr) { + g_textLabel3->Hide(); + } + g_menuFrame->Hide(); +} + void OnKeyEvent(int viewId) { - if (viewId == g_textLabel0->GetViewId()) { + if (!g_menuFrame->IsVisiable()) { + return; + } + 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()) { + ShowDialog(); + } else if (viewId == g_textLabel3->GetViewId() && g_textLabel3->IsVisiable()) { + HideDialog(); + g_logLabel->SetText("Don't remove SD Card!"); + usleep(DISPLAY_TIME); + UpdaterStatus status = UpdaterFromSdcard(); + if (status != UPDATE_SUCCESS) { + ShowUpdateFrame(false); + ShowMenu(); + return; + } + DeleteView(); PostUpdater(); utils::DoReboot(""); - } else if (viewId == g_textLabel2->GetViewId()) { + } else if (viewId == g_dialogCancalBtn->GetViewId() && g_dialogCancalBtn->IsVisiable()) { + HideDialog(); + } else if (viewId == g_dialogOkBtn->GetViewId() && g_dialogOkBtn->IsVisiable()) { + HideDialog(); + HideMenu(); g_logLabel->SetText("Wipe data"); g_updateFlag = 1; ShowUpdateFrame(true); DoProgress(); int ret = FactoryReset(USER_WIPE_DATA, "/data"); - ShowUpdateFrame(false); if (ret != 0) { - g_logResultLabel->SetText("Wipe data failed"); - } else { - g_logResultLabel->SetText("Wipe data done"); - } - } else if (viewId == g_textLabel3->GetViewId()) { - g_logLabel->SetText("Update system!"); - auto status = UpdaterFromSdcard(); - if (status != UPDATE_SUCCESS) { - g_logResultLabel->SetText("install failed.\n"); + g_logLabel->SetText("Wipe data failed"); } else { - g_logResultLabel->SetText("install success\n"); + g_logLabel->SetText("Wipe data done"); } + ShowUpdateFrame(false); + ShowMenu(); } } void LoadImgs() { - char nameBuf[MAX_IMGS_NAME_SIZE]; for (int i = 0; i < MAX_IMGS; i++) { - UPDATER_ERROR_CHECK(!memset_s(nameBuf, MAX_IMGS_NAME_SIZE + 1, 0, MAX_IMGS_NAME_SIZE), - "Memset_s failed", return); + std::string nameBuf; if (i < LOOP_TOP_PICTURES) { - UPDATER_CHECK_ONLY_RETURN(snprintf_s(nameBuf, MAX_IMGS_NAME_SIZE, MAX_IMGS_NAME_SIZE - 1, - "/resources/loop0000%d.png", i) != -1, return); + nameBuf = "/resources/loop0000"; + nameBuf.append(std::to_string(i)).append(".png"); } else { - UPDATER_CHECK_ONLY_RETURN(snprintf_s(nameBuf, MAX_IMGS_NAME_SIZE, MAX_IMGS_NAME_SIZE - 1, - "/resources/loop000%d.png", i) != -1, return); + nameBuf = "/resources/loop000"; + nameBuf.append(std::to_string(i)).append(".png"); } g_anmimationLabel->AddImg(nameBuf); } - g_anmimationLabel->AddStaticImg(nameBuf); } void ShowUpdateFrame(bool isShow) { const int sleepMs = 300 * 100; - g_updateErrFlag = 0; if (isShow) { - g_hosFrame->Hide(); + g_menuFrame->Hide(); g_updateInfoLabel->SetText(""); - g_updateStateLable->SetText(""); g_updateFrame->Show(); g_anmimationLabel->Start(); return; } usleep(sleepMs); g_anmimationLabel->Stop(); + g_progressBar->Show(); g_updateFrame->Hide(); - g_hosFrame->Show(); + g_menuFrame->Show(); g_updateFlag = 0; } @@ -134,7 +249,7 @@ void DoProgress() g_progressBar->SetProgressValue(0); while (progressvalueTmp <= maxProgressValue) { if (!(g_updateInfoLabel->IsVisiable()) || !(g_progressBar->IsVisiable()) || - !(g_updateStateLable->IsVisiable()) || !(g_updateFrame->IsVisiable())) { + !(g_updateFrame->IsVisiable())) { LOG(INFO) <<"is not visable in updater_frame"; } usleep(sleepMs); @@ -142,12 +257,10 @@ void DoProgress() progressvalueTmp = progressvalueTmp + progressValueStep; g_progressBar->SetProgressValue(progressvalueTmp); if (progressvalueTmp >= maxProgressValue) { - g_updateStateLable->SetText("100%"); + g_anmimationLabel->Stop(); usleep(maxSleepMs); return; } - progressValue = std::to_string(progressvalueTmp).append("%"); - g_updateStateLable->SetText(progressValue.c_str()); } } } @@ -162,7 +275,7 @@ struct Bold { bool bottom; }; -static void TextLableInit(TextLable *t, const std::string &text, struct Bold bold, +static void TextLabelInit(TextLabel *t, const std::string &text, struct Bold bold, struct FocusInfo focus, View::BRGA888Pixel color) { if (t != nullptr) { @@ -174,17 +287,97 @@ static void TextLableInit(TextLable *t, const std::string &text, struct Bold bol } } +static void InitDialogButton(int height, int width, View::BRGA888Pixel bgColor) +{ + const int okStartY = 450; + const int cancelNextStartY = 451; + g_dialogOkBtn = new TextLabel(0, okStartY, width, DIALOG_OK_WIDTH, g_menuFrame); + g_dialogOkBtn->Hide(); + struct FocusInfo info {false, false}; + struct Bold bold {false, false}; + g_dialogOkBtn->SetViewId(DIALOG_OK_ID); + info = {false, false}; + bold = {false, false}; + TextLabelInit(g_dialogOkBtn, "Continue", bold, info, bgColor); + if (!g_dialogOkBtn) { + LOG(ERROR) << "g_dialogOkBtn is null"; + return; + } + g_dialogOkBtn->SetOnClickCallback(OnKeyEvent); + + g_dialogCancalBtn = new TextLabel(DIALOG_CANCEL_X, cancelNextStartY, DIALOG_OK_WIDTH, DIALOG_OK_WIDTH, g_menuFrame); + g_dialogCancalBtn->Hide(); + info = {false, false}; + bold = {false, false}; + TextLabelInit(g_dialogCancalBtn, "Cancel", bold, info, bgColor); + if (!g_dialogCancalBtn) { + LOG(ERROR) << "g_dialogCancalBtn is null"; + return; + } + g_dialogCancalBtn->SetViewId(DIALOG_CANCEL_ID); + g_dialogCancalBtn->SetOnClickCallback(OnKeyEvent); +} + +static void DialogInit(int height, int width) +{ + if (g_menuFrame == nullptr) { + LOG(ERROR) << "Frame is null"; + return; + } + const int titleHeight = 100; + const int titleStartX = 250; + const int noteStartY = 350; + const int noteNextStartY = 400; + View::BRGA888Pixel color; + color.r = DIALOG_COLOR; + color.g = DIALOG_COLOR; + color.b = DIALOG_COLOR; + color.a = DIALIG_COLOR_A; + g_dialogTitle = new TextLabel(0, titleStartX, width, titleHeight, g_menuFrame); + g_dialogTitle->SetTextAlignmentMethod(TextLabel::AlignmentMethod::ALIGN_CENTER, + TextLabel::AlignmentMethod::ALIGN_CENTER); + g_dialogTitle->Hide(); + struct FocusInfo info {false, false}; + struct Bold bold {false, false}; + TextLabelInit(g_dialogTitle, "Tip", bold, info, color); + if (!g_dialogTitle) { + LOG(ERROR) << "g_dialogTitle is null"; + return; + } + + g_dialogNote = new TextLabel(0, noteStartY, width, HEIGHT4, g_menuFrame); + g_dialogNote->Hide(); + info = {false, false}; + bold = {false, false}; + TextLabelInit(g_dialogNote, "Delete user date now...", bold, info, color); + if (!g_dialogNote) { + LOG(ERROR) << "g_dialogNote is null"; + return; + } + + g_dialogNoteNext = new TextLabel(0, noteNextStartY, width, HEIGHT4, g_menuFrame); + g_dialogNoteNext->Hide(); + info = {false, false}; + bold = {false, false}; + TextLabelInit(g_dialogNoteNext, "Do you want to continue?", bold, info, color); + if (!g_dialogNoteNext) { + LOG(ERROR) << "g_dialogNoteNext is null"; + return; + } + InitDialogButton(width, height, color); +} + static void MenuItemInit(int height, int width, View::BRGA888Pixel bgColor) { - if (g_hosFrame == nullptr) { + if (g_menuFrame == nullptr) { LOG(ERROR) << "Frame is null"; return; } - g_textLabel0 = new TextLable(0, height * LABEL0_OFFSET / LABEL_HEIGHT, width, height / - LABEL_HEIGHT, g_hosFrame); - struct FocusInfo info {true, true}; + g_textLabel0 = new TextLabel(0, height * LABEL0_OFFSET / LABEL_HEIGHT, width, height / + LABEL_HEIGHT, g_menuFrame); + struct FocusInfo info {false, true}; struct Bold bold {true, false}; - TextLableInit(g_textLabel0, "Reboot to normal system", bold, info, bgColor); + TextLabelInit(g_textLabel0, "Reboot to normal system", bold, info, bgColor); if (!g_textLabel0) { LOG(ERROR) << "g_textLabel0 is null"; return; @@ -192,11 +385,11 @@ static void MenuItemInit(int height, int width, View::BRGA888Pixel bgColor) g_textLabel0->SetOnClickCallback(OnKeyEvent); g_textLabelNum++; - g_textLabel2 = new TextLable(0, height * LABEL2_OFFSET / LABEL_HEIGHT, width, height / - LABEL_HEIGHT, g_hosFrame); + g_textLabel2 = new TextLabel(0, height * LABEL1_OFFSET / LABEL_HEIGHT, width, height / + LABEL_HEIGHT, g_menuFrame); info = {false, true}; bold = {false, false}; - TextLableInit(g_textLabel2, "Userdata reset", bold, info, bgColor); + TextLabelInit(g_textLabel2, "Userdata reset", bold, info, bgColor); if (!g_textLabel2) { LOG(ERROR) << "g_textLabel2 is null"; return; @@ -204,58 +397,111 @@ static void MenuItemInit(int height, int width, View::BRGA888Pixel bgColor) g_textLabel2->SetOnClickCallback(OnKeyEvent); g_textLabelNum++; - g_textLabel3 = new TextLable(0, height * LABEL3_OFFSET / LABEL_HEIGHT, width, height / - LABEL_HEIGHT, g_hosFrame); + g_textLabel3 = new TextLabel(0, height * LABEL2_OFFSET / LABEL_HEIGHT, width, height / + LABEL_HEIGHT, g_menuFrame); info = {false, true}; bold = {false, true}; - TextLableInit(g_textLabel3, "Update from SD Card", bold, info, bgColor); + TextLabelInit(g_textLabel3, "Update from SD Card", bold, info, bgColor); if (!g_textLabel3) { LOG(ERROR) << "g_textLabel3 is null"; return; } g_textLabel3->SetOnClickCallback(OnKeyEvent); g_textLabelNum++; + g_textLabel0->SetViewId(LABEL_ID_0); + g_textLabel2->SetViewId(LABEL_ID_1); + g_textLabel3->SetViewId(LABEL_ID_2); } -void HosInit() +void UpdaterUiInit() { constexpr char alpha = 0xff; int screenH = 0; int screenW = 0; - auto *sfDev = new SurfaceDev(SurfaceDev::DevType::DRM_DEVICE); - sfDev->GetScreenSize(screenW, screenH); + g_sfDev = new SurfaceDev(SurfaceDev::DevType::DRM_DEVICE); + g_sfDev->GetScreenSize(screenW, screenH); View::BRGA888Pixel bgColor {0x00, 0x00, 0x00, alpha}; - g_hosFrame = new Frame(screenW, screenH, View::PixelFormat::BGRA888, sfDev); - g_hosFrame->SetBackgroundColor(&bgColor); - g_hosFrame->Hide(); + g_menuFrame = new Frame(screenW, screenH, View::PixelFormat::BGRA888, g_sfDev); + g_menuFrame->SetBackgroundColor(&bgColor); + g_menuFrame->Hide(); MenuItemInit(screenH, screenW, bgColor); + DialogInit(screenH, screenW); - g_logLabel = new TextLable(START_X1, START_Y1, WIDTH1, HEIGHT1, g_hosFrame); + g_logLabel = new TextLabel(START_X1, START_Y1, WIDTH1, HEIGHT1, g_menuFrame); struct FocusInfo info {false, false}; struct Bold bold {false, false}; - TextLableInit(g_logLabel, "", bold, info, bgColor); + TextLabelInit(g_logLabel, "", bold, info, bgColor); - g_logResultLabel = new TextLable(START_X2, START_Y2, WIDTH2, HEIGHT2, g_hosFrame); - TextLableInit(g_logResultLabel, "", bold, info, bgColor); + g_logResultLabel = new TextLabel(START_X2, START_Y2, WIDTH2, HEIGHT2, g_menuFrame); + TextLabelInit(g_logResultLabel, "", bold, info, bgColor); - g_updateFrame = new Frame(screenW, screenH, View::PixelFormat::BGRA888, sfDev); + g_updateFrame = new Frame(screenW, screenH, View::PixelFormat::BGRA888, g_sfDev); g_updateFrame->SetBackgroundColor(&bgColor); g_updateFrame->Hide(); - g_anmimationLabel = new AnimationLable(screenW / START_X_SCALE, screenH / START_Y_SCALE, + g_anmimationLabel = new AnimationLable(START_X_SCALE, START_Y_SCALE, screenW * WIDTH_SCALE1 / WIDTH_SCALE2, screenH >> 1, g_updateFrame); g_anmimationLabel->SetBackgroundColor(&bgColor); LoadImgs(); g_progressBar = new ProgressBar(START_X3, START_Y3, WIDTH3, HEIGHT3, g_updateFrame); - g_updateStateLable = new TextLable(START_X4, START_Y4, screenH, HEIGHT4, g_updateFrame); - g_updateStateLable->SetOutLineBold(false, false); - g_updateStateLable->SetBackgroundColor(&bgColor); - g_updateInfoLabel = new TextLable(START_X5, START_Y5, screenW, HEIGHT5, g_updateFrame); + g_updateInfoLabel = new TextLabel(START_X5, START_Y5, screenW, HEIGHT5, g_updateFrame); g_updateInfoLabel->SetOutLineBold(false, false); g_updateInfoLabel->SetBackgroundColor(&bgColor); HdfInit(); } + +void DeleteView() +{ + if (g_updateInfoLabel != nullptr) { + delete g_updateInfoLabel; + } + if (g_anmimationLabel != nullptr) { + delete g_anmimationLabel; + } + if (g_progressBar != nullptr) { + delete g_progressBar; + } + if (g_dialogTitle != nullptr) { + delete g_dialogTitle; + } + if (g_dialogNote != nullptr) { + delete g_dialogNote; + } + if (g_dialogNoteNext != nullptr) { + delete g_dialogNoteNext; + } + if (g_dialogCancalBtn != nullptr) { + delete g_dialogCancalBtn; + } + if (g_dialogOkBtn != nullptr) { + delete g_dialogOkBtn; + } + if (g_logResultLabel != nullptr) { + delete g_logResultLabel; + } + if (g_textLabel0 != nullptr) { + delete g_textLabel0; + } + if (g_textLabel2 != nullptr) { + delete g_textLabel2; + } + if (g_textLabel3 != nullptr) { + delete g_textLabel3; + } + if (g_logLabel == nullptr) { + delete g_logLabel; + } + if (g_updateFrame != nullptr) { + delete g_updateFrame; + } + if (g_menuFrame != nullptr) { + delete g_menuFrame; + } + if (g_sfDev != nullptr) { + delete g_sfDev; + } +} } // namespace updater diff --git a/services/ui/updater_ui.h b/services/ui/updater_ui.h index c7ec20fb405c0fd7e0dca1cfc36ae9a7540b5de1..d495aa16388e92b7852758a7a21570412ec3d01c 100644 --- a/services/ui/updater_ui.h +++ b/services/ui/updater_ui.h @@ -15,11 +15,18 @@ #ifndef UPDATE_UI_UPDATER_UI_H #define UPDATE_UI_UPDATER_UI_H +#include +#include "text_label.h" + namespace updater { void DoProgress(); void ShowUpdateFrame(bool isShow); -void HosInit(); +void UpdaterUiInit(); + +void ShowText(TextLabel *label, std::string text); + +void DeleteView(); } // namespace updater #endif /* UPDATE_UI_HOS_UPDATER_H */ diff --git a/services/ui/updater_ui_const.h b/services/ui/updater_ui_const.h index af0cb4496dff5b012653a42fb311535efb5e3947..be791e4530c332ab946827fe966dfc9ba2e8a4ea 100644 --- a/services/ui/updater_ui_const.h +++ b/services/ui/updater_ui_const.h @@ -25,20 +25,35 @@ constexpr int START_X2 = 0; constexpr int START_Y2 = 900; constexpr int WIDTH2 = 480; constexpr int HEIGHT2 = 30; -constexpr int START_X3 = 70; -constexpr int START_Y3 = 500; +constexpr int START_X3 = 90; +constexpr int START_Y3 = 720; constexpr int WIDTH3 = 300; -constexpr int HEIGHT3 = 20; -constexpr int START_X4 = 195; -constexpr int START_Y4 = 420; +constexpr int HEIGHT3 = 15; +constexpr int START_X4 = 210; +constexpr int START_Y4 = 630; constexpr int HEIGHT4 = 50; constexpr int START_X5 = 0; constexpr int START_Y5 = 900; constexpr int HEIGHT5 = 50; -constexpr int START_X_SCALE = 8; -constexpr int START_Y_SCALE = 8; +constexpr int START_X_SCALE = 90; +constexpr int START_Y_SCALE = 330; constexpr int WIDTH_SCALE1 = 3; constexpr int WIDTH_SCALE2 = 4; constexpr int LOOP_TOP_PICTURES = 10; +constexpr int INVALID_EVENT = -1; +constexpr int PRESS_EVENT = 0; +constexpr int RELEASE_EVENT = 1; +constexpr int LABEL0_OFFSET = 0; +constexpr int LABEL1_OFFSET = 1; +constexpr int LABEL2_OFFSET = 2; +constexpr int LABEL_ID_0 = 100; +constexpr int LABEL_ID_1 = 101; +constexpr int LABEL_ID_2 = 102; +constexpr int DIALOG_OK_ID = 200; +constexpr int DIALOG_CANCEL_ID = 201; +constexpr int DIALOG_CANCEL_X = 340; +constexpr int DIALOG_OK_WIDTH = 150; +constexpr int SCREEN_WIDTH = 480; +constexpr int SCREEN_HEIGHT = 960; } // namespace updater #endif /* UPDATE_UI_HOS_UPDATER_H */ \ No newline at end of file diff --git a/services/ui/view.cpp b/services/ui/view.cpp index 72079165fc54aaafa7d37cb70344f1ac63275e9c..3fe5e0234b0cb2535f1b11fbe0f4a7b5ab2e9234 100644 --- a/services/ui/view.cpp +++ b/services/ui/view.cpp @@ -105,7 +105,6 @@ void View::Hide() void View::Show() { if (!isVisiable_) { - LOG(DEBUG) << "isVisiable:" << isVisiable_; isVisiable_ = true; OnDraw(); } @@ -176,4 +175,9 @@ void View::OnKeyEvent(int key) { (void)(key); } + +View::~View() +{ + FreeBuffer(); +} } // namespace updater diff --git a/services/ui/view.h b/services/ui/view.h index 9f87366668d36a3ca59554b8d2c71324092e800d..afde4bd484bb18afa1275e1d659d3f6daf4db657 100644 --- a/services/ui/view.h +++ b/services/ui/view.h @@ -15,9 +15,9 @@ #ifndef UPDATER_UI_VIEW_H #define UPDATER_UI_VIEW_H #include -#include #include #include +#include #include #include @@ -41,8 +41,7 @@ public: BGRA888, }; View() {}; - virtual ~View() {}; - void* CreateBuffer(int w, int h, int pixelFormat); + virtual ~View(); virtual void SetBackgroundColor(BRGA888Pixel *color); virtual void DrawSubView(int x, int y, int w, int h, void *buf); virtual void OnKeyEvent(int key); @@ -69,6 +68,8 @@ public: int viewWidth_ = 0; int viewHeight_ = 0; std::mutex mutex_; +protected: + void* CreateBuffer(int w, int h, int pixelFormat); private: char* viewBuffer_ = nullptr; char* shadowBuffer_ = nullptr; diff --git a/services/updater.cpp b/services/updater.cpp index 03143f4eac0868ae206ccef18b97d0c1569a09c0..c3e34b775d3d76c47ad4b63dfcb254684214d2ff 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -40,12 +40,11 @@ using updater::utils::SplitString; using updater::utils::Trim; using namespace hpackage; -extern TextLable *g_updateInfoLabel; +extern TextLabel *g_updateInfoLabel; extern ProgressBar *g_progressBar; -extern TextLable *g_updateStateLable; -extern int g_updateErrFlag; -int g_percentage; +int g_percentage; +int g_tmpProgressValue; static int GetTemprature() { int temprature = FAKE_TEMPRATURE; @@ -140,14 +139,17 @@ static UpdaterStatus IsSpaceCapacitySufficient(PkgManager::PkgManagerPtr pkgMana return UPDATE_ERROR); UPDATER_ERROR_CHECK(statvfs64("/sdcard", &updaterVfs) >= 0, "Statvfs read /sdcard error!", return UPDATE_ERROR); - UPDATER_ERROR_CHECK(updaterVfs.f_bfree * updaterVfs.f_bsize > info->unpackedSize, + uint64_t freeSpaceSize = static_cast(updaterVfs.f_bfree); + uint64_t blockSize = static_cast(updaterVfs.f_bsize); + uint64_t totalFreeSize = freeSpaceSize * blockSize; + UPDATER_ERROR_CHECK(totalFreeSize > static_cast(info->unpackedSize), "Can not update, free space is not enough", - g_updateInfoLabel->SetText("Can't update, free space is not enough"); return UPDATE_ERROR); + ShowText(g_updateInfoLabel, "Free space is not enough"); return UPDATE_ERROR); } else { UPDATER_ERROR_CHECK(statvfs64("/data", &updaterVfs) >= 0, "Statvfs read /data error!", return UPDATE_ERROR); UPDATER_ERROR_CHECK(updaterVfs.f_bfree * updaterVfs.f_bsize > (info->unpackedSize + MAX_LOG_SPACE), "Can not update, free space is not enough", - g_updateInfoLabel->SetText("Can't update, free space is not enough"); return UPDATE_ERROR); + ShowText(g_updateInfoLabel, "Free space is not enough"); return UPDATE_ERROR); } return UPDATE_SUCCESS; } @@ -155,10 +157,10 @@ static UpdaterStatus IsSpaceCapacitySufficient(PkgManager::PkgManagerPtr pkgMana UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, const std::string &packagePath, int retryCount) { + g_progressBar->Hide(); ShowUpdateFrame(true); - UPDATER_ERROR_CHECK(pkgManager != nullptr, "Fail to GetPackageInstance", return UPDATE_CORRUPT); - UPDATER_CHECK_ONLY_RETURN(SetupPartitions() == 0, g_updateInfoLabel->SetText("update failed\n"); + UPDATER_CHECK_ONLY_RETURN(SetupPartitions() == 0, ShowText(g_updateInfoLabel, "update failed"); return UPDATE_ERROR); int beforeTemperature = GetTemprature(); @@ -166,7 +168,7 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons g_updateInfoLabel->SetText("Verify package..."); UPDATER_ERROR_CHECK(access(packagePath.c_str(), 0) == 0, "package is not exist", - g_updateInfoLabel->SetText("package is not exist"); return UPDATE_CORRUPT); + ShowText(g_updateInfoLabel, "package is not exist"); return UPDATE_CORRUPT); if (retryCount > 0) { LOG(INFO) << "Retry for " << retryCount << " time(s)"; } else { @@ -175,7 +177,6 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons // If it returns UPDATE_CORRUPT, which means something wrong with package manager. // Let package verify handle this. if (ret == UPDATE_ERROR) { - g_updateErrFlag = 1; return ret; } else if (ret == UPDATE_SUCCESS) { pkgManager = PkgManager::GetPackageInstance(); @@ -184,9 +185,8 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons int32_t verifyret = GetUpdatePackageInfo(pkgManager, packagePath); UPDATER_ERROR_CHECK(verifyret == PKG_SUCCESS, "Verify package Fail...", - g_updateInfoLabel->SetText("Verify package Fail...\n"); return UPDATE_CORRUPT); + ShowText(g_updateInfoLabel, "Verify package Fail..."); return UPDATE_CORRUPT); LOG(INFO) << "Package verified. start to install package..."; - g_updateInfoLabel->SetText("Start to install package..."); int32_t versionRet = UpdatePreProcess(pkgManager, packagePath); UPDATER_ERROR_CHECK(versionRet == PKG_SUCCESS, "Version Check Fail...", return UPDATE_CORRUPT); @@ -194,12 +194,10 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons UpdaterStatus updateRet = StartUpdaterProc(pkgManager, packagePath, retryCount, maxTemperature); if (updateRet == UPDATE_SUCCESS) { g_progressBar->SetProgressValue(FULL_PERCENT_PROGRESS); - g_updateStateLable->SetText("100%"); g_updateInfoLabel->SetText("Update success, reboot now"); std::this_thread::sleep_for(std::chrono::milliseconds(SHOW_FULL_PROGRESS_TIME)); LOG(INFO)<< "update success , do reboot now"; } else { - g_updateErrFlag = 1; g_updateInfoLabel->SetText("Install failed."); LOG(ERROR) << "Install package failed."; } @@ -233,10 +231,18 @@ static void HandleChildOutput(const std::string &buffer, int32_t bufferLen, if (progress.size() != DEFAULT_PROCESS_NUM) { LOG(ERROR) << "show progress with wrong arguments"; } else { + 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); - g_percentage = g_percentage / PROGRESS_VALUE_CONST; - g_updateStateLable->SetText(std::to_string(g_percentage).append("%").c_str()); + 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); } } else if (outputHeader == "set_progress") { @@ -253,8 +259,6 @@ static void HandleChildOutput(const std::string &buffer, int32_t bufferLen, UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std::string &packagePath, int retryCount, int &maxTemperature) { - ShowUpdateFrame(true); - int pfd[DEFAULT_PIPE_NUM]; /* communication between parent and child */ UPDATER_FILE_CHECK(pipe(pfd) >= 0, "Create pipe failed: ", return UPDATE_ERROR); UPDATER_ERROR_CHECK(pkgManager != nullptr, "Fail to GetPackageInstance", return UPDATE_CORRUPT); @@ -275,7 +279,7 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std:: fullPath = "/system/bin/test_update_binary"; } #endif - UPDATER_ERROR_CHECK_NOT_RETURN(chmod(fullPath.c_str(), utils::S_READ_WRITE_PERMISSION) == 0, + UPDATER_ERROR_CHECK_NOT_RETURN(chmod(fullPath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0, "Failed to change mode"); if (retryCount > 0) { @@ -291,6 +295,7 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std:: char buffer[MAX_BUFFER_SIZE]; bool retryUpdate = false; FILE* fromChild = fdopen(pipeRead, "r"); + g_tmpProgressValue = 0; g_progressBar->SetProgressValue(0); while (fgets(buffer, MAX_BUFFER_SIZE, fromChild) != nullptr) { size_t n = strlen(buffer); diff --git a/services/updater_binary/update_partitions.cpp b/services/updater_binary/update_partitions.cpp index b75e368eb95620412c3299a72bac87d46690d91d..62957696cd08a5e22955d90791977857d6afe8c8 100644 --- a/services/updater_binary/update_partitions.cpp +++ b/services/updater_binary/update_partitions.cpp @@ -47,24 +47,24 @@ int UpdatePartitions::ParsePartitionInfo(const std::string &partitionInfo, Parti cJSON_Delete(root); return 0; } - cJSON* thisPartion = cJSON_GetArrayItem(partitions, i); - UPDATER_ERROR_CHECK(thisPartion != nullptr, "Error get thisPartion", cJSON_Delete(root); break); + cJSON* thisPartition = cJSON_GetArrayItem(partitions, i); + UPDATER_ERROR_CHECK(thisPartition != nullptr, "Error get thisPartion", cJSON_Delete(root); break); - cJSON* item = cJSON_GetObjectItem(thisPartion, "start"); + cJSON* item = cJSON_GetObjectItem(thisPartition, "start"); UPDATER_ERROR_CHECK(item != nullptr, "Error get start", cJSON_Delete(root); break); myPartition->start = item->valueint; - item = cJSON_GetObjectItem(thisPartion, "length"); + item = cJSON_GetObjectItem(thisPartition, "length"); UPDATER_ERROR_CHECK(item != nullptr, "Error get length", cJSON_Delete(root); break); myPartition->length = item->valueint; myPartition->partNum = 0; myPartition->devName = "mmcblk0px"; - item = cJSON_GetObjectItem(thisPartion, "partName"); + item = cJSON_GetObjectItem(thisPartition, "partName"); UPDATER_ERROR_CHECK(item != nullptr, "Error get partName", cJSON_Delete(root); break); myPartition->partName = (item->valuestring); - item = cJSON_GetObjectItem(thisPartion, "fsType"); + item = cJSON_GetObjectItem(thisPartition, "fsType"); UPDATER_ERROR_CHECK(item != nullptr, "Error get fsType", cJSON_Delete(root); break); myPartition->fsType = (item->valuestring); diff --git a/services/updater_main.cpp b/services/updater_main.cpp index b4f85bf6c80d657e73e131f7c3eaf95bdb6775a3..8de5e775c3b1e4c3b439ee5d523f2e16ee160b6f 100644 --- a/services/updater_main.cpp +++ b/services/updater_main.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -46,11 +47,10 @@ using utils::String2Int; using namespace hpackage; using namespace updater::utils; -extern TextLable *g_logLabel; -extern TextLable* g_logResultLabel; -extern TextLable* g_updateInfoLabel; -extern int g_updateErrFlag; - +extern TextLabel *g_logLabel; +extern TextLabel *g_logResultLabel; +extern TextLabel *g_updateInfoLabel; +extern int g_updateFlag; constexpr struct option OPTIONS[] = { { "update_package", required_argument, nullptr, 0 }, { "retry_count", required_argument, nullptr, 0 }, @@ -105,19 +105,31 @@ int FactoryReset(FactoryResetMode mode, const std::string &path) UpdaterStatus UpdaterFromSdcard() { #ifndef UPDATER_UT - UPDATER_WARING_CHECK(MountForPath("/sdcard") == 0, "MountForPath /sdcard failed!", return UPDATE_ERROR); + // sdcard fsType only support ext4/vfat + if (MountForPath(SDCARD_PATH) != 0) { + std::string sdcardStr = GetBlockDeviceByMountPoint(SDCARD_PATH); + int ret = mount(sdcardStr.c_str(), SDCARD_PATH.c_str(), "vfat", 0, NULL); + UPDATER_WARING_CHECK(ret == 0, "MountForPath /sdcard failed!", return UPDATE_ERROR); + } #endif UPDATER_ERROR_CHECK(access(SDCARD_CARD_PKG_PATH.c_str(), 0) == 0, "package is not exist", - g_logLabel->SetText("package is not exist!"); + ShowText(g_logLabel, "Package is not exist!"); return UPDATE_CORRUPT); PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return UPDATE_CORRUPT); STAGE(UPDATE_STAGE_BEGIN) << "UpdaterFromSdcard"; - g_logLabel->SetText("Update start, please do not remove SD card!"); LOG(INFO) << "UpdaterFromSdcard start, sdcard updaterPath : " << SDCARD_CARD_PKG_PATH; UpdaterStatus updateRet = DoInstallUpdaterPackage(pkgManager, SDCARD_CARD_PKG_PATH.c_str(), 0); + if (updateRet != UPDATE_SUCCESS) { + std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION)); + g_logLabel->SetText("SD Card update failed!"); + STAGE(UPDATE_STAGE_FAIL) << "UpdaterFromSdcard failed"; + } else { + LOG(INFO) << "Update from SD Card successfully!"; + STAGE(UPDATE_STAGE_SUCCESS) << "UpdaterFromSdcard success"; + } return updateRet; } @@ -129,7 +141,7 @@ bool IsBatteryCapacitySufficient() static UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, const std::vector &args, PkgManager::PkgManagerPtr manager) { - UpdaterStatus status = UPDATE_NORMAL; + UpdaterStatus status = UPDATE_UNKNOWN; if (IsBatteryCapacitySufficient() == false) { g_logLabel->SetText("Battery is low.\n"); LOG(ERROR) << "Battery is not sufficient for install package."; @@ -143,12 +155,10 @@ static UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, const std::v SetRetryCountToMisc(upParams.retryCount + 1, args); } - ShowUpdateFrame(true); status = DoInstallUpdaterPackage(manager, upParams.updatePackage, upParams.retryCount); if (status != UPDATE_SUCCESS) { - ShowUpdateFrame(false); + std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION)); g_logLabel->SetText("update failed!"); - g_updateInfoLabel->SetText("update failed!"); STAGE(UPDATE_STAGE_FAIL) << "Install failed"; if (status == UPDATE_RETRY && upParams.retryCount < MAX_RETRY_COUNT) { upParams.retryCount += 1; @@ -159,18 +169,15 @@ static UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, const std::v } else { LOG(INFO) << "Install package success."; STAGE(UPDATE_STAGE_SUCCESS) << "Install package"; - PostUpdater(); - utils::DoReboot(""); } } - ShowUpdateFrame(false); return status; } static UpdaterStatus StartUpdaterEntry(PkgManager::PkgManagerPtr manager, const std::vector &args, UpdaterParams &upParams) { - UpdaterStatus status = UPDATE_SUCCESS; + UpdaterStatus status = UPDATE_UNKNOWN; if (upParams.updatePackage != "") { ShowUpdateFrame(true); status = InstallUpdaterPackage(upParams, args, manager); @@ -178,6 +185,7 @@ static UpdaterStatus StartUpdaterEntry(PkgManager::PkgManagerPtr manager, } else if (upParams.factoryWipeData) { LOG(INFO) << "Factory level FactoryReset begin"; status = UPDATE_SUCCESS; + g_updateFlag = 1; ShowUpdateFrame(true); DoProgress(); UPDATER_ERROR_CHECK(FactoryReset(FACTORY_WIPE_DATA, "/data") == 0, "FactoryReset factory level failed", @@ -191,6 +199,8 @@ static UpdaterStatus StartUpdaterEntry(PkgManager::PkgManagerPtr manager, } } else if (upParams.userWipeData) { LOG(INFO) << "User level FactoryReset begin"; + status = UPDATE_SUCCESS; + g_updateFlag = 1; ShowUpdateFrame(true); DoProgress(); UPDATER_ERROR_CHECK(FactoryReset(USER_WIPE_DATA, "/data") == 0, "FactoryReset user level failed", @@ -202,7 +212,6 @@ static UpdaterStatus StartUpdaterEntry(PkgManager::PkgManagerPtr manager, g_logResultLabel->SetText("Wipe data finished"); PostUpdater(); std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION)); - utils::DoReboot(""); } } return status; @@ -254,68 +263,6 @@ static UpdaterStatus StartUpdater(PkgManager::PkgManagerPtr manager, const std:: return StartUpdaterEntry(manager, args, upParams); } -void CompressLogs(const std::string &name) -{ - PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); - UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return); - std::vector> files; - // Build the zip file to be packaged - std::vector testFileNames; - std::string realName = GetName(name.c_str()); - testFileNames.push_back(realName); - for (auto name : testFileNames) { - ZipFileInfo file; - file.fileInfo.identity = name; - file.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP; - file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC; - std::string fileName = "/data/updater/log/" + name; - files.push_back(std::pair(fileName, file)); - } - - PkgInfo pkgInfo; - pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; - pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; - pkgInfo.pkgType = PKG_PACK_TYPE_ZIP; - - char realTime[MAX_TIME_SIZE]; - auto sysTime = std::chrono::system_clock::now(); - auto currentTime = std::chrono::system_clock::to_time_t(sysTime); - std::strftime(realTime, sizeof(realTime), "%H_%M_%S", std::localtime(¤tTime)); - char pkgName[MAX_LOG_NAME_SIZE]; - UPDATER_CHECK_ONLY_RETURN(snprintf_s(pkgName, MAX_LOG_NAME_SIZE, MAX_LOG_NAME_SIZE - 1, - "/data/updater/log/%s_%s.zip", realName.c_str(), realTime) != -1, return); - int32_t ret = pkgManager->CreatePackage(pkgName, utils::GetCertName(), &pkgInfo, files); - UPDATER_CHECK_ONLY_RETURN(ret != 0, return); - UPDATER_CHECK_ONLY_RETURN(utils::DeleteFile(name) == 0, return); -} - -bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog) -{ - UPDATER_WARING_CHECK(MountForPath(UPDATER_LOG_DIR) == 0, "MountForPath /data/log failed!", return false); - if (access(UPDATER_LOG_DIR.c_str(), 0) != 0) { - UPDATER_ERROR_CHECK(!utils::MkdirRecursive(UPDATER_LOG_DIR, S_READ_WRITE_PERMISSION), - "MkdirRecursive error!", return false); - } - - FILE* dFp = fopen(dLog.c_str(), "ab+"); - UPDATER_ERROR_CHECK(dFp != nullptr, "open log failed", return false); - - FILE* sFp = fopen(sLog.c_str(), "r"); - UPDATER_ERROR_CHECK(sFp != nullptr, "open log failed", fclose(dFp); return false); - - char buf[MAX_LOG_BUF_SIZE]; - size_t bytes; - while ((bytes = fread(buf, 1, sizeof(buf), sFp)) != 0) { - fwrite(buf, 1, bytes, dFp); - } - fseek(dFp, 0, SEEK_END); - UPDATER_INFO_CHECK(ftell(dFp) < MAX_LOG_SIZE, "log size greater than 5M!", CompressLogs(dLog)); - fclose(sFp); - fclose(dFp); - sync(); - return true; -} - static bool DeleteUpdaterPath(const std::string &path) { auto pDir = std::unique_ptr(opendir(path.c_str()), closedir); @@ -347,7 +294,7 @@ static bool ClearMisc() "ClearMisc clear boot message to misc failed", return false); auto fp = std::unique_ptr(fopen(MISC_FILE.c_str(), "rb+"), fclose); UPDATER_FILE_CHECK(fp != nullptr, "WriteVersionCode fopen failed", return false); - fseek(fp.get(), MISC_PARTITION_RECORD_OFFSET, SEEK_SET); + fseek(fp.get(), PARTITION_RECORD_OFFSET, SEEK_SET); off_t clearOffset = 0; UPDATER_FILE_CHECK(fwrite(&clearOffset, sizeof(off_t), 1, fp.get()) == 1, "ClearMisc write misc initOffset 0 failed", return false); @@ -382,9 +329,10 @@ void PostUpdater() UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_LOG, UPDATER_LOG) == true, "Copy updater log failed!"); UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_ERROR_CODE_PATH, ERROR_CODE_PATH) == true, "Copy error code log failed!"); - chmod(UPDATER_LOG.c_str(), S_ONLY_READ_PERMISSION); - chmod(UPDATER_STAGE_LOG.c_str(), S_ONLY_READ_PERMISSION); - chmod(ERROR_CODE_PATH.c_str(), S_ONLY_READ_PERMISSION); + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + chmod(UPDATER_LOG.c_str(), mode); + chmod(UPDATER_STAGE_LOG.c_str(), mode); + chmod(ERROR_CODE_PATH.c_str(), mode); STAGE(UPDATE_STAGE_SUCCESS) << "PostUpdater"; UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_STAGE_LOG, UPDATER_STAGE_LOG) == true, "Copy stage log failed!"); } @@ -410,7 +358,7 @@ std::vector ParseParams(int argc, char **argv) int UpdaterMain(int argc, char **argv) { - UpdaterStatus status = UPDATE_SUCCESS; + UpdaterStatus status = UPDATE_UNKNOWN; PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance(); InitUpdaterLogger("UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); SetLogLevel(INFO); @@ -418,19 +366,23 @@ int UpdaterMain(int argc, char **argv) std::vector args = ParseParams(argc, argv); LOG(INFO) << "Ready to start"; - HosInit(); + UpdaterUiInit(); status = StartUpdater(manager, args, argv); + std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION)); #ifndef UPDATER_UT if (status != UPDATE_SUCCESS && status != UPDATE_SKIP) { - ShowUpdateFrame(false); + ShowUpdateFrame(false); + // Wait for user input + while (true) { + pause(); + } + return 0; } #endif + DeleteView(); PostUpdater(); PkgManager::ReleasePackageInstance(manager); - // Wait for user input - while (true) { - pause(); - } + utils::DoReboot(""); return 0; } } // updater diff --git a/services/updater_main.h b/services/updater_main.h index e7adc1d78c737e32b81da3a3eaadad166b137b4b..c2862850c4b4121927ffce217070dd3eb3524875 100644 --- a/services/updater_main.h +++ b/services/updater_main.h @@ -43,10 +43,6 @@ int FactoryReset(FactoryResetMode mode, const std::string &path); UpdaterStatus UpdaterFromSdcard(); -bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog); - bool IsBatteryCapacitySufficient(); - -void CompressLogs(const std::string &name); } // namespace updater #endif // UPDATER_MAIN_H diff --git a/utils/include/utils.h b/utils/include/utils.h index 65cc924cd613db6d962d30aa099c66c53351134c..c5b4216e8973795e42fa515ae32f533af1d3e22f 100644 --- a/utils/include/utils.h +++ b/utils/include/utils.h @@ -21,15 +21,11 @@ namespace updater { namespace utils { -static constexpr int N_BIN = 2; -static constexpr int N_OCT = 8; -static constexpr int N_DEC = 10; -static constexpr int N_HEX = 16; -static constexpr int S_USER_PERMISSION = 1000; -static constexpr int S_OPEN_PERMISSION = 0600; -static constexpr int S_DIR_PERMISSION = 0700; -static constexpr int S_READ_WRITE_PERMISSION = 0755; -static constexpr int S_ONLY_READ_PERMISSION = 0644; +constexpr int N_BIN = 2; +constexpr int N_OCT = 8; +constexpr int N_DEC = 10; +constexpr int N_HEX = 16; +constexpr int O_USER_GROUP_ID = 1000; constexpr int ARGC_TWO_NUMS = 2; template T String2Int(const std::string &str, int base = N_HEX) @@ -58,6 +54,8 @@ bool ReadFully(int fd, void* data, size_t size); bool ReadFileToString(int fd, std::string &content); bool WriteStringToFile(int fd, const std::string& content); std::string GetLocalBoardId(); +bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog); +void CompressLogs(const std::string &name); } // utils } // updater #endif // UPDATER_UTILS_H diff --git a/utils/utils.cpp b/utils/utils.cpp index 4a9a51a41b8173cdefba6a57d615ebba3e31513b..7ce2b17284153863ad62c6f41b0cde2c19789556 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -13,28 +13,34 @@ * limitations under the License. */ +#include "utils.h" #include #include #include #include #include #include +#include #include -#include #include #include -#include #include #include #include "fs_manager/mount.h" #include "log/log.h" #include "misc_info/misc_info.h" +#include "package/pkg_manager.h" #include "securec.h" +#include "updater/updater_const.h" namespace updater { +using namespace hpackage; + namespace utils { constexpr uint32_t MAX_PATH_LEN = 256; constexpr uint8_t SHIFT_RIGHT_FOUR_BITS = 4; +constexpr int USER_ROOT_AUTHORITY = 0; +constexpr int GROUP_SYS_AUTHORITY = 1000; int32_t DeleteFile(const std::string& filename) { UPDATER_ERROR_CHECK (!filename.empty(), "Invalid filename", return -1); @@ -71,7 +77,7 @@ int MkdirRecursive(const std::string &pathName, mode_t mode) } int64_t GetFilesFromDirectory(const std::string &path, std::vector &files, - bool isRecursive = false) + bool isRecursive) { struct stat sb {}; UPDATER_ERROR_CHECK (stat(path.c_str(), &sb) != -1, "Failed to stat", return -1); @@ -94,11 +100,10 @@ int64_t GetFilesFromDirectory(const std::string &path, std::vector } } closedir(dirp); - return totalSize; } -std::vector SplitString(const std::string &str, const std::string del = " \t") +std::vector SplitString(const std::string &str, const std::string del) { std::vector result; size_t found = std::string::npos; @@ -157,7 +162,7 @@ std::string ConvertSha256Hex(const uint8_t* shaDigest, size_t length) void DoReboot(const std::string& rebootTarget) { LOG(INFO) << ", rebootTarget: " << rebootTarget; - static const int32_t maxCommandSize = 12; + static const int32_t maxCommandSize = 16; LoadFstab(); auto miscBlockDevice = GetBlockDeviceByMountPoint("/misc"); struct UpdateMessage msg; @@ -165,7 +170,7 @@ void DoReboot(const std::string& rebootTarget) bool ret = ReadUpdaterMessage(miscBlockDevice, msg); UPDATER_ERROR_CHECK(ret == true, "DoReboot read misc failed", return); if (strcmp(msg.command, "boot_updater") != 0) { - UPDATER_ERROR_CHECK(!memcpy_s(msg.command, maxCommandSize, "boot_updater", maxCommandSize), + UPDATER_ERROR_CHECK(!memcpy_s(msg.command, maxCommandSize, "boot_updater", maxCommandSize - 1), "Memcpy failed", return); msg.command[maxCommandSize] = 0; } @@ -267,5 +272,71 @@ std::string GetLocalBoardId() { return "HI3516"; } + +void CompressLogs(const std::string &name) +{ + PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); + UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return); + std::vector> files; + // Build the zip file to be packaged + std::vector testFileNames; + std::string realName = name.substr(name.find_last_of("/") + 1); + testFileNames.push_back(realName); + for (auto name : testFileNames) { + ZipFileInfo file; + file.fileInfo.identity = name; + file.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP; + file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC; + std::string fileName = "/data/updater/log/" + name; + files.push_back(std::pair(fileName, file)); + } + + PkgInfo pkgInfo; + pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; + pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; + pkgInfo.pkgType = PKG_PACK_TYPE_ZIP; + + char realTime[MAX_TIME_SIZE]; + auto sysTime = std::chrono::system_clock::now(); + auto currentTime = std::chrono::system_clock::to_time_t(sysTime); + std::strftime(realTime, sizeof(realTime), "%H_%M_%S", std::localtime(¤tTime)); + char pkgName[MAX_LOG_NAME_SIZE]; + UPDATER_CHECK_ONLY_RETURN(snprintf_s(pkgName, MAX_LOG_NAME_SIZE, MAX_LOG_NAME_SIZE - 1, + "/data/updater/log/%s_%s.zip", realName.c_str(), realTime) != -1, return); + int32_t ret = pkgManager->CreatePackage(pkgName, GetCertName(), &pkgInfo, files); + UPDATER_CHECK_ONLY_RETURN(ret != 0, return); + UPDATER_CHECK_ONLY_RETURN(DeleteFile(name) == 0, return); +} + +bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog) +{ + UPDATER_WARING_CHECK(MountForPath(UPDATER_LOG_DIR) == 0, "MountForPath /data/log failed!", return false); + if (access(UPDATER_LOG_DIR.c_str(), 0) != 0) { + UPDATER_ERROR_CHECK(!MkdirRecursive(UPDATER_LOG_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH), + "MkdirRecursive error!", return false); + UPDATER_ERROR_CHECK(chown(UPDATER_PATH.c_str(), USER_ROOT_AUTHORITY, GROUP_SYS_AUTHORITY) == 0, + "Chown failed!", return false); + UPDATER_ERROR_CHECK(chmod(UPDATER_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0, + "Chmod failed!", return false); + } + + FILE* dFp = fopen(dLog.c_str(), "ab+"); + UPDATER_ERROR_CHECK(dFp != nullptr, "open log failed", return false); + + FILE* sFp = fopen(sLog.c_str(), "r"); + UPDATER_ERROR_CHECK(sFp != nullptr, "open log failed", fclose(dFp); return false); + + char buf[MAX_LOG_BUF_SIZE]; + size_t bytes; + while ((bytes = fread(buf, 1, sizeof(buf), sFp)) != 0) { + fwrite(buf, 1, bytes, dFp); + } + fseek(dFp, 0, SEEK_END); + UPDATER_INFO_CHECK(ftell(dFp) < MAX_LOG_SIZE, "log size greater than 5M!", CompressLogs(dLog)); + sync(); + fclose(sFp); + fclose(dFp); + return true; +} } // utils } // namespace updater