Embed candidate_window into chrome.

To prevent a build error of the chromeos-chrome package, I'd keep the candidate_window binary for now, but the size of the binary is now ~4k.

This CL is based on satorux's work:
http://codereview.chromium.org/4543002/

BUG=chromium-os:11191
TEST=manually checked that IME candidate window works without the process

Review URL: http://codereview.chromium.org/6259019

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72934 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/cros/cros_mock.cc b/chrome/browser/chromeos/cros/cros_mock.cc
index a5d8a38..a9cfe4d 100644
--- a/chrome/browser/chromeos/cros/cros_mock.cc
+++ b/chrome/browser/chromeos/cros/cros_mock.cc
@@ -254,7 +254,7 @@
   EXPECT_CALL(*mock_input_method_library_, SetDeferImeStartup(_))
       .Times(AnyNumber())
       .RetiresOnSaturation();
-  EXPECT_CALL(*mock_input_method_library_, StopInputMethodProcesses())
+  EXPECT_CALL(*mock_input_method_library_, StopInputMethodDaemon())
       .Times(AnyNumber())
       .RetiresOnSaturation();
 }
diff --git a/chrome/browser/chromeos/cros/input_method_library.cc b/chrome/browser/chromeos/cros/input_method_library.cc
index ab2dc48..ac73cbdd 100644
--- a/chrome/browser/chromeos/cros/input_method_library.cc
+++ b/chrome/browser/chromeos/cros/input_method_library.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/browser_thread.h"
 #include "chrome/browser/chromeos/cros/cros_library.h"
 #include "chrome/browser/chromeos/cros/keyboard_library.h"
+#include "chrome/browser/chromeos/input_method/candidate_window.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/chromeos/language_preferences.h"
 #include "chrome/common/notification_observer.h"
@@ -25,7 +26,6 @@
 namespace {
 
 const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon";
-const char kCandidateWindowPath[] = "/opt/google/chrome/candidate_window";
 
 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the
 // property with |new_prop|. Returns true if such a property is found.
@@ -62,7 +62,7 @@
         enable_auto_ime_shutdown_(true),
         should_change_input_method_(false),
         ibus_daemon_process_id_(0),
-        candidate_window_process_id_(0) {
+        candidate_window_controller_(NULL) {
     // TODO(yusukes): Using both CreateFallbackInputMethodDescriptors and
     // chromeos::GetHardwareKeyboardLayoutName doesn't look clean. Probably
     // we should unify these APIs.
@@ -72,8 +72,8 @@
     if (CrosLibrary::Get()->EnsureLoaded()) {
       current_input_method_id_ = chromeos::GetHardwareKeyboardLayoutName();
     }
-    // Observe APP_EXITING to stop input method processes gracefully.
-    // Note that even if we fail to stop input method processes from
+    // Observe APP_EXITING to stop input method daemon gracefully.
+    // Note that even if we fail to stop input method daemon from
     // Chrome in case of a sudden crash, we have a way to do it from an
     // upstart script. See crosbug.com/6515 and crosbug.com/6995 for
     // details.
@@ -126,7 +126,7 @@
     current_input_method_id_ = input_method_id;
     if (EnsureLoadedAndStarted()) {
       if (input_method_id != chromeos::GetHardwareKeyboardLayoutName()) {
-        StartInputMethodProcesses();
+        StartInputMethodDaemon();
       }
       ChangeInputMethodInternal(input_method_id);
     }
@@ -166,7 +166,7 @@
   bool SetImeConfig(const std::string& section, const std::string& config_name,
                     const ImeConfigValue& value) {
     // Before calling FlushImeConfig(), start input method process if necessary.
-    MaybeStartInputMethodProcesses(section, config_name, value);
+    MaybeStartInputMethodDaemon(section, config_name, value);
 
     const ConfigKeyType key = std::make_pair(section, config_name);
     current_config_values_[key] = value;
@@ -176,7 +176,7 @@
     }
 
     // Stop input method process if necessary.
-    MaybeStopInputMethodProcesses(section, config_name, value);
+    MaybeStopInputMethodDaemon(section, config_name, value);
     return pending_config_requests_.empty();
   }
 
@@ -199,12 +199,12 @@
   }
 
  private:
-  // Starts input method processes based on the |defer_ime_startup_| flag and
+  // Starts input method daemon based on the |defer_ime_startup_| flag and
   // input method configuration being updated. |section| is a section name of
   // the input method configuration (e.g. "general", "general/hotkey").
   // |config_name| is a name of the configuration (e.g. "preload_engines",
   // "previous_engine"). |value| is the configuration value to be set.
-  void MaybeStartInputMethodProcesses(const std::string& section,
+  void MaybeStartInputMethodDaemon(const std::string& section,
                                       const std::string& config_name,
                                       const ImeConfigValue& value) {
     if (section == language_prefs::kGeneralSectionName &&
@@ -217,19 +217,19 @@
               value.string_list_value[0] == hardware_layout_name) &&
             !defer_ime_startup_) {
           // If there are no input methods other than one for the hardware
-          // keyboard, we don't start the input method processes.
+          // keyboard, we don't start the input method daemon.
           // When |defer_ime_startup_| is true, we don't start it either.
-          StartInputMethodProcesses();
+          StartInputMethodDaemon();
         }
         chromeos::SetActiveInputMethods(input_method_status_connection_, value);
       }
     }
   }
 
