update_engine_client: Add -interactive=true|false flag

This makes it easier to test the update_engine codepaths dealing with
non-interactive update attempts.

BUG=chromium:273251
TEST=Manually tested with 'update_engine_client -update -interactive=X' +
    unit tests pass.

Change-Id: Id3894261fd1c0dc2afdf2426484835f487924433
Reviewed-on: https://chromium-review.googlesource.com/168445
Reviewed-by: Chris Sosa <sosa@chromium.org>
Tested-by: David Zeuthen <zeuthen@chromium.org>
Commit-Queue: David Zeuthen <zeuthen@chromium.org>
diff --git a/UpdateEngine.conf b/UpdateEngine.conf
index a89bcac..dee64ee 100644
--- a/UpdateEngine.conf
+++ b/UpdateEngine.conf
@@ -18,6 +18,9 @@
            send_member="AttemptUpdate"/>
     <allow send_destination="org.chromium.UpdateEngine"
            send_interface="org.chromium.UpdateEngineInterface"
+           send_member="AttemptUpdateWithFlags"/>
+    <allow send_destination="org.chromium.UpdateEngine"
+           send_interface="org.chromium.UpdateEngineInterface"
            send_member="AttemptRollback"/>
     <allow send_destination="org.chromium.UpdateEngine"
            send_interface="org.chromium.UpdateEngineInterface"
diff --git a/dbus_constants.h b/dbus_constants.h
index e4173f0..625ac8d 100644
--- a/dbus_constants.h
+++ b/dbus_constants.h
@@ -12,6 +12,12 @@
     "/org/chromium/UpdateEngine";
 static const char* const kUpdateEngineServiceInterface =
     "org.chromium.UpdateEngineInterface";
+
+// Flags used in the AttemptUpdateWithFlags() D-Bus method.
+typedef enum {
+  kAttemptUpdateFlagNonInteractive = (1<<0)
+} AttemptUpdateFlags;
+
 }  // namespace chromeos_update_engine
 
 #endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_DBUS_CONSTANTS_H__
diff --git a/dbus_service.cc b/dbus_service.cc
index 97ce226..449c101 100644
--- a/dbus_service.cc
+++ b/dbus_service.cc
@@ -11,6 +11,7 @@
 #include <policy/device_policy.h>
 
 #include "update_engine/connection_manager.h"
+#include "update_engine/dbus_constants.h"
 #include "update_engine/marshal.glibmarshal.h"
 #include "update_engine/omaha_request_params.h"
 #include "update_engine/p2p_manager.h"
@@ -20,6 +21,8 @@
 
 using std::set;
 using std::string;
+using chromeos_update_engine::AttemptUpdateFlags;
+using chromeos_update_engine::kAttemptUpdateFlagNonInteractive;
 
 static const char kAUTestURLRequest[] = "autest";
 // By default autest bypasses scattering. If we want to test scattering,
@@ -72,8 +75,22 @@
                                               gchar* app_version,
                                               gchar* omaha_url,
                                               GError **error) {
+  return update_engine_service_attempt_update_with_flags(self,
+                                                         app_version,
+                                                         omaha_url,
+                                                         0, // No flags set.
+                                                         error);
+}
+
+gboolean update_engine_service_attempt_update_with_flags(
+    UpdateEngineService* self,
+    gchar* app_version,
+    gchar* omaha_url,
+    gint flags_as_int,
+    GError **error) {
   string update_app_version;
   string update_omaha_url;
+  AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(flags_as_int);
   bool interactive = true;
 
   // Only non-official (e.g., dev and test) builds can override the current
@@ -98,8 +115,11 @@
       update_omaha_url = kAUTestURL;
     }
   }
+  if (flags & kAttemptUpdateFlagNonInteractive)
+    interactive = false;
   LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
             << "omaha_url=\"" << update_omaha_url << "\" "
+            << "flags=0x" << std::hex << flags << " "
             << "interactive=" << (interactive? "yes" : "no");
   self->system_state_->update_attempter()->CheckForUpdate(update_app_version,
                                                           update_omaha_url,
diff --git a/dbus_service.h b/dbus_service.h
index e99caef..6d449df 100644
--- a/dbus_service.h
+++ b/dbus_service.h
@@ -51,6 +51,13 @@
                                               gchar* omaha_url,
                                               GError **error);
 
+gboolean update_engine_service_attempt_update_with_flags(
+    UpdateEngineService* self,
+    gchar* app_version,
+    gchar* omaha_url,
+    gint flags_as_int,
+    GError **error);
+
 gboolean update_engine_service_attempt_rollback(UpdateEngineService* self,
                                                 gboolean powerwash,
                                                 GError **error);
diff --git a/update_engine.xml b/update_engine.xml
index 44b7a7c..ad6c36b 100644
--- a/update_engine.xml
+++ b/update_engine.xml
@@ -13,6 +13,16 @@
       <arg type="s" name="app_version" />
       <arg type="s" name="omaha_url" />
     </method>
+    <!-- TODO(zeuthen,chromium:286399): Rename to AttemptUpdate and
+         update Chrome and other users of the AttemptUpdate() method
+         in lockstep.
+    -->
+    <method name="AttemptUpdateWithFlags">
+      <arg type="s" name="app_version" />
+      <arg type="s" name="omaha_url" />
+      <!-- See AttemptUpdateFlags enum in dbus_constants.h. -->
+      <arg type="i" name="flags" />
+    </method>
     <method name="AttemptRollback">
       <arg type="b" name="powerwash" />
     </method>
diff --git a/update_engine_client.cc b/update_engine_client.cc
index 6e3e4f3..e09c0d4 100644
--- a/update_engine_client.cc
+++ b/update_engine_client.cc
@@ -20,6 +20,8 @@
 using chromeos_update_engine::kUpdateEngineServiceName;
 using chromeos_update_engine::kUpdateEngineServicePath;
 using chromeos_update_engine::kUpdateEngineServiceInterface;
+using chromeos_update_engine::AttemptUpdateFlags;
+using chromeos_update_engine::kAttemptUpdateFlagNonInteractive;
 using chromeos_update_engine::utils::GetAndFreeGError;
 using std::string;
 
@@ -50,6 +52,7 @@
 DEFINE_string(p2p_update, "",
               "Enables (\"yes\") or disables (\"no\") the peer-to-peer update "
               "sharing.");
+DEFINE_bool(interactive, true, "Mark the update request as interactive.");
 
 namespace {
 
@@ -208,10 +211,14 @@
 
   CHECK(GetProxy(&proxy));
 
-  gboolean rc = update_engine_client_attempt_update(proxy,
-                                                    app_version.c_str(),
-                                                    omaha_url.c_str(),
-                                                    &error);
+  AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(
+      FLAGS_interactive ? 0 : kAttemptUpdateFlagNonInteractive);
+  gboolean rc =
+      update_engine_client_attempt_update_with_flags(proxy,
+                                                     app_version.c_str(),
+                                                     omaha_url.c_str(),
+                                                     static_cast<gint>(flags),
+                                                     &error);
   CHECK_EQ(rc, TRUE) << "Error checking for update: "
                      << GetAndFreeGError(&error);
   return true;