1 // Copyright 2019 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/renderer/extensions/accessibility_private_hooks_delegate.h"
6
7 #include "base/i18n/unicodestring.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "extensions/common/extension.h"
10 #include "extensions/renderer/bindings/api_signature.h"
11 #include "extensions/renderer/get_script_context.h"
12 #include "extensions/renderer/script_context.h"
13 #include "gin/converter.h"
14 #include "ui/base/l10n/l10n_util.h"
15
16 namespace extensions {
17
18 namespace {
19 constexpr char kGetDisplayNameForLocale[] =
20 "accessibilityPrivate.getDisplayNameForLocale";
21 constexpr char kUndeterminedLocale[] = "und";
22 } // namespace
23
24 using RequestResult = APIBindingHooks::RequestResult;
25
26 AccessibilityPrivateHooksDelegate::AccessibilityPrivateHooksDelegate() =
27 default;
28 AccessibilityPrivateHooksDelegate::~AccessibilityPrivateHooksDelegate() =
29 default;
30
HandleRequest(const std::string & method_name,const APISignature * signature,v8::Local<v8::Context> context,std::vector<v8::Local<v8::Value>> * arguments,const APITypeReferenceMap & refs)31 RequestResult AccessibilityPrivateHooksDelegate::HandleRequest(
32 const std::string& method_name,
33 const APISignature* signature,
34 v8::Local<v8::Context> context,
35 std::vector<v8::Local<v8::Value>>* arguments,
36 const APITypeReferenceMap& refs) {
37 // Error checks.
38 // Ensure we would like to call the GetDisplayNameForLocale function.
39 if (method_name != kGetDisplayNameForLocale)
40 return RequestResult(RequestResult::NOT_HANDLED);
41 // Ensure arguments are successfully parsed and converted.
42 APISignature::V8ParseResult parse_result =
43 signature->ParseArgumentsToV8(context, *arguments, refs);
44 if (!parse_result.succeeded()) {
45 RequestResult result(RequestResult::INVALID_INVOCATION);
46 result.error = std::move(*parse_result.error);
47 return result;
48 }
49 return HandleGetDisplayNameForLocale(
50 GetScriptContextFromV8ContextChecked(context), *parse_result.arguments);
51 }
52
HandleGetDisplayNameForLocale(ScriptContext * script_context,const std::vector<v8::Local<v8::Value>> & parsed_arguments)53 RequestResult AccessibilityPrivateHooksDelegate::HandleGetDisplayNameForLocale(
54 ScriptContext* script_context,
55 const std::vector<v8::Local<v8::Value>>& parsed_arguments) {
56 DCHECK(script_context->extension());
57 DCHECK_EQ(2u, parsed_arguments.size());
58 DCHECK(parsed_arguments[0]->IsString());
59 DCHECK(parsed_arguments[1]->IsString());
60
61 const std::string locale =
62 gin::V8ToString(script_context->isolate(), parsed_arguments[0]);
63 const std::string display_locale =
64 gin::V8ToString(script_context->isolate(), parsed_arguments[1]);
65
66 bool found_valid_result = false;
67 std::string locale_result;
68 if (l10n_util::IsValidLocaleSyntax(locale) &&
69 l10n_util::IsValidLocaleSyntax(display_locale)) {
70 locale_result = base::UTF16ToUTF8(l10n_util::GetDisplayNameForLocale(
71 locale, display_locale, true /* is_ui */));
72 // Check for valid locales before getting the display name.
73 // The ICU Locale class returns "und" for undetermined locales, and
74 // returns the locale string directly if it has no translation.
75 // Treat these cases as invalid results.
76 found_valid_result =
77 locale_result != kUndeterminedLocale && locale_result != locale;
78 }
79
80 // We return an empty string to communicate that we could not determine
81 // the display locale.
82 if (!found_valid_result)
83 locale_result = std::string();
84
85 RequestResult result(RequestResult::HANDLED);
86 result.return_value =
87 gin::StringToV8(script_context->isolate(), locale_result);
88 return result;
89 }
90
91 } // namespace extensions
92