-  // Stops input method processes based on the |enable_auto_ime_shutdown_| flag
+  // Stops input method daemon based on the |enable_auto_ime_shutdown_| flag
   // and input method configuration being updated.
-  // See also: MaybeStartInputMethodProcesses().
-  void MaybeStopInputMethodProcesses(const std::string& section,
+  // See also: MaybeStartInputMethodDaemon().
+  void MaybeStopInputMethodDaemon(const std::string& section,
                                      const std::string& config_name,
                                      const ImeConfigValue& value) {
     if (section == language_prefs::kGeneralSectionName &&
@@ -243,8 +243,8 @@
             enable_auto_ime_shutdown_) {
           // If there are no input methods other than one for the hardware
           // keyboard, and |enable_auto_ime_shutdown_| is true, we'll stop the
-          // input method processes.
-          StopInputMethodProcesses();
+          // input method daemon.
+          StopInputMethodDaemon();
         }
         chromeos::SetActiveInputMethods(input_method_status_connection_, value);
       }
@@ -483,9 +483,9 @@
     current_ime_properties_ = prop_list;
   }
 
-  void StartInputMethodProcesses() {
+  void StartInputMethodDaemon() {
     should_launch_ime_ = true;
-    MaybeLaunchInputMethodProcesses();
+    MaybeLaunchInputMethodDaemon();
   }
 
   void UpdateProperty(const ImePropertyList& prop_list) {
@@ -530,33 +530,27 @@
     return  true;
   }
 
-  // Launches input method processes if these are not yet running.
-  void MaybeLaunchInputMethodProcesses() {
+  // Launches input method daemon if these are not yet running.
+  void MaybeLaunchInputMethodDaemon() {
     if (!should_launch_ime_) {
       return;
     }
 
+    if (!candidate_window_controller_.get()) {
+      candidate_window_controller_.reset(new CandidateWindowController);
+      if (!candidate_window_controller_->Init()) {
+        LOG(WARNING) << "Failed to initialize the candidate window controller";
+      }
+    }
+
     if (ibus_daemon_process_id_ == 0) {
       // TODO(zork): Send output to /var/log/ibus.log
       const std::string ibus_daemon_command_line =
           StringPrintf("%s --panel=disable --cache=none --restart --replace",
                        kIBusDaemonPath);
-      if (!LaunchInputMethodProcess(ibus_daemon_command_line,
-                                    &ibus_daemon_process_id_)) {
-        // On failure, we should not attempt to launch candidate_window.
-        return;
-      }
-    }
-
-    if (candidate_window_process_id_ == 0) {
-      // Pass the UI language info to candidate_window via --lang flag.
-      const std::string candidate_window_command_line =
-          StringPrintf("%s --lang=%s", kCandidateWindowPath,
-                       g_browser_process->GetApplicationLocale().c_str());
-      if (!LaunchInputMethodProcess(candidate_window_command_line,
-                                    &candidate_window_process_id_)) {
-        // Return here just in case we add more code below.
-        return;
+      if (!LaunchInputMethodProcess(
+              ibus_daemon_command_line, &ibus_daemon_process_id_)) {
+        LOG(ERROR) << "Failed to launch " << ibus_daemon_command_line;
       }
     }
   }
@@ -567,15 +561,13 @@
     g_spawn_close_pid(pid);
     if (library->ibus_daemon_process_id_ == pid) {
       library->ibus_daemon_process_id_ = 0;
-    } else if (library->candidate_window_process_id_ == pid) {
-      library->candidate_window_process_id_ = 0;
     }
 
-    // Restart input method processes if needed.
-    library->MaybeLaunchInputMethodProcesses();
+    // Restart input method daemon if needed.
+    library->MaybeLaunchInputMethodDaemon();
   }
 
-  void StopInputMethodProcesses() {
+  void StopInputMethodDaemon() {
     should_launch_ime_ = false;
     if (ibus_daemon_process_id_) {
       const std::string xkb_engine_name =
@@ -594,12 +586,6 @@
               << "terminated";
       ibus_daemon_process_id_ = 0;
     }
-    if (candidate_window_process_id_) {
-      kill(candidate_window_process_id_, SIGTERM);
-      VLOG(1) << "candidate_window (PID=" << candidate_window_process_id_
-              << ") is terminated";
-      candidate_window_process_id_ = 0;
-    }
   }
 
   void SetDeferImeStartup(bool defer) {
@@ -615,9 +601,9 @@
   void Observe(NotificationType type,
                const NotificationSource& source,
                const NotificationDetails& details) {
-    // Stop the input processes on browser shutdown.
+    // Stop the input method daemon on browser shutdown.
     if (type.value == NotificationType::APP_EXITING) {
-      StopInputMethodProcesses();
+      StopInputMethodDaemon();
     }
   }
 
@@ -654,14 +640,14 @@
   // This is used to register this object to APP_EXITING notification.
   NotificationRegistrar notification_registrar_;
 
-  // True if we should launch the input method processes.
+  // True if we should launch the input method daemon.
   bool should_launch_ime_;
   // True if the connection to the IBus daemon is alive.
   bool ime_connected_;
   // If true, we'll defer the startup until a non-default method is
   // activated.
   bool defer_ime_startup_;
-  // True if we should stop input method processes when there are no input
+  // True if we should stop input method daemon when there are no input
   // methods other than one for the hardware keyboard.
   bool enable_auto_ime_shutdown_;
   // The ID of the current input method (ex. "mozc").
@@ -673,8 +659,9 @@
   // The process id of the IBus daemon. 0 if it's not running. The process
   // ID 0 is not used in Linux, hence it's safe to use 0 for this purpose.
   int ibus_daemon_process_id_;
-  // The process id of the candidate window. 0 if it's not running.
-  int candidate_window_process_id_;
+
+  // The candidate window.
+  scoped_ptr<CandidateWindowController> candidate_window_controller_;
 
   DISALLOW_COPY_AND_ASSIGN(InputMethodLibraryImpl);
 };
@@ -740,8 +727,8 @@
     return current_ime_properties_;
   }
 
-  virtual void StartInputMethodProcesses() {}
-  virtual void StopInputMethodProcesses() {}
+  virtual void StartInputMethodDaemon() {}
+  virtual void StopInputMethodDaemon() {}
   virtual void SetDeferImeStartup(bool defer) {}
   virtual void SetEnableAutoImeShutdown(bool enable) {}
 
diff --git a/chrome/browser/chromeos/cros/input_method_library.h b/chrome/browser/chromeos/cros/input_method_library.h
index 26df7a77..07b07efa0 100644
--- a/chrome/browser/chromeos/cros/input_method_library.h
+++ b/chrome/browser/chromeos/cros/input_method_library.h
@@ -106,11 +106,11 @@
   virtual std::string GetKeyboardOverlayId(
       const std::string& input_method_id) = 0;
 
-  // Sets the IME state to enabled, and launches its processes if needed.
-  virtual void StartInputMethodProcesses() = 0;
+  // Sets the IME state to enabled, and launches input method daemon if needed.
+  virtual void StartInputMethodDaemon() = 0;
 
-  // Disables the IME, and kills the processes if they are running.
-  virtual void StopInputMethodProcesses() = 0;
+  // Disables the IME, and kills the daemon process if they are running.
+  virtual void StopInputMethodDaemon() = 0;
 
   // Controls whether the IME process is started when preload engines are
   // specificed, or defered until a non-default method is activated.
diff --git a/chrome/browser/chromeos/cros/mock_input_method_library.h b/chrome/browser/chromeos/cros/mock_input_method_library.h
index 838326f..6957e81 100644
--- a/chrome/browser/chromeos/cros/mock_input_method_library.h
+++ b/chrome/browser/chromeos/cros/mock_input_method_library.h
@@ -35,8 +35,8 @@
   MOCK_CONST_METHOD0(current_input_method, const InputMethodDescriptor&(void));
   MOCK_CONST_METHOD0(current_ime_properties, const ImePropertyList&(void));
   MOCK_METHOD1(GetKeyboardOverlayId, std::string(const std::string&));
-  MOCK_METHOD0(StartInputMethodProcesses, void(void));
-  MOCK_METHOD0(StopInputMethodProcesses, void(void));
+  MOCK_METHOD0(StartInputMethodDaemon, void(void));
+  MOCK_METHOD0(StopInputMethodDaemon, void(void));
   MOCK_METHOD1(SetDeferImeStartup, void(bool));
   MOCK_METHOD1(SetEnableAutoImeShutdown, void(bool));
 };
diff --git a/chrome/browser/chromeos/input_method/candidate_window.cc b/chrome/browser/chromeos/input_method/candidate_window.cc
index fb96d70..769a9267 100644
--- a/chrome/browser/chromeos/input_method/candidate_window.cc
+++ b/chrome/browser/chromeos/input_method/candidate_window.cc
@@ -1397,8 +1397,8 @@
 }
 
 void CandidateWindowController::Impl::OnCandidateCommitted(int index,
-                                                     int button,
-                                                     int flags) {
+                                                           int button,
+                                                           int flags) {
   NotifyCandidateClicked(ui_status_connection_, index, button, flags);
 }
 
