1/*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *  * Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "ui/base/l10n/l10n_util.h"
27
28#include "base/logging.h"
29#include "base/string_util.h"
30#include "base/utf_string_conversions.h"
31
32#include <utils/threads.h>
33
34namespace l10n_util {
35
36class JNIHelper {
37    public:
38        JNIHelper();
39        ~JNIHelper();
40        string16 getLocalisedString(int message_id);
41
42    private:
43        bool mInited;
44        jclass mClassRef;
45        android::Mutex mGetStringLock;
46};
47
48JNIHelper jniHelper;
49
50JNIHelper::JNIHelper()
51    : mInited(false)
52{
53}
54
55JNIHelper::~JNIHelper()
56{
57    if (!mInited)
58        return;
59
60    android::jni::GetJNIEnv()->DeleteGlobalRef(mClassRef);
61}
62
63string16 JNIHelper::getLocalisedString(int message_id)
64{
65    android::Mutex::Autolock lock(mGetStringLock);
66    JNIEnv* env = android::jni::GetJNIEnv();
67    if (!mInited) {
68        jclass localClass = env->FindClass("android/webkit/L10nUtils");
69        mClassRef = static_cast<jclass>(env->NewGlobalRef(localClass));
70        env->DeleteLocalRef(localClass);
71        mInited = true;
72    }
73
74    static jmethodID getLocalisedString = env->GetStaticMethodID(mClassRef, "getLocalisedString", "(I)Ljava/lang/String;");
75    jstring result = static_cast<jstring>(env->CallStaticObjectMethod(mClassRef, getLocalisedString, message_id));
76    string16 str = android::jni::JstringToString16(env, result);
77    env->DeleteLocalRef(result);
78    return str;
79}
80
81// Implementation of the necessary libchromium l10n utility functions...
82
83string16 GetStringUTF16(int message_id)
84{
85    return jniHelper.getLocalisedString(message_id);
86}
87
88string16 GetStringFUTF16(int message_id, const string16& a, const string16& b, const string16& c)
89{
90    const string16 str = GetStringUTF16(message_id);
91    std::vector<string16> replacements;
92    replacements.push_back(a);
93    replacements.push_back(b);
94    replacements.push_back(c);
95    return ReplaceStringPlaceholders(str, replacements, NULL);
96}
97
98std::string GetApplicationLocale()
99{
100    JNIEnv* env = android::jni::GetJNIEnv();
101    jclass locale_class = env->FindClass("java/util/Locale");
102    jmethodID get_default_locale = env->GetStaticMethodID(locale_class, "getDefault", "()Ljava/util/Locale;");
103    jmethodID to_string = env->GetMethodID(locale_class, "toString", "()Ljava/lang/String;");
104    jobject locale_jobj = env->CallStaticObjectMethod(locale_class, get_default_locale);
105    jstring locale_jstr = static_cast<jstring>(env->CallObjectMethod(locale_jobj, to_string));
106    std::string locale = android::jni::JstringToStdString(env, locale_jstr);
107    env->DeleteLocalRef(locale_jstr);
108    env->DeleteLocalRef(locale_jobj);
109    env->DeleteLocalRef(locale_class);
110
111    return locale;
112}
113
114}
115