Snap for 4842501 from ad22bcbf8de1a9bafc384c1bac46f3052605a066 to qt-release

Change-Id: Ifd16f1bc84ad58e561139c838d1fa175a2371d85
diff --git a/etc/init.rc b/etc/init.rc
index 0fc6c4c..96c37b1 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -22,6 +22,7 @@
     mkdir /data
     mkdir /cache
     mkdir /sideload
+    mkdir /mnt/system
     mount tmpfs tmpfs /tmp
 
     chown root shell /tmp
@@ -87,7 +88,7 @@
 service recovery /sbin/recovery
     seclabel u:r:recovery:s0
 
-service adbd /sbin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery
+service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery
     disabled
     socket adbd stream 660 system system
     seclabel u:r:adbd:s0
diff --git a/fsck_unshare_blocks.cpp b/fsck_unshare_blocks.cpp
index a100368..2e6b5b8 100644
--- a/fsck_unshare_blocks.cpp
+++ b/fsck_unshare_blocks.cpp
@@ -115,14 +115,6 @@
   return true;
 }
 
-static const char* get_system_root() {
-  if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
-    return "/system_root";
-  } else {
-    return "/system";
-  }
-}
-
 bool do_fsck_unshare_blocks() {
   // List of partitions we will try to e2fsck -E unshare_blocks.
   std::vector<std::string> partitions = { "/odm", "/oem", "/product", "/vendor" };
@@ -130,10 +122,10 @@
   // Temporarily mount system so we can copy e2fsck_static.
   bool mounted = false;
   if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
-    mounted = ensure_path_mounted_at("/", "/system_root") != -1;
+    mounted = ensure_path_mounted_at("/", "/mnt/system") != -1;
     partitions.push_back("/");
   } else {
-    mounted = ensure_path_mounted("/system") != -1;
+    mounted = ensure_path_mounted_at("/system", "/mnt/system") != -1;
     partitions.push_back("/system");
   }
   if (!mounted) {
@@ -144,7 +136,7 @@
     LOG(ERROR) << "Could not copy e2fsck to /tmp.";
     return false;
   }
-  if (umount(get_system_root()) < 0) {
+  if (umount("/mnt/system") < 0) {
     PLOG(ERROR) << "umount failed";
     return false;
   }
diff --git a/minui/graphics.cpp b/minui/graphics.cpp
index c1aab41..cc02e9e 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 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 @@
   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 @@
   }
 }
 
-// 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 @@
   }
 }
 
-// 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_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_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 @@
     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 @@
   }
 }
 
-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 @@
 
 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 e96b7ae..ef4abe2 100644
--- a/minui/include/minui/minui.h
+++ b/minui/include/minui/minui.h
@@ -48,7 +48,13 @@
   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 @@
 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 @@
 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/recovery.cpp b/recovery.cpp
index 8f39679..f6d4212 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -820,15 +820,13 @@
         break;
       }
       case Device::MOUNT_SYSTEM:
-        // For a system image built with the root directory (i.e. system_root_image == "true"), we
-        // mount it to /system_root, and symlink /system to /system_root/system to make adb shell
-        // work (the symlink is created through the build system). (Bug: 22855115)
+        // the system partition is mounted at /mnt/system
         if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
-          if (ensure_path_mounted_at("/", "/system_root") != -1) {
+          if (ensure_path_mounted_at("/", "/mnt/system") != -1) {
             ui->Print("Mounted /system.\n");
           }
         } else {
-          if (ensure_path_mounted("/system") != -1) {
+          if (ensure_path_mounted_at("/system", "/mnt/system") != -1) {
             ui->Print("Mounted /system.\n");
           }
         }
diff --git a/screen_ui.cpp b/screen_ui.cpp
index b4ef054..f9c4a06 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -176,6 +176,8 @@
   if (progress_thread_.joinable()) {
     progress_thread_.join();
   }
+  // No-op if gr_init() (via Init()) was not called or had failed.
+  gr_exit();
 }
 
 GRSurface* ScreenRecoveryUI::GetCurrentFrame() const {
@@ -700,10 +702,10 @@
 }
 
 bool ScreenRecoveryUI::InitTextParams() {
-  if (gr_init() < 0) {
+  // gr_init() would return successfully on font initialization failure.
+  if (gr_sys_font() == nullptr) {
     return false;
   }
-
   gr_font_size(gr_sys_font(), &char_width_, &char_height_);
   text_rows_ = (ScreenHeight() - kMarginHeight * 2) / char_height_;
   text_cols_ = (ScreenWidth() - kMarginWidth * 2) / char_width_;
@@ -713,6 +715,10 @@
 bool ScreenRecoveryUI::Init(const std::string& locale) {
   RecoveryUI::Init(locale);
 
+  if (gr_init() == -1) {
+    return false;
+  }
+
   if (!InitTextParams()) {
     return false;
   }
diff --git a/tests/unit/screen_ui_test.cpp b/tests/unit/screen_ui_test.cpp
index a3dd2ad..2f4b7b0 100644
--- a/tests/unit/screen_ui_test.cpp
+++ b/tests/unit/screen_ui_test.cpp
@@ -30,6 +30,7 @@
 
 #include "common/test_constants.h"
 #include "device.h"
+#include "minui/minui.h"
 #include "otautil/paths.h"
 #include "private/resources.h"
 #include "screen_ui.h"
@@ -274,18 +275,34 @@
   const std::string kTestRtlLocaleWithSuffix = "ar-EG";
 
   void SetUp() override {
-    ui_ = std::make_unique<TestableScreenRecoveryUI>();
+    has_graphics_ = gr_init() == 0;
+    gr_exit();
+
+    if (has_graphics_) {
+      ui_ = std::make_unique<TestableScreenRecoveryUI>();
+    }
 
     testdata_dir_ = from_testdata_base("");
     Paths::Get().set_resource_dir(testdata_dir_);
     res_set_resource_dir(testdata_dir_);
   }
 
+  bool has_graphics_;
   std::unique_ptr<TestableScreenRecoveryUI> ui_;
   std::string testdata_dir_;
 };
 
+#define RETURN_IF_NO_GRAPHICS                                                 \
+  do {                                                                        \
+    if (!has_graphics_) {                                                     \
+      GTEST_LOG_(INFO) << "Test skipped due to no available graphics device"; \
+      return;                                                                 \
+    }                                                                         \
+  } while (false)
+
 TEST_F(ScreenRecoveryUITest, Init) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestLocale));
   ASSERT_EQ(kTestLocale, ui_->GetLocale());
   ASSERT_FALSE(ui_->GetRtlLocale());