@@ -1406,8 +1406,9 @@
     void* input_method_library,
     bool connected) {
   if (!connected) {
-    MessageLoopForUI::current()->PostTask(FROM_HERE,
-                                          new MessageLoop::QuitTask());
+    CandidateWindowController::Impl* controller =
+        static_cast<CandidateWindowController::Impl*>(input_method_library);
+    controller->candidate_window_->HideLookupTable();
   }
 }
 
diff --git a/chrome/browser/chromeos/input_method/candidate_window.gyp b/chrome/browser/chromeos/input_method/candidate_window.gyp
index faa3788..89ce891 100644
--- a/chrome/browser/chromeos/input_method/candidate_window.gyp
+++ b/chrome/browser/chromeos/input_method/candidate_window.gyp
@@ -10,38 +10,8 @@
     {
       'target_name': 'candidate_window',
       'type': 'executable',
-      'dependencies': [
-        '../../../../app/app.gyp:app_strings',
-        '../../../../base/base.gyp:base',
-        '../../../../build/linux/system.gyp:gtk',
-        '../../../../build/linux/system.gyp:x11',
-        '../../../../chrome/chrome.gyp:common_constants',
-        '../../../../skia/skia.gyp:skia',
-        '../../../../views/views.gyp:views',
-      ],
       'sources': [
-        'candidate_window.h',
-        'candidate_window.cc',
         'candidate_window_main.cc',
-        # For loading libcros.
-        '../cros/cros_library_loader.cc',
-      ],
-      'conditions': [
-        ['system_libcros==0', {
-          'dependencies': [
-            '../../../../third_party/cros/cros_api.gyp:cros_api',
-          ],
-          'include_dirs': [
-            '../../../../third_party/',
-          ],
-        }],
-        ['system_libcros==1', {
-          'link_settings': {
-            'libraries': [
-              '-lcrosapi',
-            ],
-          },
-        }],
       ],
     },
   ],
