Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 002959e4 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I983f361d,I899c8433,Ie6f4b029,Ic3cb9c82,I27107d05

* changes:
  Remove unused variable.
  Remove -i vendor id matching.
  Add quotes to -v INFO/OKAY/FAIL for clarity.
  Remove legacy slot-suffix support.
  Add fastboot_test.cpp and test --os-version/--os-patch-level parsing.
parents fef56f13 bd86420b
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(fastboot_cflags)
LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin)
LOCAL_CXX_STL := $(fastboot_stl)
LOCAL_HEADER_LIBRARIES := bootimg_headers
LOCAL_LDLIBS_darwin := $(fastboot_ldflags_darwin)
LOCAL_LDLIBS_windows := $(fastboot_ldlibs_windows)
LOCAL_REQUIRED_MODULES := mke2fs make_f2fs
@@ -93,8 +94,6 @@ LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES := $(fastboot_shared_libs)
LOCAL_SHARED_LIBRARIES_windows := AdbWinApi
LOCAL_STATIC_LIBRARIES := libfastboot $(fastboot_static_libs)
LOCAL_STATIC_LIBRARIES_darwin := libselinux
LOCAL_STATIC_LIBRARIES_linux := libselinux
include $(BUILD_HOST_EXECUTABLE)

#
@@ -120,8 +119,10 @@ my_dist_files :=
include $(CLEAR_VARS)
LOCAL_MODULE := fastboot_test
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_MODULE_HOST_CROSS_ARCH := x86 # Avoid trying to build for win64.

LOCAL_SRC_FILES := \
    fastboot_test.cpp \
    socket_mock.cpp \
    socket_test.cpp \
    tcp_test.cpp \
@@ -130,7 +131,10 @@ LOCAL_SRC_FILES := \
LOCAL_CFLAGS := $(fastboot_cflags)
LOCAL_CFLAGS_darwin := $(fastboot_cflags_darwin)
LOCAL_CXX_STL := $(fastboot_stl)
LOCAL_HEADER_LIBRARIES := bootimg_headers
LOCAL_LDLIBS_darwin := $(fastboot_ldflags_darwin)
LOCAL_LDLIBS_windows := $(fastboot_ldlibs_windows)
LOCAL_SHARED_LIBRARIES := $(fastboot_shared_libs)
LOCAL_SHARED_LIBRARIES_windows := AdbWinApi
LOCAL_STATIC_LIBRARIES := libfastboot $(fastboot_static_libs)
include $(BUILD_HOST_NATIVE_TEST)
+36 −94
Original line number Diff line number Diff line
@@ -77,7 +77,6 @@ char cur_product[FB_RESPONSE_SZ + 1];

static const char* serial = nullptr;

static unsigned short vendor_id = 0;
static bool g_long_listing = false;
// Don't resparse files in too-big chunks.
// libsparse will support INT_MAX, but this results in large allocations, so
@@ -190,11 +189,6 @@ static void* load_file(const std::string& path, int64_t* sz) {
}

static int match_fastboot_with_serial(usb_ifc_info* info, const char* local_serial) {
    // Require a matching vendor id if the user specified one with -i.
    if (vendor_id != 0 && info->dev_vendor != vendor_id) {
        return -1;
    }

    if (info->ifc_class != 0xff || info->ifc_subclass != 0x42 || info->ifc_protocol != 0x03) {
        return -1;
    }
@@ -381,8 +375,6 @@ static int show_help() {
            " -w                         Wipe userdata.\n"
            " -s SERIAL                  Specify a USB device.\n"
            " -s tcp|udp:HOST[:PORT]     Specify a network device.\n"
            // TODO: remove -i?
            " -i VENDOR_ID               Filter devices by USB vendor id.\n"
            " -S SIZE[K|M|G]             Use sparse files above this limit (0 to disable).\n"
            " --slot SLOT                Use SLOT; 'all' for both slots, 'other' for\n"
            "                            non-current slot (default: current active slot).\n"
@@ -881,46 +873,18 @@ static void flash_buf(const std::string& partition, struct fastboot_buffer *buf)
    }
}

