diff options
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/Android.mk | 3 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 6 | ||||
-rw-r--r-- | core/jni/android/graphics/Bitmap.cpp | 9 | ||||
-rw-r--r-- | core/jni/android_app_NativeActivity.cpp | 16 | ||||
-rw-r--r-- | core/jni/android_media_AudioSystem.cpp | 67 | ||||
-rw-r--r-- | core/jni/android_net_wifi_WifiNative.cpp (renamed from core/jni/android_net_wifi_Wifi.cpp) | 137 | ||||
-rw-r--r-- | core/jni/android_os_ParcelFileDescriptor.cpp | 151 | ||||
-rw-r--r-- | core/jni/android_view_Surface.cpp | 15 |
8 files changed, 96 insertions, 308 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 0efa227..d5d746a 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -63,7 +63,6 @@ LOCAL_SRC_FILES:= \ android_os_FileUtils.cpp \ android_os_MemoryFile.cpp \ android_os_MessageQueue.cpp \ - android_os_ParcelFileDescriptor.cpp \ android_os_Parcel.cpp \ android_os_SELinux.cpp \ android_os_SystemClock.cpp \ @@ -73,7 +72,7 @@ LOCAL_SRC_FILES:= \ android_net_LocalSocketImpl.cpp \ android_net_NetUtils.cpp \ android_net_TrafficStats.cpp \ - android_net_wifi_Wifi.cpp \ + android_net_wifi_WifiNative.cpp \ android_nio_utils.cpp \ android_text_format_Time.cpp \ android_util_AssetManager.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 91fdcc2..8472705 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -135,7 +135,6 @@ extern int register_android_text_format_Time(JNIEnv* env); extern int register_android_os_Debug(JNIEnv* env); extern int register_android_os_MessageQueue(JNIEnv* env); extern int register_android_os_Parcel(JNIEnv* env); -extern int register_android_os_ParcelFileDescriptor(JNIEnv *env); extern int register_android_os_SELinux(JNIEnv* env); extern int register_android_os_SystemProperties(JNIEnv *env); extern int register_android_os_SystemClock(JNIEnv* env); @@ -148,7 +147,7 @@ extern int register_android_print_pdf_PdfDocument(JNIEnv* env); extern int register_android_net_LocalSocketImpl(JNIEnv* env); extern int register_android_net_NetworkUtils(JNIEnv* env); extern int register_android_net_TrafficStats(JNIEnv* env); -extern int register_android_net_wifi_WifiManager(JNIEnv* env); +extern int register_android_net_wifi_WifiNative(JNIEnv* env); extern int register_android_text_AndroidCharacter(JNIEnv *env); extern int register_android_text_AndroidBidi(JNIEnv *env); extern int register_android_opengl_classes(JNIEnv *env); @@ -1178,7 +1177,6 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_FileObserver), REG_JNI(register_android_os_FileUtils), REG_JNI(register_android_os_MessageQueue), - REG_JNI(register_android_os_ParcelFileDescriptor), REG_JNI(register_android_os_SELinux), REG_JNI(register_android_os_Trace), REG_JNI(register_android_os_UEventObserver), @@ -1186,7 +1184,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_net_LocalSocketImpl), REG_JNI(register_android_net_NetworkUtils), REG_JNI(register_android_net_TrafficStats), - REG_JNI(register_android_net_wifi_WifiManager), + REG_JNI(register_android_net_wifi_WifiNative), REG_JNI(register_android_os_MemoryFile), REG_JNI(register_com_android_internal_os_ZygoteInit), REG_JNI(register_android_hardware_Camera), diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index b03d12a..0ea3bf7 100644 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -222,8 +222,12 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, }
}
- SkBitmap bitmap;
+ // ARGB_4444 is a deprecated format, convert automatically to 8888
+ if (config == SkBitmap::kARGB_4444_Config) {
+ config = SkBitmap::kARGB_8888_Config;
+ }
+ SkBitmap bitmap;
bitmap.setConfig(config, width, height);
jbyteArray buff = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL);
@@ -232,8 +236,7 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, }
if (jColors != NULL) {
- GraphicsJNI::SetPixels(env, jColors, offset, stride,
- 0, 0, width, height, bitmap);
+ GraphicsJNI::SetPixels(env, jColors, offset, stride, 0, 0, width, height, bitmap);
}
return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff, isMutable, NULL, NULL);
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp index f768ce8..5418006 100644 --- a/core/jni/android_app_NativeActivity.cpp +++ b/core/jni/android_app_NativeActivity.cpp @@ -306,19 +306,23 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName code->internalDataPath = code->internalDataPathObj.string(); env->ReleaseStringUTFChars(internalDataDir, dirStr); - dirStr = env->GetStringUTFChars(externalDataDir, NULL); - code->externalDataPathObj = dirStr; + if (externalDataDir != NULL) { + dirStr = env->GetStringUTFChars(externalDataDir, NULL); + code->externalDataPathObj = dirStr; + env->ReleaseStringUTFChars(externalDataDir, dirStr); + } code->externalDataPath = code->externalDataPathObj.string(); - env->ReleaseStringUTFChars(externalDataDir, dirStr); code->sdkVersion = sdkVersion; code->assetManager = assetManagerForJavaObject(env, jAssetMgr); - dirStr = env->GetStringUTFChars(obbDir, NULL); - code->obbPathObj = dirStr; + if (obbDir != NULL) { + dirStr = env->GetStringUTFChars(obbDir, NULL); + code->obbPathObj = dirStr; + env->ReleaseStringUTFChars(obbDir, dirStr); + } code->obbPath = code->obbPathObj.string(); - env->ReleaseStringUTFChars(obbDir, dirStr); jbyte* rawSavedState = NULL; jsize rawSavedSize = 0; diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index d6c5e4f..7d99464 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -41,11 +41,15 @@ enum AudioError { static int check_AudioSystem_Command(status_t status) { - if (status == NO_ERROR) { + switch (status) { + case DEAD_OBJECT: + return kAudioStatusMediaServerDied; + case NO_ERROR: return kAudioStatusOk; - } else { - return kAudioStatusError; + default: + break; } + return kAudioStatusError; } static int @@ -112,61 +116,19 @@ android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys) return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string()); } -static JNIEnv* AudioSystem_getJNIEnv(bool* needsDetach) { - *needsDetach = false; - JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (env == NULL) { - JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL}; - JavaVM* vm = AndroidRuntime::getJavaVM(); - int result = vm->AttachCurrentThread(&env, (void*) &args); - if (result != JNI_OK) { - ALOGE("thread attach failed: %#x", result); - return NULL; - } - *needsDetach = true; - } - return env; -} - -static void AudioSystem_detachJNI() { - JavaVM* vm = AndroidRuntime::getJavaVM(); - int result = vm->DetachCurrentThread(); - if (result != JNI_OK) { - ALOGE("thread detach failed: %#x", result); - } -} - static void android_media_AudioSystem_error_callback(status_t err) { - bool needsDetach = false; - JNIEnv *env = AudioSystem_getJNIEnv(&needsDetach); - + JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } jclass clazz = env->FindClass(kClassPathName); - int error; - - switch (err) { - case DEAD_OBJECT: - error = kAudioStatusMediaServerDied; - break; - case NO_ERROR: - error = kAudioStatusOk; - break; - default: - error = kAudioStatusError; - break; - } - - env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error); - - if (needsDetach) { - AudioSystem_detachJNI(); - } + env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, + "errorCallbackFromNative","(I)V"), + check_AudioSystem_Command(err)); } static int @@ -313,6 +275,12 @@ android_media_AudioSystem_setLowRamDevice(JNIEnv *env, jobject clazz, jboolean i return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice); } +static int +android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz) +{ + return check_AudioSystem_Command(AudioSystem::checkAudioFlinger()); +} + // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { @@ -340,6 +308,7 @@ static JNINativeMethod gMethods[] = { {"getPrimaryOutputFrameCount", "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount}, {"getOutputLatency", "(I)I", (void *)android_media_AudioSystem_getOutputLatency}, {"setLowRamDevice", "(Z)I", (void *)android_media_AudioSystem_setLowRamDevice}, + {"checkAudioFlinger", "()I", (void *)android_media_AudioSystem_checkAudioFlinger}, }; int register_android_media_AudioSystem(JNIEnv *env) diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_WifiNative.cpp index aa6dbf3..6e11192 100644 --- a/core/jni/android_net_wifi_Wifi.cpp +++ b/core/jni/android_net_wifi_WifiNative.cpp @@ -25,111 +25,91 @@ #include "wifi.h" -#define WIFI_PKG_NAME "android/net/wifi/WifiNative" -#define BUF_SIZE 256 +#define REPLY_BUF_SIZE 4096 // wpa_supplicant's maximum size. #define EVENT_BUF_SIZE 2048 namespace android { static jint DBG = false; -static int doCommand(char *cmd, char *replybuf, int replybuflen) -{ - size_t reply_len = replybuflen - 1; +static bool doCommand(JNIEnv* env, jstring javaCommand, + char* reply, size_t reply_len) { + ScopedUtfChars command(env, javaCommand); + if (command.c_str() == NULL) { + return false; // ScopedUtfChars already threw on error. + } - if (::wifi_command(cmd, replybuf, &reply_len) != 0) - return -1; - else { - // Strip off trailing newline - if (reply_len > 0 && replybuf[reply_len-1] == '\n') - replybuf[reply_len-1] = '\0'; - else - replybuf[reply_len] = '\0'; - return 0; + if (DBG) { + ALOGD("doCommand: %s", command.c_str()); } -} -static jint doIntCommand(const char* fmt, ...) -{ - char buf[BUF_SIZE]; - va_list args; - va_start(args, fmt); - int byteCount = vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - if (byteCount < 0 || byteCount >= BUF_SIZE) { - return -1; + --reply_len; // Ensure we have room to add NUL termination. + if (::wifi_command(command.c_str(), reply, &reply_len) != 0) { + return false; + } + + // Strip off trailing newline. + if (reply_len > 0 && reply[reply_len-1] == '\n') { + reply[reply_len-1] = '\0'; + } else { + reply[reply_len] = '\0'; } - char reply[BUF_SIZE]; - if (doCommand(buf, reply, sizeof(reply)) != 0) { + return true; +} + +static jint doIntCommand(JNIEnv* env, jstring javaCommand) { + char reply[REPLY_BUF_SIZE]; + if (!doCommand(env, javaCommand, reply, sizeof(reply))) { return -1; } return static_cast<jint>(atoi(reply)); } -static jboolean doBooleanCommand(const char* expect, const char* fmt, ...) -{ - char buf[BUF_SIZE]; - va_list args; - va_start(args, fmt); - int byteCount = vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - if (byteCount < 0 || byteCount >= BUF_SIZE) { - return JNI_FALSE; - } - char reply[BUF_SIZE]; - if (doCommand(buf, reply, sizeof(reply)) != 0) { +static jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) { + char reply[REPLY_BUF_SIZE]; + if (!doCommand(env, javaCommand, reply, sizeof(reply))) { return JNI_FALSE; } - return (strcmp(reply, expect) == 0); + return (strcmp(reply, "OK") == 0); } -// Send a command to the supplicant, and return the reply as a String -static jstring doStringCommand(JNIEnv* env, const char* fmt, ...) { - char buf[BUF_SIZE]; - va_list args; - va_start(args, fmt); - int byteCount = vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - if (byteCount < 0 || byteCount >= BUF_SIZE) { - return NULL; - } - char reply[4096]; - if (doCommand(buf, reply, sizeof(reply)) != 0) { +// Send a command to the supplicant, and return the reply as a String. +static jstring doStringCommand(JNIEnv* env, jstring javaCommand) { + char reply[REPLY_BUF_SIZE]; + if (!doCommand(env, javaCommand, reply, sizeof(reply))) { return NULL; } - // TODO: why not just NewStringUTF? - String16 str((char *)reply); - return env->NewString((const jchar *)str.string(), str.size()); + return env->NewStringUTF(reply); } static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject) { - return (jboolean)(::is_wifi_driver_loaded() == 1); + return (::is_wifi_driver_loaded() == 1); } static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject) { - return (jboolean)(::wifi_load_driver() == 0); + return (::wifi_load_driver() == 0); } static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject) { - return (jboolean)(::wifi_unload_driver() == 0); + return (::wifi_unload_driver() == 0); } static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) { - return (jboolean)(::wifi_start_supplicant(p2pSupported) == 0); + return (::wifi_start_supplicant(p2pSupported) == 0); } static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) { - return (jboolean)(::wifi_stop_supplicant(p2pSupported) == 0); + return (::wifi_stop_supplicant(p2pSupported) == 0); } static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject) { - return (jboolean)(::wifi_connect_to_supplicant() == 0); + return (::wifi_connect_to_supplicant() == 0); } static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject) @@ -148,36 +128,16 @@ static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject) } } -static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring jCommand) -{ - ScopedUtfChars command(env, jCommand); - - if (command.c_str() == NULL) { - return JNI_FALSE; - } - if (DBG) ALOGD("doBoolean: %s", command.c_str()); - return doBooleanCommand("OK", "%s", command.c_str()); +static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) { + return doBooleanCommand(env, javaCommand); } -static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring jCommand) -{ - ScopedUtfChars command(env, jCommand); - - if (command.c_str() == NULL) { - return -1; - } - if (DBG) ALOGD("doInt: %s", command.c_str()); - return doIntCommand("%s", command.c_str()); +static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) { + return doIntCommand(env, javaCommand); } -static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring jCommand) -{ - ScopedUtfChars command(env, jCommand); - if (command.c_str() == NULL) { - return NULL; - } - if (DBG) ALOGD("doString: %s", command.c_str()); - return doStringCommand(env, "%s", command.c_str()); +static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) { + return doStringCommand(env,javaCommand); } @@ -205,10 +165,9 @@ static JNINativeMethod gWifiMethods[] = { (void*) android_net_wifi_doStringCommand }, }; -int register_android_net_wifi_WifiManager(JNIEnv* env) -{ +int register_android_net_wifi_WifiNative(JNIEnv* env) { return AndroidRuntime::registerNativeMethods(env, - WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods)); + "android/net/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods)); } }; // namespace android diff --git a/core/jni/android_os_ParcelFileDescriptor.cpp b/core/jni/android_os_ParcelFileDescriptor.cpp deleted file mode 100644 index 99a2d04..0000000 --- a/core/jni/android_os_ParcelFileDescriptor.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 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_NDEBUG 0 - -#include "JNIHelp.h" - -#include <fcntl.h> -#include <sys/stat.h> -#include <stdio.h> - -#include <utils/Log.h> - -#include <android_runtime/AndroidRuntime.h> - -namespace android -{ - -static struct parcel_file_descriptor_offsets_t -{ - jfieldID mFileDescriptor; -} gParcelFileDescriptorOffsets; - -static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFd(JNIEnv* env, - jobject clazz, jint origfd) -{ - int fd = dup(origfd); - if (fd < 0) { - jniThrowException(env, "java/io/IOException", strerror(errno)); - return NULL; - } - return jniCreateFileDescriptor(env, fd); -} - -static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup(JNIEnv* env, - jobject clazz, jint fd) -{ - return jniCreateFileDescriptor(env, fd); -} - -static void android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env, - jobject clazz, jobjectArray outFds) -{ - int fds[2]; - if (pipe(fds) < 0) { - int therr = errno; - jniThrowException(env, "java/io/IOException", strerror(therr)); - return; - } - - for (int i=0; i<2; i++) { - jobject fdObj = jniCreateFileDescriptor(env, fds[i]); - env->SetObjectArrayElement(outFds, i, fdObj); - } -} - -static jint getFd(JNIEnv* env, jobject clazz) -{ - jobject descriptor = env->GetObjectField(clazz, gParcelFileDescriptorOffsets.mFileDescriptor); - if (descriptor == NULL) return -1; - return jniGetFDFromFileDescriptor(env, descriptor); -} - -static jlong android_os_ParcelFileDescriptor_getStatSize(JNIEnv* env, - jobject clazz) -{ - jint fd = getFd(env, clazz); - if (fd < 0) { - jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor"); - return -1; - } - - struct stat st; - if (fstat(fd, &st) != 0) { - return -1; - } - - if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { - return st.st_size; - } - - return -1; -} - -static jlong android_os_ParcelFileDescriptor_seekTo(JNIEnv* env, - jobject clazz, jlong pos) -{ - jint fd = getFd(env, clazz); - if (fd < 0) { - jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor"); - return -1; - } - - return lseek(fd, pos, SEEK_SET); -} - -static jlong android_os_ParcelFileDescriptor_getFdNative(JNIEnv* env, jobject clazz) -{ - jint fd = getFd(env, clazz); - if (fd < 0) { - jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor"); - return -1; - } - - return fd; -} - -static const JNINativeMethod gParcelFileDescriptorMethods[] = { - {"getFileDescriptorFromFd", "(I)Ljava/io/FileDescriptor;", - (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFd}, - {"getFileDescriptorFromFdNoDup", "(I)Ljava/io/FileDescriptor;", - (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup}, - {"createPipeNative", "([Ljava/io/FileDescriptor;)V", - (void*)android_os_ParcelFileDescriptor_createPipeNative}, - {"getStatSize", "()J", - (void*)android_os_ParcelFileDescriptor_getStatSize}, - {"seekTo", "(J)J", - (void*)android_os_ParcelFileDescriptor_seekTo}, - {"getFdNative", "()I", - (void*)android_os_ParcelFileDescriptor_getFdNative} -}; - -const char* const kParcelFileDescriptorPathName = "android/os/ParcelFileDescriptor"; - -int register_android_os_ParcelFileDescriptor(JNIEnv* env) -{ - jclass clazz = env->FindClass(kParcelFileDescriptorPathName); - LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor"); - gParcelFileDescriptorOffsets.mFileDescriptor = env->GetFieldID(clazz, "mFileDescriptor", "Ljava/io/FileDescriptor;"); - LOG_FATAL_IF(gParcelFileDescriptorOffsets.mFileDescriptor == NULL, - "Unable to find mFileDescriptor field in android.os.ParcelFileDescriptor"); - - return AndroidRuntime::registerNativeMethods( - env, kParcelFileDescriptorPathName, - gParcelFileDescriptorMethods, NELEM(gParcelFileDescriptorMethods)); -} - -} diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 304514b..3f54fd7 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -196,13 +196,13 @@ static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCa SkSafeUnref(previousCanvas); } -static void nativeLockCanvas(JNIEnv* env, jclass clazz, +static jint nativeLockCanvas(JNIEnv* env, jclass clazz, jint nativeObject, jobject canvasObj, jobject dirtyRectObj) { sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject)); if (!isSurfaceValid(surface)) { doThrowIAE(env); - return; + return 0; } Rect dirtyRect; @@ -223,7 +223,7 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz, OutOfResourcesException : "java/lang/IllegalArgumentException"; jniThrowException(env, exception, NULL); - return; + return 0; } // Associate a SkCanvas object to this surface @@ -255,6 +255,13 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz, env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right); env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom); } + + // Create another reference to the surface and return it. This reference + // should be passed to nativeUnlockCanvasAndPost in place of mNativeObject, + // because the latter could be replaced while the surface is locked. + sp<Surface> lockedSurface(surface); + lockedSurface->incStrong(&sRefBaseOwner); + return (int) lockedSurface.get(); } static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, @@ -351,7 +358,7 @@ static JNINativeMethod gSurfaceMethods[] = { (void*)nativeIsValid }, {"nativeIsConsumerRunningBehind", "(I)Z", (void*)nativeIsConsumerRunningBehind }, - {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V", + {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)I", (void*)nativeLockCanvas }, {"nativeUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V", (void*)nativeUnlockCanvasAndPost }, |