Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/extensions/input_method_api.h"
      6 
      7 #include "base/lazy_instance.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/chromeos/extensions/input_method_event_router.h"
     10 #include "chrome/browser/chromeos/input_method/input_method_util.h"
     11 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
     12 #include "chromeos/ime/extension_ime_util.h"
     13 #include "chromeos/ime/input_method_descriptor.h"
     14 #include "chromeos/ime/input_method_manager.h"
     15 #include "extensions/browser/extension_function_registry.h"
     16 #include "extensions/browser/extension_system.h"
     17 #include "extensions/common/value_builder.h"
     18 
     19 namespace {
     20 
     21 // Prefix, which is used by XKB.
     22 const char kXkbPrefix[] = "xkb:";
     23 
     24 }  // namespace
     25 
     26 namespace extensions {
     27 
     28 ExtensionFunction::ResponseAction GetCurrentInputMethodFunction::Run() {
     29 #if !defined(OS_CHROMEOS)
     30   EXTENSION_FUNCTION_VALIDATE(false);
     31 #else
     32   chromeos::input_method::InputMethodManager* manager =
     33       chromeos::input_method::InputMethodManager::Get();
     34   return RespondNow(OneArgument(
     35       new base::StringValue(manager->GetCurrentInputMethod().id())));
     36 #endif
     37 }
     38 
     39 ExtensionFunction::ResponseAction SetCurrentInputMethodFunction::Run() {
     40 #if !defined(OS_CHROMEOS)
     41   EXTENSION_FUNCTION_VALIDATE(false);
     42 #else
     43   std::string new_input_method;
     44   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &new_input_method));
     45   chromeos::input_method::InputMethodManager* manager =
     46       chromeos::input_method::InputMethodManager::Get();
     47   const std::vector<std::string>& input_methods =
     48       manager->GetActiveInputMethodIds();
     49   for (size_t i = 0; i < input_methods.size(); ++i) {
     50     const std::string& input_method = input_methods[i];
     51     if (input_method == new_input_method) {
     52       manager->ChangeInputMethod(new_input_method);
     53       return RespondNow(NoArguments());
     54     }
     55   }
     56   return RespondNow(Error("Invalid input method id."));
     57 #endif
     58 }
     59 
     60 ExtensionFunction::ResponseAction GetInputMethodsFunction::Run() {
     61 #if !defined(OS_CHROMEOS)
     62   EXTENSION_FUNCTION_VALIDATE(false);
     63 #else
     64   base::ListValue* output = new base::ListValue();
     65   chromeos::input_method::InputMethodManager* manager =
     66       chromeos::input_method::InputMethodManager::Get();
     67   chromeos::input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
     68   scoped_ptr<chromeos::input_method::InputMethodDescriptors> input_methods =
     69       manager->GetActiveInputMethods();
     70   for (size_t i = 0; i < input_methods->size(); ++i) {
     71     const chromeos::input_method::InputMethodDescriptor& input_method =
     72         (*input_methods)[i];
     73     base::DictionaryValue* val = new base::DictionaryValue();
     74     val->SetString("id", input_method.id());
     75     val->SetString("name", util->GetInputMethodLongName(input_method));
     76     val->SetString("indicator", util->GetInputMethodShortName(input_method));
     77     output->Append(val);
     78   }
     79   return RespondNow(OneArgument(output));
     80 #endif
     81 }
     82 
     83 // static
     84 const char InputMethodAPI::kOnInputMethodChanged[] =
     85     "inputMethodPrivate.onChanged";
     86 
     87 InputMethodAPI::InputMethodAPI(content::BrowserContext* context)
     88     : context_(context) {
     89   EventRouter::Get(context_)->RegisterObserver(this, kOnInputMethodChanged);
     90   ExtensionFunctionRegistry* registry =
     91       ExtensionFunctionRegistry::GetInstance();
     92   registry->RegisterFunction<GetCurrentInputMethodFunction>();
     93   registry->RegisterFunction<SetCurrentInputMethodFunction>();
     94   registry->RegisterFunction<GetInputMethodsFunction>();
     95 }
     96 
     97 InputMethodAPI::~InputMethodAPI() {
     98 }
     99 
    100 // static
    101 std::string InputMethodAPI::GetInputMethodForXkb(const std::string& xkb_id) {
    102   std::string xkb_prefix =
    103       chromeos::extension_ime_util::GetInputMethodIDByEngineID(kXkbPrefix);
    104   size_t prefix_length = xkb_prefix.length();
    105   DCHECK(xkb_id.substr(0, prefix_length) == xkb_prefix);
    106   return xkb_id.substr(prefix_length);
    107 }
    108 
    109 void InputMethodAPI::Shutdown() {
    110   // UnregisterObserver may have already been called in OnListenerAdded,
    111   // but it is safe to call it more than once.
    112   EventRouter::Get(context_)->UnregisterObserver(this);
    113 }
    114 
    115 void InputMethodAPI::OnListenerAdded(
    116     const extensions::EventListenerInfo& details) {
    117   DCHECK(!input_method_event_router_.get());
    118   input_method_event_router_.reset(
    119       new chromeos::ExtensionInputMethodEventRouter(context_));
    120   EventRouter::Get(context_)->UnregisterObserver(this);
    121 }
    122 
    123 static base::LazyInstance<BrowserContextKeyedAPIFactory<InputMethodAPI> >
    124     g_factory = LAZY_INSTANCE_INITIALIZER;
    125 
    126 // static
    127 BrowserContextKeyedAPIFactory<InputMethodAPI>*
    128 InputMethodAPI::GetFactoryInstance() {
    129   return g_factory.Pointer();
    130 }
    131 
    132 }  // namespace extensions
    133