diff --git a/chrome/browser/chromeos/input_method/candidate_window_main.cc b/chrome/browser/chromeos/input_method/candidate_window_main.cc
index 0ffed0d2..56252a1 100644
--- a/chrome/browser/chromeos/input_method/candidate_window_main.cc
+++ b/chrome/browser/chromeos/input_method/candidate_window_main.cc
@@ -2,81 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/chromeos/input_method/candidate_window.h"
-
-#include <gtk/gtk.h>
-
-#include <string>
-
-#include "app/app_paths.h"
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/message_loop.h"
-#include "base/path_service.h"
-#include "base/process_util.h"
-#include "chrome/browser/chromeos/cros/cros_library_loader.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
-#include "grit/app_locale_settings.h"
-#include "third_party/cros/chromeos_cros_api.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/ui_base_paths.h"
-#include "views/focus/accelerator_handler.h"
-
+// TODO(yusukes): Modify build script so build bots don't build and install
+// candidate_window (crosbug.com/11380). Then, remove this file and the gyp
+// target (crosbug.com/11381).
 int main(int argc, char** argv) {
-  // Initialize gtk stuff.
-  g_thread_init(NULL);
-  g_type_init();
-  gtk_init(&argc, &argv);
-
-  // Initialize Chrome stuff.
-  base::AtExitManager exit_manager;
-  base::EnableTerminationOnHeapCorruption();
-  app::RegisterPathProvider();
-  ui::RegisterPathProvider();
-  CommandLine::Init(argc, argv);
-
-  // Check if the UI language code is passed from the command line,
-  // otherwise, default to "en-US".
-  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
-  std::string ui_language_code =
-      command_line.GetSwitchValueASCII(switches::kCandidateWindowLang);
-  if (ui_language_code.empty()) {
-    ui_language_code = "en-US";
-  }
-  ResourceBundle::InitSharedInstance(ui_language_code);
-
-  // Change the UI font if needed.
-  const std::string font_name =
-      l10n_util::GetStringUTF8(IDS_UI_FONT_FAMILY_CROS);
-  // The font name should not be empty here, but just in case.
-  if (font_name != "default" && !font_name.empty()) {
-    // Don't use gtk_util::SetGtkFont() in chrome/browser/ui/gtk not to
-    // introduce a dependency to it.
-    g_object_set(gtk_settings_get_default(),
-                 "gtk-font-name", font_name.c_str(), NULL);
-  }
-
-  // Load libcros.
-  chrome::RegisterPathProvider();  // for libcros.so.
-  chromeos::CrosLibraryLoader lib_loader;
-  std::string error_string;
-  CHECK(lib_loader.Load(&error_string))
-      << "Failed to load libcros, " << error_string;
-
-  // Create the main message loop.
-  MessageLoop main_message_loop(MessageLoop::TYPE_UI);
-
-  // Create the candidate window controller.
-  chromeos::CandidateWindowController controller;
-  if (!controller.Init()) {
-    return 1;
-  }
-
-  // Start the main loop.
-  views::AcceleratorHandler accelerator_handler;
-  MessageLoopForUI::current()->Run(&accelerator_handler);
-
   return 0;
 }
