shill: add BinderControl and stub/skeleton adaptor implementations

Add BinderControl, an RPC control module for Binder on shill.
Add stub adaptor implementations for shill RPC interfaces that
we do not support on Binder (Profile, IPConfig, and RPCTask), and
skeleton implementations for RPC interfaces we do support
(Device, Manager, and Service).

Also:
- Rename the ENABLE_ANDROID_BINDER flag to ENABLE_BINDER, since
  the binder file naming convention does not include an android
  prefix.
- Rename the |callbacks| argument in IService.aidl to |callback|
  so this argument name matches those in the other .aidl files.

BUG: 25160005
Change-Id: I2a5c71b8a302d2a7243d1c8e2eba90e4c5022f8a
TEST: shill compiles on Android and all unit tests pass.
diff --git a/Android.mk b/Android.mk
index 6c4a6de..83b6a1b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -37,7 +37,7 @@
       -DENABLE_CHROMEOS_DBUS \
       -DENABLE_JSON_STORE
   ifeq ($(SHILL_USE_BINDER), true)
-    LOCAL_CFLAGS += -DENABLE_ANDROID_BINDER
+    LOCAL_CFLAGS += -DENABLE_BINDER
   endif # SHILL_USE_BINDER
   ifneq ($(SHILL_USE_WIFI), true)
     LOCAL_CFLAGS += -DDISABLE_WIFI
@@ -183,13 +183,6 @@
     external/cros/system_api/
 LOCAL_SRC_FILES := \
     shims/protos/crypto_util.proto \
-    dbus_bindings/org.chromium.flimflam.Device.dbus-xml \
-    dbus_bindings/org.chromium.flimflam.IPConfig.dbus-xml \
-    dbus_bindings/org.chromium.flimflam.Manager.dbus-xml \
-    dbus_bindings/org.chromium.flimflam.Profile.dbus-xml \
-    dbus_bindings/org.chromium.flimflam.Service.dbus-xml \
-    dbus_bindings/org.chromium.flimflam.Task.dbus-xml \
-    dbus_bindings/org.chromium.flimflam.ThirdPartyVpn.dbus-xml \
     json_store.cc \
     active_link_monitor.cc \
     arp_client.cc \
@@ -206,19 +199,10 @@
     connectivity_trial.cc \
     crypto_rot47.cc \
     crypto_util_proxy.cc \
-    dbus/chromeos_dbus_adaptor.cc \
-    dbus/chromeos_dbus_control.cc \
     dbus/chromeos_dbus_service_watcher.cc \
-    dbus/chromeos_device_dbus_adaptor.cc \
     dbus/chromeos_dhcpcd_listener.cc \
     dbus/chromeos_dhcpcd_proxy.cc \
     dbus/chromeos_firewalld_proxy.cc \
-    dbus/chromeos_ipconfig_dbus_adaptor.cc \
-    dbus/chromeos_manager_dbus_adaptor.cc \
-    dbus/chromeos_profile_dbus_adaptor.cc \
-    dbus/chromeos_rpc_task_dbus_adaptor.cc \
-    dbus/chromeos_service_dbus_adaptor.cc \
-    dbus/chromeos_third_party_vpn_dbus_adaptor.cc \
     default_profile.cc \
     device.cc \
     device_claimer.cc \
@@ -297,12 +281,40 @@
 LOCAL_AIDL_INCLUDES := \
     system/connectivity/shill/binder \
     frameworks/native/aidl/binder
-LOCAL_SHARED_LIBRARIES += libbinder libutils
+LOCAL_SHARED_LIBRARIES += libbinder libutils libbrillo-binder
 LOCAL_SRC_FILES += \
+    adaptor_stub.cc \
     binder/android/system/connectivity/shill/IDevice.aidl \
     binder/android/system/connectivity/shill/IManager.aidl \
+    binder/android/system/connectivity/shill/IPropertyChangedCallback.aidl \
     binder/android/system/connectivity/shill/IService.aidl \
-    binder/android/system/connectivity/shill/IPropertyChangedCallback.aidl
+    binder/binder_adaptor.cc \
+    binder/binder_control.cc \
+    binder/device_binder_adaptor.cc \
+    binder/manager_binder_adaptor.cc \
+    binder/service_binder_adaptor.cc \
+    ipconfig_adaptor_stub.cc \
+    profile_adaptor_stub.cc \
+    rpc_task_adaptor_stub.cc \
+    third_party_vpn_adaptor_stub.cc
+else
+LOCAL_SRC_FILES += \
+    dbus/chromeos_dbus_adaptor.cc \
+    dbus/chromeos_dbus_control.cc \
+    dbus/chromeos_device_dbus_adaptor.cc \
+    dbus/chromeos_ipconfig_dbus_adaptor.cc \
+    dbus/chromeos_manager_dbus_adaptor.cc \
+    dbus/chromeos_profile_dbus_adaptor.cc \
+    dbus/chromeos_rpc_task_dbus_adaptor.cc \
+    dbus/chromeos_service_dbus_adaptor.cc \
+    dbus/chromeos_third_party_vpn_dbus_adaptor.cc \
+    dbus_bindings/org.chromium.flimflam.Device.dbus-xml \
+    dbus_bindings/org.chromium.flimflam.IPConfig.dbus-xml \
+    dbus_bindings/org.chromium.flimflam.Manager.dbus-xml \
+    dbus_bindings/org.chromium.flimflam.Profile.dbus-xml \
+    dbus_bindings/org.chromium.flimflam.Service.dbus-xml \
+    dbus_bindings/org.chromium.flimflam.Task.dbus-xml \
+    dbus_bindings/org.chromium.flimflam.ThirdPartyVpn.dbus-xml
 endif # SHILL_USE_BINDER
 ifeq ($(SHILL_USE_WIFI), true)
 LOCAL_SRC_FILES += \
@@ -359,7 +371,7 @@
     libmetrics \
     libprotobuf-cpp-lite
 ifeq ($(SHILL_USE_BINDER), true)
-LOCAL_SHARED_LIBRARIES += libbrillo-binder
+LOCAL_SHARED_LIBRARIES += libbinder libutils libbrillo-binder
 endif # SHILL_USE_BINDER
 ifdef BRILLO
 LOCAL_SHARED_LIBRARIES += libhardware
@@ -391,9 +403,6 @@
     libbrillo-dbus \
     libchrome-dbus \
     libprotobuf-cpp-lite