@@ -299,6 +316,8 @@
 }
 
 TEST_F(ScreenRecoveryUITest, ShowText) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestLocale));
   ASSERT_FALSE(ui_->IsTextVisible());
   ui_->ShowText(true);
@@ -311,16 +330,22 @@
 }
 
 TEST_F(ScreenRecoveryUITest, RtlLocale) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestRtlLocale));
   ASSERT_TRUE(ui_->GetRtlLocale());
 }
 
 TEST_F(ScreenRecoveryUITest, RtlLocaleWithSuffix) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestRtlLocaleWithSuffix));
   ASSERT_TRUE(ui_->GetRtlLocale());
 }
 
 TEST_F(ScreenRecoveryUITest, ShowMenu) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestLocale));
   ui_->SetKeyBuffer({
       KeyCode::UP,
@@ -347,6 +372,8 @@
 }
 
 TEST_F(ScreenRecoveryUITest, ShowMenu_NotMenuOnly) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestLocale));
   ui_->SetKeyBuffer({
       KeyCode::MAGIC,
@@ -358,6 +385,8 @@
 }
 
 TEST_F(ScreenRecoveryUITest, ShowMenu_TimedOut) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestLocale));
   ui_->SetKeyBuffer({
       KeyCode::TIMEOUT,
@@ -366,6 +395,8 @@
 }
 
 TEST_F(ScreenRecoveryUITest, ShowMenu_TimedOut_TextWasEverVisible) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestLocale));
   ui_->ShowText(true);
   ui_->ShowText(false);
@@ -382,6 +413,8 @@
 }
 
 TEST_F(ScreenRecoveryUITest, LoadAnimation) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestLocale));
   // Make a few copies of loop00000.png from testdata.
   std::string image_data;
@@ -410,6 +443,8 @@
 }
 
 TEST_F(ScreenRecoveryUITest, LoadAnimation_MissingAnimation) {
+  RETURN_IF_NO_GRAPHICS;
+
   ASSERT_TRUE(ui_->Init(kTestLocale));
   TemporaryDir resource_dir;
   Paths::Get().set_resource_dir(resource_dir.path);
@@ -417,3 +452,5 @@
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   ASSERT_EXIT(ui_->RunLoadAnimation(), ::testing::KilledBySignal(SIGABRT), "");
 }
+
+#undef RETURN_IF_NO_GRAPHICS
diff --git a/updater_sample/src/com/example/android/systemupdatersample/util/UpdateEngineErrorCodes.java b/updater_sample/src/com/example/android/systemupdatersample/util/UpdateEngineErrorCodes.java
index 7d55ff8..13df88b 100644
--- a/updater_sample/src/com/example/android/systemupdatersample/util/UpdateEngineErrorCodes.java
+++ b/updater_sample/src/com/example/android/systemupdatersample/util/UpdateEngineErrorCodes.java
@@ -54,6 +54,7 @@
         CODE_TO_NAME_MAP.put(12, "DOWNLOAD_PAYLOAD_VERIFICATION_ERROR");
         CODE_TO_NAME_MAP.put(15, "NEW_ROOTFS_VERIFICATION_ERROR");
         CODE_TO_NAME_MAP.put(20, "DOWNLOAD_STATE_INITIALIZATION_ERROR");
+        CODE_TO_NAME_MAP.put(26, "DOWNLOAD_METADATA_SIGNATURE_MISMATCH");
         CODE_TO_NAME_MAP.put(48, "USER_CANCELLED");
         CODE_TO_NAME_MAP.put(52, "UPDATED_BUT_NOT_ACTIVE");
     }