diff options
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/Android.mk | 1 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android/graphics/pdf/PdfEditor.cpp | 161 | ||||
-rw-r--r-- | core/jni/android_view_SurfaceControl.cpp | 21 | ||||
-rw-r--r-- | core/jni/com_android_internal_net_NetworkStatsFactory.cpp | 36 | ||||
-rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 18 |
6 files changed, 205 insertions, 34 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 2106d38..dbaa4b8 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -129,6 +129,7 @@ LOCAL_SRC_FILES:= \ android/graphics/Xfermode.cpp \ android/graphics/YuvToJpegEncoder.cpp \ android/graphics/pdf/PdfDocument.cpp \ + android/graphics/pdf/PdfEditor.cpp \ android/graphics/pdf/PdfRenderer.cpp \ android_media_AudioRecord.cpp \ android_media_AudioSystem.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 62d8036..a63258c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -126,6 +126,7 @@ extern int register_android_graphics_Region(JNIEnv* env); extern int register_android_graphics_SurfaceTexture(JNIEnv* env); extern int register_android_graphics_Xfermode(JNIEnv* env); extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env); +extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env); extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env); extern int register_android_view_DisplayEventReceiver(JNIEnv* env); extern int register_android_view_RenderNode(JNIEnv* env); @@ -1305,6 +1306,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_graphics_Xfermode), REG_JNI(register_android_graphics_YuvImage), REG_JNI(register_android_graphics_pdf_PdfDocument), + REG_JNI(register_android_graphics_pdf_PdfEditor), REG_JNI(register_android_graphics_pdf_PdfRenderer), REG_JNI(register_android_database_CursorWindow), diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp new file mode 100644 index 0000000..5f60c9e --- /dev/null +++ b/core/jni/android/graphics/pdf/PdfEditor.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2014 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. + */ + +#include "jni.h" +#include "JNIHelp.h" +#include "fpdfview.h" +#include "fpdfedit.h" +#include "fpdfsave.h" + +#include <android_runtime/AndroidRuntime.h> +#include <vector> +#include <utils/Log.h> +#include <unistd.h> +#include <sys/types.h> +#include <unistd.h> + +namespace android { + +static Mutex sLock; + +static int sUnmatchedInitRequestCount = 0; + +static void initializeLibraryIfNeeded() { + Mutex::Autolock _l(sLock); + if (sUnmatchedInitRequestCount == 0) { + FPDF_InitLibrary(NULL); + } + sUnmatchedInitRequestCount++; +} + +static void destroyLibraryIfNeeded() { + Mutex::Autolock _l(sLock); + sUnmatchedInitRequestCount--; + if (sUnmatchedInitRequestCount == 0) { + FPDF_DestroyLibrary(); + } +} + +static int getBlock(void* param, unsigned long position, unsigned char* outBuffer, + unsigned long size) { + const int fd = reinterpret_cast<intptr_t>(param); + const int readCount = pread(fd, outBuffer, size, position); + if (readCount < 0) { + ALOGE("Cannot read from file descriptor. Error:%d", errno); + return 0; + } + return 1; +} + +static jlong nativeOpen(JNIEnv* env, jclass thiz, jint fd, jlong size) { + initializeLibraryIfNeeded(); + + FPDF_FILEACCESS loader; + loader.m_FileLen = size; + loader.m_Param = reinterpret_cast<void*>(intptr_t(fd)); + loader.m_GetBlock = &getBlock; + + FPDF_DOCUMENT document = FPDF_LoadCustomDocument(&loader, NULL); + + if (!document) { + const long error = FPDF_GetLastError(); + jniThrowException(env, "java/io/IOException", + "cannot create document. Error:" + error); + destroyLibraryIfNeeded(); + return -1; + } + + return reinterpret_cast<jlong>(document); +} + +static void nativeClose(JNIEnv* env, jclass thiz, jlong documentPtr) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + FPDF_CloseDocument(document); + destroyLibraryIfNeeded(); +} + +static jint nativeGetPageCount(JNIEnv* env, jclass thiz, jlong documentPtr) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + return FPDF_GetPageCount(document); +} + +static jint nativeRemovePage(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + FPDFPage_Delete(document, pageIndex); + return FPDF_GetPageCount(document); +} + +struct PdfToFdWriter : FPDF_FILEWRITE { + int dstFd; +}; + +static bool writeAllBytes(const int fd, const void* buffer, const size_t byteCount) { + char* writeBuffer = static_cast<char*>(const_cast<void*>(buffer)); + size_t remainingBytes = byteCount; + while (remainingBytes > 0) { + ssize_t writtenByteCount = write(fd, writeBuffer, remainingBytes); + if (writtenByteCount == -1) { + if (errno == EINTR) { + continue; + } + __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, + "Error writing to buffer: %d", errno); + return false; + } + remainingBytes -= writtenByteCount; + writeBuffer += writtenByteCount; + } + return true; +} + +static int writeBlock(FPDF_FILEWRITE* owner, const void* buffer, unsigned long size) { + const PdfToFdWriter* writer = reinterpret_cast<PdfToFdWriter*>(owner); + const bool success = writeAllBytes(writer->dstFd, buffer, size); + if (success < 0) { + ALOGE("Cannot write to file descriptor. Error:%d", errno); + return 0; + } + return 1; +} + +static void nativeWrite(JNIEnv* env, jclass thiz, jlong documentPtr, jint fd) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + PdfToFdWriter writer; + writer.dstFd = fd; + writer.WriteBlock = &writeBlock; + const bool success = FPDF_SaveAsCopy(document, &writer, FPDF_NO_INCREMENTAL); + if (!success) { + jniThrowException(env, "java/io/IOException", + "cannot write to fd. Error:" + errno); + destroyLibraryIfNeeded(); + } +} + +static JNINativeMethod gPdfEditor_Methods[] = { + {"nativeOpen", "(IJ)J", (void*) nativeOpen}, + {"nativeClose", "(J)V", (void*) nativeClose}, + {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount}, + {"nativeRemovePage", "(JI)I", (void*) nativeRemovePage}, + {"nativeWrite", "(JI)V", (void*) nativeWrite} +}; + +int register_android_graphics_pdf_PdfEditor(JNIEnv* env) { + return android::AndroidRuntime::registerNativeMethods( + env, "android/graphics/pdf/PdfEditor", gPdfEditor_Methods, + NELEM(gPdfEditor_Methods)); +}; + +}; diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 8f30f5d..06c22ae 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -117,7 +117,8 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject sourceCropObj, jint width, jint height, - jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { + jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform, + int rotation) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken == NULL) { return NULL; @@ -131,17 +132,13 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, SkAutoTDelete<ScreenshotClient> screenshot(new ScreenshotClient()); status_t res; - if (width > 0 && height > 0) { - if (allLayers) { - res = screenshot->update(displayToken, sourceCrop, width, height, - useIdentityTransform); - } else { - res = screenshot->update(displayToken, sourceCrop, width, height, - minLayer, maxLayer, useIdentityTransform); - } - } else { - res = screenshot->update(displayToken, sourceCrop, useIdentityTransform); + if (allLayers) { + minLayer = 0; + maxLayer = -1UL; } + + res = screenshot->update(displayToken, sourceCrop, width, height, + minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation)); if (res != NO_ERROR) { return NULL; } @@ -588,7 +585,7 @@ static JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeRelease }, {"nativeDestroy", "(J)V", (void*)nativeDestroy }, - {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;", + {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;", (void*)nativeScreenshotBitmap }, {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V", (void*)nativeScreenshot }, diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp index c84a466..2e2d0c7 100644 --- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp +++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp @@ -175,17 +175,23 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, continue; } } - // Skip whitespace. - while (*pos == ' ') { - pos++; - } - // Next field is tag. - rawTag = strtoll(pos, &endPos, 16); - //ALOGI("Index #%d: %s", idx, buffer); - if (pos == endPos) { - ALOGE("bad tag: %s", pos); - fclose(fp); - return -1; + + // Ignore whitespace + while (*pos == ' ') pos++; + + // Find end of tag field + endPos = pos; + while (*endPos != ' ') endPos++; + + // Three digit field is always 0x0, otherwise parse + if (endPos - pos == 3) { + rawTag = 0; + } else { + if (sscanf(pos, "%llx", &rawTag) != 1) { + ALOGE("bad tag: %s", pos); + fclose(fp); + return -1; + } } s.tag = rawTag >> 32; if (limitTag != -1 && s.tag != limitTag) { @@ -193,10 +199,10 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, continue; } pos = endPos; - // Skip whitespace. - while (*pos == ' ') { - pos++; - } + + // Ignore whitespace + while (*pos == ' ') pos++; + // Parse remaining fields. if (sscanf(pos, "%u %u %llu %llu %llu %llu", &s.uid, &s.set, &s.rxBytes, &s.rxPackets, diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 3d2d471..451d97a 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -421,7 +421,8 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, - bool is_system_server, jintArray fdsToClose) { + bool is_system_server, jintArray fdsToClose, + jstring instructionSet) { uint64_t start = MsTime(); SetSigChldHandler(); ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler"); @@ -542,7 +543,8 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra ckTime(start, "ForkAndSpecializeCommon:child process setup"); - env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags); + env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags, + is_system_server ? NULL : instructionSet); ckTime(start, "ForkAndSpecializeCommon:PostForkChildHooks returns"); if (env->ExceptionCheck()) { ALOGE("Error calling post fork hooks."); @@ -561,7 +563,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, jint debug_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose) { + jintArray fdsToClose, jstring instructionSet) { // Grant CAP_WAKE_ALARM to the Bluetooth process. jlong capabilities = 0; if (uid == AID_BLUETOOTH) { @@ -570,7 +572,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, capabilities, capabilities, mount_external, se_info, - se_name, false, fdsToClose); + se_name, false, fdsToClose, instructionSet); } static jint com_android_internal_os_Zygote_nativeForkSystemServer( @@ -580,7 +582,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, - MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL); + MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL, NULL); if (pid > 0) { // The zygote process checks whether the child process has died or not. ALOGI("System server process %d has been created", pid); @@ -598,7 +600,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( } static JNINativeMethod gMethods[] = { - { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I)I", + { "nativeForkAndSpecialize", + "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;)I", (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize }, { "nativeForkSystemServer", "(II[II[[IJJ)I", (void *) com_android_internal_os_Zygote_nativeForkSystemServer } @@ -609,7 +612,8 @@ int register_com_android_internal_os_Zygote(JNIEnv* env) { if (gZygoteClass == NULL) { RuntimeAbort(env); } - gCallPostForkChildHooks = env->GetStaticMethodID(gZygoteClass, "callPostForkChildHooks", "(I)V"); + gCallPostForkChildHooks = env->GetStaticMethodID(gZygoteClass, "callPostForkChildHooks", + "(ILjava/lang/String;)V"); return AndroidRuntime::registerNativeMethods(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods)); |