Change source to be a unique_ptr.

The current code keeps a pointer to a local variable which doesn't
work too well. Change this to a unique_ptr and allocate the source
object that will be used instead.

Test: All unit tests pass.
Test: fastboot -w flashall on a mokey which crashed without this change.
Change-Id: Ief5437374181e514928c45dd540b42898901a137
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 3ce8141..b12e584 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1525,7 +1525,7 @@
         fb->ResizePartition(pname, std::to_string(buf.image_size));
     }
     std::string flash_pname = repack_ramdisk(pname, &buf, fp->fb);
-    flash_buf(fp->source, flash_pname, &buf, apply_vbmeta);
+    flash_buf(fp->source.get(), flash_pname, &buf, apply_vbmeta);
 }
 
 // Sets slot_override as the active slot. If slot_override is blank,
@@ -1679,7 +1679,7 @@
     }
     for (size_t i = 0; i < tasks->size(); i++) {
         if (auto flash_task = tasks->at(i)->AsFlashTask()) {
-            if (FlashTask::IsDynamicParitition(fp->source, flash_task)) {
+            if (FlashTask::IsDynamicParitition(fp->source.get(), flash_task)) {
                 if (!loc) {
                     loc = i;
                 }
@@ -1810,7 +1810,8 @@
     if (fp_->exclude_dynamic_partitions) {
         auto is_non_static_flash_task = [&](const auto& task) -> bool {
             if (auto flash_task = task->AsFlashTask()) {
-                if (!should_flash_in_userspace(fp_->source, flash_task->GetPartitionAndSlot())) {
+                if (!should_flash_in_userspace(fp_->source.get(),
+                                               flash_task->GetPartitionAndSlot())) {
                     return false;
                 }
             }
@@ -1884,9 +1885,10 @@
         // On these devices, secondary slots must be flashed as physical
         // partitions (otherwise they would not mount on first boot). To enforce
         // this, we delete any logical partitions for the "other" slot.
-        if (is_retrofit_device(fp_->source)) {
+        if (is_retrofit_device(fp_->source.get())) {
             std::string partition_name = image->part_name + "_" + slot;
-            if (image->IsSecondary() && should_flash_in_userspace(fp_->source, partition_name)) {
+            if (image->IsSecondary() &&
+                should_flash_in_userspace(fp_->source.get(), partition_name)) {
                 tasks.emplace_back(std::make_unique<DeleteTask>(fp_, partition_name));
             }
         }
@@ -1949,8 +1951,7 @@
     if (error != 0) {
         die("failed to open zip file '%s': %s", filename, ErrorCodeString(error));
     }
-    ZipImageSource zp = ZipImageSource(zip);
-    fp->source = &zp;
+    fp->source.reset(new ZipImageSource(zip));
     FlashAllTool tool(fp);
     tool.Flash();
 
@@ -1971,8 +1972,7 @@
 }
 
 static void do_flashall(FlashingPlan* fp) {
-    LocalImageSource s = LocalImageSource();
-    fp->source = &s;
+    fp->source.reset(new LocalImageSource());
     FlashAllTool tool(fp);
     tool.Flash();
 }
@@ -2089,7 +2089,7 @@
         die("Cannot read image: %s", strerror(errno));
     }
 
-    flash_buf(fp->source, partition, &buf, is_vbmeta_partition(partition));
+    flash_buf(fp->source.get(), partition, &buf, is_vbmeta_partition(partition));
     return;
 
 failed:
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index 4859ceb..cd7bc2d 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -28,6 +28,7 @@
 #pragma once
 
 #include <functional>
+#include <memory>
 #include <string>
 #include "fastboot_driver_interface.h"
 #include "filesystem.h"
@@ -89,7 +90,7 @@
     // If the image uses the default slot, or the user specified "all", then
     // the paired string will be empty. If the image requests a specific slot
     // (for example, system_other) it is specified instead.
-    ImageSource* source;
+    std::unique_ptr<ImageSource> source;
     bool wants_wipe = false;
     bool skip_reboot = false;
     bool wants_set_active = false;
diff --git a/fastboot/task.cpp b/fastboot/task.cpp
index 4b2b9e3..25c5a6e 100644
--- a/fastboot/task.cpp
+++ b/fastboot/task.cpp
@@ -41,7 +41,7 @@
 
 void FlashTask::Run() {
     auto flash = [&](const std::string& partition) {
-        if (should_flash_in_userspace(fp_->source, partition) && !is_userspace_fastboot() &&
+        if (should_flash_in_userspace(fp_->source.get(), partition) && !is_userspace_fastboot() &&
             !fp_->force_flash) {
             die("The partition you are trying to flash is dynamic, and "
                 "should be flashed via fastbootd. Please run:\n"
@@ -174,7 +174,7 @@
         LOG(VERBOSE) << "Cannot optimize flashing super for all slots";
         return nullptr;
     }
-    if (!CanOptimize(fp->source, tasks)) {
+    if (!CanOptimize(fp->source.get(), tasks)) {
         return nullptr;
     }
 
diff --git a/fastboot/task_test.cpp b/fastboot/task_test.cpp
index 1e25b6f..9cde1a8 100644
--- a/fastboot/task_test.cpp
+++ b/fastboot/task_test.cpp
@@ -192,8 +192,7 @@
         GTEST_SKIP();
     }
 
-    LocalImageSource s;
-    fp->source = &s;
+    fp->source.reset(new LocalImageSource);
     fp->sparse_limit = std::numeric_limits<int64_t>::max();
 
     fastboot::MockFastbootDriver fb;
@@ -239,8 +238,7 @@
         GTEST_SKIP();
     }
 
-    LocalImageSource s;
-    fp->source = &s;
+    fp->source.reset(new LocalImageSource);
 
     fastboot::MockFastbootDriver fb;
     fp->fb = &fb;
@@ -260,7 +258,7 @@
                 ParseFastbootInfoLine(fp.get(), android::base::Tokenize(test.first, " "));
         auto flash_task = task->AsFlashTask();
         ASSERT_FALSE(flash_task == nullptr);
-        ASSERT_EQ(FlashTask::IsDynamicParitition(fp->source, flash_task), test.second);
+        ASSERT_EQ(FlashTask::IsDynamicParitition(fp->source.get(), flash_task), test.second);
     }
 }
 
@@ -269,8 +267,7 @@
         GTEST_SKIP();
     }
 
-    LocalImageSource s;
-    fp->source = &s;
+    fp->source.reset(new LocalImageSource);
     fp->sparse_limit = std::numeric_limits<int64_t>::max();
 
     fastboot::MockFastbootDriver fb;
@@ -301,7 +298,7 @@
     for (auto& test : patternmatchtest) {
         std::vector<std::unique_ptr<Task>> tasks = ParseFastbootInfo(fp.get(), test.first);
         tasks.erase(std::remove_if(tasks.begin(), tasks.end(), remove_if_callback), tasks.end());
-        ASSERT_EQ(OptimizedFlashSuperTask::CanOptimize(fp->source, tasks), test.second);
+        ASSERT_EQ(OptimizedFlashSuperTask::CanOptimize(fp->source.get(), tasks), test.second);
     }
 }
 
@@ -312,8 +309,7 @@
         GTEST_SKIP();
     }
 
-    LocalImageSource s;
-    fp->source = &s;
+    fp->source.reset(new LocalImageSource);
     fp->sparse_limit = std::numeric_limits<int64_t>::max();
 
     fastboot::MockFastbootDriver fb;
@@ -362,7 +358,7 @@
                     contains_optimized_task = true;
                 }
                 if (auto flash_task = task->AsFlashTask()) {
-                    if (FlashTask::IsDynamicParitition(fp->source, flash_task)) {
+                    if (FlashTask::IsDynamicParitition(fp->source.get(), flash_task)) {
                         return false;
                     }
                 }