From acc855f711ae7bce20e4fc896c829e135a6801fc Mon Sep 17 00:00:00 2001 From: Tom Marshall Date: Fri, 6 Nov 2015 16:27:01 -0800 Subject: recovery: Handle oemunlock command * Conditionally compile support based on TARGET_HAVE_OEMLOCK. * Use liboemunlock for device specific support. Change-Id: I1cf1fef8e30075b0586bb86625b7df49723974cb --- recovery.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) (limited to 'recovery.cpp') diff --git a/recovery.cpp b/recovery.cpp index d3dc398..3a1fd61 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -61,6 +61,39 @@ extern "C" { struct selabel_handle *sehandle; +#ifdef HAVE_OEMLOCK + +/* + * liboemlock must supply the following C symbols: + * + * - int oemlock_get() + * + * Returns the current state of the OEM lock, if available. + * -1: Not available and/or error + * 0: Unlocked + * 1: Locked + * + * - int oemlock_set(int lock) + * + * Sets the state of the OEM lock. The "lock" parameter will be set + * to 0 for unlock and 1 for lock. + * + * Returns 0 on success, -1 on error + */ +extern "C" { +int oemlock_get(); +int oemlock_set(int lock); +} + +enum OemLockOp { + OEM_LOCK_NONE, + OEM_LOCK_UNLOCK +}; + +static OemLockOp oem_lock = OEM_LOCK_NONE; + +#endif + static const struct option OPTIONS[] = { { "send_intent", required_argument, NULL, 'i' }, { "update_package", required_argument, NULL, 'u' }, @@ -302,6 +335,14 @@ get_args(int *argc, char ***argv) { (*argv)[0] = strdup(arg); for (*argc = 1; *argc < MAX_ARGS; ++*argc) { if ((arg = strtok(NULL, "\n")) == NULL) break; + // Arguments that may only be passed in BCB +#ifdef HAVE_OEMLOCK + if (strcmp(arg, "--oemunlock") == 0) { + oem_lock = OEM_LOCK_UNLOCK; + --*argc; + continue; + } +#endif (*argv)[*argc] = strdup(arg); } LOGI("Got arguments from boot message\n"); @@ -510,7 +551,7 @@ typedef struct _saved_log_file { struct _saved_log_file* next; } saved_log_file; -static bool erase_volume(const char* volume) { +static bool erase_volume(const char* volume, bool force = false) { bool is_cache = (strcmp(volume, CACHE_ROOT) == 0); ui->SetBackground(RecoveryUI::ERASING); @@ -518,7 +559,7 @@ static bool erase_volume(const char* volume) { saved_log_file* head = NULL; - if (is_cache) { + if (!force && is_cache) { // If we're reformatting /cache, we load any past logs // (i.e. "/cache/recovery/last_*") and the current log // ("/cache/recovery/log") into memory, so we can restore them after @@ -568,9 +609,9 @@ static bool erase_volume(const char* volume) { if (volume[0] == '/') { ensure_path_unmounted(volume); } - int result = format_volume(volume); + int result = format_volume(volume, force); - if (is_cache) { + if (!force && is_cache) { while (head) { FILE* f = fopen_path(head->name, "wb"); if (f) { @@ -1343,6 +1384,17 @@ main(int argc, char **argv) { int status = INSTALL_SUCCESS; +#ifdef HAVE_OEMLOCK + if (oem_lock == OEM_LOCK_UNLOCK) { + if (device->WipeData()) status = INSTALL_ERROR; + if (erase_volume("/data", true)) status = INSTALL_ERROR; + if (wipe_cache && erase_volume("/cache", true)) status = INSTALL_ERROR; + if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n"); + if (oemlock_set(0)) status = INSTALL_ERROR; + // Force reboot regardless of actual status + status = INSTALL_SUCCESS; + } else +#endif if (update_package != NULL) { status = install_package(update_package, &should_wipe_cache, TEMPORARY_INSTALL_FILE, true); if (status == INSTALL_SUCCESS && should_wipe_cache) { -- cgit v1.1