shill: Notify upstart when shill is offline

Add an Upstart proxy, which can ask the upstart process to emit
events.  Invoke this event whenever the shill manager becomes
idle.

BUG=chromium:447796
TEST=Unit tests + manual:
Create a dummy "offline.conf" file in /etc/init which starts
with "start on shill-disconnected", and ensure that this script
is invoked if we disconnect the network.

Change-Id: Ide473098b7b93fd3da57b820e78b0a710c287cba
Reviewed-on: https://chromium-review.googlesource.com/241033
Reviewed-by: Zeping Qiu <zqiu@chromium.org>
Commit-Queue: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/upstart/upstart_unittest.cc b/upstart/upstart_unittest.cc
new file mode 100644
index 0000000..8fa5eff
--- /dev/null
+++ b/upstart/upstart_unittest.cc
@@ -0,0 +1,63 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/upstart/upstart.h"
+
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "shill/proxy_factory.h"
+#include "shill/upstart/mock_upstart_proxy.h"
+#include "shill/upstart/upstart_proxy_interface.h"
+
+using testing::_;
+using testing::Test;
+
+namespace shill {
+
+namespace {
+
+class FakeProxyFactory : public ProxyFactory {
+ public:
+  FakeProxyFactory()
+      : upstart_proxy_raw_(new MockUpstartProxy),
+        upstart_proxy_(upstart_proxy_raw_) {}
+
+  UpstartProxyInterface *CreateUpstartProxy() override {
+    CHECK(upstart_proxy_);
+    // Passes ownership.
+    return upstart_proxy_.release();
+  }
+
+  // Can not guarantee that the returned object is alive.
+  MockUpstartProxy *upstart_proxy() const {
+    return upstart_proxy_raw_;
+  }
+
+ private:
+  MockUpstartProxy *const upstart_proxy_raw_;
+  std::unique_ptr<MockUpstartProxy> upstart_proxy_;
+};
+
+}  // namespace
+
+class UpstartTest : public Test {
+ public:
+  UpstartTest()
+      : upstart_(&factory_),
+        upstart_proxy_(factory_.upstart_proxy()) {}
+
+ protected:
+  FakeProxyFactory factory_;
+  Upstart upstart_;
+  MockUpstartProxy *const upstart_proxy_;
+};
+
+TEST_F(UpstartTest, NotifyDisconnected) {
+  EXPECT_CALL(*upstart_proxy_, EmitEvent("shill-disconnected", _, false));
+  upstart_.NotifyDisconnected();
+}
+
+}  // namespace shill