diff --git a/chrome/browser/chromeos/login/user_manager.cc b/chrome/browser/chromeos/login/user_manager.cc
index 38de932..9221b46 100644
--- a/chrome/browser/chromeos/login/user_manager.cc
+++ b/chrome/browser/chromeos/login/user_manager.cc
@@ -434,7 +434,7 @@
       SetDeferImeStartup(false);
   // Shut down the IME so that it will reload the user's settings.
   chromeos::CrosLibrary::Get()->GetInputMethodLibrary()->
-      StopInputMethodProcesses();
+      StopInputMethodDaemon();
   // Let the window manager know that we're logged in now.
   WmIpc::instance()->SetLoggedInProperty(true);
   // Ensure we've opened the real user's key/certificate database.
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 3dcf6295..1dc95c9 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -529,6 +529,8 @@
         'browser/chromeos/google_update_chromeos.cc',
         'browser/chromeos/gview_request_interceptor.cc',
         'browser/chromeos/gview_request_interceptor.h',
+        'browser/chromeos/input_method/candidate_window.h',
+        'browser/chromeos/input_method/candidate_window.cc',
         'browser/chromeos/input_method/input_method_util.cc',
         'browser/chromeos/input_method/input_method_util.h',
         'browser/chromeos/language_preferences.cc',
diff --git a/tools/cros.DEPS/DEPS b/tools/cros.DEPS/DEPS
index 31b2bca..3f737d6 100644
--- a/tools/cros.DEPS/DEPS
+++ b/tools/cros.DEPS/DEPS
@@ -4,5 +4,5 @@
 
 deps = {
   "src/third_party/cros":
-    Var("chromium_git") + "/cros.git@34a0e132",
+    Var("chromium_git") + "/cros.git@43fbb59c",
 }