recovery: Allow bypassing signature verification on non-release builds

For non-release (userdebug, eng) builds, when signature verification
fails, ask the user whether they wish to install anyway.

[aleasto]
Rewritten to minimize the diff footprint for maintainability

Change-Id: I950ad455e6f698cabe348f0482eb64287cc88a08
diff --git a/install/install.cpp b/install/install.cpp
index 78455f2..9f9a29d 100644
--- a/install/install.cpp
+++ b/install/install.cpp
@@ -55,12 +55,15 @@
 #include "otautil/sysutil.h"
 #include "otautil/verifier.h"
 #include "private/setup_commands.h"
+#include "recovery_ui/device.h"
 #include "recovery_ui/ui.h"
 #include "recovery_utils/roots.h"
 #include "recovery_utils/thermalutil.h"
 
 using namespace std::chrono_literals;
 
+bool ask_to_continue_unverified(Device* device);
+
 static constexpr int kRecoveryApiVersion = 3;
 // We define RECOVERY_API_VERSION in Android.mk, which will be picked up by build system and packed
 // into target_files.zip. Assert the version defined in code and in Android.mk are consistent.
@@ -599,7 +602,9 @@
   // Verify package.
   if (!verify_package(package, ui)) {
     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
-    return INSTALL_CORRUPT;
+    if (!ui->IsTextVisible() || !ask_to_continue_unverified(ui->GetDevice())) {
+        return INSTALL_CORRUPT;
+    }
   }
 
   // Verify and install the contents of the package.
diff --git a/recovery.cpp b/recovery.cpp
index 918e661..3903890 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -169,6 +169,15 @@
   return (chosen_item == 1);
 }
 
+bool ask_to_continue_unverified(Device* device) {
+  if (get_build_type() == "user") {
+    return false;
+  } else {
+    device->GetUI()->SetProgressType(RecoveryUI::EMPTY);
+    return yes_no(device, "Signature verification failed", "Install anyway?");
+  }
+}
+
 static bool ask_to_wipe_data(Device* device) {
   std::vector<std::string> headers{ "Format user data?", "This includes internal storage.", "THIS CANNOT BE UNDONE!" };
   std::vector<std::string> items{ " Cancel", " Format data" };
diff --git a/recovery.h b/recovery.h
index f050549..08bacbf 100644
--- a/recovery.h
+++ b/recovery.h
@@ -22,3 +22,5 @@
 #include "recovery_ui/device.h"
 
 Device::BuiltinAction start_recovery(Device* device, const std::vector<std::string>& args);
+
+std::string get_build_type();
diff --git a/recovery_main.cpp b/recovery_main.cpp
index d029eb2..31f6d36 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -73,7 +73,7 @@
   return "orange" == android::base::GetProperty("ro.boot.verifiedbootstate", "");
 }
 
-static std::string get_build_type() {
+std::string get_build_type() {
   return android::base::GetProperty("ro.build.type", "");
 }
 
diff --git a/recovery_ui/device.cpp b/recovery_ui/device.cpp
index 0e96b1e..4408c9f 100644
--- a/recovery_ui/device.cpp
+++ b/recovery_ui/device.cpp
@@ -74,6 +74,7 @@
 }
 
 Device::Device(RecoveryUI* ui) : ui_(ui) {
+  ui->SetDevice(this);
   PopulateMenuItems();
 }
 
diff --git a/recovery_ui/include/recovery_ui/ui.h b/recovery_ui/include/recovery_ui/ui.h
index 2042c97..6e0f89e 100644
--- a/recovery_ui/include/recovery_ui/ui.h
+++ b/recovery_ui/include/recovery_ui/ui.h
@@ -28,6 +28,8 @@
 #include <thread>
 #include <vector>
 
+class Device;
+
 static constexpr const char* DEFAULT_LOCALE = "en-US";
 
 /*
@@ -144,6 +146,14 @@
 
   virtual ~RecoveryUI();
 
+  void SetDevice(Device* device) {
+    device_ = device;
+  }
+
+  Device* GetDevice() {
+    return device_;
+  }
+
   // Initializes the object; called before anything else. UI texts will be initialized according
   // to the given locale. Returns true on success.
   virtual bool Init(const std::string& locale);
@@ -310,6 +320,8 @@
     OFF,
   };
 
+  Device* device_;
+
   // The sensitivity when detecting a swipe.
   const int touch_low_threshold_;
   const int touch_high_threshold_;