bool CoreRP::addExfat() { const std::string mount("sbin/mount.exfat"); const std::string fsck("sbin/fsck.exfat"); const std::string mountSig("sbin/mount.exfat.sig"); const std::string fsckSig("sbin/fsck.exfat.sig"); std::string mountPath(m_impl->pc->dataDirectory()); mountPath += "/binaries/android/"; mountPath += mb_device_architecture(m_impl->info->device()); mountPath += "/mount.exfat"; std::string sigPath(mountPath); sigPath += ".sig"; m_impl->cpio->remove(mount); m_impl->cpio->remove(fsck); m_impl->cpio->remove(mountSig); m_impl->cpio->remove(fsckSig); if (!m_impl->cpio->addFile(mountPath, mount, 0750) || !m_impl->cpio->addFile(sigPath, mountSig, 0640) || !m_impl->cpio->addSymlink("mount.exfat", fsck) || !m_impl->cpio->addSymlink("mount.exfat.sig", fsckSig)) { m_impl->error = m_impl->cpio->error(); return false; } return true; }
bool CoreRP::addMbtool() { const std::string mbtool("mbtool"); const std::string sig("mbtool.sig"); std::string mbtoolPath(m_impl->pc->dataDirectory()); mbtoolPath += "/binaries/android/"; mbtoolPath += mb_device_architecture(m_impl->info->device()); mbtoolPath += "/mbtool"; std::string sigPath(mbtoolPath); sigPath += ".sig"; m_impl->cpio->remove(mbtool); m_impl->cpio->remove(sig); if (!m_impl->cpio->addFile(mbtoolPath, mbtool, 0750) || !m_impl->cpio->addFile(sigPath, sig, 0640)) { m_impl->error = m_impl->cpio->error(); return false; } return true; }
bool CoreRP::addFsckWrapper() { const std::string wrapper("sbin/fsck-wrapper"); const std::string sig("sbin/fsck-wrapper.sig"); std::string wrapperPath(m_impl->pc->dataDirectory()); wrapperPath += "/binaries/android/"; wrapperPath += mb_device_architecture(m_impl->info->device()); wrapperPath += "/fsck-wrapper"; std::string sigPath(wrapperPath); sigPath += ".sig"; m_impl->cpio->remove(wrapper); m_impl->cpio->remove(sig); if (!m_impl->cpio->addFile(wrapperPath, wrapper, 0750) || !m_impl->cpio->addFile(sigPath, sig, 0640)) { m_impl->error = m_impl->cpio->error(); return false; } return true; }
bool OdinPatcher::Impl::patchTar() { #ifdef __ANDROID__ static const char *prefix = "/proc/self/fd/"; fd = -1; if (StringUtils::starts_with(info->inputPath(), prefix)) { std::string fdStr = info->inputPath().substr(strlen(prefix)); if (!convertToInt(fdStr.c_str(), &fd)) { LOGE("Invalid fd: %s", fdStr.c_str()); error = ErrorCode::FileOpenError; return false; } LOGD("Input path '%s' is a file descriptor: %d", info->inputPath().c_str(), fd); } #endif // Get file size for progress information #ifdef __ANDROID__ if (fd > 0) { off64_t offset = lseek64(fd, 0, SEEK_END); if (offset < 0 || lseek64(fd, 0, SEEK_SET) < 0) { LOGE("%s: Failed to seek fd: %s", info->inputPath().c_str(), strerror(errno)); error = ErrorCode::FileSeekError; return false; } maxBytes = offset; } else { #endif io::File file; if (!file.open(info->inputPath(), io::File::OpenRead)) { LOGE("%s: Failed to open: %s", info->inputPath().c_str(), file.errorString().c_str()); error = ErrorCode::FileOpenError; return false; } if (!file.seek(0, io::File::SeekEnd)) { LOGE("%s: Failed to seek: %s", info->inputPath().c_str(), file.errorString().c_str()); error = ErrorCode::FileReadError; return false; } if (!file.tell(&maxBytes)) { LOGE("%s: Failed to get position: %s", info->inputPath().c_str(), file.errorString().c_str()); error = ErrorCode::FileReadError; return false; } file.close(); #ifdef __ANDROID__ } #endif updateProgress(bytes, maxBytes); if (!openInputArchive()) { return false; } if (!openOutputArchive()) { return false; } if (cancelled) return false; if (!processContents()) { return false; } std::vector<CopySpec> toCopy{ { pc->dataDirectory() + "/binaries/android/" + mb_device_architecture(info->device()) + "/odinupdater", "META-INF/com/google/android/update-binary.orig" }, { pc->dataDirectory() + "/binaries/android/" + mb_device_architecture(info->device()) + "/odinupdater.sig", "META-INF/com/google/android/update-binary.orig.sig" }, { pc->dataDirectory() + "/binaries/android/" + mb_device_architecture(info->device()) + "/fuse-sparse", "fuse-sparse" }, { pc->dataDirectory() + "/binaries/android/" + mb_device_architecture(info->device()) + "/fuse-sparse.sig", "fuse-sparse.sig" }, { pc->dataDirectory() + "/binaries/android/" + mb_device_architecture(info->device()) + "/mbtool_recovery", "META-INF/com/google/android/update-binary" }, { pc->dataDirectory() + "/binaries/android/" + mb_device_architecture(info->device()) + "/mbtool_recovery.sig", "META-INF/com/google/android/update-binary.sig" }, { pc->dataDirectory() + "/scripts/bb-wrapper.sh", "multiboot/bb-wrapper.sh" }, { pc->dataDirectory() + "/scripts/bb-wrapper.sh.sig", "multiboot/bb-wrapper.sh.sig" } }; zipFile zf = MinizipUtils::ctxGetZipFile(zOutput); ErrorCode result; for (const CopySpec &spec : toCopy) { if (cancelled) return false; updateDetails(spec.target); result = MinizipUtils::addFile(zf, spec.target, spec.source); if (result != ErrorCode::NoError) { error = result; return false; } } if (cancelled) return false; updateDetails("multiboot/info.prop"); const std::string infoProp = MultiBootPatcher::createInfoProp(pc, info->romId()); result = MinizipUtils::addFile( zf, "multiboot/info.prop", std::vector<unsigned char>(infoProp.begin(), infoProp.end())); if (result != ErrorCode::NoError) { error = result; return false; } if (cancelled) return false; updateDetails("block_devs.prop"); std::string blockDevsProp; blockDevsProp += "system="; blockDevsProp += mb_device_system_block_devs(info->device())[0]; blockDevsProp += "\n"; blockDevsProp += "boot="; blockDevsProp += mb_device_boot_block_devs(info->device())[0]; blockDevsProp += "\n"; result = MinizipUtils::addFile( zf, "block_devs.prop", std::vector<unsigned char>( blockDevsProp.begin(), blockDevsProp.end())); if (result != ErrorCode::NoError) { error = result; return false; } if (cancelled) return false; updateDetails("multiboot/device.json"); char *json = mb_device_to_json(info->device()); if (!json) { error = ErrorCode::MemoryAllocationError; return false; } result = MinizipUtils::addFile( zf, "multiboot/device.json", std::vector<unsigned char>(json, json + strlen(json))); free(json); if (result != ErrorCode::NoError) { error = result; return false; } if (cancelled) return false; return true; }
TEST(JsonTest, LoadCompleteDefinition) { ScopedDevice sd(sample_complete); ASSERT_NE(sd.device, nullptr); ASSERT_STREQ(mb_device_id(sd.device), "test"); const char *codenames[] = { "test1", "test2", "test3", "test4", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_codenames(sd.device), codenames)); ASSERT_STREQ(mb_device_name(sd.device), "Test Device"); ASSERT_STREQ(mb_device_architecture(sd.device), "arm64-v8a"); uint64_t device_flags = FLAG_HAS_COMBINED_BOOT_AND_RECOVERY; ASSERT_EQ(mb_device_flags(sd.device), device_flags); const char *base_dirs[] = { "/dev/block/bootdevice/by-name", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_block_dev_base_dirs(sd.device), base_dirs)); const char *system_devs[] = { "/dev/block/bootdevice/by-name/system", "/dev/block/sda1", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_system_block_devs(sd.device), system_devs)); const char *cache_devs[] = { "/dev/block/bootdevice/by-name/cache", "/dev/block/sda2", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_cache_block_devs(sd.device), cache_devs)); const char *data_devs[] = { "/dev/block/bootdevice/by-name/userdata", "/dev/block/sda3", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_data_block_devs(sd.device), data_devs)); const char *boot_devs[] = { "/dev/block/bootdevice/by-name/boot", "/dev/block/sda4", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_boot_block_devs(sd.device), boot_devs)); const char *recovery_devs[] = { "/dev/block/bootdevice/by-name/recovery", "/dev/block/sda5", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_recovery_block_devs(sd.device), recovery_devs)); const char *extra_devs[] = { "/dev/block/bootdevice/by-name/modem", "/dev/block/sda6", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_extra_block_devs(sd.device), extra_devs)); /* Boot UI */ ASSERT_EQ(mb_device_tw_supported(sd.device), true); uint64_t flags = FLAG_TW_TOUCHSCREEN_SWAP_XY | FLAG_TW_TOUCHSCREEN_FLIP_X | FLAG_TW_TOUCHSCREEN_FLIP_Y | FLAG_TW_GRAPHICS_FORCE_USE_LINELENGTH | FLAG_TW_SCREEN_BLANK_ON_BOOT | FLAG_TW_BOARD_HAS_FLIPPED_SCREEN | FLAG_TW_IGNORE_MAJOR_AXIS_0 | FLAG_TW_IGNORE_MT_POSITION_0 | FLAG_TW_IGNORE_ABS_MT_TRACKING_ID | FLAG_TW_NEW_ION_HEAP | FLAG_TW_NO_SCREEN_BLANK | FLAG_TW_NO_SCREEN_TIMEOUT | FLAG_TW_ROUND_SCREEN | FLAG_TW_NO_CPU_TEMP | FLAG_TW_QCOM_RTC_FIX | FLAG_TW_HAS_DOWNLOAD_MODE | FLAG_TW_PREFER_LCD_BACKLIGHT; ASSERT_EQ(mb_device_tw_flags(sd.device), flags); ASSERT_EQ(mb_device_tw_pixel_format(sd.device), TW_PIXEL_FORMAT_RGBA_8888); ASSERT_EQ(mb_device_tw_force_pixel_format(sd.device), TW_FORCE_PIXEL_FORMAT_RGB_565); ASSERT_EQ(mb_device_tw_overscan_percent(sd.device), 10); ASSERT_EQ(mb_device_tw_default_x_offset(sd.device), 20); ASSERT_EQ(mb_device_tw_default_y_offset(sd.device), 30); ASSERT_STREQ(mb_device_tw_brightness_path(sd.device), "/sys/class/backlight"); ASSERT_STREQ(mb_device_tw_secondary_brightness_path(sd.device), "/sys/class/lcd-backlight"); ASSERT_EQ(mb_device_tw_max_brightness(sd.device), 255); ASSERT_EQ(mb_device_tw_default_brightness(sd.device), 100); ASSERT_STREQ(mb_device_tw_battery_path(sd.device), "/sys/class/battery"); ASSERT_STREQ(mb_device_tw_cpu_temp_path(sd.device), "/sys/class/cputemp"); ASSERT_STREQ(mb_device_tw_input_blacklist(sd.device), "foo"); ASSERT_STREQ(mb_device_tw_input_whitelist(sd.device), "bar"); const char *graphics_backends[] = { "overlay_msm_old", "fbdev", nullptr }; ASSERT_TRUE(string_array_eq(mb_device_tw_graphics_backends(sd.device), graphics_backends)); ASSERT_STREQ(mb_device_tw_theme(sd.device), "portrait_hdpi"); }