diff options
author | Bernhard Rosenkränzer <Bernhard.Rosenkranzer@linaro.org> | 2013-12-12 03:41:37 +0100 |
---|---|---|
committer | Bernhard Rosenkränzer <Bernhard.Rosenkranzer@linaro.org> | 2013-12-12 03:41:37 +0100 |
commit | 20b61bb2b12ab193b7fad45ebe8208a170104db8 (patch) | |
tree | f0e46dd5b593fa5552a9a05abc4d4c62ad31011d | |
parent | 9a727bc52511e41a482f39873e442eb42c86fffc (diff) | |
download | base-20b61bb2b12ab193b7fad45ebe8208a170104db8.tar.gz |
frameworks/base: Fix build in ISO C++11 mode
Fix various incompatibilities with ISO C++11:
- Assumption that char16_t is defined to uint16_t
- constexpr usage
- macro constructs that could be interpreted as string literals
- enum typesafety
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
Conflicts:
core/jni/android_os_FileUtils.cpp
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.cpp | 4 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.h | 2 | ||||
-rw-r--r-- | core/jni/android_hardware_Camera.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_media_AudioSystem.cpp | 4 | ||||
-rw-r--r-- | core/jni/android_os_Debug.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_os_FileUtils.cpp | 92 | ||||
-rw-r--r-- | core/jni/android_os_Parcel.cpp | 10 | ||||
-rw-r--r-- | core/jni/android_server_BluetoothEventLoop.cpp | 1585 | ||||
-rw-r--r-- | core/jni/android_util_AssetManager.cpp | 12 | ||||
-rw-r--r-- | core/jni/android_util_Binder.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_util_Process.cpp | 6 | ||||
-rw-r--r-- | core/jni/android_util_XmlBlock.cpp | 8 | ||||
-rw-r--r-- | core/jni/android_view_KeyCharacterMap.cpp | 4 | ||||
-rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 102 | ||||
-rw-r--r-- | media/jni/android_mtp_MtpDatabase.cpp | 4 | ||||
-rw-r--r-- | media/jni/mediaeditor/VideoEditorClasses.cpp | 46 | ||||
-rw-r--r-- | media/jni/mediaeditor/VideoEditorMain.cpp | 12 |
17 files changed, 1766 insertions, 131 deletions
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index 92d253f0458e..f7d55d2396b6 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -407,7 +407,7 @@ void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars, } else if (!U_SUCCESS(status) || rc < 1) { ALOGW("Need to force to single run -- string = '%s'," " status = %d, rc = %d", - String8(chars + start, count).string(), status, int(rc)); + String8((const char16_t*)chars + start, count).string(), status, int(rc)); isRTL = (paraDir == 1); useSingleRun = true; } else { @@ -918,7 +918,7 @@ sp<TextLayoutValue> TextLayoutEngine::getValue(const SkPaint* paint, const jchar contextCount, dirFlags); if (value == NULL) { ALOGE("Cannot get TextLayoutCache value for text = '%s'", - String8(text + start, count).string()); + String8((const char16_t*)text + start, count).string()); } #else value = new TextLayoutValue(count); diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index 54704ec741f2..477da5dcbd10 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -80,7 +80,7 @@ public: static int compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs); - inline const UChar* getText() const { return textCopy.string(); } + inline const UChar* getText() const { return (UChar*)textCopy.string(); } bool operator==(const TextLayoutCacheKey& other) const { return compare(*this, other) == 0; diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 09d8d0f3de2b..67c793626cd7 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -725,7 +725,7 @@ static void android_hardware_Camera_setParameters(JNIEnv *env, jobject thiz, jst const jchar* str = env->GetStringCritical(params, 0); String8 params8; if (params) { - params8 = String8(str, env->GetStringLength(params)); + params8 = String8((char16_t*)str, env->GetStringLength(params)); env->ReleaseStringCritical(params, str); } if (camera->setParameters(params8) != NO_ERROR) { diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 7d99464d0bbb..1dde9014d7db 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -97,7 +97,7 @@ android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyVa const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0); String8 c_keyValuePairs8; if (keyValuePairs) { - c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs)); + c_keyValuePairs8 = String8((char16_t*)c_keyValuePairs, env->GetStringLength(keyValuePairs)); env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs); } int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8)); @@ -110,7 +110,7 @@ android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys) const jchar* c_keys = env->GetStringCritical(keys, 0); String8 c_keys8; if (keys) { - c_keys8 = String8(c_keys, env->GetStringLength(keys)); + c_keys8 = String8((char16_t*)c_keys, env->GetStringLength(keys)); env->ReleaseStringCritical(keys, c_keys); } return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string()); diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index 054ee4f694f9..a7a2c605febe 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -896,7 +896,7 @@ static void android_os_Debug_dumpNativeBacktraceToFile(JNIEnv* env, jobject claz const jchar* str = env->GetStringCritical(fileName, 0); String8 fileName8; if (str) { - fileName8 = String8(str, env->GetStringLength(fileName)); + fileName8 = String8((char16_t*)str, env->GetStringLength(fileName)); env->ReleaseStringCritical(fileName, str); } diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp new file mode 100644 index 000000000000..2d20185c7232 --- /dev/null +++ b/core/jni/android_os_FileUtils.cpp @@ -0,0 +1,92 @@ +/* //device/libs/android_runtime/android_util_Process.cpp +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#define LOG_TAG "FileUtils" + +#include <utils/Log.h> + +#include <android_runtime/AndroidRuntime.h> + +#include "JNIHelp.h" + +#include <sys/errno.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/ioctl.h> +#include <linux/msdos_fs.h> + +namespace android { + +jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz, + jstring file, jint mode, + jint uid, jint gid) +{ + const jchar* str = env->GetStringCritical(file, 0); + String8 file8; + if (str) { + file8 = String8((const char16_t*)str, env->GetStringLength(file)); + env->ReleaseStringCritical(file, str); + } + if (file8.size() <= 0) { + return ENOENT; + } + if (uid >= 0 || gid >= 0) { + int res = chown(file8.string(), uid, gid); + if (res != 0) { + return errno; + } + } + return chmod(file8.string(), mode) == 0 ? 0 : errno; +} + +jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path) +{ + if (path == NULL) { + jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + return -1; + } + const char *pathStr = env->GetStringUTFChars(path, NULL); + int result = -1; + // only if our system supports this ioctl + #ifdef VFAT_IOCTL_GET_VOLUME_ID + int fd = open(pathStr, O_RDONLY); + if (fd >= 0) { + result = ioctl(fd, VFAT_IOCTL_GET_VOLUME_ID); + close(fd); + } + #endif + + env->ReleaseStringUTFChars(path, pathStr); + return result; +} + +static const JNINativeMethod methods[] = { + {"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId}, +}; + +static const char* const kFileUtilsPathName = "android/os/FileUtils"; + +int register_android_os_FileUtils(JNIEnv* env) +{ + return AndroidRuntime::registerNativeMethods( + env, kFileUtilsPathName, + methods, NELEM(methods)); +} + +} diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index aa451e3a12a8..d7eaa23943c4 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -236,7 +236,7 @@ static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jint native if (val) { const jchar* str = env->GetStringCritical(val, 0); if (str) { - err = parcel->writeString16(str, env->GetStringLength(val)); + err = parcel->writeString16((char16_t*)str, env->GetStringLength(val)); env->ReleaseStringCritical(val, str); } } else { @@ -340,7 +340,7 @@ static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jint nati size_t len; const char16_t* str = parcel->readString16Inplace(&len); if (str) { - return env->NewString(str, len); + return env->NewString((const jchar*)str, len); } return NULL; } @@ -382,7 +382,7 @@ static jobject android_os_Parcel_openFileDescriptor(JNIEnv* env, jclass clazz, jniThrowException(env, "java/lang/IllegalStateException", NULL); return NULL; } - String8 name8(str, env->GetStringLength(name)); + String8 name8((const char16_t*)str, env->GetStringLength(name)); env->ReleaseStringCritical(name, str); int flags=0; switch (mode&0x30000000) { @@ -577,7 +577,7 @@ static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jin // the caller expects to be invoking const jchar* str = env->GetStringCritical(name, 0); if (str != NULL) { - parcel->writeInterfaceToken(String16(str, env->GetStringLength(name))); + parcel->writeInterfaceToken(String16((const char16_t*)str, env->GetStringLength(name))); env->ReleaseStringCritical(name, str); } } @@ -594,7 +594,7 @@ static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jint n IPCThreadState* threadState = IPCThreadState::self(); const int32_t oldPolicy = threadState->getStrictModePolicy(); const bool isValid = parcel->enforceInterface( - String16(str, env->GetStringLength(name)), + String16((const char16_t*)str, env->GetStringLength(name)), threadState); env->ReleaseStringCritical(name, str); if (isValid) { diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp new file mode 100644 index 000000000000..e498f0a44ac5 --- /dev/null +++ b/core/jni/android_server_BluetoothEventLoop.cpp @@ -0,0 +1,1585 @@ +/* +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#define LOG_TAG "BluetoothEventLoop.cpp" + +#include "android_bluetooth_common.h" +#include "android_runtime/AndroidRuntime.h" +#include "cutils/sockets.h" +#include "JNIHelp.h" +#include "jni.h" +#include "utils/Log.h" +#include "utils/misc.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> + +#ifdef HAVE_BLUETOOTH +#include <dbus/dbus.h> +#endif + +namespace android { + +#define CREATE_DEVICE_ALREADY_EXISTS 1 +#define CREATE_DEVICE_SUCCESS 0 +#define CREATE_DEVICE_FAILED -1 + +#ifdef HAVE_BLUETOOTH +static jfieldID field_mNativeData; + +static jmethodID method_onPropertyChanged; +static jmethodID method_onDevicePropertyChanged; +static jmethodID method_onDeviceFound; +static jmethodID method_onDeviceDisappeared; +static jmethodID method_onDeviceCreated; +static jmethodID method_onDeviceRemoved; +static jmethodID method_onDeviceDisconnectRequested; +static jmethodID method_onNetworkDeviceDisconnected; +static jmethodID method_onNetworkDeviceConnected; + +static jmethodID method_onCreatePairedDeviceResult; +static jmethodID method_onCreateDeviceResult; +static jmethodID method_onDiscoverServicesResult; +static jmethodID method_onGetDeviceServiceChannelResult; + +static jmethodID method_onRequestPinCode; +static jmethodID method_onRequestPasskey; +static jmethodID method_onRequestPasskeyConfirmation; +static jmethodID method_onRequestPairingConsent; +static jmethodID method_onDisplayPasskey; +static jmethodID method_onRequestOobData; +static jmethodID method_onAgentOutOfBandDataAvailable; +static jmethodID method_onAgentAuthorize; +static jmethodID method_onAgentCancel; + +static jmethodID method_onInputDevicePropertyChanged; +static jmethodID method_onInputDeviceConnectionResult; +static jmethodID method_onPanDevicePropertyChanged; +static jmethodID method_onPanDeviceConnectionResult; +static jmethodID method_onHealthDevicePropertyChanged; +static jmethodID method_onHealthDeviceChannelChanged; +static jmethodID method_onHealthDeviceConnectionResult; + +typedef event_loop_native_data_t native_data_t; + +#define EVENT_LOOP_REFS 10 + +static inline native_data_t * get_native_data(JNIEnv *env, jobject object) { + return (native_data_t *)(env->GetIntField(object, + field_mNativeData)); +} + +native_data_t *get_EventLoop_native_data(JNIEnv *env, jobject object) { + return get_native_data(env, object); +} + +#endif +static void classInitNative(JNIEnv* env, jclass clazz) { + ALOGV("%s", __FUNCTION__); + +#ifdef HAVE_BLUETOOTH + method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged", + "([Ljava/lang/String;)V"); + method_onDevicePropertyChanged = env->GetMethodID(clazz, + "onDevicePropertyChanged", + "(Ljava/lang/String;[Ljava/lang/String;)V"); + method_onDeviceFound = env->GetMethodID(clazz, "onDeviceFound", + "(Ljava/lang/String;[Ljava/lang/String;)V"); + method_onDeviceDisappeared = env->GetMethodID(clazz, "onDeviceDisappeared", + "(Ljava/lang/String;)V"); + method_onDeviceCreated = env->GetMethodID(clazz, "onDeviceCreated", "(Ljava/lang/String;)V"); + method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V"); + method_onDeviceDisconnectRequested = env->GetMethodID(clazz, "onDeviceDisconnectRequested", + "(Ljava/lang/String;)V"); + method_onNetworkDeviceConnected = env->GetMethodID(clazz, "onNetworkDeviceConnected", + "(Ljava/lang/String;Ljava/lang/String;I)V"); + method_onNetworkDeviceDisconnected = env->GetMethodID(clazz, "onNetworkDeviceDisconnected", + "(Ljava/lang/String;)V"); + + method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult", + "(Ljava/lang/String;I)V"); + method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult", + "(Ljava/lang/String;I)V"); + method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult", + "(Ljava/lang/String;Z)V"); + + method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize", + "(Ljava/lang/String;Ljava/lang/String;I)V"); + method_onAgentOutOfBandDataAvailable = env->GetMethodID(clazz, "onAgentOutOfBandDataAvailable", + "(Ljava/lang/String;)Z"); + method_onAgentCancel = env->GetMethodID(clazz, "onAgentCancel", "()V"); + method_onRequestPinCode = env->GetMethodID(clazz, "onRequestPinCode", + "(Ljava/lang/String;I)V"); + method_onRequestPasskey = env->GetMethodID(clazz, "onRequestPasskey", + "(Ljava/lang/String;I)V"); + method_onRequestPasskeyConfirmation = env->GetMethodID(clazz, "onRequestPasskeyConfirmation", + "(Ljava/lang/String;II)V"); + method_onRequestPairingConsent = env->GetMethodID(clazz, "onRequestPairingConsent", + "(Ljava/lang/String;I)V"); + method_onDisplayPasskey = env->GetMethodID(clazz, "onDisplayPasskey", + "(Ljava/lang/String;II)V"); + method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged", + "(Ljava/lang/String;[Ljava/lang/String;)V"); + method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult", + "(Ljava/lang/String;I)V"); + method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged", + "(Ljava/lang/String;[Ljava/lang/String;)V"); + method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult", + "(Ljava/lang/String;I)V"); + method_onHealthDeviceConnectionResult = env->GetMethodID(clazz, + "onHealthDeviceConnectionResult", + "(II)V"); + method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged", + "(Ljava/lang/String;[Ljava/lang/String;)V"); + method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged", + "(Ljava/lang/String;Ljava/lang/String;Z)V"); + method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData", + "(Ljava/lang/String;I)V"); + + field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I"); +#endif +} + +static void initializeNativeDataNative(JNIEnv* env, jobject object) { + ALOGV("%s", __FUNCTION__); +#ifdef HAVE_BLUETOOTH + native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t)); + if (NULL == nat) { + ALOGE("%s: out of memory!", __FUNCTION__); + return; + } + + pthread_mutex_init(&(nat->thread_mutex), NULL); + + env->SetIntField(object, field_mNativeData, (jint)nat); + + { + DBusError err; + dbus_error_init(&err); + dbus_threads_init_default(); + nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (dbus_error_is_set(&err)) { + ALOGE("%s: Could not get onto the system bus!", __FUNCTION__); + dbus_error_free(&err); + } + dbus_connection_set_exit_on_disconnect(nat->conn, FALSE); + } +#endif +} + +static void cleanupNativeDataNative(JNIEnv* env, jobject object) { + ALOGV("%s", __FUNCTION__); +#ifdef HAVE_BLUETOOTH + native_data_t *nat = + (native_data_t *)env->GetIntField(object, field_mNativeData); + + pthread_mutex_destroy(&(nat->thread_mutex)); + + if (nat) { + free(nat); + } +#endif +} + +#ifdef HAVE_BLUETOOTH +static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, + void *data); +DBusHandlerResult agent_event_filter(DBusConnection *conn, + DBusMessage *msg, + void *data); +static int register_agent(native_data_t *nat, + const char *agent_path, const char *capabilities); + +static const DBusObjectPathVTable agent_vtable = { + NULL, agent_event_filter, NULL, NULL, NULL, NULL +}; + +static unsigned int unix_events_to_dbus_flags(short events) { + return (events & DBUS_WATCH_READABLE ? POLLIN : 0) | + (events & DBUS_WATCH_WRITABLE ? POLLOUT : 0) | + (events & DBUS_WATCH_ERROR ? POLLERR : 0) | + (events & DBUS_WATCH_HANGUP ? POLLHUP : 0); +} + +static short dbus_flags_to_unix_events(unsigned int flags) { + return (flags & POLLIN ? DBUS_WATCH_READABLE : 0) | + (flags & POLLOUT ? DBUS_WATCH_WRITABLE : 0) | + (flags & POLLERR ? DBUS_WATCH_ERROR : 0) | + (flags & POLLHUP ? DBUS_WATCH_HANGUP : 0); +} + +static jboolean setUpEventLoop(native_data_t *nat) { + ALOGV("%s", __FUNCTION__); + + if (nat != NULL && nat->conn != NULL) { + dbus_threads_init_default(); + DBusError err; + dbus_error_init(&err); + + const char *agent_path = "/android/bluetooth/agent"; + const char *capabilities = "DisplayYesNo"; + if (register_agent(nat, agent_path, capabilities) < 0) { + dbus_connection_unregister_object_path (nat->conn, agent_path); + return JNI_FALSE; + } + + // Add a filter for all incoming messages + if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){ + return JNI_FALSE; + } + + // Set which messages will be processed by this dbus connection + dbus_bus_add_match(nat->conn, + "type='signal',interface='org.freedesktop.DBus'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + dbus_bus_add_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".Adapter'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + dbus_bus_add_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".Device'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + dbus_bus_add_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".Input'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + dbus_bus_add_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".Network'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + dbus_bus_add_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".NetworkServer'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + + dbus_bus_add_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".HealthDevice'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + + dbus_bus_add_match(nat->conn, + "type='signal',interface='org.bluez.AudioSink'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + return JNI_FALSE; + } + + return JNI_TRUE; + } + return JNI_FALSE; +} + + +const char * get_adapter_path(DBusConnection *conn) { + DBusMessage *msg = NULL, *reply = NULL; + DBusError err; + const char *device_path = NULL; + int attempt = 0; + + for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) { + msg = dbus_message_new_method_call("org.bluez", "/", + "org.bluez.Manager", "DefaultAdapter"); + if (!msg) { + ALOGE("%s: Can't allocate new method call for get_adapter_path!", + __FUNCTION__); + return NULL; + } + dbus_message_append_args(msg, DBUS_TYPE_INVALID); + dbus_error_init(&err); + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + + if (!reply) { + if (dbus_error_is_set(&err)) { + if (dbus_error_has_name(&err, + "org.freedesktop.DBus.Error.ServiceUnknown")) { + // bluetoothd is still down, retry + LOG_AND_FREE_DBUS_ERROR(&err); + usleep(10000); // 10 ms + continue; + } else { + // Some other error we weren't expecting + LOG_AND_FREE_DBUS_ERROR(&err); + } + } + goto failed; + } + } + if (attempt == 1000) { + ALOGE("Time out while trying to get Adapter path, is bluetoothd up ?"); + goto failed; + } + + if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH, + &device_path, DBUS_TYPE_INVALID) + || !device_path){ + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + goto failed; + } + dbus_message_unref(msg); + return device_path; + +failed: + dbus_message_unref(msg); + return NULL; +} + +static int register_agent(native_data_t *nat, + const char * agent_path, const char * capabilities) +{ + DBusMessage *msg, *reply; + DBusError err; + dbus_bool_t oob = TRUE; + + if (!dbus_connection_register_object_path(nat->conn, agent_path, + &agent_vtable, nat)) { + ALOGE("%s: Can't register object path %s for agent!", + __FUNCTION__, agent_path); + return -1; + } + + nat->adapter = get_adapter_path(nat->conn); + if (nat->adapter == NULL) { + return -1; + } + msg = dbus_message_new_method_call("org.bluez", nat->adapter, + "org.bluez.Adapter", "RegisterAgent"); + if (!msg) { + ALOGE("%s: Can't allocate new method call for agent!", + __FUNCTION__); + return -1; + } + dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path, + DBUS_TYPE_STRING, &capabilities, + DBUS_TYPE_INVALID); + + dbus_error_init(&err); + reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err); + dbus_message_unref(msg); + + if (!reply) { + ALOGE("%s: Can't register agent!", __FUNCTION__); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + return -1; + } + + dbus_message_unref(reply); + dbus_connection_flush(nat->conn); + + return 0; +} + +static void tearDownEventLoop(native_data_t *nat) { + ALOGV("%s", __FUNCTION__); + if (nat != NULL && nat->conn != NULL) { + + DBusMessage *msg, *reply; + DBusError err; + dbus_error_init(&err); + const char * agent_path = "/android/bluetooth/agent"; + + msg = dbus_message_new_method_call("org.bluez", + nat->adapter, + "org.bluez.Adapter", + "UnregisterAgent"); + if (msg != NULL) { + dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path, + DBUS_TYPE_INVALID); + reply = dbus_connection_send_with_reply_and_block(nat->conn, + msg, -1, &err); + + if (!reply) { + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + dbus_error_free(&err); + } + } else { + dbus_message_unref(reply); + } + dbus_message_unref(msg); + } else { + ALOGE("%s: Can't create new method call!", __FUNCTION__); + } + + dbus_connection_flush(nat->conn); + dbus_connection_unregister_object_path(nat->conn, agent_path); + + dbus_bus_remove_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".AudioSink'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".Device'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".Input'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".Network'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".NetworkServer'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".HealthDevice'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='org.bluez.audio.Manager'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='" BLUEZ_DBUS_BASE_IFC ".Adapter'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + dbus_bus_remove_match(nat->conn, + "type='signal',interface='org.freedesktop.DBus'", + &err); + if (dbus_error_is_set(&err)) { + LOG_AND_FREE_DBUS_ERROR(&err); + } + + dbus_connection_remove_filter(nat->conn, event_filter, nat); + } +} + + +#define EVENT_LOOP_EXIT 1 +#define EVENT_LOOP_ADD 2 +#define EVENT_LOOP_REMOVE 3 +#define EVENT_LOOP_WAKEUP 4 + +dbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) { + native_data_t *nat = (native_data_t *)data; + + if (dbus_watch_get_enabled(watch)) { + // note that we can't just send the watch and inspect it later + // because we may get a removeWatch call before this data is reacted + // to by our eventloop and remove this watch.. reading the add first + // and then inspecting the recently deceased watch would be bad. + char control = EVENT_LOOP_ADD; + write(nat->controlFdW, &control, sizeof(char)); + + int fd = dbus_watch_get_fd(watch); + write(nat->controlFdW, &fd, sizeof(int)); + + unsigned int flags = dbus_watch_get_flags(watch); + write(nat->controlFdW, &flags, sizeof(unsigned int)); + + write(nat->controlFdW, &watch, sizeof(DBusWatch*)); + } + return true; +} + +void dbusRemoveWatch(DBusWatch *watch, void *data) { + native_data_t *nat = (native_data_t *)data; + + char control = EVENT_LOOP_REMOVE; + write(nat->controlFdW, &control, sizeof(char)); + + int fd = dbus_watch_get_fd(watch); + write(nat->controlFdW, &fd, sizeof(int)); + + unsigned int flags = dbus_watch_get_flags(watch); + write(nat->controlFdW, &flags, sizeof(unsigned int)); +} + +void dbusToggleWatch(DBusWatch *watch, void *data) { + if (dbus_watch_get_enabled(watch)) { + dbusAddWatch(watch, data); + } else { + dbusRemoveWatch(watch, data); + } +} + +void dbusWakeup(void *data) { + native_data_t *nat = (native_data_t *)data; + + char control = EVENT_LOOP_WAKEUP; + write(nat->controlFdW, &control, sizeof(char)); +} + +static void handleWatchAdd(native_data_t *nat) { + DBusWatch *watch; + int newFD; + unsigned int flags; + + read(nat->controlFdR, &newFD, sizeof(int)); + read(nat->controlFdR, &flags, sizeof(unsigned int)); + read(nat->controlFdR, &watch, sizeof(DBusWatch *)); + short events = dbus_flags_to_unix_events(flags); + + for (int y = 0; y<nat->pollMemberCount; y++) { + if ((nat->pollData[y].fd == newFD) && + (nat->pollData[y].events == events)) { + ALOGV("DBusWatch duplicate add"); + return; + } + } + if (nat->pollMemberCount == nat->pollDataSize) { + ALOGV("Bluetooth EventLoop poll struct growing"); + struct pollfd *temp = (struct pollfd *)malloc( + sizeof(struct pollfd) * (nat->pollMemberCount+1)); + if (!temp) { + return; + } + memcpy(temp, nat->pollData, sizeof(struct pollfd) * + nat->pollMemberCount); + free(nat->pollData); + nat->pollData = temp; + DBusWatch **temp2 = (DBusWatch **)malloc(sizeof(DBusWatch *) * + (nat->pollMemberCount+1)); + if (!temp2) { + return; + } + memcpy(temp2, nat->watchData, sizeof(DBusWatch *) * + nat->pollMemberCount); + free(nat->watchData); + nat->watchData = temp2; + nat->pollDataSize++; + } + nat->pollData[nat->pollMemberCount].fd = newFD; + nat->pollData[nat->pollMemberCount].revents = 0; + nat->pollData[nat->pollMemberCount].events = events; + nat->watchData[nat->pollMemberCount] = watch; + nat->pollMemberCount++; +} + +static void handleWatchRemove(native_data_t *nat) { + int removeFD; + unsigned int flags; + + read(nat->controlFdR, &removeFD, sizeof(int)); + read(nat->controlFdR, &flags, sizeof(unsigned int)); + short events = dbus_flags_to_unix_events(flags); + + for (int y = 0; y < nat->pollMemberCount; y++) { + if ((nat->pollData[y].fd == removeFD) && + (nat->pollData[y].events == events)) { + int newCount = --nat->pollMemberCount; + // copy the last live member over this one + nat->pollData[y].fd = nat->pollData[newCount].fd; + nat->pollData[y].events = nat->pollData[newCount].events; + nat->pollData[y].revents = nat->pollData[newCount].revents; + nat->watchData[y] = nat->watchData[newCount]; + return; + } + } + ALOGW("WatchRemove given with unknown watch"); +} + +static void *eventLoopMain(void *ptr) { + native_data_t *nat = (native_data_t *)ptr; + JNIEnv *env; + + JavaVMAttachArgs args; + char name[] = "BT EventLoop"; + args.version = nat->envVer; + args.name = name; + args.group = NULL; + + nat->vm->AttachCurrentThread(&env, &args); + + dbus_connection_set_watch_functions(nat->conn, dbusAddWatch, + dbusRemoveWatch, dbusToggleWatch, ptr, NULL); + dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL); + + nat->running = true; + + while (1) { + for (int i = 0; i < nat->pollMemberCount; i++) { + if (!nat->pollData[i].revents) { + continue; + } + if (nat->pollData[i].fd == nat->controlFdR) { + char data; + while (recv(nat->controlFdR, &data, sizeof(char), MSG_DONTWAIT) + != -1) { + switch (data) { + case EVENT_LOOP_EXIT: + { + dbus_connection_set_watch_functions(nat->conn, + NULL, NULL, NULL, NULL, NULL); + tearDownEventLoop(nat); + nat->vm->DetachCurrentThread(); + + int fd = nat->controlFdR; + nat->controlFdR = 0; + close(fd); + return NULL; + } + case EVENT_LOOP_ADD: + { + handleWatchAdd(nat); + break; + } + case EVENT_LOOP_REMOVE: + { + handleWatchRemove(nat); + break; + } + case EVENT_LOOP_WAKEUP: + { + // noop + break; + } + } + } + } else { + short events = nat->pollData[i].revents; + unsigned int flags = unix_events_to_dbus_flags(events); + dbus_watch_handle(nat->watchData[i], flags); + nat->pollData[i].revents = 0; + // can only do one - it may have caused a 'remove' + break; + } + } + while (dbus_connection_dispatch(nat->conn) == + DBUS_DISPATCH_DATA_REMAINS) { + } + + poll(nat->pollData, nat->pollMemberCount, -1); + } +} +#endif // HAVE_BLUETOOTH + +static jboolean startEventLoopNative(JNIEnv *env, jobject object) { + jboolean result = JNI_FALSE; +#ifdef HAVE_BLUETOOTH + event_loop_native_data_t *nat = get_native_data(env, object); + + pthread_mutex_lock(&(nat->thread_mutex)); + + nat->running = false; + + if (nat->pollData) { + ALOGW("trying to start EventLoop a second time!"); + pthread_mutex_unlock( &(nat->thread_mutex) ); + return JNI_FALSE; + } + + nat->pollData = (struct pollfd *)calloc( + DEFAULT_INITIAL_POLLFD_COUNT, sizeof(struct pollfd)); + if (!nat->pollData) { + ALOGE("out of memory error starting EventLoop!"); + goto done; + } + + nat->watchData = (DBusWatch **)calloc( + DEFAULT_INITIAL_POLLFD_COUNT, sizeof(DBusWatch *)); + if (!nat->watchData) { + ALOGE("out of memory error starting EventLoop!"); + goto done; + } + + nat->pollDataSize = DEFAULT_INITIAL_POLLFD_COUNT; + nat->pollMemberCount = 1; + + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, &(nat->controlFdR))) { + ALOGE("Error getting BT control socket"); + goto done; + } + nat->pollData[0].fd = nat->controlFdR; + nat->pollData[0].events = POLLIN; + + env->GetJavaVM( &(nat->vm) ); + nat->envVer = env->GetVersion(); + + nat->me = env->NewGlobalRef(object); + + if (setUpEventLoop(nat) != JNI_TRUE) { + ALOGE("failure setting up Event Loop!"); + goto done; + } + + pthread_create(&(nat->thread), NULL, eventLoopMain, nat); + result = JNI_TRUE; + +done: + if (JNI_FALSE == result) { + if (nat->controlFdW) { + close(nat->controlFdW); + nat->controlFdW = 0; + } + if (nat->controlFdR) { + close(nat->controlFdR); + nat->controlFdR = 0; + } + if (nat->me) env->DeleteGlobalRef(nat->me); + nat->me = NULL; + if (nat->pollData) free(nat->pollData); + nat->pollData = NULL; + if (nat->watchData) free(nat->watchData); + nat->watchData = NULL; + nat->pollDataSize = 0; + nat->pollMemberCount = 0; + } + + pthread_mutex_unlock(&(nat->thread_mutex)); +#endif // HAVE_BLUETOOTH + return result; +} + +static void stopEventLoopNative(JNIEnv *env, jobject object) { +#ifdef HAVE_BLUETOOTH + native_data_t *nat = get_native_data(env, object); + + pthread_mutex_lock(&(nat->thread_mutex)); + if (nat->pollData) { + char data = EVENT_LOOP_EXIT; + ssize_t t = write(nat->controlFdW, &data, sizeof(char)); + void *ret; + pthread_join(nat->thread, &ret); + + env->DeleteGlobalRef(nat->me); + nat->me = NULL; + free(nat->pollData); + nat->pollData = NULL; + free(nat->watchData); + nat->watchData = NULL; + nat->pollDataSize = 0; + nat->pollMemberCount = 0; + + int fd = nat->controlFdW; + nat->controlFdW = 0; + close(fd); + } + nat->running = false; + pthread_mutex_unlock(&(nat->thread_mutex)); +#endif // HAVE_BLUETOOTH +} + +static jboolean isEventLoopRunningNative(JNIEnv *env, jobject object) { + jboolean result = JNI_FALSE; +#ifdef HAVE_BLUETOOTH + native_data_t *nat = get_native_data(env, object); + + pthread_mutex_lock(&(nat->thread_mutex)); + if (nat->running) { + result = JNI_TRUE; + } + pthread_mutex_unlock(&(nat->thread_mutex)); + +#endif // HAVE_BLUETOOTH + return result; +} + +#ifdef HAVE_BLUETOOTH +extern DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env); + +// Called by dbus during WaitForAndDispatchEventNative() +static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg, + void *data) { + native_data_t *nat; + JNIEnv *env; + DBusError err; + DBusHandlerResult ret; + + dbus_error_init(&err); + + nat = (native_data_t *)data; + nat->vm->GetEnv((void**)&env, nat->envVer); + if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) { + ALOGV("%s: not interested (not a signal).", __FUNCTION__); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + ALOGV("%s: Received signal %s:%s from %s", __FUNCTION__, + dbus_message_get_interface(msg), dbus_message_get_member(msg), + dbus_message_get_path(msg)); + + env->PushLocalFrame(EVENT_LOOP_REFS); + if (dbus_message_is_signal(msg, + "org.bluez.Adapter", + "DeviceFound")) { + char *c_address; + DBusMessageIter iter; + jobjectArray str_array = NULL; + if (dbus_message_iter_init(msg, &iter)) { + dbus_message_iter_get_basic(&iter, &c_address); + if (dbus_message_iter_next(&iter)) + str_array = + parse_remote_device_properties(env, &iter); + } + if (str_array != NULL) { + env->CallVoidMethod(nat->me, + method_onDeviceFound, + env->NewStringUTF(c_address), + str_array); + } else + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.Adapter", + "DeviceDisappeared")) { + char *c_address; + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &c_address, + DBUS_TYPE_INVALID)) { + ALOGV("... address = %s", c_address); + env->CallVoidMethod(nat->me, method_onDeviceDisappeared, + env->NewStringUTF(c_address)); + } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.Adapter", + "DeviceCreated")) { + char *c_object_path; + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_OBJECT_PATH, &c_object_path, + DBUS_TYPE_INVALID)) { + ALOGV("... address = %s", c_object_path); + env->CallVoidMethod(nat->me, + method_onDeviceCreated, + env->NewStringUTF(c_object_path)); + } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.Adapter", + "DeviceRemoved")) { + char *c_object_path; + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_OBJECT_PATH, &c_object_path, + DBUS_TYPE_INVALID)) { + ALOGV("... Object Path = %s", c_object_path); + env->CallVoidMethod(nat->me, + method_onDeviceRemoved, + env->NewStringUTF(c_object_path)); + } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.Adapter", + "PropertyChanged")) { + jobjectArray str_array = parse_adapter_property_change(env, msg); + if (str_array != NULL) { + /* Check if bluetoothd has (re)started, if so update the path. */ + jstring property =(jstring) env->GetObjectArrayElement(str_array, 0); + const char *c_property = env->GetStringUTFChars(property, NULL); + if (!strncmp(c_property, "Powered", strlen("Powered"))) { + jstring value = + (jstring) env->GetObjectArrayElement(str_array, 1); + const char *c_value = env->GetStringUTFChars(value, NULL); + if (!strncmp(c_value, "true", strlen("true"))) + nat->adapter = get_adapter_path(nat->conn); + env->ReleaseStringUTFChars(value, c_value); + } + env->ReleaseStringUTFChars(property, c_property); + + env->CallVoidMethod(nat->me, + method_onPropertyChanged, + str_array); + } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.Device", + "PropertyChanged")) { + jobjectArray str_array = parse_remote_device_property_change(env, msg); + if (str_array != NULL) { + const char *remote_device_path = dbus_message_get_path(msg); + env->CallVoidMethod(nat->me, + method_onDevicePropertyChanged, + env->NewStringUTF(remote_device_path), + str_array); + } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.Device", + "DisconnectRequested")) { + const char *remote_device_path = dbus_message_get_path(msg); + env->CallVoidMethod(nat->me, + method_onDeviceDisconnectRequested, + env->NewStringUTF(remote_device_path)); + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.Input", + "PropertyChanged")) { + + jobjectArray str_array = + parse_input_property_change(env, msg); + if (str_array != NULL) { + const char *c_path = dbus_message_get_path(msg); + env->CallVoidMethod(nat->me, + method_onInputDevicePropertyChanged, + env->NewStringUTF(c_path), + str_array); + } else { + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + } + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.Network", + "PropertyChanged")) { + + jobjectArray str_array = + parse_pan_property_change(env, msg); + if (str_array != NULL) { + const char *c_path = dbus_message_get_path(msg); + env->CallVoidMethod(nat->me, + method_onPanDevicePropertyChanged, + env->NewStringUTF(c_path), + str_array); + } else { + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + } + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.NetworkServer", + "DeviceDisconnected")) { + char *c_address; + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &c_address, + DBUS_TYPE_INVALID)) { + env->CallVoidMethod(nat->me, + method_onNetworkDeviceDisconnected, + env->NewStringUTF(c_address)); + } else { + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + } + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.NetworkServer", + "DeviceConnected")) { + char *c_address; + char *c_iface; + uint16_t uuid; + + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &c_address, + DBUS_TYPE_STRING, &c_iface, + DBUS_TYPE_UINT16, &uuid, + DBUS_TYPE_INVALID)) { + env->CallVoidMethod(nat->me, + method_onNetworkDeviceConnected, + env->NewStringUTF(c_address), + env->NewStringUTF(c_iface), + uuid); + } else { + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + } + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.HealthDevice", + "ChannelConnected")) { + const char *c_path = dbus_message_get_path(msg); + const char *c_channel_path; + jboolean exists = JNI_TRUE; + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_OBJECT_PATH, &c_channel_path, + DBUS_TYPE_INVALID)) { + env->CallVoidMethod(nat->me, + method_onHealthDeviceChannelChanged, + env->NewStringUTF(c_path), + env->NewStringUTF(c_channel_path), + exists); + } else { + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + } + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.HealthDevice", + "ChannelDeleted")) { + + const char *c_path = dbus_message_get_path(msg); + const char *c_channel_path; + jboolean exists = JNI_FALSE; + if (dbus_message_get_args(msg, &err, + DBUS_TYPE_OBJECT_PATH, &c_channel_path, + DBUS_TYPE_INVALID)) { + env->CallVoidMethod(nat->me, + method_onHealthDeviceChannelChanged, + env->NewStringUTF(c_path), + env->NewStringUTF(c_channel_path), + exists); + } else { + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + } + goto success; + } else if (dbus_message_is_signal(msg, + "org.bluez.HealthDevice", + "PropertyChanged")) { + jobjectArray str_array = + parse_health_device_property_change(env, msg); + if (str_array != NULL) { + const char *c_path = dbus_message_get_path(msg); + env->CallVoidMethod(nat->me, + method_onHealthDevicePropertyChanged, + env->NewStringUTF(c_path), + str_array); + } else { + LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg); + } + goto success; + } + + ret = a2dp_event_filter(msg, env); + env->PopLocalFrame(NULL); + return ret; + +success: + env->PopLocalFrame(NULL); + return DBUS_HANDLER_RESULT_HANDLED; +} + +// Called by dbus during WaitForAndDispatchEventNative() +DBusHandlerResult agent_event_filter(DBusConnection *conn, + DBusMessage *msg, void *data) { + native_data_t *nat = (native_data_t *)data; + JNIEnv *env; + if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) { + ALOGV("%s: not interested (not a method call).", __FUNCTION__); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + ALOGI("%s: Received method %s:%s", __FUNCTION__, + dbus_message_get_interface(msg), dbus_message_get_member(msg)); + + if (nat == NULL) return DBUS_HANDLER_RESULT_HANDLED; + + nat->vm->GetEnv((void**)&env, nat->envVer); + env->PushLocalFrame(EVENT_LOOP_REFS); + + if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "Cancel")) { + env->CallVoidMethod(nat->me, method_onAgentCancel); + // reply + DBusMessage *reply = dbus_message_new_method_return(msg); + if (!reply) { + ALOGE("%s: Cannot create message reply\n", __FUNCTION__); + goto failure; + } + dbus_connection_send(nat->conn, reply, NULL); + dbus_message_unref(reply); + goto success; + + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "Authorize")) { + char *object_path; + const char *uuid; + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID)) { + ALOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__); + goto failure; + } + + ALOGV("... object_path = %s", object_path); + ALOGV("... uuid = %s", uuid); + + dbus_message_ref(msg); // increment refcount because we pass to java + env->CallVoidMethod(nat->me, method_onAgentAuthorize, + env->NewStringUTF(object_path), env->NewStringUTF(uuid), + int(msg)); + + goto success; + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "OutOfBandAvailable")) { + char *object_path; + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_INVALID)) { + ALOGE("%s: Invalid arguments for OutOfBandData available() method", __FUNCTION__); + goto failure; + } + + ALOGV("... object_path = %s", object_path); + + bool available = + env->CallBooleanMethod(nat->me, method_onAgentOutOfBandDataAvailable, + env->NewStringUTF(object_path)); + + + // reply + if (available) { + DBusMessage *reply = dbus_message_new_method_return(msg); + if (!reply) { + ALOGE("%s: Cannot create message reply\n", __FUNCTION__); + goto failure; + } + dbus_connection_send(nat->conn, reply, NULL); + dbus_message_unref(reply); + } else { + DBusMessage *reply = dbus_message_new_error(msg, + "org.bluez.Error.DoesNotExist", "OutofBand data not available"); + if (!reply) { + ALOGE("%s: Cannot create message reply\n", __FUNCTION__); + goto failure; + } + dbus_connection_send(nat->conn, reply, NULL); + dbus_message_unref(reply); + } + goto success; + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "RequestPinCode")) { + char *object_path; + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_INVALID)) { + ALOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__); + goto failure; + } + + dbus_message_ref(msg); // increment refcount because we pass to java + env->CallVoidMethod(nat->me, method_onRequestPinCode, + env->NewStringUTF(object_path), + int(msg)); + goto success; + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "RequestPasskey")) { + char *object_path; + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_INVALID)) { + ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__); + goto failure; + } + + dbus_message_ref(msg); // increment refcount because we pass to java + env->CallVoidMethod(nat->me, method_onRequestPasskey, + env->NewStringUTF(object_path), + int(msg)); + goto success; + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "RequestOobData")) { + char *object_path; + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_INVALID)) { + ALOGE("%s: Invalid arguments for RequestOobData() method", __FUNCTION__); + goto failure; + } + + dbus_message_ref(msg); // increment refcount because we pass to java + env->CallVoidMethod(nat->me, method_onRequestOobData, + env->NewStringUTF(object_path), + int(msg)); + goto success; + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "DisplayPasskey")) { + char *object_path; + uint32_t passkey; + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_UINT32, &passkey, + DBUS_TYPE_INVALID)) { + ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__); + goto failure; + } + + dbus_message_ref(msg); // increment refcount because we pass to java + env->CallVoidMethod(nat->me, method_onDisplayPasskey, + env->NewStringUTF(object_path), + passkey, + int(msg)); + goto success; + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "RequestConfirmation")) { + char *object_path; + uint32_t passkey; + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_UINT32, &passkey, + DBUS_TYPE_INVALID)) { + ALOGE("%s: Invalid arguments for RequestConfirmation() method", __FUNCTION__); + goto failure; + } + + dbus_message_ref(msg); // increment refcount because we pass to java + env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation, + env->NewStringUTF(object_path), + passkey, + int(msg)); + goto success; + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "RequestPairingConsent")) { + char *object_path; + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_INVALID)) { + ALOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__); + goto failure; + } + + dbus_message_ref(msg); // increment refcount because we pass to java + env->CallVoidMethod(nat->me, method_onRequestPairingConsent, + env->NewStringUTF(object_path), + int(msg)); + goto success; + } else if (dbus_message_is_method_call(msg, + "org.bluez.Agent", "Release")) { + // reply + DBusMessage *reply = dbus_message_new_method_return(msg); + if (!reply) { + ALOGE("%s: Cannot create message reply\n", __FUNCTION__); + goto failure; + } + dbus_connection_send(nat->conn, reply, NULL); + dbus_message_unref(reply); + goto success; + } else { + ALOGV("%s:%s is ignored", dbus_message_get_interface(msg), dbus_message_get_member(msg)); + } + +failure: + env->PopLocalFrame(NULL); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +success: + env->PopLocalFrame(NULL); + return DBUS_HANDLER_RESULT_HANDLED; + +} +#endif + + +#ifdef HAVE_BLUETOOTH + +void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) { + ALOGV("%s", __FUNCTION__); + + native_data_t *nat = (native_data_t *)n; + const char *address = (const char *)user; + DBusError err; + dbus_error_init(&err); + JNIEnv *env; + jstring addr; + + nat->vm->GetEnv((void**)&env, nat->envVer); + + ALOGV("... address = %s", address); + + jint result = BOND_RESULT_SUCCESS; + if (dbus_set_error_from_message(&err, msg)) { + if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) { + // Pins did not match, or remote device did not respond to pin + // request in time + ALOGV("... error = %s (%s)\n", err.name, err.message); + result = BOND_RESULT_AUTH_FAILED; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationRejected")) { + // We rejected pairing, or the remote side rejected pairing. This + // happens if either side presses 'cancel' at the pairing dialog. + ALOGV("... error = %s (%s)\n", err.name, err.message); + result = BOND_RESULT_AUTH_REJECTED; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationCanceled")) { + // Not sure if this happens + ALOGV("... error = %s (%s)\n", err.name, err.message); + result = BOND_RESULT_AUTH_CANCELED; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.ConnectionAttemptFailed")) { + // Other device is not responding at all + ALOGV("... error = %s (%s)\n", err.name, err.message); + result = BOND_RESULT_REMOTE_DEVICE_DOWN; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AlreadyExists")) { + // already bonded + ALOGV("... error = %s (%s)\n", err.name, err.message); + result = BOND_RESULT_SUCCESS; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") && + !strcmp(err.message, "Bonding in progress")) { + ALOGV("... error = %s (%s)\n", err.name, err.message); + goto done; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") && + !strcmp(err.message, "Discover in progress")) { + ALOGV("... error = %s (%s)\n", err.name, err.message); + result = BOND_RESULT_DISCOVERY_IN_PROGRESS; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.RepeatedAttempts")) { + ALOGV("... error = %s (%s)\n", err.name, err.message); + result = BOND_RESULT_REPEATED_ATTEMPTS; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) { + ALOGV("... error = %s (%s)\n", err.name, err.message); + result = BOND_RESULT_AUTH_TIMEOUT; + } else { + ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message); + result = BOND_RESULT_ERROR; + } + } + + addr = env->NewStringUTF(address); + env->CallVoidMethod(nat->me, + method_onCreatePairedDeviceResult, + addr, + result); + env->DeleteLocalRef(addr); +done: + dbus_error_free(&err); + free(user); +} + +void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) { + ALOGV("%s", __FUNCTION__); + + native_data_t *nat = (native_data_t *)n; + const char *address= (const char *)user; + DBusError err; + dbus_error_init(&err); + JNIEnv *env; + nat->vm->GetEnv((void**)&env, nat->envVer); + + ALOGV("... Address = %s", address); + + jint result = CREATE_DEVICE_SUCCESS; + if (dbus_set_error_from_message(&err, msg)) { + if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) { + result = CREATE_DEVICE_ALREADY_EXISTS; + } else { + result = CREATE_DEVICE_FAILED; + } + LOG_AND_FREE_DBUS_ERROR(&err); + } + jstring addr = env->NewStringUTF(address); + env->CallVoidMethod(nat->me, + method_onCreateDeviceResult, + addr, + result); + env->DeleteLocalRef(addr); + free(user); +} + +void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) { + ALOGV("%s", __FUNCTION__); + + native_data_t *nat = (native_data_t *)n; + const char *path = (const char *)user; + DBusError err; + dbus_error_init(&err); + JNIEnv *env; + nat->vm->GetEnv((void**)&env, nat->envVer); + + ALOGV("... Device Path = %s", path); + + bool result = JNI_TRUE; + if (dbus_set_error_from_message(&err, msg)) { + LOG_AND_FREE_DBUS_ERROR(&err); + result = JNI_FALSE; + } + jstring jPath = env->NewStringUTF(path); + env->CallVoidMethod(nat->me, + method_onDiscoverServicesResult, + jPath, + result); + env->DeleteLocalRef(jPath); + free(user); +} + +void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) { + ALOGV("%s", __FUNCTION__); + + const char *address = (const char *) user; + native_data_t *nat = (native_data_t *) n; + + DBusError err; + dbus_error_init(&err); + JNIEnv *env; + nat->vm->GetEnv((void**)&env, nat->envVer); + + jint channel = -2; + + ALOGV("... address = %s", address); + + if (dbus_set_error_from_message(&err, msg) || + !dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &channel, + DBUS_TYPE_INVALID)) { + ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message); + dbus_error_free(&err); + } + +done: + jstring addr = env->NewStringUTF(address); + env->CallVoidMethod(nat->me, + method_onGetDeviceServiceChannelResult, + addr, + channel); + env->DeleteLocalRef(addr); + free(user); +} + +void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) { + ALOGV("%s", __FUNCTION__); + + native_data_t *nat = (native_data_t *)n; + const char *path = (const char *)user; + DBusError err; + dbus_error_init(&err); + JNIEnv *env; + nat->vm->GetEnv((void**)&env, nat->envVer); + + jint result = INPUT_OPERATION_SUCCESS; + if (dbus_set_error_from_message(&err, msg)) { + if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) { + result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED; + } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) { + result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED; + } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) { + // TODO():This is flaky, need to change Bluez to add new error codes + if (!strcmp(err.message, "Transport endpoint is not connected")) { + result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED; + } else { + result = INPUT_OPERATION_GENERIC_FAILURE; + } + } else { + result = INPUT_OPERATION_GENERIC_FAILURE; + } + LOG_AND_FREE_DBUS_ERROR(&err); + } + + ALOGV("... Device Path = %s, result = %d", path, result); + jstring jPath = env->NewStringUTF(path); + env->CallVoidMethod(nat->me, + method_onInputDeviceConnectionResult, + jPath, + result); + env->DeleteLocalRef(jPath); + free(user); +} + +void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) { + ALOGV("%s", __FUNCTION__); + + native_data_t *nat = (native_data_t *)n; + const char *path = (const char *)user; + DBusError err; + dbus_error_init(&err); + JNIEnv *env; + nat->vm->GetEnv((void**)&env, nat->envVer); + + jint result = PAN_OPERATION_SUCCESS; + if (dbus_set_error_from_message(&err, msg)) { + if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) { + result = PAN_CONNECT_FAILED_ATTEMPT_FAILED; + } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) { + // TODO():This is flaky, need to change Bluez to add new error codes + if (!strcmp(err.message, "Device already connected")) { + result = PAN_CONNECT_FAILED_ALREADY_CONNECTED; + } else if (!strcmp(err.message, "Device not connected")) { + result = PAN_DISCONNECT_FAILED_NOT_CONNECTED; + } else { + result = PAN_OPERATION_GENERIC_FAILURE; + } + } else { + result = PAN_OPERATION_GENERIC_FAILURE; + } + LOG_AND_FREE_DBUS_ERROR(&err); + } + + ALOGV("... Pan Device Path = %s, result = %d", path, result); + jstring jPath = env->NewStringUTF(path); + env->CallVoidMethod(nat->me, + method_onPanDeviceConnectionResult, + jPath, + result); + env->DeleteLocalRef(jPath); + free(user); +} + +void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) { + ALOGV("%s", __FUNCTION__); + + native_data_t *nat = (native_data_t *)n; + DBusError err; + dbus_error_init(&err); + JNIEnv *env; + nat->vm->GetEnv((void**)&env, nat->envVer); + + jint result = HEALTH_OPERATION_SUCCESS; + if (dbus_set_error_from_message(&err, msg)) { + if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) { + result = HEALTH_OPERATION_INVALID_ARGS; + } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) { + result = HEALTH_OPERATION_ERROR; + } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) { + result = HEALTH_OPERATION_NOT_FOUND; + } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) { + result = HEALTH_OPERATION_NOT_ALLOWED; + } else { + result = HEALTH_OPERATION_GENERIC_FAILURE; + } + LOG_AND_FREE_DBUS_ERROR(&err); + } + + jint code = *(int *) user; + ALOGV("... Health Device Code = %d, result = %d", code, result); + env->CallVoidMethod(nat->me, + method_onHealthDeviceConnectionResult, + code, + result); + free(user); +} +#endif + +static JNINativeMethod sMethods[] = { + /* name, signature, funcPtr */ + {"classInitNative", "()V", (void *)classInitNative}, + {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative}, + {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative}, + {"startEventLoopNative", "()V", (void *)startEventLoopNative}, + {"stopEventLoopNative", "()V", (void *)stopEventLoopNative}, + {"isEventLoopRunningNative", "()Z", (void *)isEventLoopRunningNative} +}; + +int register_android_server_BluetoothEventLoop(JNIEnv *env) { + return AndroidRuntime::registerNativeMethods(env, + "android/server/BluetoothEventLoop", sMethods, NELEM(sMethods)); +} + +} /* namespace android */ diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 2c23f9db9468..2f2d62732b9b 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -556,22 +556,22 @@ static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobj } const char16_t* defType16 = defType - ? env->GetStringChars(defType, NULL) : NULL; + ? (char16_t*)env->GetStringChars(defType, NULL) : NULL; jsize defTypeLen = defType ? env->GetStringLength(defType) : 0; const char16_t* defPackage16 = defPackage - ? env->GetStringChars(defPackage, NULL) : NULL; + ? (char16_t*)env->GetStringChars(defPackage, NULL) : NULL; jsize defPackageLen = defPackage ? env->GetStringLength(defPackage) : 0; jint ident = am->getResources().identifierForName( - name16.get(), name16.size(), defType16, defTypeLen, defPackage16, defPackageLen); + (char16_t*)name16.get(), name16.size(), defType16, defTypeLen, defPackage16, defPackageLen); if (defPackage16) { - env->ReleaseStringChars(defPackage, defPackage16); + env->ReleaseStringChars(defPackage, (jchar*)defPackage16); } if (defType16) { - env->ReleaseStringChars(defType, defType16); + env->ReleaseStringChars(defType, (jchar*)defType16); } return ident; @@ -1502,7 +1502,7 @@ static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* str = env->NewStringUTF(str8); } else { const char16_t* str16 = pool->stringAt(value.data, &strLen); - str = env->NewString(str16, strLen); + str = env->NewString((jchar*)str16, strLen); } // If one of our NewString{UTF} calls failed due to memory, an diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 3ac2225ebbdb..ae7dc402c4ab 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -924,7 +924,7 @@ static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobjec IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); if (target != NULL) { const String16& desc = target->getInterfaceDescriptor(); - return env->NewString(desc.string(), desc.size()); + return env->NewString((jchar*)desc.string(), desc.size()); } jniThrowException(env, "java/lang/RuntimeException", "No binder found for object"); diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 8325217cc9fd..bb4847c0cccb 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -105,7 +105,7 @@ jint android_os_Process_getUidForName(JNIEnv* env, jobject clazz, jstring name) const jchar* str16 = env->GetStringCritical(name, 0); String8 name8; if (str16) { - name8 = String8(str16, env->GetStringLength(name)); + name8 = String8((char16_t*)str16, env->GetStringLength(name)); env->ReleaseStringCritical(name, str16); } @@ -136,7 +136,7 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name) const jchar* str16 = env->GetStringCritical(name, 0); String8 name8; if (str16) { - name8 = String8(str16, env->GetStringLength(name)); + name8 = String8((char16_t*)str16, env->GetStringLength(name)); env->ReleaseStringCritical(name, str16); } @@ -397,7 +397,7 @@ void android_os_Process_setArgV0(JNIEnv* env, jobject clazz, jstring name) const jchar* str = env->GetStringCritical(name, 0); String8 name8; if (str) { - name8 = String8(str, env->GetStringLength(name)); + name8 = String8((char16_t*)str, env->GetStringLength(name)); env->ReleaseStringCritical(name, str); } diff --git a/core/jni/android_util_XmlBlock.cpp b/core/jni/android_util_XmlBlock.cpp index ad6033b1c175..c3c48d9bd804 100644 --- a/core/jni/android_util_XmlBlock.cpp +++ b/core/jni/android_util_XmlBlock.cpp @@ -264,19 +264,19 @@ static jint android_content_XmlBlock_nativeGetAttributeIndex(JNIEnv* env, jobjec const char16_t* ns16 = NULL; jsize nsLen = 0; if (ns) { - ns16 = env->GetStringChars(ns, NULL); + ns16 = (char16_t*)env->GetStringChars(ns, NULL); nsLen = env->GetStringLength(ns); } - const char16_t* name16 = env->GetStringChars(name, NULL); + const char16_t* name16 = (char16_t*)env->GetStringChars(name, NULL); jsize nameLen = env->GetStringLength(name); jint idx = (jint)st->indexOfAttribute(ns16, nsLen, name16, nameLen); if (ns) { - env->ReleaseStringChars(ns, ns16); + env->ReleaseStringChars(ns, (jchar*)ns16); } - env->ReleaseStringChars(name, name16); + env->ReleaseStringChars(name, (jchar*)name16); return idx; } diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp index ffe2deaba8c6..d8724cba6015 100644 --- a/core/jni/android_view_KeyCharacterMap.cpp +++ b/core/jni/android_view_KeyCharacterMap.cpp @@ -148,7 +148,7 @@ static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jint ptr, jint keyCode, return 0; } - char16_t result = map->getMap()->getMatch(keyCode, chars, size_t(numChars), metaState); + char16_t result = map->getMap()->getMatch(keyCode, (const char16_t*)chars, size_t(numChars), metaState); env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT); return result; @@ -176,7 +176,7 @@ static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, Vector<KeyEvent> events; jobjectArray result = NULL; - if (map->getMap()->getEvents(map->getDeviceId(), chars, size_t(numChars), events)) { + if (map->getMap()->getEvents(map->getDeviceId(), (const char16_t*)chars, size_t(numChars), events)) { result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL); if (result) { for (size_t i = 0; i < events.size(); i++) { diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index ac9f82c430b4..6ea9cbdb4b8f 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -564,7 +564,7 @@ decodeLength(const uint8_t** str) return len; } -const uint16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const +const char16_t* ResStringPool::stringAt(size_t idx, size_t* u16len) const { if (mError == NO_ERROR && idx < mHeader->stringCount) { const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0; @@ -886,7 +886,7 @@ int32_t ResXMLParser::getCommentID() const const uint16_t* ResXMLParser::getComment(size_t* outLen) const { int32_t id = getCommentID(); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } uint32_t ResXMLParser::getLineNumber() const @@ -905,7 +905,7 @@ int32_t ResXMLParser::getTextID() const const uint16_t* ResXMLParser::getText(size_t* outLen) const { int32_t id = getTextID(); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } ssize_t ResXMLParser::getTextValue(Res_value* outValue) const @@ -929,7 +929,7 @@ const uint16_t* ResXMLParser::getNamespacePrefix(size_t* outLen) const { int32_t id = getNamespacePrefixID(); //printf("prefix=%d event=%p\n", id, mEventCode); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } int32_t ResXMLParser::getNamespaceUriID() const @@ -944,7 +944,7 @@ const uint16_t* ResXMLParser::getNamespaceUri(size_t* outLen) const { int32_t id = getNamespaceUriID(); //printf("uri=%d event=%p\n", id, mEventCode); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } int32_t ResXMLParser::getElementNamespaceID() const @@ -961,7 +961,7 @@ int32_t ResXMLParser::getElementNamespaceID() const const uint16_t* ResXMLParser::getElementNamespace(size_t* outLen) const { int32_t id = getElementNamespaceID(); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } int32_t ResXMLParser::getElementNameID() const @@ -978,7 +978,7 @@ int32_t ResXMLParser::getElementNameID() const const uint16_t* ResXMLParser::getElementName(size_t* outLen) const { int32_t id = getElementNameID(); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } size_t ResXMLParser::getAttributeCount() const @@ -1009,7 +1009,7 @@ const uint16_t* ResXMLParser::getAttributeNamespace(size_t idx, size_t* outLen) int32_t id = getAttributeNamespaceID(idx); //printf("attribute namespace=%d idx=%d event=%p\n", id, idx, mEventCode); //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id)); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } const char* ResXMLParser::getAttributeNamespace8(size_t idx, size_t* outLen) const @@ -1040,7 +1040,7 @@ const uint16_t* ResXMLParser::getAttributeName(size_t idx, size_t* outLen) const int32_t id = getAttributeNameID(idx); //printf("attribute name=%d idx=%d event=%p\n", id, idx, mEventCode); //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id)); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } const char* ResXMLParser::getAttributeName8(size_t idx, size_t* outLen) const @@ -1079,7 +1079,7 @@ const uint16_t* ResXMLParser::getAttributeStringValue(size_t idx, size_t* outLen { int32_t id = getAttributeValueStringID(idx); //XML_NOISY(printf("getAttributeValue 0x%x=0x%x\n", idx, id)); - return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL; + return id >= 0 ? (const uint16_t*)mTree.mStrings.stringAt(id, outLen) : NULL; } int32_t ResXMLParser::getAttributeDataType(size_t idx) const @@ -1144,63 +1144,21 @@ ssize_t ResXMLParser::indexOfAttribute(const char16_t* ns, size_t nsLen, return NAME_NOT_FOUND; } const size_t N = getAttributeCount(); - if (mTree.mStrings.isUTF8()) { - String8 ns8, attr8; - if (ns != NULL) { - ns8 = String8(ns, nsLen); - } - attr8 = String8(attr, attrLen); - STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF8 %s (%d) / %s (%d)", ns8.string(), nsLen, - attr8.string(), attrLen)); - for (size_t i=0; i<N; i++) { - size_t curNsLen = 0, curAttrLen = 0; - const char* curNs = getAttributeNamespace8(i, &curNsLen); - const char* curAttr = getAttributeName8(i, &curAttrLen); - STRING_POOL_NOISY(ALOGI(" curNs=%s (%d), curAttr=%s (%d)", curNs, curNsLen, - curAttr, curAttrLen)); - if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen - && memcmp(attr8.string(), curAttr, attrLen) == 0) { - if (ns == NULL) { - if (curNs == NULL) { - STRING_POOL_NOISY(ALOGI(" FOUND!")); - return i; - } - } else if (curNs != NULL) { - //printf(" --> ns=%s, curNs=%s\n", - // String8(ns).string(), String8(curNs).string()); - if (memcmp(ns8.string(), curNs, nsLen) == 0) { - STRING_POOL_NOISY(ALOGI(" FOUND!")); - return i; - } - } - } - } - } else { - STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF16 %s (%d) / %s (%d)", - String8(ns, nsLen).string(), nsLen, - String8(attr, attrLen).string(), attrLen)); - for (size_t i=0; i<N; i++) { - size_t curNsLen = 0, curAttrLen = 0; - const char16_t* curNs = getAttributeNamespace(i, &curNsLen); - const char16_t* curAttr = getAttributeName(i, &curAttrLen); - STRING_POOL_NOISY(ALOGI(" curNs=%s (%d), curAttr=%s (%d)", - String8(curNs, curNsLen).string(), curNsLen, - String8(curAttr, curAttrLen).string(), curAttrLen)); - if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen - && (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) { - if (ns == NULL) { - if (curNs == NULL) { - STRING_POOL_NOISY(ALOGI(" FOUND!")); - return i; - } - } else if (curNs != NULL) { - //printf(" --> ns=%s, curNs=%s\n", - // String8(ns).string(), String8(curNs).string()); - if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) { - STRING_POOL_NOISY(ALOGI(" FOUND!")); - return i; - } - } + for (size_t i=0; i<N; i++) { + size_t curNsLen, curAttrLen; + const char16_t* curNs = (const char16_t*)getAttributeNamespace(i, &curNsLen); + const char16_t* curAttr = (const char16_t*)getAttributeName(i, &curAttrLen); + //printf("%d: ns=%p attr=%p curNs=%p curAttr=%p\n", + // i, ns, attr, curNs, curAttr); + //printf(" --> attr=%s, curAttr=%s\n", + // String8(attr).string(), String8(curAttr).string()); + if (attr && curAttr && (strzcmp16(attr, attrLen, curAttr, curAttrLen) == 0)) { + if (ns == NULL) { + if (curNs == NULL) return i; + } else if (curNs != NULL) { + //printf(" --> ns=%s, curNs=%s\n", + // String8(ns).string(), String8(curNs).string()); + if (strzcmp16(ns, nsLen, curNs, curNsLen) == 0) return i; } } } @@ -3915,7 +3873,7 @@ bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen, { const char16_t* packageEnd = NULL; const char16_t* typeEnd = NULL; - const char16_t* p = refStr; + const char16_t* p = (const char16_t*)refStr; const char16_t* const end = p + refLen; while (p < end) { if (*p == ':') packageEnd = p; @@ -3925,7 +3883,7 @@ bool ResTable::expandResourceRef(const uint16_t* refStr, size_t refLen, } p++; } - p = refStr; + p = (char16_t*)refStr; if (*p == '@') p++; if (outPublicOnly != NULL) { @@ -4324,7 +4282,7 @@ bool ResTable::stringToValue(Res_value* outValue, String16* outString, resourceNameLen = len - 1; } String16 package, type, name; - if (!expandResourceRef(resourceRefName,resourceNameLen, &package, &type, &name, + if (!expandResourceRef((const uint16_t*)resourceRefName,resourceNameLen, &package, &type, &name, defType, defPackage, &errorMsg)) { if (accessor != NULL) { accessor->reportError(accessorCookie, errorMsg); @@ -4474,7 +4432,7 @@ bool ResTable::stringToValue(Res_value* outValue, String16* outString, static const String16 attr16("attr"); String16 package, type, name; - if (!expandResourceRef(s+1, len-1, &package, &type, &name, + if (!expandResourceRef((const uint16_t*)s+1, len-1, &package, &type, &name, &attr16, defPackage, &errorMsg)) { if (accessor != NULL) { accessor->reportError(accessorCookie, errorMsg); @@ -5156,7 +5114,7 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, idx = mPackageGroups.size()+1; char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)]; - strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t)); + strcpy16_dtoh((uint16_t*)tmpName, (const uint16_t*)pkg->name, sizeof(pkg->name)/sizeof(char16_t)); group = new PackageGroup(this, String16(tmpName), id); if (group == NULL) { delete package; diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index 77c796652442..f74d78f2c9a0 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -786,7 +786,7 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED; jchar* str = env->GetCharArrayElements(mStringBuffer, 0); - MtpString temp(str); + MtpString temp((char16_t*)str); info.mName = strdup((const char *)temp); env->ReleaseCharArrayElements(mStringBuffer, str, 0); @@ -859,7 +859,7 @@ MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle, } jchar* str = env->GetCharArrayElements(mStringBuffer, 0); - outFilePath.setTo(str, strlen16(str)); + outFilePath.setTo((char16_t*)str, strlen16((char16_t*)str)); env->ReleaseCharArrayElements(mStringBuffer, str, 0); jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0); diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp index d8099dd2fd07..fa88818acc58 100644 --- a/media/jni/mediaeditor/VideoEditorClasses.cpp +++ b/media/jni/mediaeditor/VideoEditorClasses.cpp @@ -551,24 +551,24 @@ VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(ClipSettings, CLIP_SETTINGS_CLASS_NAME) VIDEOEDIT_JAVA_DEFINE_FIELDS(EditSettings) { - VIDEOEDIT_JAVA_FIELD_INIT("clipSettingsArray", "[L"CLIP_SETTINGS_CLASS_NAME";" ), - VIDEOEDIT_JAVA_FIELD_INIT("transitionSettingsArray", "[L"TRANSITION_SETTINGS_CLASS_NAME";" ), - VIDEOEDIT_JAVA_FIELD_INIT("effectSettingsArray", "[L"EFFECT_SETTINGS_CLASS_NAME";" ), - VIDEOEDIT_JAVA_FIELD_INIT("videoFrameRate", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("outputFile", "Ljava/lang/String;" ), - VIDEOEDIT_JAVA_FIELD_INIT("videoFrameSize", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("videoFormat", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("videoProfile", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("videoLevel", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("audioFormat", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("audioSamplingFreq", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("maxFileSize", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("audioChannels", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("videoBitrate", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("audioBitrate", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("clipSettingsArray", "[L" CLIP_SETTINGS_CLASS_NAME ";" ), + VIDEOEDIT_JAVA_FIELD_INIT("transitionSettingsArray", "[L" TRANSITION_SETTINGS_CLASS_NAME ";" ), + VIDEOEDIT_JAVA_FIELD_INIT("effectSettingsArray", "[L" EFFECT_SETTINGS_CLASS_NAME ";" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoFrameRate", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("outputFile", "Ljava/lang/String;" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoFrameSize", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoFormat", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoProfile", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoLevel", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioFormat", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioSamplingFreq", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("maxFileSize", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioChannels", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoBitrate", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioBitrate", "I" ), VIDEOEDIT_JAVA_FIELD_INIT("backgroundMusicSettings",\ - "L"BACKGROUND_MUSIC_SETTINGS_CLASS_NAME";"), - VIDEOEDIT_JAVA_FIELD_INIT("primaryTrackVolume", "I" ) + "L" BACKGROUND_MUSIC_SETTINGS_CLASS_NAME ";"), + VIDEOEDIT_JAVA_FIELD_INIT("primaryTrackVolume", "I" ) }; VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(EditSettings, EDIT_SETTINGS_CLASS_NAME) @@ -625,12 +625,12 @@ VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(SlideTransitionSettings, SLIDE_TRANSITION_SETT VIDEOEDIT_JAVA_DEFINE_FIELDS(TransitionSettings) { - VIDEOEDIT_JAVA_FIELD_INIT("duration", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("videoTransitionType", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("audioTransitionType", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("transitionBehaviour", "I" ), - VIDEOEDIT_JAVA_FIELD_INIT("alphaSettings", "L"ALPHA_MAGIC_SETTINGS_CLASS_NAME";" ), - VIDEOEDIT_JAVA_FIELD_INIT("slideSettings", "L"SLIDE_TRANSITION_SETTINGS_CLASS_NAME";") + VIDEOEDIT_JAVA_FIELD_INIT("duration", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("videoTransitionType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("audioTransitionType", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("transitionBehaviour", "I" ), + VIDEOEDIT_JAVA_FIELD_INIT("alphaSettings", "L" ALPHA_MAGIC_SETTINGS_CLASS_NAME ";" ), + VIDEOEDIT_JAVA_FIELD_INIT("slideSettings", "L" SLIDE_TRANSITION_SETTINGS_CLASS_NAME ";") }; VIDEOEDIT_JAVA_DEFINE_FIELD_CLASS(TransitionSettings, TRANSITION_SETTINGS_CLASS_NAME) diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp index c1ad516977da..76fc384c7527 100644 --- a/media/jni/mediaeditor/VideoEditorMain.cpp +++ b/media/jni/mediaeditor/VideoEditorMain.cpp @@ -269,15 +269,15 @@ static void videoEditor_clearSurface(JNIEnv* pEnv, jobject surface); static JNINativeMethod gManualEditMethods[] = { - {"getVersion", "()L"VERSION_CLASS_NAME";", + {"getVersion", "()L" VERSION_CLASS_NAME ";", (void *)videoEditor_getVersion }, {"_init", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)videoEditor_init }, {"nativeStartPreview", "(Landroid/view/Surface;JJIZ)V", (void *)videoEditor_startPreview }, {"nativePopulateSettings", - "(L"EDIT_SETTINGS_CLASS_NAME";L"PREVIEW_PROPERTIES_CLASS_NAME";L" - AUDIO_SETTINGS_CLASS_NAME";)V", + "(L" EDIT_SETTINGS_CLASS_NAME ";L" PREVIEW_PROPERTIES_CLASS_NAME ";L" + AUDIO_SETTINGS_CLASS_NAME ";)V", (void *)videoEditor_populateSettings }, {"nativeRenderPreviewFrame", "(Landroid/view/Surface;JII)I", (int *)videoEditor_renderPreviewFrame }, @@ -301,7 +301,7 @@ static JNINativeMethod gManualEditMethods[] = { (int *)videoEditor_generateAudioWaveFormSync }, {"nativeGenerateRawAudio", "(Ljava/lang/String;Ljava/lang/String;)I", (int *)videoEditor_generateAudioRawFile }, - {"nativeGenerateClip", "(L"EDIT_SETTINGS_CLASS_NAME";)I", + {"nativeGenerateClip", "(L" EDIT_SETTINGS_CLASS_NAME ";)I", (void *)videoEditor_generateClip }, {"nativeClearSurface", "(Landroid/view/Surface;)V", (void *)videoEditor_clearSurface }, @@ -1585,7 +1585,7 @@ videoEditor_populateSettings( "not initialized"); jfieldID fid = pEnv->GetFieldID(mPreviewClipPropClazz,"clipProperties", - "[L"PROPERTIES_CLASS_NAME";" ); + "[L" PROPERTIES_CLASS_NAME ";" ); videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, (M4OSA_NULL == fid), "not initialized"); @@ -1655,7 +1655,7 @@ videoEditor_populateSettings( M4OSA_TRACE1_0("cannot find object field for mEffectsClazz"); goto videoEditor_populateSettings_cleanup; } - fid = pEnv->GetFieldID(mEditClazz,"effectSettingsArray", "[L"EFFECT_SETTINGS_CLASS_NAME";" ); + fid = pEnv->GetFieldID(mEditClazz,"effectSettingsArray", "[L" EFFECT_SETTINGS_CLASS_NAME ";" ); if(fid == M4OSA_NULL) { M4OSA_TRACE1_0("cannot find field for effectSettingsArray Array"); |