shill: IPConfig: Don't reset StaticIP on failure

If the IP address associated with an IPConfig is provided by
StaticIP, the entire configuration should be retained even if
the automatic configuration method fails.  Otherwise,
configuration parameters provided outside of the automatic
configuration mechanism will be lost.

To accomplish this cleanly, we need to change the contract
between IPConfig and Device objects.  The failure and success
events are now split into separate callbacks.  Intead of
passing a bool parameter to OnIPConfigUpdated, failure cases
are handled by a separate method.  Further, there is no
expectation in the failure case that the IPConfig resets
itself, so the IPConfig provides a public method for the
Device to call if it chooses.

BUG=chromium:318290
TEST=Unittest, new autotest network_DhcpFailureWithStaticIP (CL:179783)
All other network_Dhcp* unit tests run.

Change-Id: I55ed5a7adfc5d97e45ce832e25caab97ff39cea6
Reviewed-on: https://chromium-review.googlesource.com/179786
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Paul Stewart <pstew@chromium.org>
diff --git a/ipconfig.h b/ipconfig.h
index 94f2963..cf8aba3 100644
--- a/ipconfig.h
+++ b/ipconfig.h
@@ -69,6 +69,8 @@
     kReleaseReasonStaticIP
   };
 
+  typedef base::Callback<void(const IPConfigRefPtr&)> Callback;
+
   IPConfig(ControlInterface *control_interface, const std::string &device_name);
   IPConfig(ControlInterface *control_interface,
            const std::string &device_name,
@@ -82,25 +84,32 @@
   std::string GetRpcIdentifier();
 
   // Registers a callback that's executed every time the configuration
-  // properties change. Takes ownership of |callback|. Pass NULL to remove a
-  // callback. The callback's first argument is a pointer to this IP
+  // properties are acquired. Takes ownership of |callback|.  Pass NULL
+  // to remove a callback. The callback's argument is a pointer to this IP
   // configuration instance allowing clients to more easily manage multiple IP
-  // configurations. The callback's second argument is set to false if IP
-  // configuration failed.
-  void RegisterUpdateCallback(
-      const base::Callback<void(const IPConfigRefPtr&, bool)> &callback);
+  // configurations.
+  void RegisterUpdateCallback(const Callback &callback);
+
+  // Registers a callback that's executed every time the configuration
+  // properties fail to be acquired. Takes ownership of |callback|.  Pass NULL
+  // to remove a callback. The callback's argument is a pointer to this IP
+  // configuration instance allowing clients to more easily manage multiple IP
+  // configurations.
+  void RegisterFailureCallback(const Callback &callback);
 
   // Registers a callback that's executed every time the Refresh method
   // on the ipconfig is called.  Takes ownership of |callback|. Pass NULL
   // to remove a callback. The callback's argument is a pointer to this IP
   // configuration instance allowing clients to more easily manage multiple IP
   // configurations.
-  void RegisterRefreshCallback(
-      const base::Callback<void(const IPConfigRefPtr&)> &callback);
+  void RegisterRefreshCallback(const Callback &callback);
 
   void set_properties(const Properties &props) { properties_ = props; }
   virtual const Properties &properties() const { return properties_; }
 
+  // Reset the IPConfig properties to their default values.
+  virtual void ResetProperties();
+
   // Request, renew and release IP configuration. Return true on success, false
   // otherwise. The default implementation always returns false indicating a
   // failure.  ReleaseIP is advisory: if we are no longer connected, it is not
@@ -134,8 +143,11 @@
   virtual void EmitChanges();
 
   // Updates the IP configuration properties and notifies registered listeners
-  // about the event. |success| is set to false if the IP configuration failed.
-  virtual void UpdateProperties(const Properties &properties, bool success);
+  // about the event.
+  virtual void UpdateProperties(const Properties &properties);
+
+  // Notifies registered listeners that the configuration process has failed.
+  virtual void NotifyFailure();
 
   // |id_suffix| is appended to the storage id, intended to bind this instance
   // to its associated device.
@@ -169,8 +181,9 @@
   const uint serial_;
   scoped_ptr<IPConfigAdaptorInterface> adaptor_;
   Properties properties_;
-  base::Callback<void(const IPConfigRefPtr&, bool)> update_callback_;
-  base::Callback<void(const IPConfigRefPtr&)> refresh_callback_;
+  Callback update_callback_;
+  Callback failure_callback_;
+  Callback refresh_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(IPConfig);
 };