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(new base::StringValue(
     35       manager->GetActiveIMEState()->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   scoped_refptr<chromeos::input_method::InputMethodManager::State> ime_state =
     46       chromeos::input_method::InputMethodManager::Get()->GetActiveIMEState();
     47   const std::vector<std::string>& input_methods =
     48       ime_state->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       ime_state->ChangeInputMethod(new_input_method, false /* show_message */);
     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_refptr<chromeos::input_method::InputMethodManager::State> ime_state =
     69       manager->GetActiveIMEState();
     70   scoped_ptr<chromeos::input_method::InputMethodDescriptors> input_methods =
     71       ime_state->GetActiveInputMethods();
     72   for (size_t i = 0; i < input_methods->size(); ++i) {
     73     const chromeos::input_method::InputMethodDescriptor& input_method =
     74         (*input_methods)[i];
     75     base::DictionaryValue* val = new base::DictionaryValue();
     76     val->SetString("id", input_method.id());
     77     val->SetString("name", util->GetInputMethodLongName(input_method));
     78     val->SetString("indicator", util->GetInputMethodShortName(input_method));
     79     output->Append(val);
     80   }
     81   return RespondNow(OneArgument(output));
     82 #endif
     83 }
     84 
     85 // static
     86 const char InputMethodAPI::kOnInputMethodChanged[] =
     87     "inputMethodPrivate.onChanged";
     88 
     89 InputMethodAPI::InputMethodAPI(content::BrowserContext* context)
     90     : context_(context) {
     91   EventRouter::Get(context_)->RegisterObserver(this, kOnInputMethodChanged);
     92   ExtensionFunctionRegistry* registry =
     93       ExtensionFunctionRegistry::GetInstance();
     94   registry->RegisterFunction<GetCurrentInputMethodFunction>();
     95   registry->RegisterFunction<SetCurrentInputMethodFunction>();
     96   registry->RegisterFunction<GetInputMethodsFunction>();
     97 }
     98 
     99 InputMethodAPI::~InputMethodAPI() {
    100 }
    101 
    102 // static
    103 std::string InputMethodAPI::GetInputMethodForXkb(const std::string& xkb_id) {
    104   std::string xkb_prefix =
    105       chromeos::extension_ime_util::GetInputMethodIDByEngineID(kXkbPrefix);
    106   size_t prefix_length = xkb_prefix.length();
    107   DCHECK(xkb_id.substr(0, prefix_length) == xkb_prefix);
    108   return xkb_id.substr(prefix_length);
    109 }
    110 
    111 void InputMethodAPI::Shutdown() {
    112   // UnregisterObserver may have already been called in OnListenerAdded,
    113   // but it is safe to call it more than once.
    114   EventRouter::Get(context_)->UnregisterObserver(this);
    115 }
    116 
    117 void InputMethodAPI::OnListenerAdded(
    118     const extensions::EventListenerInfo& details) {
    119   DCHECK(!input_method_event_router_.get());
    120   input_method_event_router_.reset(
    121       new chromeos::ExtensionInputMethodEventRouter(context_));
    122   EventRouter::Get(context_)->UnregisterObserver(this);
    123 }
    124 
    125 static base::LazyInstance<BrowserContextKeyedAPIFactory<InputMethodAPI> >
    126     g_factory = LAZY_INSTANCE_INITIALIZER;
    127 
    128 // static
    129 BrowserContextKeyedAPIFactory<InputMethodAPI>*
    130 InputMethodAPI::GetFactoryInstance() {
    131   return g_factory.Pointer();
    132 }
    133 
    134 }  // namespace extensions
    135