static std::string get_current_slot(Transport* transport)
{
static std::string get_current_slot(Transport* transport) {
    std::string current_slot;
    if (fb_getvar(transport, "current-slot", &current_slot)) {
        if (current_slot == "_a") return "a"; // Legacy support
        if (current_slot == "_b") return "b"; // Legacy support
    if (!fb_getvar(transport, "current-slot", &current_slot)) return "";
    return current_slot;
}
    return "";
}

// Legacy support
static std::vector<std::string> get_suffixes_obsolete(Transport* transport) {
    std::vector<std::string> suffixes;
    std::string suffix_list;
    if (!fb_getvar(transport, "slot-suffixes", &suffix_list)) {
        return suffixes;
    }
    suffixes = android::base::Split(suffix_list, ",");
    // Unfortunately some devices will return an error message in the
    // guise of a valid value. If we only see only one suffix, it's probably
    // not real.
    if (suffixes.size() == 1) {
        suffixes.clear();
    }
    return suffixes;
}

// Legacy support
static bool supports_AB_obsolete(Transport* transport) {
  return !get_suffixes_obsolete(transport).empty();
}

static int get_slot_count(Transport* transport) {
    std::string var;
    int count;
    if (!fb_getvar(transport, "slot-count", &var)) {
        if (supports_AB_obsolete(transport)) return 2; // Legacy support
    int count = 0;
    if (!fb_getvar(transport, "slot-count", &var) || !android::base::ParseInt(var, &count)) {
        return 0;
    }
    if (!android::base::ParseInt(var, &count)) return 0;
    return count;
}

@@ -950,8 +914,6 @@ static std::string get_other_slot(Transport* transport) {

static std::string verify_slot(Transport* transport, const std::string& slot_name, bool allow_all) {
    std::string slot = slot_name;
    if (slot == "_a") slot = "a"; // Legacy support
    if (slot == "_b") slot = "b"; // Legacy support
    if (slot == "all") {
        if (allow_all) {
            return "all";
@@ -1063,20 +1025,14 @@ static void do_update_signature(ZipArchiveHandle zip, const char* filename) {
// Sets slot_override as the active slot. If slot_override is blank,
// set current slot as active instead. This clears slot-unbootable.
static void set_active(Transport* transport, const std::string& slot_override) {
    std::string separator = "";
    if (!supports_AB(transport)) {
        if (supports_AB_obsolete(transport)) {
            separator = "_"; // Legacy support
        } else {
            return;
        }
    }
    if (!supports_AB(transport)) return;

    if (slot_override != "") {
        fb_set_active(separator + slot_override);
        fb_set_active(slot_override);
    } else {
        std::string current_slot = get_current_slot(transport);
        if (current_slot != "") {
            fb_set_active(separator + current_slot);
            fb_set_active(current_slot);
        }
    }
}
@@ -1459,7 +1415,7 @@ int FastBoot::Main(int argc, char* argv[]) {
    serial = getenv("ANDROID_SERIAL");

    int c;
    while ((c = getopt_long(argc, argv, "a::hi:ls:S:vw", longopts, &longindex)) != -1) {
    while ((c = getopt_long(argc, argv, "a::hls:S:vw", longopts, &longindex)) != -1) {
        if (c == 0) {
            std::string name{longopts[longindex].name};
            if (name == "base") {
@@ -1475,24 +1431,9 @@ int FastBoot::Main(int argc, char* argv[]) {
            } else if (name == "kernel-offset") {
                g_boot_img_hdr.kernel_addr = strtoul(optarg, 0, 16);
            } else if (name == "os-patch-level") {
                unsigned year, month, day;
                if (sscanf(optarg, "%u-%u-%u", &year, &month, &day) != 3) {
                    syntax_error("OS patch level should be YYYY-MM-DD: %s", optarg);
                }
                if (year < 2000 || year >= 2128) syntax_error("year out of range: %d", year);
                if (month < 1 || month > 12) syntax_error("month out of range: %d", month);
                g_boot_img_hdr.SetOsPatchLevel(year, month);
                ParseOsPatchLevel(&g_boot_img_hdr, optarg);
            } else if (name == "os-version") {
                unsigned major = 0, minor = 0, patch = 0;
                std::vector<std::string> versions = android::base::Split(optarg, ".");
                if (versions.size() < 1 || versions.size() > 3 ||
                    (versions.size() >= 1 && !android::base::ParseUint(versions[0], &major)) ||
                    (versions.size() >= 2 && !android::base::ParseUint(versions[1], &minor)) ||
                    (versions.size() == 3 && !android::base::ParseUint(versions[2], &patch)) ||
                    (major > 0x7f || minor > 0x7f || patch > 0x7f)) {
                    syntax_error("bad OS version: %s", optarg);
                }
                g_boot_img_hdr.SetOsVersion(major, minor, patch);
                ParseOsVersion(&g_boot_img_hdr, optarg);
            } else if (name == "page-size") {
                g_boot_img_hdr.page_size = strtoul(optarg, nullptr, 0);
                if (g_boot_img_hdr.page_size == 0) die("invalid page size");
@@ -1529,16 +1470,6 @@ int FastBoot::Main(int argc, char* argv[]) {
                    break;
                case 'h':
                    return show_help();
                case 'i':
                    {
                        char *endptr = nullptr;
                        unsigned long val = strtoul(optarg, &endptr, 0);
                        if (!endptr || *endptr != '\0' || (val & ~0xffff)) {
                            die("invalid vendor id '%s'", optarg);
                        }
                        vendor_id = (unsigned short)val;
                        break;
                    }
                case 'l':
                    g_long_listing = true;
                    break;
@@ -1584,9 +1515,6 @@ int FastBoot::Main(int argc, char* argv[]) {

    const double start = now();

    if (!supports_AB(transport) && supports_AB_obsolete(transport)) {
        fprintf(stderr, "Warning: Device A/B support is outdated. Bootloader update required.\n");
    }
    if (slot_override != "") slot_override = verify_slot(transport, slot_override);
    if (next_active != "") next_active = verify_slot(transport, next_active, false);

@@ -1730,15 +1658,6 @@ int FastBoot::Main(int argc, char* argv[]) {
            wants_reboot = true;
        } else if (command == "set_active") {
            std::string slot = verify_slot(transport, next_arg(&args), false);

            // Legacy support: verify_slot() removes leading underscores, we need to put them back
            // in for old bootloaders. Legacy bootloaders do not have the slot-count variable but
            // do have slot-suffixes.
            std::string var;
            if (!fb_getvar(transport, "slot-count", &var) &&
                    fb_getvar(transport, "slot-suffixes", &var)) {
                slot = "_" + slot;
            }
            fb_set_active(slot);
        } else if (command == "stage") {
            std::string filename = next_arg(&args);
@@ -1801,3 +1720,26 @@ int FastBoot::Main(int argc, char* argv[]) {
    fprintf(stderr, "Finished. Total time: %.3fs\n", (now() - start));
    return status;
}

void FastBoot::ParseOsPatchLevel(boot_img_hdr_v1* hdr, const char* arg) {
    unsigned year, month, day;
    if (sscanf(arg, "%u-%u-%u", &year, &month, &day) != 3) {
        syntax_error("OS patch level should be YYYY-MM-DD: %s", arg);
    }
    if (year < 2000 || year >= 2128) syntax_error("year out of range: %d", year);
    if (month < 1 || month > 12) syntax_error("month out of range: %d", month);
    hdr->SetOsPatchLevel(year, month);
}

void FastBoot::ParseOsVersion(boot_img_hdr_v1* hdr, const char* arg) {
    unsigned major = 0, minor = 0, patch = 0;
    std::vector<std::string> versions = android::base::Split(arg, ".");
    if (versions.size() < 1 || versions.size() > 3 ||
        (versions.size() >= 1 && !android::base::ParseUint(versions[0], &major)) ||
        (versions.size() >= 2 && !android::base::ParseUint(versions[1], &minor)) ||
        (versions.size() == 3 && !android::base::ParseUint(versions[2], &patch)) ||
        (major > 0x7f || minor > 0x7f || patch > 0x7f)) {
        syntax_error("bad OS version: %s", arg);
    }
    hdr->SetOsVersion(major, minor, patch);
}
+6 −4
Original line number Diff line number Diff line
@@ -26,14 +26,15 @@
 * SUCH DAMAGE.
 */

#ifndef _FASTBOOT_H_
#define _FASTBOOT_H_
#pragma once

#include <inttypes.h>
#include <stdlib.h>

#include <string>

#include <bootimg.h>

class Transport;
struct sparse_file;

@@ -99,6 +100,7 @@ extern char cur_product[FB_RESPONSE_SZ + 1];
class FastBoot {
  public:
    int Main(int argc, char* argv[]);
};

#endif
    void ParseOsPatchLevel(boot_img_hdr_v1*, const char*);
    void ParseOsVersion(boot_img_hdr_v1*, const char*);
};
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 "fastboot.h"

#include <gtest/gtest.h>

TEST(FastBoot, ParseOsPatchLevel) {
    FastBoot fb;
    boot_img_hdr_v1 hdr;

    hdr = {};
    fb.ParseOsPatchLevel(&hdr, "2018-01-05");
    ASSERT_EQ(2018U, 2000U + ((hdr.os_version >> 4) & 0x7f));
    ASSERT_EQ(1U, ((hdr.os_version >> 0) & 0xf));

    EXPECT_DEATH(fb.ParseOsPatchLevel(&hdr, "2018"), "should be YYYY-MM-DD");
    EXPECT_DEATH(fb.ParseOsPatchLevel(&hdr, "2018-01"), "should be YYYY-MM-DD");
    EXPECT_DEATH(fb.ParseOsPatchLevel(&hdr, "2128-01-05"), "year out of range");
    EXPECT_DEATH(fb.ParseOsPatchLevel(&hdr, "2018-13-05"), "month out of range");
}

TEST(FastBoot, ParseOsVersion) {
    FastBoot fb;
    boot_img_hdr_v1 hdr;

    hdr = {};
    fb.ParseOsVersion(&hdr, "1.2.3");
    ASSERT_EQ(1U, ((hdr.os_version >> 25) & 0x7f));
    ASSERT_EQ(2U, ((hdr.os_version >> 18) & 0x7f));
    ASSERT_EQ(3U, ((hdr.os_version >> 11) & 0x7f));

    fb.ParseOsVersion(&hdr, "1.2");
    ASSERT_EQ(1U, ((hdr.os_version >> 25) & 0x7f));
    ASSERT_EQ(2U, ((hdr.os_version >> 18) & 0x7f));
    ASSERT_EQ(0U, ((hdr.os_version >> 11) & 0x7f));

    fb.ParseOsVersion(&hdr, "1");
    ASSERT_EQ(1U, ((hdr.os_version >> 25) & 0x7f));
    ASSERT_EQ(0U, ((hdr.os_version >> 18) & 0x7f));
    ASSERT_EQ(0U, ((hdr.os_version >> 11) & 0x7f));

    EXPECT_DEATH(fb.ParseOsVersion(&hdr, ""), "bad OS version");
    EXPECT_DEATH(fb.ParseOsVersion(&hdr, "1.2.3.4"), "bad OS version");
    EXPECT_DEATH(fb.ParseOsVersion(&hdr, "128.2.3"), "bad OS version");
    EXPECT_DEATH(fb.ParseOsVersion(&hdr, "1.128.3"), "bad OS version");
    EXPECT_DEATH(fb.ParseOsVersion(&hdr, "1.2.128"), "bad OS version");
}
+1 −4
Original line number Diff line number Diff line
#ifndef _FS_H_
#define _FS_H_
#pragma once

#include <string>
#include <stdint.h>
@@ -9,5 +8,3 @@ struct fs_generator;
const struct fs_generator* fs_get_generator(const std::string& fs_type);
int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize,
    const std::string& initial_dir, unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0);

#endif
Loading