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 "base/android/jni_string.h" 6 7 #include "base/android/jni_android.h" 8 #include "base/logging.h" 9 #include "base/strings/utf_string_conversions.h" 10 11 namespace { 12 13 // Internal version that does not use a scoped local pointer. 14 jstring ConvertUTF16ToJavaStringImpl(JNIEnv* env, 15 const base::StringPiece16& str) { 16 jstring result = env->NewString(str.data(), str.length()); 17 base::android::CheckException(env); 18 return result; 19 } 20 21 } // namespace 22 23 namespace base { 24 namespace android { 25 26 void ConvertJavaStringToUTF8(JNIEnv* env, jstring str, std::string* result) { 27 DCHECK(str); 28 if (!str) { 29 LOG(WARNING) << "ConvertJavaStringToUTF8 called with null string."; 30 result->clear(); 31 return; 32 } 33 const jsize length = env->GetStringLength(str); 34 if (!length) { 35 result->clear(); 36 CheckException(env); 37 return; 38 } 39 // JNI's GetStringUTFChars() returns strings in Java "modified" UTF8, so 40 // instead get the String in UTF16 and convert using chromium's conversion 41 // function that yields plain (non Java-modified) UTF8. 42 const jchar* chars = env->GetStringChars(str, NULL); 43 DCHECK(chars); 44 UTF16ToUTF8(chars, length, result); 45 env->ReleaseStringChars(str, chars); 46 CheckException(env); 47 } 48 49 std::string ConvertJavaStringToUTF8(JNIEnv* env, jstring str) { 50 std::string result; 51 ConvertJavaStringToUTF8(env, str, &result); 52 return result; 53 } 54 55 std::string ConvertJavaStringToUTF8(const JavaRef<jstring>& str) { 56 return ConvertJavaStringToUTF8(AttachCurrentThread(), str.obj()); 57 } 58 59 std::string ConvertJavaStringToUTF8(JNIEnv* env, const JavaRef<jstring>& str) { 60 return ConvertJavaStringToUTF8(env, str.obj()); 61 } 62 63 ScopedJavaLocalRef<jstring> ConvertUTF8ToJavaString( 64 JNIEnv* env, 65 const base::StringPiece& str) { 66 // JNI's NewStringUTF expects "modified" UTF8 so instead create the string 67 // via our own UTF16 conversion utility. 68 // Further, Dalvik requires the string passed into NewStringUTF() to come from 69 // a trusted source. We can't guarantee that all UTF8 will be sanitized before 70 // it gets here, so constructing via UTF16 side-steps this issue. 71 // (Dalvik stores strings internally as UTF16 anyway, so there shouldn't be 72 // a significant performance hit by doing it this way). 73 return ScopedJavaLocalRef<jstring>(env, ConvertUTF16ToJavaStringImpl( 74 env, UTF8ToUTF16(str))); 75 } 76 77 void ConvertJavaStringToUTF16(JNIEnv* env, jstring str, string16* result) { 78 DCHECK(str); 79 if (!str) { 80 LOG(WARNING) << "ConvertJavaStringToUTF16 called with null string."; 81 result->clear(); 82 return; 83 } 84 const jsize length = env->GetStringLength(str); 85 if (!length) { 86 result->clear(); 87 CheckException(env); 88 return; 89 } 90 const jchar* chars = env->GetStringChars(str, NULL); 91 DCHECK(chars); 92 // GetStringChars isn't required to NULL-terminate the strings 93 // it returns, so the length must be explicitly checked. 94 result->assign(chars, length); 95 env->ReleaseStringChars(str, chars); 96 CheckException(env); 97 } 98 99 string16 ConvertJavaStringToUTF16(JNIEnv* env, jstring str) { 100 string16 result; 101 ConvertJavaStringToUTF16(env, str, &result); 102 return result; 103 } 104 105 string16 ConvertJavaStringToUTF16(const JavaRef<jstring>& str) { 106 return ConvertJavaStringToUTF16(AttachCurrentThread(), str.obj()); 107 } 108 109 string16 ConvertJavaStringToUTF16(JNIEnv* env, const JavaRef<jstring>& str) { 110 return ConvertJavaStringToUTF16(env, str.obj()); 111 } 112 113 ScopedJavaLocalRef<jstring> ConvertUTF16ToJavaString( 114 JNIEnv* env, 115 const base::StringPiece16& str) { 116 return ScopedJavaLocalRef<jstring>(env, 117 ConvertUTF16ToJavaStringImpl(env, str)); 118 } 119 120 } // namespace android 121 } // namespace base 122