1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "NativeCursorWindow" 18 19 #include <jni.h> 20 #include <fcntl.h> 21 #include <sys/mman.h> 22 #include <linux/ashmem.h> 23 #include <utils/Log.h> 24 25 struct Header { 26 // Offset of the lowest unused byte in the window. 27 uint32_t freeOffset; 28 29 // Offset of the first row slot chunk. 30 uint32_t firstChunkOffset; 31 32 uint32_t numRows; 33 uint32_t numColumns; 34 }; 35 36 struct RowSlot { 37 uint32_t offset; 38 }; 39 40 #define ROW_SLOT_CHUNK_NUM_ROWS 100 41 42 struct RowSlotChunk { 43 struct RowSlot slots[ROW_SLOT_CHUNK_NUM_ROWS]; 44 uint32_t nextChunkOffset; 45 }; 46 47 /* Field types. */ 48 enum { 49 FIELD_TYPE_NULL = 0, 50 FIELD_TYPE_INTEGER = 1, 51 FIELD_TYPE_FLOAT = 2, 52 FIELD_TYPE_STRING = 3, 53 FIELD_TYPE_BLOB = 4, 54 }; 55 56 /* Opaque type that describes a field slot. */ 57 struct FieldSlot { 58 int32_t type; 59 union { 60 double d; 61 int64_t l; 62 struct { 63 uint32_t offset; 64 uint32_t size; 65 } buffer; 66 } data; 67 } __attribute((packed)); 68 69 JNIEXPORT jint JNICALL 70 Java_android_content_cts_CursorWindowContentProvider_makeNativeCursorWindowFd(JNIEnv *env, jclass clazz, 71 jint offset, jint size, jboolean isBlob) { 72 int fd = open("/dev/ashmem", O_RDWR); 73 ioctl(fd, ASHMEM_SET_NAME, "Fake CursorWindow"); 74 75 ioctl(fd, ASHMEM_SET_SIZE, 1024); 76 77 void *data = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 78 79 struct Header *header = (struct Header *) data; 80 unsigned rowSlotChunkOffset = sizeof(struct Header); 81 struct RowSlotChunk *rowSlotChunk = (struct RowSlotChunk *)(data + rowSlotChunkOffset); 82 unsigned fieldSlotOffset = rowSlotChunkOffset + sizeof(struct RowSlotChunk); 83 struct FieldSlot *fieldSlot = (struct FieldSlot *) (data + fieldSlotOffset); 84 85 header->numRows = 1; 86 header->numColumns = 1; 87 header->firstChunkOffset = rowSlotChunkOffset; 88 89 rowSlotChunk->slots[0].offset = fieldSlotOffset; 90 91 fieldSlot->type = isBlob ? FIELD_TYPE_BLOB : FIELD_TYPE_STRING; 92 fieldSlot->data.buffer.offset = offset; 93 fieldSlot->data.buffer.size = size; 94 95 munmap(data, 1024); 96 97 return fd; 98 99 } 100