diff options
-rw-r--r-- | minui/graphics.cpp | 32 | ||||
-rw-r--r-- | minui/include/minui/minui.h | 19 | ||||
-rw-r--r-- | tests/component/updater_test.cpp | 23 | ||||
-rw-r--r-- | updater/blockimg.cpp | 34 | ||||
-rw-r--r-- | updater_sample/Android.mk | 5 | ||||
-rw-r--r-- | updater_sample/README.md | 8 | ||||
-rw-r--r-- | updater_sample/proguard.flags | 23 | ||||
-rw-r--r-- | updater_sample/tests/Android.mk | 6 | ||||
-rw-r--r-- | updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java | 2 | ||||
-rwxr-xr-x | updater_sample/tools/gen_update_config.py | 6 |
10 files changed, 102 insertions, 56 deletions
diff --git a/minui/graphics.cpp b/minui/graphics.cpp index c1aab412d..cc02e9e82 100644 --- a/minui/graphics.cpp +++ b/minui/graphics.cpp @@ -28,7 +28,7 @@ #include "graphics_fbdev.h" #include "minui/minui.h" -static GRFont* gr_font = NULL; +static GRFont* gr_font = nullptr; static MinuiBackend* gr_backend = nullptr; static int overscan_percent = OVERSCAN_PERCENT; @@ -38,7 +38,8 @@ static int overscan_offset_y = 0; static uint32_t gr_current = ~0; static constexpr uint32_t alpha_mask = 0xff000000; -static GRSurface* gr_draw = NULL; +// gr_draw is owned by backends. +static const GRSurface* gr_draw = nullptr; static GRRotation rotation = ROTATION_NONE; static bool outside(int x, int y) { @@ -86,7 +87,7 @@ static inline uint32_t pixel_blend(uint8_t alpha, uint32_t pix) { return (out_r & 0xff) | (out_g & 0xff00) | (out_b & 0xff0000) | (gr_current & 0xff000000); } -// increments pixel pointer right, with current rotation. +// Increments pixel pointer right, with current rotation. static void incr_x(uint32_t** p, int row_pixels) { if (rotation % 2) { *p = *p + (rotation == 1 ? 1 : -1) * row_pixels; @@ -95,7 +96,7 @@ static void incr_x(uint32_t** p, int row_pixels) { } } -// increments pixel pointer down, with current rotation. +// Increments pixel pointer down, with current rotation. static void incr_y(uint32_t** p, int row_pixels) { if (rotation % 2) { *p = *p + (rotation == 1 ? -1 : 1); @@ -104,8 +105,8 @@ static void incr_y(uint32_t** p, int row_pixels) { } } -// returns pixel pointer at given coordinates with rotation adjustment. -static uint32_t* pixel_at(GRSurface* surf, int x, int y, int row_pixels) { +// Returns pixel pointer at given coordinates with rotation adjustment. +static uint32_t* pixel_at(const GRSurface* surf, int x, int y, int row_pixels) { switch (rotation) { case ROTATION_NONE: return reinterpret_cast<uint32_t*>(surf->data) + y * row_pixels + x; @@ -172,7 +173,7 @@ void gr_text(const GRFont* font, int x, int y, const char* s, bool bold) { } void gr_texticon(int x, int y, GRSurface* icon) { - if (icon == NULL) return; + if (icon == nullptr) return; if (icon->pixel_bytes != 1) { printf("gr_texticon: source has wrong format\n"); @@ -243,7 +244,7 @@ void gr_fill(int x1, int y1, int x2, int y2) { } void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) { - if (source == NULL) return; + if (source == nullptr) return; if (gr_draw->pixel_bytes != source->pixel_bytes) { printf("gr_blit: source has wrong format\n"); @@ -275,8 +276,7 @@ void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) { unsigned char* src_p = source->data + sy * source->row_bytes + sx * source->pixel_bytes; unsigned char* dst_p = gr_draw->data + dy * gr_draw->row_bytes + dx * gr_draw->pixel_bytes; - int i; - for (i = 0; i < h; ++i) { + for (int i = 0; i < h; ++i) { memcpy(dst_p, src_p, w * source->pixel_bytes); src_p += source->row_bytes; dst_p += gr_draw->row_bytes; @@ -284,15 +284,15 @@ void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) { } } -unsigned int gr_get_width(GRSurface* surface) { - if (surface == NULL) { +unsigned int gr_get_width(const GRSurface* surface) { + if (surface == nullptr) { return 0; } return surface->width; } -unsigned int gr_get_height(GRSurface* surface) { - if (surface == NULL) { +unsigned int gr_get_height(const GRSurface* surface) { + if (surface == nullptr) { return 0; } return surface->height; @@ -372,6 +372,10 @@ int gr_init() { void gr_exit() { delete gr_backend; + gr_backend = nullptr; + + delete gr_font; + gr_font = nullptr; } int gr_fb_width() { diff --git a/minui/include/minui/minui.h b/minui/include/minui/minui.h index e96b7ae08..ef4abe252 100644 --- a/minui/include/minui/minui.h +++ b/minui/include/minui/minui.h @@ -48,7 +48,13 @@ enum GRRotation { ROTATION_LEFT = 3, }; +// Initializes the graphics backend and loads font file. Returns 0 on success, or -1 on error. Note +// that the font initialization failure would be non-fatal, as caller may not need to draw any text +// at all. Caller can check the font initialization result via gr_sys_font() as needed. int gr_init(); + +// Frees the allocated resources. The function is idempotent, and safe to be called if gr_init() +// didn't finish successfully. void gr_exit(); int gr_fb_width(); @@ -57,7 +63,8 @@ int gr_fb_height(); void gr_flip(); void gr_fb_blank(bool blank); -void gr_clear(); // clear entire surface to current color +// Clears entire surface to current color. +void gr_clear(); void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a); void gr_fill(int x1, int y1, int x2, int y2); @@ -66,16 +73,16 @@ void gr_texticon(int x, int y, GRSurface* icon); const GRFont* gr_sys_font(); int gr_init_font(const char* name, GRFont** dest); void gr_text(const GRFont* font, int x, int y, const char* s, bool bold); -// Return -1 if font is nullptr. +// Returns -1 if font is nullptr. int gr_measure(const GRFont* font, const char* s); -// Return -1 if font is nullptr. +// Returns -1 if font is nullptr. int gr_font_size(const GRFont* font, int* x, int* y); void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy); -unsigned int gr_get_width(GRSurface* surface); -unsigned int gr_get_height(GRSurface* surface); +unsigned int gr_get_width(const GRSurface* surface); +unsigned int gr_get_height(const GRSurface* surface); -// Set rotation, flips gr_fb_width/height if 90 degree rotation difference +// Sets rotation, flips gr_fb_width/height if 90 degree rotation difference void gr_rotate(GRRotation rotation); // diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp index 6f3a3a2a7..fe4f45e15 100644 --- a/tests/component/updater_test.cpp +++ b/tests/component/updater_test.cpp @@ -100,7 +100,8 @@ static void BuildUpdatePackage(const PackageEntries& entries, int fd) { } static void RunBlockImageUpdate(bool is_verify, const PackageEntries& entries, - const std::string& image_file, const std::string& result) { + const std::string& image_file, const std::string& result, + CauseCode cause_code = kNoCause) { CHECK(entries.find("transfer_list") != entries.end()); // Build the update package. @@ -124,7 +125,7 @@ static void RunBlockImageUpdate(bool is_verify, const PackageEntries& entries, std::string script = is_verify ? "block_image_verify" : "block_image_update"; script += R"((")" + image_file + R"(", package_extract_file("transfer_list"), ")" + new_data + R"(", "patch_data"))"; - expect(result.c_str(), script.c_str(), kNoCause, &updater_info); + expect(result.c_str(), script.c_str(), cause_code, &updater_info); ASSERT_EQ(0, fclose(updater_info.cmd_pipe)); CloseArchive(handle); @@ -504,6 +505,24 @@ TEST_F(UpdaterTest, show_progress) { ASSERT_EQ(0, fclose(updater_info.cmd_pipe)); } +TEST_F(UpdaterTest, block_image_update_parsing_error) { + std::vector<std::string> transfer_list{ + // clang-format off + "4", + "2", + "0", + // clang-format on + }; + + PackageEntries entries{ + { "new_data", "" }, + { "patch_data", "" }, + { "transfer_list", android::base::Join(transfer_list, '\n') }, + }; + + RunBlockImageUpdate(false, entries, image_file_, "", kArgsParsingFailure); +} + TEST_F(UpdaterTest, block_image_update_patch_data) { std::string src_content = std::string(4096, 'a') + std::string(4096, 'c'); std::string tgt_content = std::string(4096, 'b') + std::string(4096, 'd'); diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp index f2811bccf..ff1d20a78 100644 --- a/updater/blockimg.cpp +++ b/updater/blockimg.cpp @@ -1091,9 +1091,8 @@ static int LoadSourceBlocks(CommandParameters& params, const RangeSet& tgt, size * If the return value is 0, source blocks have expected content and the command can be performed. */ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet* tgt, size_t* src_blocks, - bool onehash, bool* overlap) { + bool onehash) { CHECK(src_blocks != nullptr); - CHECK(overlap != nullptr); if (params.cpos >= params.tokens.size()) { LOG(ERROR) << "missing source hash"; @@ -1135,15 +1134,16 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet* tgt, size_t* } // Load source blocks. - if (LoadSourceBlocks(params, *tgt, src_blocks, overlap) == -1) { + bool overlap = false; + if (LoadSourceBlocks(params, *tgt, src_blocks, &overlap) == -1) { return -1; } if (VerifyBlocks(srchash, params.buffer, *src_blocks, true) == 0) { - // If source and target blocks overlap, stash the source blocks so we can - // resume from possible write errors. In verify mode, we can skip stashing - // because the source blocks won't be overwritten. - if (*overlap && params.canwrite) { + // If source and target blocks overlap, stash the source blocks so we can resume from possible + // write errors. In verify mode, we can skip stashing because the source blocks won't be + // overwritten. + if (overlap && params.canwrite) { LOG(INFO) << "stashing " << *src_blocks << " overlapping blocks to " << srchash; bool stash_exists = false; @@ -1164,7 +1164,7 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet* tgt, size_t* return 0; } - if (*overlap && LoadStash(params, srchash, true, ¶ms.buffer, true) == 0) { + if (overlap && LoadStash(params, srchash, true, ¶ms.buffer, true) == 0) { // Overlapping source blocks were previously stashed, command can proceed. We are recovering // from an interrupted command, so we don't know if the stash can safely be deleted after this // command. @@ -1182,9 +1182,8 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet* tgt, size_t* static int PerformCommandMove(CommandParameters& params) { size_t blocks = 0; - bool overlap = false; RangeSet tgt; - int status = LoadSrcTgtVersion3(params, &tgt, &blocks, true, &overlap); + int status = LoadSrcTgtVersion3(params, &tgt, &blocks, true); if (status == -1) { LOG(ERROR) << "failed to read blocks for move"; @@ -1382,8 +1381,7 @@ static int PerformCommandDiff(CommandParameters& params) { RangeSet tgt; size_t blocks = 0; - bool overlap = false; - int status = LoadSrcTgtVersion3(params, &tgt, &blocks, false, &overlap); + int status = LoadSrcTgtVersion3(params, &tgt, &blocks, false); if (status == -1) { LOG(ERROR) << "failed to read blocks for diff"; @@ -1628,9 +1626,10 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, } } + static constexpr size_t kTransferListHeaderLines = 4; std::vector<std::string> lines = android::base::Split(transfer_list_value->data, "\n"); - if (lines.size() < 2) { - ErrorAbort(state, kArgsParsingFailure, "too few lines in the transfer list [%zd]", + if (lines.size() < kTransferListHeaderLines) { + ErrorAbort(state, kArgsParsingFailure, "too few lines in the transfer list [%zu]", lines.size()); return StringValue(""); } @@ -1654,12 +1653,6 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, return StringValue("t"); } - if (lines.size() < 4) { - ErrorAbort(state, kArgsParsingFailure, "too few lines in the transfer list [%zu]", - lines.size()); - return StringValue(""); - } - // Third line is how many stash entries are needed simultaneously. LOG(INFO) << "maximum stash entries " << lines[2]; @@ -1698,7 +1691,6 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int rc = -1; - static constexpr size_t kTransferListHeaderLines = 4; // Subsequent lines are all individual transfer commands for (size_t i = kTransferListHeaderLines; i < lines.size(); i++) { const std::string& line = lines[i]; diff --git a/updater_sample/Android.mk b/updater_sample/Android.mk index 7662111b7..a5deee1c8 100644 --- a/updater_sample/Android.mk +++ b/updater_sample/Android.mk @@ -20,9 +20,8 @@ include $(CLEAR_VARS) LOCAL_PACKAGE_NAME := SystemUpdaterSample LOCAL_MODULE_TAGS := samples LOCAL_SDK_VERSION := system_current - -# TODO: enable proguard and use proguard.flags file -LOCAL_PROGUARD_ENABLED := disabled +LOCAL_PRIVILEGED_MODULE := true +LOCAL_PROGUARD_FLAG_FILES := proguard.flags LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/updater_sample/README.md b/updater_sample/README.md index 8ec43d3c6..11b55eb91 100644 --- a/updater_sample/README.md +++ b/updater_sample/README.md @@ -140,6 +140,9 @@ Start an update attempt to download an apply the provided `payload_url` if no other update is running. The extra `key_value_pair_headers` will be included when fetching the payload. +`key_value_pair_headers` argument also accepts properties other than HTTP Headers. +List of allowed properties can be found in `system/update_engine/common/constants.cc`. + ### UpdateEngine#cancel Cancel the ongoing update. The update could be running or suspended, but it @@ -181,9 +184,8 @@ Called whenever an update attempt is completed. - [x] Deferred switch slot demo - [x] Add UpdateManager; extract update logic from MainActivity - [x] Add Sample app update state (separate from update_engine status) -- [-] Add smart update completion detection using onStatusUpdate -- [ ] Add pause/resume demo -- [ ] Add demo for passing NETWORK_ID to `UpdateEngine#applyPayload` +- [x] Add smart update completion detection using onStatusUpdate +- [x] Add pause/resume demo - [ ] Verify system partition checksum for package - [?] Add non-A/B updates demo diff --git a/updater_sample/proguard.flags b/updater_sample/proguard.flags new file mode 100644 index 000000000..5883608d7 --- /dev/null +++ b/updater_sample/proguard.flags @@ -0,0 +1,23 @@ +# 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. + +# Keep, used in tests. +-keep public class com.example.android.systemupdatersample.UpdateManager { + public int getUpdaterState(); +} + +# Keep, used in tests. +-keep public class com.example.android.systemupdatersample.UpdateConfig { + public <init>(java.lang.String, java.lang.String, int); +} diff --git a/updater_sample/tests/Android.mk b/updater_sample/tests/Android.mk index 9aec372e3..415760454 100644 --- a/updater_sample/tests/Android.mk +++ b/updater_sample/tests/Android.mk @@ -22,10 +22,10 @@ LOCAL_SDK_VERSION := system_current LOCAL_MODULE_TAGS := tests LOCAL_JAVA_LIBRARIES := \ android.test.base.stubs \ - android.test.runner.stubs \ - guava + android.test.runner.stubs LOCAL_STATIC_JAVA_LIBRARIES := android-support-test \ - mockito-target-minus-junit4 + mockito-target-minus-junit4 \ + guava LOCAL_INSTRUMENTATION_FOR := SystemUpdaterSample LOCAL_PROGUARD_ENABLED := disabled diff --git a/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java b/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java index 3ba84c116..03086930e 100644 --- a/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java +++ b/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java @@ -65,7 +65,7 @@ public class PayloadSpecsTest { mTargetContext = InstrumentationRegistry.getTargetContext(); mTestContext = InstrumentationRegistry.getContext(); - mTestDir = mTargetContext.getFilesDir(); + mTestDir = mTargetContext.getCacheDir(); mPayloadSpecs = new PayloadSpecs(); } diff --git a/updater_sample/tools/gen_update_config.py b/updater_sample/tools/gen_update_config.py index 7fb64f7fc..b43e49df8 100755 --- a/updater_sample/tools/gen_update_config.py +++ b/updater_sample/tools/gen_update_config.py @@ -131,10 +131,10 @@ def main(): # pylint: disable=missing-docstring choices=ab_install_type_choices, help='A/B update installation type') parser.add_argument('--ab_force_switch_slot', - type=bool, default=False, - help='if set true device will boot to a new slot, otherwise user manually ' - 'switches slot on the screen') + action='store_true', + help='if set device will boot to a new slot, otherwise user ' + 'manually switches slot on the screen') parser.add_argument('package', type=str, help='OTA package zip file') |