-ifeq ($(SHILL_USE_BINDER), true)
-LOCAL_SHARED_LIBRARIES += libbrillo-binder
-endif # SHILL_USE_BINDER
 LOCAL_STATIC_LIBRARIES := libshill libgmock libchrome_test_helpers
 proto_header_dir := $(call local-generated-sources-dir)/proto/$(shill_parent_dir)
 LOCAL_C_INCLUDES := \
@@ -418,7 +427,6 @@
     connectivity_trial_unittest.cc \
     crypto_rot47_unittest.cc \
     crypto_util_proxy_unittest.cc \
-    dbus/chromeos_dbus_adaptor_unittest.cc \
     default_profile_unittest.cc \
     device_claimer_unittest.cc \
     device_info_unittest.cc \
@@ -545,6 +553,12 @@
     virtual_device_unittest.cc \
     vpn/mock_vpn_provider.cc \
     json_store_unittest.cc
+ifeq ($(SHILL_USE_BINDER), true)
+LOCAL_SHARED_LIBRARIES += libbinder libutils libbrillo-binder
+else
+LOCAL_SRC_FILES += \
+    dbus/chromeos_dbus_adaptor_unittest.cc
+endif # SHILL_USE_BINDER
 ifeq ($(SHILL_USE_WIFI), true)
 LOCAL_SRC_FILES += \
     net/netlink_manager_unittest.cc \
