Local build and force system flash.

Add a option for forcing a system flash.
Make LocalBuildProvider inherit from StubBuildProvider in order to
make use of its options.
Also add more log verbosity when device becomes unavailable.

Change-Id: Idfdec462466b27e464d484d94c6bcafc294d87f0
diff --git a/src/com/android/tradefed/build/BuildInfo.java b/src/com/android/tradefed/build/BuildInfo.java
index ec2c250..f2ce892 100644
--- a/src/com/android/tradefed/build/BuildInfo.java
+++ b/src/com/android/tradefed/build/BuildInfo.java
@@ -115,7 +115,7 @@
     /**
      * Helper method to copy build attributes, branch, and flavor from other build.
      */
-    protected void addAllBuildAttributes(BuildInfo build) {
+    public void addAllBuildAttributes(BuildInfo build) {
         mBuildAttributes.putAll(build.getAttributesMultiMap());
         setBuildFlavor(build.getBuildFlavor());
         setBuildBranch(build.getBuildBranch());
diff --git a/src/com/android/tradefed/build/LocalBuildProvider.java b/src/com/android/tradefed/build/LocalBuildProvider.java
index 41b0994..4a69bd0 100644
--- a/src/com/android/tradefed/build/LocalBuildProvider.java
+++ b/src/com/android/tradefed/build/LocalBuildProvider.java
@@ -27,21 +27,12 @@
  * local path.
  */
 @OptionClass(alias = "local-build")
-public class LocalBuildProvider implements IBuildProvider {
+public class LocalBuildProvider extends StubBuildProvider {
 
     private static final String IMAGE_FILE_OPTION_NAME = "device-image-file";
     private static final String TEST_DIR_OPTION_NAME = "test-dir";
     private static final String DATA_FILE_OPTION_NAME = "user-data-file";
 
-    @Option(name = "device-build-id", description = "the id of device build.")
-    private String mBuildId = null;
-
-    @Option(name = "test-target", description = "the test target name.")
-    private String mTestTarget = null;
-
-    @Option(name = "build-name", description = "the build name.")
-    private String mBuildName = null;
-
     @Option(name = IMAGE_FILE_OPTION_NAME, description = "the device image file to use.",
             importance = Importance.IF_UNSET)
     private File mDeviceImageFile = null;
@@ -66,13 +57,10 @@
                     "Please provide a valid path via --%s", mDeviceImageFile.getAbsolutePath(),
                     IMAGE_FILE_OPTION_NAME));
         }
-        DeviceBuildInfo buildInfo = null;
-
-        if (mBuildId != null && mTestTarget != null && mBuildName != null) {
-            buildInfo = new DeviceBuildInfo(mBuildId, mTestTarget, mBuildName);
-        } else {
-            buildInfo = new DeviceBuildInfo();
-        }
+        BuildInfo stubBuild = (BuildInfo)super.getBuild();
+        DeviceBuildInfo buildInfo = new DeviceBuildInfo(stubBuild.getBuildId(),
+                stubBuild.getTestTag(), stubBuild.getBuildTargetName());
+        buildInfo.addAllBuildAttributes(stubBuild);
 
         try {
             buildInfo.setDeviceImageFile(mDeviceImageFile);
diff --git a/src/com/android/tradefed/targetprep/DeviceFlashPreparer.java b/src/com/android/tradefed/targetprep/DeviceFlashPreparer.java
index d7cb3e7..1226398 100644
--- a/src/com/android/tradefed/targetprep/DeviceFlashPreparer.java
+++ b/src/com/android/tradefed/targetprep/DeviceFlashPreparer.java
@@ -49,6 +49,11 @@
         "specify if userdata partition should be encrypted")
     private boolean mEncryptUserData = false;
 
+    @Option(name="force-system-flash", description=
+        "specify if system should always be flashed even if already running desired build.")
+    private boolean mForceSystemFlash = false;
+
+
     /**
      * Sets the device boot time
      * <p/>
@@ -98,6 +103,7 @@
         device.setRecoveryMode(RecoveryMode.ONLINE);
         IDeviceFlasher flasher = createFlasher(device);
         flasher.setUserDataFlashOption(mUserDataFlashOption);
+        flasher.setForceSystemFlash(mForceSystemFlash);
         preEncryptDevice(device, flasher);
         flasher.flash(device, deviceBuild);
         device.waitForDeviceOnline();
diff --git a/src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java b/src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java
index 40fea20..1bd626a 100644
--- a/src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java
+++ b/src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java
@@ -39,6 +39,8 @@
     // TODO: make this list configurable
     private ITestsZipInstaller mTestsZipInstaller = new DefaultTestsZipInstaller("media");
 
+    private boolean mForceSystemFlash;
+
     /**
      * {@inheritDoc}
      */
@@ -409,7 +411,8 @@
      */
     protected boolean checkAndFlashSystem(ITestDevice device, String systemBuildId,
             IDeviceBuildInfo deviceBuild) throws DeviceNotAvailableException, TargetSetupError {
-        if (systemBuildId != null && ! systemBuildId.equals(deviceBuild.getBuildId())) {
+        if (mForceSystemFlash ||
+                (systemBuildId != null && ! systemBuildId.equals(deviceBuild.getBuildId()))) {
             CLog.i("Flashing system %s", deviceBuild.getBuildId());
             flashSystem(device, deviceBuild);
             return true;
@@ -523,4 +526,12 @@
             return result.getStdout();
         }
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setForceSystemFlash(boolean forceSystemFlash) {
+        mForceSystemFlash = forceSystemFlash;
+    }
 }
diff --git a/src/com/android/tradefed/targetprep/IDeviceFlasher.java b/src/com/android/tradefed/targetprep/IDeviceFlasher.java
index e268ed5..9cb7ba1 100644
--- a/src/com/android/tradefed/targetprep/IDeviceFlasher.java
+++ b/src/com/android/tradefed/targetprep/IDeviceFlasher.java
@@ -65,6 +65,12 @@
     public UserDataFlashOption getUserDataFlashOption();
 
     /**
+     * Sets if system should always be flashed even if running current build
+     * @param forceSystemFlash
+     */
+    public void setForceSystemFlash(boolean forceSystemFlash);
+
+    /**
      * Flashes build on device.
      * <p/>
      * Returns immediately after flashing is complete. Callers should wait for device to be
diff --git a/src/com/android/tradefed/targetprep/SystemUpdaterDeviceFlasher.java b/src/com/android/tradefed/targetprep/SystemUpdaterDeviceFlasher.java
index 7037b96..d86eda5 100644
--- a/src/com/android/tradefed/targetprep/SystemUpdaterDeviceFlasher.java
+++ b/src/com/android/tradefed/targetprep/SystemUpdaterDeviceFlasher.java
@@ -40,6 +40,8 @@
     @SuppressWarnings("unused")
     private UserDataFlashOption mFlashOption = UserDataFlashOption.TESTS_ZIP;
 
+    private boolean mForceSystemFlash;
+
     /**
      * {@inheritDoc}
      */
@@ -80,7 +82,7 @@
             throws DeviceNotAvailableException, TargetSetupError {
         // FIXME same high level logic as in
         // FastbootDeviceFlasher#checkAndFlashSystem, could be de-duped
-        if (device.getBuildId() == deviceBuild.getBuildId()) {
+        if (!mForceSystemFlash && deviceBuild.getBuildId().equals(device.getBuildId())) {
             Log.i(LOG_TAG, String.format("System is already version %s, skipping install",
                     device.getBuildId()));
             // reboot
@@ -136,4 +138,12 @@
     public UserDataFlashOption getUserDataFlashOption() {
         return mFlashOption;
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setForceSystemFlash(boolean forceSystemFlash) {
+        mForceSystemFlash = forceSystemFlash;
+    }
 }