Add BinderWatcher.

Add a class that bridges between base::MessageLoop and
libbinder. When instantiated, the binder FD will be watched
and libbinder will be notified about transactions.

Change-Id: If68d2765fa5161196489c4004360f2d0c56e59d0
diff --git a/Android.mk b/Android.mk
index 2a6f1b6..a68f68e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -38,7 +38,10 @@
     chromeos/strings/string_utils.cc \
     chromeos/syslog_logging.cc \
     chromeos/type_name_undecorate.cc \
-    chromeos/url_utils.cc
+    chromeos/url_utils.cc \
+
+libchromeos_binder_sources := \
+    chromeos/binder_watcher.cc \
 
 libchromeos_dbus_sources := \
     chromeos/any.cc \
@@ -52,7 +55,7 @@
     chromeos/dbus/dbus_signal.cc \
     chromeos/dbus/exported_object_manager.cc \
     chromeos/dbus/exported_property_set.cc \
-    chromeos/dbus/utils.cc
+    chromeos/dbus/utils.cc \
 
 libchromeos_http_sources := \
     chromeos/http/curl_api.cc \
@@ -61,11 +64,11 @@
     chromeos/http/http_request.cc \
     chromeos/http/http_transport.cc \
     chromeos/http/http_transport_curl.cc \
-    chromeos/http/http_utils.cc
+    chromeos/http/http_utils.cc \
 
 libchromeos_policy_sources := \
     policy/device_policy.cc \
-    policy/libpolicy.cc
+    policy/libpolicy.cc \
 
 libchromeos_stream_sources := \
     chromeos/streams/file_stream.cc \
@@ -76,7 +79,7 @@
     chromeos/streams/stream.cc \
     chromeos/streams/stream_errors.cc \
     chromeos/streams/stream_utils.cc \
-    chromeos/streams/tls_stream.cc
+    chromeos/streams/tls_stream.cc \
 
 libchromeos_test_helpers_sources := \
     chromeos/http/http_connection_fake.cc \
@@ -113,7 +116,7 @@
     chromeos/streams/stream_unittest.cc \
     chromeos/streams/stream_utils_unittest.cc \
     chromeos/strings/string_utils_unittest.cc \
-    chromeos/url_utils_unittest.cc
+    chromeos/url_utils_unittest.cc \
 
 libchromeos_CFLAGS := -Wall \
     -Wno-char-subscripts -Wno-missing-field-initializers \
@@ -139,6 +142,22 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
 include $(BUILD_SHARED_LIBRARY)
 
+# Shared binder library for target
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_CPP_EXTENSION := $(libchromeos_cpp_extension)
+LOCAL_MODULE := libchromeos-binder
+LOCAL_SRC_FILES := $(libchromeos_binder_sources)
+LOCAL_C_INCLUDES := $(libchromeos_includes)
+LOCAL_SHARED_LIBRARIES := $(libchromeos_shared_libraries) \
+    libbinder libutils
+LOCAL_CFLAGS := $(libchromeos_CFLAGS)
+LOCAL_CPPFLAGS := $(libchromeos_CPPFLAGS)
+LOCAL_RTTI_FLAG := -frtti
+LOCAL_CLANG := true
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+include $(BUILD_SHARED_LIBRARY)
+
 # Shared dbus library for target
 # ========================================================
 include $(CLEAR_VARS)
diff --git a/chromeos/binder_watcher.cc b/chromeos/binder_watcher.cc
new file mode 100644
index 0000000..30e7754
--- /dev/null
+++ b/chromeos/binder_watcher.cc
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 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 <chromeos/binder_watcher.h>
+
+#include <base/logging.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+
+using android::IPCThreadState;
+using android::ProcessState;
+
+namespace chromeos {
+
+BinderWatcher::BinderWatcher() = default;
+
+BinderWatcher::~BinderWatcher() = default;
+
+bool BinderWatcher::Init() {
+  int binder_fd = -1;
+  ProcessState::self()->setThreadPoolMaxThreadCount(0);
+  IPCThreadState::self()->disableBackgroundScheduling(true);
+  IPCThreadState::self()->setupPolling(&binder_fd);
+  LOG(INFO) << "Got binder FD " << binder_fd;
+  if (binder_fd < 0)
+    return false;
+
+  if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
+          binder_fd, true /* persistent */, base::MessageLoopForIO::WATCH_READ,
+          &watcher_, this)) {
+    LOG(ERROR) << "Failed to watch binder FD";
+    return false;
+  }
+  return true;
+}
+
+void BinderWatcher::OnFileCanReadWithoutBlocking(int fd) {
+  IPCThreadState::self()->handlePolledCommands();
+}
+
+void BinderWatcher::OnFileCanWriteWithoutBlocking(int fd) {
+  NOTREACHED() << "Unexpected writable notification for FD " << fd;
+}
+
+}  // namespace chromeos
diff --git a/chromeos/binder_watcher.h b/chromeos/binder_watcher.h
new file mode 100644
index 0000000..198f4f8
--- /dev/null
+++ b/chromeos/binder_watcher.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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 LIBCHROMEOS_CHROMEOS_BINDER_WATCHER_H_
+#define LIBCHROMEOS_CHROMEOS_BINDER_WATCHER_H_
+
+#include <base/macros.h>
+#include <base/message_loop/message_loop.h>
+
+namespace chromeos {
+
+// Bridge between libbinder and base::MessageLoop. Construct at startup to make
+// the message loop watch for binder events and pass them to libbinder.
+class BinderWatcher : public base::MessageLoopForIO::Watcher {
+ public:
+  BinderWatcher();
+  ~BinderWatcher() override;
+
+  // Initializes the object, returning true on success.
+  bool Init();
+
+  // base::MessageLoopForIO::Watcher:
+  void OnFileCanReadWithoutBlocking(int fd) override;
+  void OnFileCanWriteWithoutBlocking(int fd) override;
+
+ private:
+  base::MessageLoopForIO::FileDescriptorWatcher watcher_;
+
+  DISALLOW_COPY_AND_ASSIGN(BinderWatcher);
+};
+
+}  // namespace chromeos
+
+#endif  // LIBCHROMEOS_CHROMEOS_BINDER_WATCHER_H_