diff --git a/adaptor_stub.cc b/adaptor_stub.cc
new file mode 100644
index 0000000..9d016ea
--- /dev/null
+++ b/adaptor_stub.cc
@@ -0,0 +1,23 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/adaptor_stub.h"
+
+namespace shill {
+
+AdaptorStub::AdaptorStub(const std::string& id) : rpc_id_(id) {}
+
+}  // namespace shill
diff --git a/adaptor_stub.h b/adaptor_stub.h
new file mode 100644
index 0000000..142324f
--- /dev/null
+++ b/adaptor_stub.h
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_ADAPTOR_STUB_H_
+#define SHILL_ADAPTOR_STUB_H_
+
+#include <string>
+
+#include <base/macros.h>
+
+namespace shill {
+
+class AdaptorStub {
+ public:
+  explicit AdaptorStub(const std::string& id);
+
+ protected:
+  const std::string& rpc_id() { return rpc_id_; }
+
+ private:
+  std::string rpc_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(AdaptorStub);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_ADAPTOR_STUB_H_
diff --git a/binder/android/system/connectivity/shill/IService.aidl b/binder/android/system/connectivity/shill/IService.aidl
index 426ac2f..b7ced60 100644
--- a/binder/android/system/connectivity/shill/IService.aidl
+++ b/binder/android/system/connectivity/shill/IService.aidl
@@ -141,6 +141,5 @@
    *
    * @param callback Binder reference to call back
    */
-  void RegisterPropertyChangedSignalHandler(
-      IPropertyChangedCallback callbacks);
+  void RegisterPropertyChangedSignalHandler(IPropertyChangedCallback callback);
 }
diff --git a/binder/binder_adaptor.cc b/binder/binder_adaptor.cc
new file mode 100644
index 0000000..260b164
--- /dev/null
+++ b/binder/binder_adaptor.cc
@@ -0,0 +1,55 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/binder/binder_adaptor.h"
+
+#include <string>
+
+#include <utils/String16.h>
+
+#include "android/system/connectivity/shill/IPropertyChangedCallback.h"
+#include "shill/logging.h"
+
+using android::sp;
+using android::String16;
+using android::system::connectivity::shill::IPropertyChangedCallback;
+using std::string;
+
+namespace shill {
+
+namespace Logging {
+static auto kModuleLogScope = ScopeLogger::kBinder;
+static string ObjectID(BinderAdaptor* b) {
+  return "(binder_adaptor)";
+}
+}  // namespace Logging
+
+BinderAdaptor::BinderAdaptor(const string& id) : id_(id) {
+  SLOG(this, 2) << "BinderAdaptor: " << id;
+}
+
+void BinderAdaptor::AddPropertyChangedSignalHandler(
+    const sp<IPropertyChangedCallback>& property_changed_callback) {
+  property_changed_callbacks_.push_back(property_changed_callback);
+}
+
+void BinderAdaptor::SendPropertyChangedSignal(const string& name) {
+  for (const auto& callback : property_changed_callbacks_) {
+    callback->OnPropertyChanged(String16(name.c_str()));
+  }
+}
+
+}  // namespace shill
diff --git a/binder/binder_adaptor.h b/binder/binder_adaptor.h
new file mode 100644
index 0000000..30346b5
--- /dev/null
+++ b/binder/binder_adaptor.h
@@ -0,0 +1,73 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_BINDER_BINDER_ADAPTOR_H_
+#define SHILL_BINDER_BINDER_ADAPTOR_H_
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace system {
+namespace connectivity {
+namespace shill {
+class IPropertyChangedCallback;
+}  // shill
+}  // connectivity
+}  // system
+}  // android
+
+namespace shill {
+
+// Superclass for all Binder-backed Adaptor objects.
+class BinderAdaptor {
+ public:
+  explicit BinderAdaptor(const std::string& id);
+  ~BinderAdaptor() = default;
+
+ protected:
+  // Add a IPropertyChangedCallback binder to |property_changed_callbacks_|.
+  // This binder's OnPropertyChanged() method will be invoked when shill
+  // properties change.
+  void AddPropertyChangedSignalHandler(
+      const android::sp<
+          android::system::connectivity::shill::IPropertyChangedCallback>&
+          property_changed_callback);
+
+  // Signals all registered listeners the shill property |name| has changed by
+  // calling the OnPropertyChanged() method of all IPropertyChangedCallback
+  // binders in |property_changed_callbacks_|.
+  void SendPropertyChangedSignal(const std::string& name);
+
+  const std::string& id() { return id_; }
+
+ private:
+  // Used to uniquely identify this Binder adaptor.
+  std::string id_;
+
+  std::vector<android::sp<
+      android::system::connectivity::shill::IPropertyChangedCallback>>
+      property_changed_callbacks_;
+
+  DISALLOW_COPY_AND_ASSIGN(BinderAdaptor);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_BINDER_BINDER_ADAPTOR_H_
diff --git a/binder/binder_control.cc b/binder/binder_control.cc
new file mode 100644
index 0000000..96adbad
--- /dev/null
+++ b/binder/binder_control.cc
@@ -0,0 +1,197 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/binder/binder_control.h"
+
+#include <base/bind.h>
+#include <binder/IServiceManager.h>
+#include <brillo/binder_watcher.h>
+
+// TODO(samueltan): remove when shill is no longer dependent on DBus proxies.
+#include <dbus/service_constants.h>
+
+#include "shill/manager.h"
+
+#include "shill/binder/device_binder_adaptor.h"
+#include "shill/binder/manager_binder_adaptor.h"
+#include "shill/binder/service_binder_adaptor.h"
+#include "shill/dbus/chromeos_dhcpcd_listener.h"
+#include "shill/dbus/chromeos_dhcpcd_proxy.h"
+#include "shill/ipconfig_adaptor_stub.h"
+#include "shill/profile_adaptor_stub.h"
+#include "shill/rpc_task_adaptor_stub.h"
+#include "shill/third_party_vpn_adaptor_stub.h"
+#include "shill/dbus/chromeos_firewalld_proxy.h"
+#include "shill/power_manager_proxy_stub.h"
+#include "shill/upstart/upstart_proxy_stub.h"
+#include "shill/dbus/chromeos_dbus_service_watcher.h"
+#if !defined(DISABLE_WIFI)
+#include "shill/dbus/chromeos_supplicant_bss_proxy.h"
+#endif  // DISABLE_WIFI
+#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
+#include "shill/dbus/chromeos_supplicant_interface_proxy.h"
+#include "shill/dbus/chromeos_supplicant_network_proxy.h"
+#include "shill/dbus/chromeos_supplicant_process_proxy.h"
+#endif  // DISABLE_WIFI || DISABLE_WIRED_8021X
+
+using android::defaultServiceManager;
+using std::string;
+using std::to_string;
+
+namespace shill {
+
+// static.
+const char BinderControl::kNullRpcIdentifier[] = "-1";
+
+BinderControl::BinderControl(EventDispatcher* dispatcher)
+    : next_unique_binder_adaptor_id_(0),
+      dispatcher_(dispatcher),
+      null_identifier_(kNullRpcIdentifier) {
+  // Watch Binder events in the main loop
+  brillo::BinderWatcher binder_watcher;
+  CHECK(binder_watcher.Init()) << "Binder FD watcher init failed";
+
+  // Also initialize D-Bus, which we will use alongside Binder for IPC with
+  // daemons that do not yet support Binder.
+  // TODO(samueltan): remove when shill is no longer dependent on DBus proxies.
+  dbus::Bus::Options options;
+  options.bus_type = dbus::Bus::SYSTEM;
+  proxy_bus_ = new dbus::Bus(options);
+  CHECK(proxy_bus_->Connect());
+}
+
+BinderControl::~BinderControl() {
+  // TODO(samueltan): remove when shill is no longer dependent on DBus proxies.
+  if (proxy_bus_) {
+    proxy_bus_->ShutdownAndBlock();
+  }
+}
+
+const string& BinderControl::NullRPCIdentifier() { return null_identifier_; }
+
+void BinderControl::RegisterManagerObject(
+    Manager* manager, const base::Closure& registration_done_callback) {
+  // Binder manager object registration is performed synchronously, and
+  // ManagerBinderAdaptor::RegisterAsync does not
+  // actually use the callback passed to it. However, since the caller of this
+  // function expects |registration_done_callback| to be called asynchronously,
+  // post the callback to the message loop ourselves.
+  manager->RegisterAsync(base::Callback<void(bool)>());
+  dispatcher_->PostTask(registration_done_callback);
+}
+
+DeviceAdaptorInterface* BinderControl::CreateDeviceAdaptor(Device* device) {
+  return CreateAdaptor<Device, DeviceAdaptorInterface, DeviceBinderAdaptor>(
+      device);
+}
+
+IPConfigAdaptorInterface* BinderControl::CreateIPConfigAdaptor(
+    IPConfig* config) {
+  return new IPConfigAdaptorStub(to_string(next_unique_binder_adaptor_id_++));
+}
+
+ManagerAdaptorInterface* BinderControl::CreateManagerAdaptor(Manager* manager) {
+  return CreateAdaptor<Manager, ManagerAdaptorInterface, ManagerBinderAdaptor>(
+      manager);
+}
+
+ProfileAdaptorInterface* BinderControl::CreateProfileAdaptor(Profile* profile) {
+  return new ProfileAdaptorStub(to_string(next_unique_binder_adaptor_id_++));
+}
+
+RPCTaskAdaptorInterface* BinderControl::CreateRPCTaskAdaptor(RPCTask* task) {
+  return new RPCTaskAdaptorStub(to_string(next_unique_binder_adaptor_id_++));
+}
+
+ServiceAdaptorInterface* BinderControl::CreateServiceAdaptor(Service* service) {
+  return CreateAdaptor<Service, ServiceAdaptorInterface, ServiceBinderAdaptor>(
+      service);
+}
+
+#ifndef DISABLE_VPN
+ThirdPartyVpnAdaptorInterface* BinderControl::CreateThirdPartyVpnAdaptor(
+    ThirdPartyVpnDriver* driver) {
+  return new ThirdPartyVpnAdaptorStub(
+      to_string(next_unique_binder_adaptor_id_++));
+}
+#endif
+
+RPCServiceWatcherInterface* BinderControl::CreateRPCServiceWatcher(
+    const string& connection_name,
+    const base::Closure& on_connection_vanished) {
+  return new ChromeosDBusServiceWatcher(proxy_bus_, connection_name,
+                                        on_connection_vanished);
+}
+
+PowerManagerProxyInterface* BinderControl::CreatePowerManagerProxy(
+    PowerManagerProxyDelegate* delegate,
+    const base::Closure& service_appeared_callback,
+    const base::Closure& service_vanished_callback) {
+  return new PowerManagerProxyStub();
+}
+
+#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
+SupplicantProcessProxyInterface* BinderControl::CreateSupplicantProcessProxy(
+    const base::Closure& service_appeared_callback,
+    const base::Closure& service_vanished_callback) {
+  return new ChromeosSupplicantProcessProxy(dispatcher_, proxy_bus_,
+                                            service_appeared_callback,
+                                            service_vanished_callback);
+}
+
+SupplicantInterfaceProxyInterface*
+BinderControl::CreateSupplicantInterfaceProxy(
+    SupplicantEventDelegateInterface* delegate, const string& object_path) {
+  return new ChromeosSupplicantInterfaceProxy(proxy_bus_, object_path,
+                                              delegate);
+}
+
+SupplicantNetworkProxyInterface* BinderControl::CreateSupplicantNetworkProxy(
+    const string& object_path) {
+  return new ChromeosSupplicantNetworkProxy(proxy_bus_, object_path);
+}
+#endif  // DISABLE_WIFI || DISABLE_WIRED_8021X
+
+#if !defined(DISABLE_WIFI)
+SupplicantBSSProxyInterface* BinderControl::CreateSupplicantBSSProxy(
+    WiFiEndpoint* wifi_endpoint, const string& object_path) {
+  return new ChromeosSupplicantBSSProxy(proxy_bus_, object_path, wifi_endpoint);
+}
+#endif  // DISABLE_WIFI
+
+DHCPCDListenerInterface* BinderControl::CreateDHCPCDListener(
+    DHCPProvider* provider) {
+  return new ChromeosDHCPCDListener(proxy_bus_, dispatcher_, provider);
+}
+
+DHCPProxyInterface* BinderControl::CreateDHCPProxy(const string& service) {
+  return new ChromeosDHCPCDProxy(proxy_bus_, service);
+}
+
+UpstartProxyInterface* BinderControl::CreateUpstartProxy() {
+  return new UpstartProxyStub();
+}
+
+FirewallProxyInterface* BinderControl::CreateFirewallProxy() {
+  return new ChromeosFirewalldProxy(proxy_bus_);
+}
+
+template <typename Object, typename AdaptorInterface, typename Adaptor>
+AdaptorInterface* BinderControl::CreateAdaptor(Object* object) {
+  return new Adaptor(object, to_string(next_unique_binder_adaptor_id_++));
+}
+
+}  // namespace shill
diff --git a/binder/binder_control.h b/binder/binder_control.h
new file mode 100644
index 0000000..e29b41e
--- /dev/null
+++ b/binder/binder_control.h
@@ -0,0 +1,110 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_BINDER_BINDER_CONTROL_H_
+#define SHILL_BINDER_BINDER_CONTROL_H_
+
+#include <map>
+#include <string>
+
+#include <binder/IBinder.h>
+#include <utils/StrongPointer.h>
+
+#include "shill/control_interface.h"
+
+namespace shill {
+
+class EventDispatcher;
+class Manager;
+
+class BinderControl : public ControlInterface {
+ public:
+  BinderControl(EventDispatcher* dispatcher);
+  ~BinderControl() override;
+
+  void RegisterManagerObject(
+      Manager* manager,
+      const base::Closure& registration_done_callback) override;
+  DeviceAdaptorInterface* CreateDeviceAdaptor(Device* device) override;
+  IPConfigAdaptorInterface* CreateIPConfigAdaptor(IPConfig* ipconfig) override;
+  ManagerAdaptorInterface* CreateManagerAdaptor(Manager* manager) override;
+  ProfileAdaptorInterface* CreateProfileAdaptor(Profile* profile) override;
+  RPCTaskAdaptorInterface* CreateRPCTaskAdaptor(RPCTask* task) override;
+  ServiceAdaptorInterface* CreateServiceAdaptor(Service* service) override;
+
+  const std::string& NullRPCIdentifier() override;
+
+  RPCServiceWatcherInterface* CreateRPCServiceWatcher(
+      const std::string& connection_name,
+      const base::Closure& on_connection_vanished) override;
+
+  // The caller retains ownership of 'delegate'.  It must not be deleted before
+  // the proxy.
+  PowerManagerProxyInterface* CreatePowerManagerProxy(
+      PowerManagerProxyDelegate* delegate,
+      const base::Closure& service_appeared_callback,
+      const base::Closure& service_vanished_callback) override;
+
+#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
+  SupplicantProcessProxyInterface* CreateSupplicantProcessProxy(
+      const base::Closure& service_appeared_callback,
+      const base::Closure& service_vanished_callback) override;
+
+  SupplicantInterfaceProxyInterface* CreateSupplicantInterfaceProxy(
+      SupplicantEventDelegateInterface* delegate,
+      const std::string& object_path) override;
+
+  SupplicantNetworkProxyInterface* CreateSupplicantNetworkProxy(
+      const std::string& object_path) override;
+#endif  // DISABLE_WIFI || DISABLE_WIRED_8021X
+
+#if !defined(DISABLE_WIFI)
+  // See comment in supplicant_bss_proxy.h, about bare pointer.
+  SupplicantBSSProxyInterface* CreateSupplicantBSSProxy(
+      WiFiEndpoint* wifi_endpoint, const std::string& object_path) override;
+#endif  // DISABLE_WIFI
+
+  UpstartProxyInterface* CreateUpstartProxy() override;
+
+  DHCPCDListenerInterface* CreateDHCPCDListener(
+      DHCPProvider* provider) override;
+
+  DHCPProxyInterface* CreateDHCPProxy(const std::string& service) override;
+
+  FirewallProxyInterface* CreateFirewallProxy() override;
+
+ private:
+  static const char kNullRpcIdentifier[];
+
+  template <typename Object, typename AdaptorInterface, typename Adaptor>
+  AdaptorInterface* CreateAdaptor(Object* object);
+
+  // This counter is used to assign unique IDs to binder adaptors. The string
+  // representation of this integer will assigned to as a unique ID to the next
+  // binder adaptor created. This unique ID will then be used as the Binder
+  // adaptor's RPC identifier.
+  uint32_t next_unique_binder_adaptor_id_;
+  std::map<std::string, android::sp<android::IBinder>> rpc_id_to_binder_map_;
+  EventDispatcher* dispatcher_;
+  std::string null_identifier_;
+
+  // TODO(samueltan): remove when shill is no longer dependent on DBus proxies.
+  scoped_refptr<dbus::Bus> proxy_bus_;
+};
+
+}  // namespace shill
+
+#endif  // SHILL_BINDER_BINDER_CONTROL_H_
diff --git a/binder/device_binder_adaptor.cc b/binder/device_binder_adaptor.cc
new file mode 100644
index 0000000..597aa2c
--- /dev/null
+++ b/binder/device_binder_adaptor.cc
@@ -0,0 +1,130 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/binder/device_binder_adaptor.h"
+
+#include <binder/Status.h>
+#include <utils/String16.h>
+
+#include "shill/device.h"
+#include "shill/logging.h"
+
+using android::binder::Status;
+using android::IBinder;
+using android::sp;
+using android::String16;
+using android::system::connectivity::shill::IPropertyChangedCallback;
+using std::string;
+using std::vector;
+
+namespace shill {
+
+namespace Logging {
+static auto kModuleLogScope = ScopeLogger::kBinder;
+static string ObjectID(DeviceBinderAdaptor* d) {
+  return "Device binder adaptor (id " + d->GetRpcIdentifier() + ", " +
+         d->device()->UniqueName() + ")";
+}
+}  // namespace Logging
+
+DeviceBinderAdaptor::DeviceBinderAdaptor(Device* device, const string& id)
+    : BinderAdaptor(id), device_(device) {}
+
+DeviceBinderAdaptor::~DeviceBinderAdaptor() { device_ = nullptr; }
+
+void DeviceBinderAdaptor::EmitBoolChanged(const string& name, bool /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitUintChanged(const string& name,
+                                          uint32_t /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitUint16Changed(const string& name,
+                                            uint16_t /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitIntChanged(const string& name, int /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitStringChanged(const string& name,
+                                            const string& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitStringmapChanged(const string& name,
+                                               const Stringmap& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitStringmapsChanged(const string& name,
+                                                const Stringmaps& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitStringsChanged(const string& name,
+                                             const Strings& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitKeyValueStoreChanged(
+    const string& name, const KeyValueStore& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitRpcIdentifierChanged(
+    const std::string& name, const std::string& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void DeviceBinderAdaptor::EmitRpcIdentifierArrayChanged(
+    const string& name, const vector<string>& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+Status DeviceBinderAdaptor::GetInterface(String16* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status DeviceBinderAdaptor::GetSelectedService(sp<IBinder>* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status DeviceBinderAdaptor::RegisterPropertyChangedSignalHandler(
+    const sp<IPropertyChangedCallback>& callback) {
+  AddPropertyChangedSignalHandler(callback);
+  return Status::ok();
+}
+
+}  // namespace shill
diff --git a/binder/device_binder_adaptor.h b/binder/device_binder_adaptor.h
new file mode 100644
index 0000000..c11a033
--- /dev/null
+++ b/binder/device_binder_adaptor.h
@@ -0,0 +1,102 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_BINDER_DEVICE_BINDER_ADAPTOR_H_
+#define SHILL_BINDER_DEVICE_BINDER_ADAPTOR_H_
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <utils/StrongPointer.h>
+
+#include "android/system/connectivity/shill/BnDevice.h"
+
+#include "shill/adaptor_interfaces.h"
+#include "shill/binder/binder_adaptor.h"
+
+namespace android {
+class String16;
+namespace binder {
+class Status;
+}  // namespace binder
+namespace system {
+namespace connectivity {
+namespace shill {
+class IPropertyChangedCallback;
+}  // namespace shill
+}  // namespace connectivity
+}  // namespace system
+}  // namespace android
+
+namespace shill {
+
+class Device;
+
+// There is a 1:1 mapping between Device and DeviceBinderAdaptor instances.
+// Furthermore, the Device owns the DeviceBinderAdaptor and manages its
+// lifetime, so we're OK with DeviceBinderAdaptor having a bare pointer to its
+// owner device.
+class DeviceBinderAdaptor
+    : public android::system::connectivity::shill::BnDevice,
+      public BinderAdaptor,
+      public DeviceAdaptorInterface {
+ public:
+DeviceBinderAdaptor(Device* device, const std::string& id);
+  ~DeviceBinderAdaptor() override;
+
+  // Implementation of DeviceAdaptorInterface.
+  const std::string& GetRpcIdentifier() override { return id(); }
+  void EmitBoolChanged(const std::string& name, bool value) override;
+  void EmitUintChanged(const std::string& name, uint32_t value) override;
+  void EmitUint16Changed(const std::string& name, uint16_t value) override;
+  void EmitIntChanged(const std::string& name, int value) override;
+  void EmitStringChanged(const std::string& name,
+                         const std::string& value) override;
+  void EmitStringmapChanged(const std::string& name,
+                            const Stringmap& value) override;
+  void EmitStringmapsChanged(const std::string& name,
+                             const Stringmaps& value) override;
+  void EmitStringsChanged(const std::string& name,
+                          const Strings& value) override;
+  void EmitKeyValueStoreChanged(const std::string& name,
+                                const KeyValueStore& value) override;
+  void EmitRpcIdentifierChanged(const std::string& name,
+                                const std::string& value) override;
+  void EmitRpcIdentifierArrayChanged(
+      const std::string& name, const std::vector<std::string>& value) override;
+
+  // Implementation of BnDevice.
+  android::binder::Status GetInterface(
+      android::String16* _aidl_return) override;
+  android::binder::Status GetSelectedService(
+      android::sp<IBinder>* _aidl_return) override;
+  android::binder::Status RegisterPropertyChangedSignalHandler(
+      const android::sp<
+          android::system::connectivity::shill::IPropertyChangedCallback>&
+          callback) override;
+
+  Device* device() const { return device_; }
+
+ private:
+  Device* device_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeviceBinderAdaptor);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_BINDER_DEVICE_BINDER_ADAPTOR_H_
diff --git a/binder/manager_binder_adaptor.cc b/binder/manager_binder_adaptor.cc
new file mode 100644
index 0000000..43ce1e6
--- /dev/null
+++ b/binder/manager_binder_adaptor.cc
@@ -0,0 +1,147 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/binder/manager_binder_adaptor.h"
+
+#include <binder/IServiceManager.h>
+#include <binder/Status.h>
+#include <utils/String16.h>
+
+#include "shill/logging.h"
+#include "shill/manager.h"
+
+using android::binder::Status;
+using android::defaultServiceManager;
+using android::IBinder;
+using android::sp;
+using android::String16;
+using android::system::connectivity::shill::IPropertyChangedCallback;
+using std::string;
+using std::vector;
+
+namespace shill {
+
+namespace Logging {
+static auto kModuleLogScope = ScopeLogger::kBinder;
+static string ObjectID(ManagerBinderAdaptor* m) {
+  return "Manager binder adaptor (id " + m->GetRpcIdentifier() + ")";
+}
+}  // namespace Logging
+
+ManagerBinderAdaptor::ManagerBinderAdaptor(Manager* manager,
+                                           const std::string& id)
+    : BinderAdaptor(id), manager_(manager) {}
+
+ManagerBinderAdaptor::~ManagerBinderAdaptor() { manager_ = nullptr; }
+
+void ManagerBinderAdaptor::RegisterAsync(
+    const base::Callback<void(bool)>& /*completion_callback*/) {
+  // Registration is performed synchronously in Binder.
+  defaultServiceManager()->addService(getInterfaceDescriptor(), this);
+}
+
+void ManagerBinderAdaptor::EmitBoolChanged(const string& name, bool /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ManagerBinderAdaptor::EmitUintChanged(const string& name,
+                                           uint32_t /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ManagerBinderAdaptor::EmitIntChanged(const string& name, int /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ManagerBinderAdaptor::EmitStringChanged(const string& name,
+                                             const string& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ManagerBinderAdaptor::EmitStringsChanged(const string& name,
+                                              const vector<string>& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ManagerBinderAdaptor::EmitRpcIdentifierChanged(const string& name,
+                                                    const string& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ManagerBinderAdaptor::EmitRpcIdentifierArrayChanged(
+    const string& name, const vector<string>& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+Status ManagerBinderAdaptor::SetupApModeInterface(String16* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  return Status::ok();
+}
+
+Status ManagerBinderAdaptor::SetupStationModeInterface(String16* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ManagerBinderAdaptor::ClaimInterface(const String16& claimer_name,
+                                            const String16& interface_name) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ManagerBinderAdaptor::ReleaseInterface(const String16& claimer_name,
+                                              const String16& interface_name) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ManagerBinderAdaptor::ConfigureService(
+    const android::os::PersistableBundle& properties,
+    sp<IBinder>* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ManagerBinderAdaptor::RequestScan(int32_t type) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ManagerBinderAdaptor::GetDevices(vector<sp<IBinder>>* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ManagerBinderAdaptor::RegisterPropertyChangedSignalHandler(
+    const sp<IPropertyChangedCallback>& callback) {
+  AddPropertyChangedSignalHandler(callback);
+  return Status::ok();
+}
+
+}  // namespace shill
diff --git a/binder/manager_binder_adaptor.h b/binder/manager_binder_adaptor.h
new file mode 100644
index 0000000..802df34
--- /dev/null
+++ b/binder/manager_binder_adaptor.h
@@ -0,0 +1,106 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_BINDER_MANAGER_BINDER_ADAPTOR_H_
+#define SHILL_BINDER_MANAGER_BINDER_ADAPTOR_H_
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <utils/StrongPointer.h>
+
+#include "android/system/connectivity/shill/BnManager.h"
+#include "shill/adaptor_interfaces.h"
+#include "shill/binder/binder_adaptor.h"
+
+namespace android {
+class String16;
+namespace binder {
+class Status;
+}  // namespace binder
+namespace system {
+namespace connectivity {
+namespace shill {
+class IPropertyChangedCallback;
+}  // namespace shill
+}  // namespace connectivity
+}  // namespace system
+}  // namespace android
+
+namespace shill {
+
+class Manager;
+
+// Subclass of BinderAdaptor for Manager objects
+// There is a 1:1 mapping between Manager and ManagerBinderAdaptor
+// instances.  Furthermore, the Manager owns the ManagerBinderAdaptor
+// and manages its lifetime, so we're OK with ManagerBinderAdaptor
+// having a bare pointer to its owner manager.
+class ManagerBinderAdaptor
+    : public android::system::connectivity::shill::BnManager,
+      public BinderAdaptor,
+      public ManagerAdaptorInterface {
+ public:
+  ManagerBinderAdaptor(Manager* manager, const std::string& id);
+  ~ManagerBinderAdaptor() override;
+
+  // Implementation of ManagerAdaptorInterface.
+  void RegisterAsync(
+      const base::Callback<void(bool)>& completion_callback) override;
+  const std::string& GetRpcIdentifier() override { return id(); }
+  void EmitBoolChanged(const std::string& name, bool value) override;
+  void EmitUintChanged(const std::string& name, uint32_t value) override;
+  void EmitIntChanged(const std::string& name, int value) override;
+  void EmitStringChanged(const std::string& name,
+                         const std::string& value) override;
+  void EmitStringsChanged(const std::string& name,
+                          const std::vector<std::string>& value) override;
+  void EmitRpcIdentifierChanged(
+      const std::string& name, const std::string& value) override;
+  void EmitRpcIdentifierArrayChanged(
+      const std::string& name, const std::vector<std::string>& value) override;
+
+  // Implementation of BnManager.
+  android::binder::Status SetupApModeInterface(android::String16* _aidl_return);
+  android::binder::Status SetupStationModeInterface(
+      android::String16* _aidl_return);
+  android::binder::Status ClaimInterface(
+      const android::String16& claimer_name,
+      const android::String16& interface_name);
+  android::binder::Status ReleaseInterface(
+      const android::String16& claimer_name,
+      const android::String16& interface_name);
+  android::binder::Status ConfigureService(
+      const android::os::PersistableBundle& properties,
+      android::sp<android::IBinder>* _aidl_return);
+  android::binder::Status RequestScan(int32_t type);
+  android::binder::Status GetDevices(
+      ::std::vector<android::sp<android::IBinder>>* _aidl_return);
+  android::binder::Status RegisterPropertyChangedSignalHandler(
+      const android::sp<
+          android::system::connectivity::shill::IPropertyChangedCallback>&
+          callback);
+
+ private:
+  Manager* manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(ManagerBinderAdaptor);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_BINDER_MANAGER_BINDER_ADAPTOR_H_
diff --git a/binder/service_binder_adaptor.cc b/binder/service_binder_adaptor.cc
new file mode 100644
index 0000000..7742628
--- /dev/null
+++ b/binder/service_binder_adaptor.cc
@@ -0,0 +1,128 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/binder/service_binder_adaptor.h"
+
+#include <binder/Status.h>
+
+#include "shill/logging.h"
+#include "shill/service.h"
+
+using android::binder::Status;
+using android::IBinder;
+using android::sp;
+using android::system::connectivity::shill::IPropertyChangedCallback;
+using std::string;
+
+namespace shill {
+
+namespace Logging {
+static auto kModuleLogScope = ScopeLogger::kBinder;
+static string ObjectID(ServiceBinderAdaptor* s) {
+  return "Service binder adaptor (id " + s->GetRpcIdentifier() + ", " +
+         s->service()->unique_name() + ")";
+}
+}  // namespace Logging
+
+ServiceBinderAdaptor::ServiceBinderAdaptor(Service* service,
+                                           const std::string& id)
+    : BinderAdaptor(id), service_(service) {}
+
+ServiceBinderAdaptor::~ServiceBinderAdaptor() { service_ = nullptr; }
+
+void ServiceBinderAdaptor::EmitBoolChanged(const string& name, bool /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ServiceBinderAdaptor::EmitUint8Changed(const string& name,
+                                            uint8_t /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ServiceBinderAdaptor::EmitUint16Changed(const string& name,
+                                             uint16_t /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ServiceBinderAdaptor::EmitUint16sChanged(const string& name,
+                                              const Uint16s& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ServiceBinderAdaptor::EmitUintChanged(const string& name,
+                                           uint32_t /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ServiceBinderAdaptor::EmitIntChanged(const string& name, int /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ServiceBinderAdaptor::EmitRpcIdentifierChanged(const string& name,
+                                                    const string& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ServiceBinderAdaptor::EmitStringChanged(const string& name,
+                                             const string& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+void ServiceBinderAdaptor::EmitStringmapChanged(const string& name,
+                                                const Stringmap& /*value*/) {
+  SLOG(this, 2) << __func__ << ": " << name;
+  SendPropertyChangedSignal(name);
+}
+
+Status ServiceBinderAdaptor::Connect() {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ServiceBinderAdaptor::GetState(int32_t* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ServiceBinderAdaptor::GetStrength(int8_t* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ServiceBinderAdaptor::GetError(int32_t* _aidl_return) {
+  // STUB IMPLEMENTATION.
+  // TODO(samueltan): replace this with proper implementation.
+  return Status::ok();
+}
+
+Status ServiceBinderAdaptor::RegisterPropertyChangedSignalHandler(
+    const sp<IPropertyChangedCallback>& callback) {
+  AddPropertyChangedSignalHandler(callback);
+  return Status::ok();
+}
+
+}  // namespace shill
diff --git a/binder/service_binder_adaptor.h b/binder/service_binder_adaptor.h
new file mode 100644
index 0000000..535f7af
--- /dev/null
+++ b/binder/service_binder_adaptor.h
@@ -0,0 +1,95 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_BINDER_SERVICE_BINDER_ADAPTOR_H_
+#define SHILL_BINDER_SERVICE_BINDER_ADAPTOR_H_
+
+#include <string>
+
+#include <base/macros.h>
+#include <utils/StrongPointer.h>
+
+#include "android/system/connectivity/shill/BnService.h"
+#include "shill/adaptor_interfaces.h"
+#include "shill/binder/binder_adaptor.h"
+
+namespace android {
+namespace binder {
+class Status;
+}  // namespace binder
+namespace system {
+namespace connectivity {
+namespace shill {
+class IPropertyChangedCallback;
+}  // namespace shill
+}  // namespace connectivity
+}  // namespace system
+}  // namespace android
+
+namespace shill {
+
+class Service;
+
+// Subclass of DBusAdaptor for Service objects
+// There is a 1:1 mapping between Service and ServiceBinderAdaptor
+// instances.  Furthermore, the Service owns the ServiceBinderAdaptor
+// and manages its lifetime, so we're OK with ServiceBinderAdaptor
+// having a bare pointer to its owner service.
+class ServiceBinderAdaptor
+    : public android::system::connectivity::shill::BnService,
+      public BinderAdaptor,
+      public ServiceAdaptorInterface {
+ public:
+  ServiceBinderAdaptor(Service* service, const std::string& id);
+  ~ServiceBinderAdaptor() override;
+
+  // Implementation of ServiceAdaptorInterface.
+  const std::string& GetRpcIdentifier() override { return id(); }
+  void EmitBoolChanged(const std::string& name, bool value) override;
+  void EmitUint8Changed(const std::string& name, uint8_t value) override;
+  void EmitUint16Changed(const std::string& name, uint16_t value) override;
+  void EmitUint16sChanged(const std::string& name,
+                          const Uint16s& value) override;
+  void EmitUintChanged(const std::string& name, uint32_t value) override;
+  void EmitIntChanged(const std::string& name, int value) override;
+  void EmitRpcIdentifierChanged(
+      const std::string& name, const std::string& value) override;
+  void EmitStringChanged(
+      const std::string& name, const std::string& value) override;
+  void EmitStringmapChanged(const std::string& name,
+                            const Stringmap& value) override;
+
+  // Implementation of BnService.
+  android::binder::Status Connect();
+  android::binder::Status GetState(int32_t* _aidl_return);
+  android::binder::Status GetStrength(int8_t* _aidl_return);
+  android::binder::Status GetError(int32_t* _aidl_return);
+  android::binder::Status RegisterPropertyChangedSignalHandler(
+      const android::sp<
+          android::system::connectivity::shill::IPropertyChangedCallback>&
+          callback);
+
+  Service* service() const { return service_; }
+
+ private:
+  Service* service_;
+
+  DISALLOW_COPY_AND_ASSIGN(ServiceBinderAdaptor);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_BINDER_SERVICE_BINDER_ADAPTOR_H_
diff --git a/chromeos_daemon.cc b/chromeos_daemon.cc
index 6acf8b8..5c32755 100644
--- a/chromeos_daemon.cc
+++ b/chromeos_daemon.cc
@@ -27,9 +27,11 @@
 #endif
 
 #include "shill/control_interface.h"
-#if defined(ENABLE_CHROMEOS_DBUS)
+#if defined(ENABLE_BINDER)
+#include "shill/binder/binder_control.h"
+#elif defined(ENABLE_CHROMEOS_DBUS)
 #include "shill/dbus/chromeos_dbus_control.h"
-#endif  // ENABLE_CHROMEOS_DBUS
+#endif  // ENABLE_BINDER, ENABLE_CHROMEOS_DBUS
 #include "shill/dhcp/dhcp_provider.h"
 #include "shill/error.h"
 #include "shill/logging.h"
@@ -180,12 +182,14 @@
   }
 
   dispatcher_.reset(new EventDispatcher());
-#if defined(ENABLE_CHROMEOS_DBUS)
+#if defined(ENABLE_BINDER)
+  control_.reset(new BinderControl(dispatcher_.get()));
+#elif defined(ENABLE_CHROMEOS_DBUS)
   control_.reset(new ChromeosDBusControl(dispatcher_.get()));
 #else
   // TODO(zqiu): use default stub control interface.
 #error Control interface type not specified.
-#endif  // ENABLE_CHROMEOS_DBUS
+#endif  // ENABLE_BINDER, ENABLE_CHROMEOS_DBUS
   metrics_.reset(new Metrics(dispatcher_.get()));
   rtnl_handler_ = RTNLHandler::GetInstance();
   routing_table_ = RoutingTable::GetInstance();
diff --git a/dbus/chromeos_dbus_control.h b/dbus/chromeos_dbus_control.h
index d71eafd..2806926 100644
--- a/dbus/chromeos_dbus_control.h
+++ b/dbus/chromeos_dbus_control.h
@@ -29,7 +29,6 @@
 class EventDispatcher;
 class Manager;
 
-// This is the Interface for the  DBus control channel for Shill.
 class ChromeosDBusControl : public ControlInterface {
  public:
   ChromeosDBusControl(EventDispatcher* dispatcher);
diff --git a/ipconfig_adaptor_stub.cc b/ipconfig_adaptor_stub.cc
new file mode 100644
index 0000000..c9edbda
--- /dev/null
+++ b/ipconfig_adaptor_stub.cc
@@ -0,0 +1,25 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/ipconfig_adaptor_stub.h"
+
+namespace shill {
+
+IPConfigAdaptorStub::IPConfigAdaptorStub(const std::string& id)
+    : AdaptorStub(id) {}
+
+}  // namespace shill
+
diff --git a/ipconfig_adaptor_stub.h b/ipconfig_adaptor_stub.h
new file mode 100644
index 0000000..4fb63dc
--- /dev/null
+++ b/ipconfig_adaptor_stub.h
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_IPCONFIG_ADAPTOR_STUB_H_
+#define SHILL_IPCONFIG_ADAPTOR_STUB_H_
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+
+#include "shill/adaptor_interfaces.h"
+#include "shill/adaptor_stub.h"
+
+namespace shill {
+
+class IPConfigAdaptorStub : public AdaptorStub,
+                            public IPConfigAdaptorInterface {
+ public:
+  explicit IPConfigAdaptorStub(const std::string& id);
+
+  const std::string& GetRpcIdentifier() override { return rpc_id(); }
+  void EmitBoolChanged(const std::string& name, bool value) override {};
+  void EmitUintChanged(const std::string& name, uint32_t value) override {};
+  void EmitIntChanged(const std::string& name, int value) override {};
+  void EmitStringChanged(const std::string& name,
+                         const std::string& value) override {};
+  void EmitStringsChanged(const std::string& name,
+                          const std::vector<std::string>& value) override {};
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(IPConfigAdaptorStub);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_IPCONFIG_ADAPTOR_STUB_H_
diff --git a/profile_adaptor_stub.cc b/profile_adaptor_stub.cc
new file mode 100644
index 0000000..3452962
--- /dev/null
+++ b/profile_adaptor_stub.cc
@@ -0,0 +1,24 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/profile_adaptor_stub.h"
+
+namespace shill {
+
+ProfileAdaptorStub::ProfileAdaptorStub(const std::string& id)
+    : AdaptorStub(id) {}
+
+}  // namespace shill
diff --git a/profile_adaptor_stub.h b/profile_adaptor_stub.h
new file mode 100644
index 0000000..00fbbe7
--- /dev/null
+++ b/profile_adaptor_stub.h
@@ -0,0 +1,46 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_PROFILE_ADAPTOR_STUB_H_
+#define SHILL_PROFILE_ADAPTOR_STUB_H_
+
+#include <string>
+
+#include <base/macros.h>
+
+#include "shill/adaptor_interfaces.h"
+#include "shill/adaptor_stub.h"
+
+namespace shill {
+
+class ProfileAdaptorStub : public AdaptorStub, public ProfileAdaptorInterface {
+ public:
+  explicit ProfileAdaptorStub(const std::string& id);
+
+  const std::string& GetRpcIdentifier() override { return rpc_id(); }
+  void EmitBoolChanged(const std::string& name, bool value) override {}
+  void EmitUintChanged(const std::string& name, uint32_t value) override {}
+  void EmitIntChanged(const std::string& name, int value) override {}
+  void EmitStringChanged(const std::string& name,
+                         const std::string& value) override {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProfileAdaptorStub);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_PROFILE_ADAPTOR_STUB_H_
diff --git a/rpc_task_adaptor_stub.cc b/rpc_task_adaptor_stub.cc
new file mode 100644
index 0000000..36f8bda
--- /dev/null
+++ b/rpc_task_adaptor_stub.cc
@@ -0,0 +1,25 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/rpc_task_adaptor_stub.h"
+
+namespace shill {
+
+RPCTaskAdaptorStub::RPCTaskAdaptorStub(const std::string& id)
+    : AdaptorStub(id) {}
+
+}  // namespace shill
+
diff --git a/rpc_task_adaptor_stub.h b/rpc_task_adaptor_stub.h
new file mode 100644
index 0000000..c991649
--- /dev/null
+++ b/rpc_task_adaptor_stub.h
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_RPC_TASK_ADAPTOR_STUB_H_
+#define SHILL_RPC_TASK_ADAPTOR_STUB_H_
+
+#include <string>
+
+#include <base/macros.h>
+
+#include "shill/adaptor_interfaces.h"
+#include "shill/adaptor_stub.h"
+
+namespace shill {
+
+class RPCTaskAdaptorStub : public AdaptorStub, public RPCTaskAdaptorInterface {
+ public:
+  explicit RPCTaskAdaptorStub(const std::string& id);
+
+  const std::string& GetRpcIdentifier() override { return rpc_id(); }
+  const std::string& GetRpcConnectionIdentifier() override { return rpc_id(); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(RPCTaskAdaptorStub);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_RPC_TASK_ADAPTOR_STUB_H_
diff --git a/third_party_vpn_adaptor_stub.cc b/third_party_vpn_adaptor_stub.cc
new file mode 100644
index 0000000..e2255b3
--- /dev/null
+++ b/third_party_vpn_adaptor_stub.cc
@@ -0,0 +1,25 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "shill/third_party_vpn_adaptor_stub.h"
+
+namespace shill {
+
+ThirdPartyVpnAdaptorStub::ThirdPartyVpnAdaptorStub(const std::string& id)
+    : AdaptorStub(id) {}
+
+}  // namespace shill
+
diff --git a/third_party_vpn_adaptor_stub.h b/third_party_vpn_adaptor_stub.h
new file mode 100644
index 0000000..190baf8
--- /dev/null
+++ b/third_party_vpn_adaptor_stub.h
@@ -0,0 +1,43 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef SHILL_THIRD_PARTY_VPN_ADAPTOR_STUB_H_
+#define SHILL_THIRD_PARTY_VPN_ADAPTOR_STUB_H_
+
+#include <vector>
+
+#include <base/macros.h>
+
+#include "shill/adaptor_interfaces.h"
+#include "shill/adaptor_stub.h"
+
+namespace shill {
+
+class ThirdPartyVpnAdaptorStub : public AdaptorStub,
+                                 public ThirdPartyVpnAdaptorInterface {
+ public:
+  explicit ThirdPartyVpnAdaptorStub(const std::string& id);
+
+  void EmitPacketReceived(const std::vector<uint8_t>& packet) override {}
+  void EmitPlatformMessage(uint32_t message) override {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ThirdPartyVpnAdaptorStub);
+};
+
+}  // namespace shill
+
+#endif  // SHILL_THIRD_PARTY_VPN_ADAPTOR_STUB_H_