summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2009-07-01 18:33:18 -0700
committerMathias Agopian <mathias@google.com>2009-07-01 18:33:18 -0700
commitdfe983bd7979ccb1602f29b8f9804c98411d9cd6 (patch)
tree8a5547078b72cb262e54f0640dd4ed746b5805ef /core/jni
parent3a6b160a3b52cd96fb383d5ee93c22e5e938e0e2 (diff)
parent7f32b426cd6a865ac5e6e3e9fa833e9327fb415a (diff)
downloadframeworks_base-dfe983bd7979ccb1602f29b8f9804c98411d9cd6.zip
frameworks_base-dfe983bd7979ccb1602f29b8f9804c98411d9cd6.tar.gz
frameworks_base-dfe983bd7979ccb1602f29b8f9804c98411d9cd6.tar.bz2
Merge commit 'goog/master' into merge_master
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/Android.mk4
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/Time.cpp199
-rw-r--r--core/jni/TimeUtils.h89
-rw-r--r--core/jni/android_backup_BackupHelperDispatcher.cpp259
-rw-r--r--core/jni/android_bluetooth_common.cpp380
-rw-r--r--core/jni/android_hardware_Camera.cpp57
-rw-r--r--core/jni/android_text_format_Time.cpp2
-rw-r--r--core/jni/android_util_AssetManager.cpp5
-rw-r--r--core/jni/android_util_Process.cpp6
10 files changed, 745 insertions, 258 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index b5d3b26..e99971a 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -25,6 +25,7 @@ LOCAL_SRC_FILES:= \
ActivityManager.cpp \
AndroidRuntime.cpp \
CursorWindow.cpp \
+ Time.cpp \
com_google_android_gles_jni_EGLImpl.cpp \
com_google_android_gles_jni_GLImpl.cpp.arm \
android_opengl_GLES10.cpp \
@@ -123,7 +124,8 @@ LOCAL_SRC_FILES:= \
com_android_internal_graphics_NativeUtils.cpp \
android_backup_BackupDataInput.cpp \
android_backup_BackupDataOutput.cpp \
- android_backup_FileBackupHelperBase.cpp
+ android_backup_FileBackupHelperBase.cpp \
+ android_backup_BackupHelperDispatcher.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f8a4df0..c322b17 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -156,6 +156,7 @@ extern int register_android_location_GpsLocationProvider(JNIEnv* env);
extern int register_android_backup_BackupDataInput(JNIEnv *env);
extern int register_android_backup_BackupDataOutput(JNIEnv *env);
extern int register_android_backup_FileBackupHelperBase(JNIEnv *env);
+extern int register_android_backup_BackupHelperDispatcher(JNIEnv *env);
static AndroidRuntime* gCurRuntime = NULL;
@@ -1241,6 +1242,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_backup_BackupDataInput),
REG_JNI(register_android_backup_BackupDataOutput),
REG_JNI(register_android_backup_FileBackupHelperBase),
+ REG_JNI(register_android_backup_BackupHelperDispatcher),
};
/*
diff --git a/core/jni/Time.cpp b/core/jni/Time.cpp
new file mode 100644
index 0000000..f3037f3
--- /dev/null
+++ b/core/jni/Time.cpp
@@ -0,0 +1,199 @@
+#include "TimeUtils.h"
+#include <stdio.h>
+#include <cutils/tztime.h>
+
+namespace android {
+
+static void
+dump(const Time& t)
+{
+ #ifdef HAVE_TM_GMTOFF
+ long tm_gmtoff = t.t.tm_gmtoff;
+ #else
+ long tm_gmtoff = 0;
+ #endif
+ printf("%04d-%02d-%02d %02d:%02d:%02d (%d,%ld,%d,%d)\n",
+ t.t.tm_year+1900, t.t.tm_mon+1, t.t.tm_mday,
+ t.t.tm_hour, t.t.tm_min, t.t.tm_sec,
+ t.t.tm_isdst, tm_gmtoff, t.t.tm_wday, t.t.tm_yday);
+}
+
+Time::Time()
+{
+ t.tm_sec = 0;
+ t.tm_min = 0;
+ t.tm_hour = 0;
+ t.tm_mday = 0;
+ t.tm_mon = 0;
+ t.tm_year = 0;
+ t.tm_wday = 0;
+ t.tm_yday = 0;
+ t.tm_isdst = -1; // we don't know, so let the C library determine
+ #ifdef HAVE_TM_GMTOFF
+ t.tm_gmtoff = 0;
+ #endif
+}
+
+
+#define COMPARE_FIELD(field) do { \
+ int diff = a.t.field - b.t.field; \
+ if (diff != 0) return diff; \
+ } while(0)
+
+int
+Time::compare(Time& a, Time& b)
+{
+ if (0 == strcmp(a.timezone, b.timezone)) {
+ // if the timezones are the same, we can easily compare the two
+ // times. Otherwise, convert to milliseconds and compare that.
+ // This requires that object be normalized.
+ COMPARE_FIELD(tm_year);
+ COMPARE_FIELD(tm_mon);
+ COMPARE_FIELD(tm_mday);
+ COMPARE_FIELD(tm_hour);
+ COMPARE_FIELD(tm_min);
+ COMPARE_FIELD(tm_sec);
+ return 0;
+ } else {
+ int64_t am = a.toMillis(false /* use isDst */);
+ int64_t bm = b.toMillis(false /* use isDst */);
+ int64_t diff = am-bm;
+ return (diff < 0) ? -1 : ((diff > 0) ? 1 : 0);
+ }
+}
+
+static const int DAYS_PER_MONTH[] = {
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ };
+
+static inline int days_this_month(int year, int month)
+{
+ int n = DAYS_PER_MONTH[month];
+ if (n != 28) {
+ return n;
+ } else {
+ int y = year;
+ return ((y%4)==0&&((y%100)!=0||(y%400)==0)) ? 29 : 28;
+ }
+}
+
+void
+Time::switchTimezone(const char* timezone)
+{
+ time_t seconds = mktime_tz(&(this->t), this->timezone);
+ localtime_tz(&seconds, &(this->t), timezone);
+}
+
+String8
+Time::format(const char *format, const struct strftime_locale *locale) const
+{
+ char buf[257];
+ int n = strftime_tz(buf, 257, format, &(this->t), locale);
+ if (n > 0) {
+ return String8(buf);
+ } else {
+ return String8();
+ }
+}
+
+static inline short
+tochar(int n)
+{
+ return (n >= 0 && n <= 9) ? ('0'+n) : ' ';
+}
+
+static inline short
+next_char(int *m, int k)
+{
+ int n = *m / k;
+ *m = *m % k;
+ return tochar(n);
+}
+
+void
+Time::format2445(short* buf, bool hasTime) const
+{
+ int n;
+
+ n = t.tm_year+1900;
+ buf[0] = next_char(&n, 1000);
+ buf[1] = next_char(&n, 100);
+ buf[2] = next_char(&n, 10);
+ buf[3] = tochar(n);
+
+ n = t.tm_mon+1;
+ buf[4] = next_char(&n, 10);
+ buf[5] = tochar(n);
+
+ n = t.tm_mday;
+ buf[6] = next_char(&n, 10);
+ buf[7] = tochar(n);
+
+ if (hasTime) {
+ buf[8] = 'T';
+
+ n = t.tm_hour;
+ buf[9] = next_char(&n, 10);
+ buf[10] = tochar(n);
+
+ n = t.tm_min;
+ buf[11] = next_char(&n, 10);
+ buf[12] = tochar(n);
+
+ n = t.tm_sec;
+ buf[13] = next_char(&n, 10);
+ buf[14] = tochar(n);
+ bool inUtc = strcmp("UTC", timezone) == 0;
+ if (inUtc) {
+ buf[15] = 'Z';
+ }
+ }
+}
+
+String8
+Time::toString() const
+{
+ String8 str;
+ char* s = str.lockBuffer(150);
+ #ifdef HAVE_TM_GMTOFF
+ long tm_gmtoff = t.tm_gmtoff;
+ #else
+ long tm_gmtoff = 0;
+ #endif
+ sprintf(s, "%04d%02d%02dT%02d%02d%02d%s(%d,%d,%ld,%d,%d)",
+ t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min,
+ t.tm_sec, timezone, t.tm_wday, t.tm_yday, tm_gmtoff, t.tm_isdst,
+ (int)(((Time*)this)->toMillis(false /* use isDst */)/1000));
+ str.unlockBuffer();
+ return str;
+}
+
+void
+Time::setToNow()
+{
+ time_t seconds;
+ time(&seconds);
+ localtime_tz(&seconds, &(this->t), this->timezone);
+}
+
+int64_t
+Time::toMillis(bool ignoreDst)
+{
+ if (ignoreDst) {
+ this->t.tm_isdst = -1;
+ }
+ int64_t r = mktime_tz(&(this->t), this->timezone);
+ if (r == -1)
+ return -1;
+ return r * 1000;
+}
+
+void
+Time::set(int64_t millis)
+{
+ time_t seconds = millis / 1000;
+ localtime_tz(&seconds, &(this->t), this->timezone);
+}
+
+}; // namespace android
+
diff --git a/core/jni/TimeUtils.h b/core/jni/TimeUtils.h
new file mode 100644
index 0000000..b19e021
--- /dev/null
+++ b/core/jni/TimeUtils.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+#ifndef ANDROID_TIME_H
+#define ANDROID_TIME_H
+
+#include <time.h>
+#include <cutils/tztime.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+namespace android {
+
+/*
+ * This class is the core implementation of the android.util.Time java
+ * class. It doesn't implement some of the methods that are implemented
+ * in Java. They could be done here, but it's not expected that this class
+ * will be used. If that assumption is incorrect, feel free to update this
+ * file. The reason to do it here is to not mix the implementation of this
+ * class and the jni glue code.
+ */
+class Time
+{
+public:
+ struct tm t;
+
+ // this object doesn't own this string
+ const char *timezone;
+
+ enum {
+ SEC = 1,
+ MIN = 2,
+ HOUR = 3,
+ MDAY = 4,
+ MON = 5,
+ YEAR = 6,
+ WDAY = 7,
+ YDAY = 8
+ };
+
+ static int compare(Time& a, Time& b);
+
+ Time();
+
+ void switchTimezone(const char *timezone);
+ String8 format(const char *format, const struct strftime_locale *locale) const;
+ void format2445(short* buf, bool hasTime) const;
+ String8 toString() const;
+ void setToNow();
+ int64_t toMillis(bool ignoreDst);
+ void set(int64_t millis);
+
+ inline void set(int sec, int min, int hour, int mday, int mon, int year,
+ int isdst)
+ {
+ this->t.tm_sec = sec;
+ this->t.tm_min = min;
+ this->t.tm_hour = hour;
+ this->t.tm_mday = mday;
+ this->t.tm_mon = mon;
+ this->t.tm_year = year;
+ this->t.tm_isdst = isdst;
+#ifdef HAVE_TM_GMTOFF
+ this->t.tm_gmtoff = 0;
+#endif
+ this->t.tm_wday = 0;
+ this->t.tm_yday = 0;
+ }
+};
+
+}; // namespace android
+
+#endif // ANDROID_TIME_H
diff --git a/core/jni/android_backup_BackupHelperDispatcher.cpp b/core/jni/android_backup_BackupHelperDispatcher.cpp
new file mode 100644
index 0000000..2e3f0b9
--- /dev/null
+++ b/core/jni/android_backup_BackupHelperDispatcher.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2009 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 "BackupHelperDispatcher_native"
+#include <utils/Log.h>
+
+#include "JNIHelp.h"
+#include <android_runtime/AndroidRuntime.h>
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+
+#define VERSION_1_HEADER 0x01706c48 // 'Hlp'1 little endian
+
+namespace android
+{
+
+struct chunk_header_v1 {
+ int headerSize;
+ int version;
+ int dataSize; // corresponds to Header.chunkSize
+ int nameLength; // not including the NULL terminator, which is not written to the file
+};
+
+// java.io.FileDescriptor
+static jfieldID s_descriptorField = 0;
+static jfieldID s_chunkSizeField = 0;
+static jfieldID s_keyPrefixField = 0;
+
+static int
+readHeader_native(JNIEnv* env, jobject clazz, jobject headerObj, jobject fdObj)
+{
+ chunk_header_v1 flattenedHeader;
+ int fd;
+ ssize_t amt;
+ String8 keyPrefix;
+ char* buf;
+
+ fd = env->GetIntField(fdObj, s_descriptorField);
+
+ amt = read(fd, &flattenedHeader.headerSize, sizeof(flattenedHeader.headerSize));
+ if (amt != sizeof(flattenedHeader.headerSize)) {
+ return -1;
+ }
+
+ int remainingHeader = flattenedHeader.headerSize - sizeof(flattenedHeader.headerSize);
+
+ if (flattenedHeader.headerSize < (int)sizeof(chunk_header_v1)) {
+ LOGW("Skipping unknown header: %d bytes", flattenedHeader.headerSize);
+ if (remainingHeader > 0) {
+ lseek(fd, remainingHeader, SEEK_CUR);
+ // >0 means skip this chunk
+ return 1;
+ }
+ }
+
+ amt = read(fd, &flattenedHeader.version,
+ sizeof(chunk_header_v1)-sizeof(flattenedHeader.headerSize));
+ if (amt <= 0) {
+ LOGW("Failed reading chunk header");
+ return -1;
+ }
+ remainingHeader -= sizeof(chunk_header_v1)-sizeof(flattenedHeader.headerSize);
+
+ if (flattenedHeader.version != VERSION_1_HEADER) {
+ LOGW("Skipping unknown header version: 0x%08x, %d bytes", flattenedHeader.version,
+ flattenedHeader.headerSize);
+ if (remainingHeader > 0) {
+ lseek(fd, remainingHeader, SEEK_CUR);
+ // >0 means skip this chunk
+ return 1;
+ }
+ }
+
+#if 0
+ LOGD("chunk header:");
+ LOGD(" headerSize=%d", flattenedHeader.headerSize);
+ LOGD(" version=0x%08x", flattenedHeader.version);
+ LOGD(" dataSize=%d", flattenedHeader.dataSize);
+ LOGD(" nameLength=%d", flattenedHeader.nameLength);
+#endif
+
+ if (flattenedHeader.dataSize < 0 || flattenedHeader.nameLength < 0 ||
+ remainingHeader < flattenedHeader.nameLength) {
+ LOGW("Malformed V1 header remainingHeader=%d dataSize=%d nameLength=%d", remainingHeader,
+ flattenedHeader.dataSize, flattenedHeader.nameLength);
+ return -1;
+ }
+
+ buf = keyPrefix.lockBuffer(flattenedHeader.nameLength);
+ if (buf == NULL) {
+ LOGW("unable to allocate %d bytes", flattenedHeader.nameLength);
+ return -1;
+ }
+
+ amt = read(fd, buf, flattenedHeader.nameLength);
+ buf[flattenedHeader.nameLength] = 0;
+
+ keyPrefix.unlockBuffer(flattenedHeader.nameLength);
+
+ remainingHeader -= flattenedHeader.nameLength;
+
+ if (remainingHeader > 0) {
+ lseek(fd, remainingHeader, SEEK_CUR);
+ }
+
+ env->SetIntField(headerObj, s_chunkSizeField, flattenedHeader.dataSize);
+ env->SetObjectField(headerObj, s_keyPrefixField, env->NewStringUTF(keyPrefix.string()));
+
+ return 0;
+}
+
+static int
+skipChunk_native(JNIEnv* env, jobject clazz, jobject fdObj, jint bytesToSkip)
+{
+ int fd;
+
+ fd = env->GetIntField(fdObj, s_descriptorField);
+
+ lseek(fd, bytesToSkip, SEEK_CUR);
+
+ return 0;
+}
+
+static int
+padding_len(int len)
+{
+ len = len % 4;
+ return len == 0 ? len : 4 - len;
+}
+
+static int
+allocateHeader_native(JNIEnv* env, jobject clazz, jobject headerObj, jobject fdObj)
+{
+ int pos;
+ jstring nameObj;
+ int nameLength;
+ int namePadding;
+ int headerSize;
+ int fd;
+
+ fd = env->GetIntField(fdObj, s_descriptorField);
+
+ nameObj = (jstring)env->GetObjectField(headerObj, s_keyPrefixField);
+
+ nameLength = env->GetStringUTFLength(nameObj);
+ namePadding = padding_len(nameLength);
+
+ headerSize = sizeof(chunk_header_v1) + nameLength + namePadding;
+
+ pos = lseek(fd, 0, SEEK_CUR);
+
+ lseek(fd, headerSize, SEEK_CUR);
+
+ return pos;
+}
+
+static int
+writeHeader_native(JNIEnv* env, jobject clazz, jobject headerObj, jobject fdObj, jint pos)
+{
+ int err;
+ chunk_header_v1 header;
+ int fd;
+ int namePadding;
+ int prevPos;
+ jstring nameObj;
+ const char* buf;
+
+ fd = env->GetIntField(fdObj, s_descriptorField);
+ prevPos = lseek(fd, 0, SEEK_CUR);
+
+ nameObj = (jstring)env->GetObjectField(headerObj, s_keyPrefixField);
+ header.nameLength = env->GetStringUTFLength(nameObj);
+ namePadding = padding_len(header.nameLength);
+
+ header.headerSize = sizeof(chunk_header_v1) + header.nameLength + namePadding;
+ header.version = VERSION_1_HEADER;
+ header.dataSize = prevPos - (pos + header.headerSize);
+
+ lseek(fd, pos, SEEK_SET);
+ err = write(fd, &header, sizeof(chunk_header_v1));
+ if (err != sizeof(chunk_header_v1)) {
+ return errno;
+ }
+
+ buf = env->GetStringUTFChars(nameObj, NULL);
+ err = write(fd, buf, header.nameLength);
+ env->ReleaseStringUTFChars(nameObj, buf);
+ if (err != header.nameLength) {
+ return errno;
+ }
+
+ if (namePadding != 0) {
+ int zero = 0;
+ err = write(fd, &zero, namePadding);
+ if (err != namePadding) {
+ return errno;
+ }
+ }
+
+ lseek(fd, prevPos, SEEK_SET);
+ return 0;
+}
+
+static const JNINativeMethod g_methods[] = {
+ { "readHeader_native",
+ "(Landroid/backup/BackupHelperDispatcher$Header;Ljava/io/FileDescriptor;)I",
+ (void*)readHeader_native },
+ { "skipChunk_native",
+ "(Ljava/io/FileDescriptor;I)I",
+ (void*)skipChunk_native },
+ { "allocateHeader_native",
+ "(Landroid/backup/BackupHelperDispatcher$Header;Ljava/io/FileDescriptor;)I",
+ (void*)allocateHeader_native },
+ { "writeHeader_native",
+ "(Landroid/backup/BackupHelperDispatcher$Header;Ljava/io/FileDescriptor;I)I",
+ (void*)writeHeader_native },
+};
+
+int register_android_backup_BackupHelperDispatcher(JNIEnv* env)
+{
+ jclass clazz;
+
+ clazz = env->FindClass("java/io/FileDescriptor");
+ LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor");
+ s_descriptorField = env->GetFieldID(clazz, "descriptor", "I");
+ LOG_FATAL_IF(s_descriptorField == NULL,
+ "Unable to find descriptor field in java.io.FileDescriptor");
+
+ clazz = env->FindClass("android/backup/BackupHelperDispatcher$Header");
+ LOG_FATAL_IF(clazz == NULL,
+ "Unable to find class android.backup.BackupHelperDispatcher.Header");
+ s_chunkSizeField = env->GetFieldID(clazz, "chunkSize", "I");
+ LOG_FATAL_IF(s_chunkSizeField == NULL,
+ "Unable to find chunkSize field in android.backup.BackupHelperDispatcher.Header");
+ s_keyPrefixField = env->GetFieldID(clazz, "keyPrefix", "Ljava/lang/String;");
+ LOG_FATAL_IF(s_keyPrefixField == NULL,
+ "Unable to find keyPrefix field in android.backup.BackupHelperDispatcher.Header");
+
+ return AndroidRuntime::registerNativeMethods(env, "android/backup/BackupHelperDispatcher",
+ g_methods, NELEM(g_methods));
+}
+
+}
diff --git a/core/jni/android_bluetooth_common.cpp b/core/jni/android_bluetooth_common.cpp
index 8361212..343fa53 100644
--- a/core/jni/android_bluetooth_common.cpp
+++ b/core/jni/android_bluetooth_common.cpp
@@ -67,6 +67,11 @@ static Properties adapter_properties[] = {
{"Devices", DBUS_TYPE_ARRAY},
};
+typedef union {
+ char *str_val;
+ int int_val;
+ char **array_val;
+} property_value;
jfieldID get_field(JNIEnv *env, jclass clazz, const char *member,
const char *mtype) {
@@ -466,258 +471,217 @@ void append_variant(DBusMessageIter *iter, int type, void *val)
dbus_message_iter_close_container(iter, &value_iter);
}
-
-//TODO(): Remove code duplication between parse_properties and
-//parse_property_change
-jobjectArray parse_properties(JNIEnv *env, DBusMessageIter *iter, Properties *properties,
- const int max_num_properties) {
- DBusMessageIter dict_entry, dict, prop_val, device_val, array_val_iter;
- jobjectArray strArray = NULL;
- char * property;
- char values[max_num_properties][256];
- char **uuid_array = NULL;
- char **device_path = NULL;
- char **array_elements = NULL;
- char *string_val;
- uint32_t int_val, bool_val;
- int i, j, k, type, array_type, num_array_elements = 0;
- int ret, num_properties = 0, num_uuids = 0, num_devices = 0;
-
-
- jclass stringClass = env->FindClass("java/lang/String");
- DBusError err;
- dbus_error_init(&err);
-
- for (i = 0; i < max_num_properties; i++)
- memset(values[i], '\0', 128 * sizeof(char));
-
- if(dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
- goto failure;
- dbus_message_iter_recurse(iter, &dict);
- do {
- if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY)
- goto failure;
- dbus_message_iter_recurse(&dict, &dict_entry);
- if (dbus_message_iter_get_arg_type(&dict_entry) != DBUS_TYPE_STRING)
- goto failure;
- dbus_message_iter_get_basic(&dict_entry, &property);
- if (!dbus_message_iter_next(&dict_entry))
- goto failure;
- if (dbus_message_iter_get_arg_type(&dict_entry) != DBUS_TYPE_VARIANT)
- goto failure;
-
- for (i = 0; i < max_num_properties; i++) {
- if (!strncmp(properties[i].name, property, strlen(property))) {
- num_properties ++;
- break;
- }
- }
- if (i == max_num_properties)
- goto failure;
-
- type = properties[i].type;
- dbus_message_iter_recurse(&dict_entry, &prop_val);
- if(dbus_message_iter_get_arg_type(&prop_val) != type) {
- LOGE("Property type mismatch in parse_properties: %d, expected:%d",
- dbus_message_iter_get_arg_type(&prop_val), type);
- goto failure;
- }
-
- switch(type) {
- case DBUS_TYPE_STRING:
- case DBUS_TYPE_OBJECT_PATH:
- dbus_message_iter_get_basic(&prop_val, &string_val);
- strcpy(values[i], string_val);
- break;
- case DBUS_TYPE_UINT32:
- case DBUS_TYPE_INT16:
- dbus_message_iter_get_basic(&prop_val, &int_val);
- sprintf(values[i], "%d", int_val);
- break;
- case DBUS_TYPE_BOOLEAN:
- dbus_message_iter_get_basic(&prop_val, &bool_val);
- sprintf(values[i], "%s", bool_val ? "true" : "false");
- break;
- case DBUS_TYPE_ARRAY:
- dbus_message_iter_recurse(&prop_val, &array_val_iter);
- array_type = dbus_message_iter_get_arg_type(&array_val_iter);
- num_array_elements = 0;
- if (array_type == DBUS_TYPE_OBJECT_PATH ||
- array_type == DBUS_TYPE_STRING){
- do {
- num_array_elements++;
- } while(dbus_message_iter_next(&array_val_iter));
- dbus_message_iter_recurse(&prop_val, &array_val_iter);
- // Allocate an array
- array_elements = (char **)malloc(sizeof(char *) *
- num_array_elements);
- if (!array_elements)
- goto failure;
-
- j = 0;
- do {
- dbus_message_iter_get_basic(&array_val_iter, &array_elements[j]);
- j++;
- } while(dbus_message_iter_next(&array_val_iter));
- if (!strncmp(property, "UUIDs", strlen("UUIDs"))) {
- num_uuids = num_array_elements;
- uuid_array = array_elements;
- } else {
- num_devices = num_array_elements;
- device_path = array_elements;
- }
- }
- break;
- default:
- goto failure;
- }
- } while(dbus_message_iter_next(&dict));
-
- // Convert it to a array of strings.
- strArray = env->NewObjectArray((num_properties + num_array_elements) * 2,
- stringClass, NULL);
-
- j = 0;
- for (i = 0; i < max_num_properties; i++) {
- if (properties[i].type == DBUS_TYPE_ARRAY) {
- if (!strncmp(properties[i].name, "UUIDs", strlen("UUIDs"))) {
- num_array_elements = num_uuids;
- array_elements = uuid_array;
- } else {
- num_array_elements = num_devices;
- array_elements = device_path;
- }
-
- for (k = 0; k < num_array_elements; k++) {
- set_object_array_element(env, strArray, properties[i].name, j++);
- set_object_array_element(env, strArray, array_elements[k], j++);
- }
- } else if (values[i][0] != '\0') {
- set_object_array_element(env, strArray, properties[i].name, j++);
- set_object_array_element(env, strArray, values[i], j++);
- }
- }
-
- if (uuid_array)
- free(uuid_array);
- if (device_path)
- free(device_path);
- return strArray;
-
-failure:
- if (dbus_error_is_set(&err))
- LOG_AND_FREE_DBUS_ERROR(&err);
- if (uuid_array)
- free(uuid_array);
- if (device_path)
- free(device_path);
- return NULL;
-}
-
-jobjectArray create_prop_array(JNIEnv *env, Properties *properties,
- int prop_index, void *value, int len ) {
- jclass stringClass= env->FindClass("java/lang/String");
- char **prop_val = NULL;
- char buf[32] = {'\0'};
- int i, j;
-
- jobjectArray strArray = env->NewObjectArray(1 + len, stringClass, NULL);
- j = 0;
- set_object_array_element(env, strArray, properties[prop_index].name, j++);
-
- if (properties[prop_index].type == DBUS_TYPE_UINT32) {
- sprintf(buf, "%d", *(int *) value);
- set_object_array_element(env, strArray, buf, j++);
- } else if (properties[prop_index].type == DBUS_TYPE_BOOLEAN) {
- sprintf(buf, "%s", *(int *) value ? "true" : "false");
- set_object_array_element(env, strArray, buf, j++);
- } else if (properties[prop_index].type == DBUS_TYPE_ARRAY) {
- prop_val = (char **) value;
- for (i = 0; i < len; i++)
- set_object_array_element(env, strArray, prop_val[i], j++);
- } else {
- set_object_array_element(env, strArray, (const char *) value, j++);
- }
- if (prop_val)
- free (prop_val);
- return strArray;
-}
-
-jobjectArray parse_property_change(JNIEnv *env, DBusMessage *msg,
- Properties *properties, int max_num_properties) {
- DBusMessageIter iter, prop_val, array_val_iter;
- DBusError err;
- void *value;
- char *property;
+int get_property(DBusMessageIter iter, Properties *properties,
+ int max_num_properties, int *prop_index, property_value *value, int *len) {
+ DBusMessageIter prop_val, array_val_iter;
+ char *property = NULL;
uint32_t array_type;
- int i, j, type, len, prop_index;
+ char *str_val;
+ int i, j, type, int_val;
- dbus_error_init(&err);
- if (!dbus_message_iter_init(msg, &iter))
- goto failure;
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- goto failure;
+ return -1;
dbus_message_iter_get_basic(&iter, &property);
if (!dbus_message_iter_next(&iter))
- goto failure;
+ return -1;
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- goto failure;
+ return -1;
for (i = 0; i < max_num_properties; i++) {
- if (!strncmp(property, properties[i].name, strlen(properties[i].name)))
+ if (!strncmp(property, properties[i].name, strlen(property)))
break;
}
- prop_index = i;
+ *prop_index = i;
if (i == max_num_properties)
- goto failure;
+ return -1;
dbus_message_iter_recurse(&iter, &prop_val);
- type = properties[prop_index].type;
+ type = properties[*prop_index].type;
if (dbus_message_iter_get_arg_type(&prop_val) != type) {
- LOGE("Property type mismatch in parse_properties: %d, expected:%d",
- dbus_message_iter_get_arg_type(&prop_val), type);
- goto failure;
+ LOGE("Property type mismatch in get_property: %d, expected:%d, index:%d",
+ dbus_message_iter_get_arg_type(&prop_val), type, *prop_index);
+ return -1;
}
switch(type) {
case DBUS_TYPE_STRING:
case DBUS_TYPE_OBJECT_PATH:
- dbus_message_iter_get_basic(&prop_val, &value);
- len = 1;
+ dbus_message_iter_get_basic(&prop_val, &value->str_val);
+ *len = 1;
break;
case DBUS_TYPE_UINT32:
case DBUS_TYPE_INT16:
case DBUS_TYPE_BOOLEAN:
- uint32_t int_val;
dbus_message_iter_get_basic(&prop_val, &int_val);
- value = &int_val;
- len = 1;
+ value->int_val = int_val;
+ *len = 1;
break;
case DBUS_TYPE_ARRAY:
dbus_message_iter_recurse(&prop_val, &array_val_iter);
array_type = dbus_message_iter_get_arg_type(&array_val_iter);
- len = 0;
+ *len = 0;
+ value->array_val = NULL;
if (array_type == DBUS_TYPE_OBJECT_PATH ||
array_type == DBUS_TYPE_STRING){
+ j = 0;
do {
- len ++;
+ j ++;
} while(dbus_message_iter_next(&array_val_iter));
dbus_message_iter_recurse(&prop_val, &array_val_iter);
// Allocate an array of char *
- char **tmp = (char **)malloc(sizeof(char *) * len);
+ *len = j;
+ char **tmp = (char **)malloc(sizeof(char *) * *len);
if (!tmp)
- goto failure;
+ return -1;
j = 0;
do {
dbus_message_iter_get_basic(&array_val_iter, &tmp[j]);
j ++;
} while(dbus_message_iter_next(&array_val_iter));
- value = (char **) tmp;
+ value->array_val = tmp;
}
break;
default:
+ return -1;
+ }
+ return 0;
+}
+
+void create_prop_array(JNIEnv *env, jobjectArray strArray, Properties *property,
+ property_value *value, int len, int *array_index ) {
+ char **prop_val = NULL;
+ char buf[32] = {'\0'}, buf1[32] = {'\0'};
+ int i;
+
+ char *name = property->name;
+ int prop_type = property->type;
+
+ set_object_array_element(env, strArray, name, *array_index);
+ *array_index += 1;
+
+ if (prop_type == DBUS_TYPE_UINT32 || prop_type == DBUS_TYPE_INT16) {
+ sprintf(buf, "%d", value->int_val);
+ set_object_array_element(env, strArray, buf, *array_index);
+ *array_index += 1;
+ } else if (prop_type == DBUS_TYPE_BOOLEAN) {
+ sprintf(buf, "%s", value->int_val ? "true" : "false");
+
+ set_object_array_element(env, strArray, buf, *array_index);
+ *array_index += 1;
+ } else if (prop_type == DBUS_TYPE_ARRAY) {
+ // Write the length first
+ sprintf(buf1, "%d", len);
+ set_object_array_element(env, strArray, buf1, *array_index);
+ *array_index += 1;
+
+ prop_val = value->array_val;
+ for (i = 0; i < len; i++) {
+ set_object_array_element(env, strArray, prop_val[i], *array_index);
+ *array_index += 1;
+ }
+ } else {
+ set_object_array_element(env, strArray, (const char *) value->str_val, *array_index);
+ *array_index += 1;
+ }
+}
+
+jobjectArray parse_properties(JNIEnv *env, DBusMessageIter *iter, Properties *properties,
+ const int max_num_properties) {
+ DBusMessageIter dict_entry, dict;
+ jobjectArray strArray = NULL;
+ property_value value;
+ int i, size = 0,array_index = 0;
+ int len = 0, prop_type = DBUS_TYPE_INVALID, prop_index = -1, type;
+ struct {
+ property_value value;
+ int len;
+ bool used;
+ } values[max_num_properties];
+ int t, j;
+
+ jclass stringClass = env->FindClass("java/lang/String");
+ DBusError err;
+ dbus_error_init(&err);
+
+ for (i = 0; i < max_num_properties; i++) {
+ values[i].used = false;
+ }
+
+ if(dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ goto failure;
+ dbus_message_iter_recurse(iter, &dict);
+ do {
+ len = 0;
+ if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY)
+ goto failure;
+ dbus_message_iter_recurse(&dict, &dict_entry);
+
+ if (!get_property(dict_entry, properties, max_num_properties, &prop_index,
+ &value, &len)) {
+ size += 2;
+ if (properties[prop_index].type == DBUS_TYPE_ARRAY)
+ size += len;
+ values[prop_index].value = value;
+ values[prop_index].len = len;
+ values[prop_index].used = true;
+ } else {
+ goto failure;
+ }
+ } while(dbus_message_iter_next(&dict));
+
+ strArray = env->NewObjectArray(size, stringClass, NULL);
+
+ for (i = 0; i < max_num_properties; i++) {
+ if (values[i].used) {
+ create_prop_array(env, strArray, &properties[i], &values[i].value, values[i].len,
+ &array_index);
+
+ if (properties[i].type == DBUS_TYPE_ARRAY && values[i].used
+ && values[i].value.array_val != NULL)
+ free(values[i].value.array_val);
+ }
+
+ }
+ return strArray;
+
+failure:
+ if (dbus_error_is_set(&err))
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ for (i = 0; i < max_num_properties; i++)
+ if (properties[i].type == DBUS_TYPE_ARRAY && values[i].used == true
+ && values[i].value.array_val != NULL)
+ free(values[i].value.array_val);
+ return NULL;
+}
+
+jobjectArray parse_property_change(JNIEnv *env, DBusMessage *msg,
+ Properties *properties, int max_num_properties) {
+ DBusMessageIter iter;
+ DBusError err;
+ jobjectArray strArray = NULL;
+ jclass stringClass= env->FindClass("java/lang/String");
+ int len = 0, prop_index = -1;
+ int array_index = 0, size = 0;
+ property_value value;
+
+ dbus_error_init(&err);
+ if (!dbus_message_iter_init(msg, &iter))
goto failure;
+
+ if (!get_property(iter, properties, max_num_properties,
+ &prop_index, &value, &len)) {
+ size += 2;
+ if (properties[prop_index].type == DBUS_TYPE_ARRAY)
+ size += len;
+ strArray = env->NewObjectArray(size, stringClass, NULL);
+
+ create_prop_array(env, strArray, &properties[prop_index],
+ &value, len, &array_index);
+
+ if (properties[prop_index].type == DBUS_TYPE_ARRAY && value.array_val != NULL)
+ free(value.array_val);
+
+ return strArray;
}
- return create_prop_array(env, properties, prop_index, value, len);
failure:
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
return NULL;
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index c7cc9b3..0420918 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -125,37 +125,8 @@ void JNICameraContext::notify(int32_t msgType, int32_t ext1, int32_t ext2)
return;
}
JNIEnv *env = AndroidRuntime::getJNIEnv();
-
- // parse message
- switch (msgType) {
- case CAMERA_MSG_ERROR:
- LOGV("errorCallback");
- int error;
- switch (ext1) {
- case DEAD_OBJECT:
- error = kCameraErrorMediaServer;
- break;
- default:
- error = kCameraErrorUnknown;
- break;
- }
- env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, kErrorCallback, error, 0, NULL);
- break;
- case CAMERA_MSG_FOCUS:
- LOGV("autoFocusCallback");
- env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, kAutoFocusCallback, ext1, 0, NULL);
- break;
- case CAMERA_MSG_SHUTTER:
- LOGV("shutterCallback");
- env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, kShutterCallback, 0, 0, NULL);
- break;
- default:
- LOGV("notifyCallback(%d, %d, %d)", msgType, ext1, ext2);
- break;
- }
+ env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
+ mCameraJObjectWeak, msgType, ext1, ext2);
}
void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int msgType)
@@ -200,30 +171,27 @@ void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr)
// VM pointer will be NULL if object is released
Mutex::Autolock _l(mLock);
JNIEnv *env = AndroidRuntime::getJNIEnv();
+ if (mCameraJObjectWeak == NULL) {
+ LOGW("callback on dead camera object");
+ return;
+ }
// return data based on callback type
switch(msgType) {
- case CAMERA_MSG_PREVIEW_FRAME:
- LOGV("previewCallback");
- copyAndPost(env, dataPtr, kPreviewCallback);
- break;
case CAMERA_MSG_VIDEO_FRAME:
- LOGV("recordingCallback");
+ // should never happen
break;
+ // don't return raw data to Java
case CAMERA_MSG_RAW_IMAGE:
LOGV("rawCallback");
env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, kRawCallback, 0, 0, NULL);
- break;
- case CAMERA_MSG_COMPRESSED_IMAGE:
- LOGV("jpegCallback");
- copyAndPost(env, dataPtr, kJpegCallback);
+ mCameraJObjectWeak, msgType, 0, 0, NULL);
break;
default:
LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
+ copyAndPost(env, dataPtr, msgType);
break;
}
-
}
// connect to camera service
@@ -298,7 +266,10 @@ static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz,
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return;
- sp<Surface> surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface));
+ sp<Surface> surface = NULL;
+ if (jSurface != NULL) {
+ surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface));
+ }
if (camera->setPreviewDisplay(surface) != NO_ERROR) {
jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");
}
diff --git a/core/jni/android_text_format_Time.cpp b/core/jni/android_text_format_Time.cpp
index 7c208e9..98f4e03 100644
--- a/core/jni/android_text_format_Time.cpp
+++ b/core/jni/android_text_format_Time.cpp
@@ -23,7 +23,7 @@
#include "jni.h"
#include "utils/misc.h"
#include "android_runtime/AndroidRuntime.h"
-#include <utils/TimeUtils.h>
+#include "TimeUtils.h"
#include <nativehelper/JNIHelp.h>
#include <cutils/tztime.h>
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index d147bcc..2d90ba4 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -535,7 +535,7 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c
jint keyboard, jint keyboardHidden,
jint navigation,
jint screenWidth, jint screenHeight,
- jint sdkVersion)
+ jint screenLayout, jint sdkVersion)
{
AssetManager* am = assetManagerForJavaObject(env, clazz);
if (am == NULL) {
@@ -557,6 +557,7 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c
config.navigation = (uint8_t)navigation;
config.screenWidth = (uint16_t)screenWidth;
config.screenHeight = (uint16_t)screenHeight;
+ config.screenLayout = (uint8_t)screenLayout;
config.sdkVersion = (uint16_t)sdkVersion;
config.minorVersion = 0;
am->setConfiguration(config, locale8);
@@ -1567,7 +1568,7 @@ static JNINativeMethod gAssetManagerMethods[] = {
(void*) android_content_AssetManager_setLocale },
{ "getLocales", "()[Ljava/lang/String;",
(void*) android_content_AssetManager_getLocales },
- { "setConfiguration", "(IILjava/lang/String;IIIIIIIII)V",
+ { "setConfiguration", "(IILjava/lang/String;IIIIIIIIII)V",
(void*) android_content_AssetManager_setConfiguration },
{ "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void*) android_content_AssetManager_getResourceIdentifier },
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 1c9ee7d..770c755 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -269,9 +269,9 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
jint pid, jint pri)
{
- if (pri == ANDROID_PRIORITY_BACKGROUND) {
+ if (pri >= ANDROID_PRIORITY_BACKGROUND) {
add_pid_to_cgroup(pid, ANDROID_TGROUP_BG_NONINTERACT);
- } else if (getpriority(PRIO_PROCESS, pid) == ANDROID_PRIORITY_BACKGROUND) {
+ } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
add_pid_to_cgroup(pid, ANDROID_TGROUP_DEFAULT);
}
@@ -496,7 +496,7 @@ void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileSt
const String8& field = fields[i];
if (strncmp(p, field.string(), field.length()) == 0) {
p += field.length();
- while (*p == ' ') p++;
+ while (*p == ' ' || *p == '\t') p++;
char* num = p;
while (*p >= '0' && *p <= '9') p++;
skipToEol = *p != '\n';