TEST_F(PointerCoordsTest, Parcel) { Parcel parcel; PointerCoords inCoords; inCoords.clear(); PointerCoords outCoords; // Round trip with empty coords. inCoords.writeToParcel(&parcel); parcel.setDataPosition(0); outCoords.readFromParcel(&parcel); ASSERT_EQ(0ULL, outCoords.bits); // Round trip with some values. parcel.freeData(); inCoords.setAxisValue(2, 5); inCoords.setAxisValue(5, 8); inCoords.writeToParcel(&parcel); parcel.setDataPosition(0); outCoords.readFromParcel(&parcel); ASSERT_EQ(outCoords.bits, inCoords.bits); ASSERT_EQ(outCoords.values[0], inCoords.values[0]); ASSERT_EQ(outCoords.values[1], inCoords.values[1]); }
/** * Check a parcel containing metadata is well formed. The header * is checked as well as the individual records format. However, the * data inside the record is not checked because we do lazy access * (we check/unmarshall only data the user asks for.) * * Format of a metadata parcel: <pre> 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | metadata total size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 'M' | 'E' | 'T' | 'A' | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | .... metadata records .... | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ </pre> * * @param parcel With the serialized data. Metadata keeps a * reference on it to access it later on. The caller * should not modify the parcel after this call (and * not call recycle on it.) * @return false if an error occurred. */ bool CedarMetadata::parse(Parcel& parcel) { if (parcel.dataAvail() < (size_t)kMetaHeaderSize) { ALOGE("Not enough data %d", parcel.dataAvail()); return false; } const int pin = parcel.dataPosition(); // to roll back in case of errors. const int size = parcel.readInt32(); // The extra kInt32Size below is to account for the int32 'size' just read. if (parcel.dataAvail() + kInt32Size < (size_t)size || size < kMetaHeaderSize) { ALOGE("Bad size %d avail %d position %d", size, parcel.dataAvail(), pin); parcel.setDataPosition(pin); return false; } // Checks if the 'M' 'E' 'T' 'A' marker is present. const int kShouldBeMetaMarker = parcel.readInt32(); if (kShouldBeMetaMarker != kMetaMarker ) { ALOGE("Marker missing"); parcel.setDataPosition(pin); return false; } // Scan the records to collect metadata ids and offsets. if (!scanAllRecords(parcel, size - kMetaHeaderSize)) { parcel.setDataPosition(pin); return false; } mParcel = &parcel; return true; }
status_t Status::readFromParcel(const Parcel& parcel) { status_t status = parcel.readInt32(&mException); if (status != OK) { setFromStatusT(status); return status; } // Skip over fat response headers. Not used (or propagated) in native code. if (mException == EX_HAS_REPLY_HEADER) { // Note that the header size includes the 4 byte size field. const int32_t header_start = parcel.dataPosition(); int32_t header_size; status = parcel.readInt32(&header_size); if (status != OK) { setFromStatusT(status); return status; } parcel.setDataPosition(header_start + header_size); // And fat response headers are currently only used when there are no // exceptions, so act like there was no error. mException = EX_NONE; } if (mException == EX_NONE) { return status; } // The remote threw an exception. Get the message back. String16 message; status = parcel.readString16(&message); if (status != OK) { setFromStatusT(status); return status; } mMessage = String8(message); if (mException == EX_SERVICE_SPECIFIC) { status = parcel.readInt32(&mErrorCode); } else if (mException == EX_PARCELABLE) { // Skip over the blob of Parcelable data const int32_t header_start = parcel.dataPosition(); int32_t header_size; status = parcel.readInt32(&header_size); if (status != OK) { setFromStatusT(status); return status; } parcel.setDataPosition(header_start + header_size); } if (status != OK) { setFromStatusT(status); return status; } return status; }
void CheckDataEquals(const Parcel& parcel, const char* content) { int32_t intval; parcel.setDataPosition(16); parcel.readInt32(&intval); parcel.setDataPosition(24); const char* data = (const char*) parcel.readInplace(intval); int32_t content_len = strlen(content); EXPECT_EQ(content_len, intval); EXPECT_TRUE(strncmp(data, content, content_len) == 0); }
/* * packRILcommandString * Used for packing standard AT command string to RIL command. * * IN *inStr : AT command string with NULL terminate * IN *prefix : prefix of AT response * OUT **outCmd : RAW RIL command out. Caller is responsible to free this resource. * RETUURN : Length of outCmd data. */ size_t packRILCommand(char *inStr, char *prefix, char **outCmd) { /* |Request Enum |Request Token|Number of Strings|Srings.....| * |<--4 bytes-->|<--4 bytes-->|<--- 4 bytes --->|<------ ->| */ size_t length = 0; char *cmdStr[2] = {NULL,NULL}; char *pData = NULL; Parcel p; static int s_token = 0; if ((NULL == inStr)||(NULL == outCmd)) { return 0; } cmdStr[0] = inStr; cmdStr[1] = prefix; // p.writeInt32(length); /* fake write to reserve space */ p.writeInt32(RIL_REQUEST_OEM_HOOK_STRINGS); p.writeInt32(s_token++); packStrings(p,cmdStr,2*sizeof(char *)); /* ONLY support 1 string now */ length = p.dataSize(); #if 0 offset = p.dataPosition(); /* Store data position */ p.setDataPosition(0); /* Move to the buffer pointer to head */ p.writeInt32(length - 4); /* Update data length */ p.setDataPosition(offset); /* Restore data position */ #endif /* 0 */ pData = (char *) malloc(length); if (NULL != pData) { memcpy(pData,p.data(),length); *outCmd = pData; LOGI("packRILCommand: %d bytes\n",length); printRawData((const void *) pData, length); } else { return 0; } return length; }
static void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jlong nativePtr, jint pos) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { parcel->setDataPosition(pos); } }
bool CmdImp:: initSurface() { mi4SurfaceID = 0; // create a client to surfaceflinger mpSurfaceClient = new SurfaceComposerClient(); mpSurfaceControl = mpSurfaceClient->createSurface( String8("surface"), mi4SurfaceID, 480, 800, PIXEL_FORMAT_RGBA_8888 ); SurfaceComposerClient::openGlobalTransaction(); mpSurfaceControl->setLayer(100000); SurfaceComposerClient::closeGlobalTransaction(); // pretend it went cross-process Parcel parcel; SurfaceControl::writeSurfaceToParcel(mpSurfaceControl, &parcel); parcel.setDataPosition(0); mpSurface = Surface::readFromParcel(parcel); mpWindow = mpSurface.get(); // CAM_LOGD("setupSurface: %p", mpSurface.get()); return (mpSurface != 0); }
bool CmdImp:: initSurface() { mi4SurfaceID = 0; // create a client to surfaceflinger mpSurfaceClient = new SurfaceComposerClient(); #if (PLATFORM_VERSION_MAJOR == 2) mpSurfaceControl = mpSurfaceClient->createSurface(getpid(), 0, 480, 800, PIXEL_FORMAT_RGBA_8888, ISurfaceComposer::ePushBuffers); #else mpSurfaceControl = mpSurfaceClient->createSurface( String8("surface"), /*mi4SurfaceID,*/ 480, 800, PIXEL_FORMAT_RGBA_8888 ); #endif SurfaceComposerClient::openGlobalTransaction(); mpSurfaceControl->setLayer(100000); SurfaceComposerClient::closeGlobalTransaction(); // pretend it went cross-process Parcel parcel; SurfaceControl::writeSurfaceToParcel(mpSurfaceControl, &parcel); parcel.setDataPosition(0); mpSurface = Surface::readFromParcel(parcel); // CAM_LOGD("setupSurface: %p", mpSurface.get()); return (mpSurface != 0); }
bool CmdImp:: initSurface() { mi4SurfaceID = 0; // create a client to surfaceflinger mpSurfaceClient = new SurfaceComposerClient(); mpSurfaceControl = mpSurfaceClient->createSurface( String8("surface"), mi4SurfaceID, 540, 960, PIXEL_FORMAT_RGBA_8888 ); SurfaceComposerClient::openGlobalTransaction(); mpSurfaceControl->setLayer(100000); SurfaceComposerClient::closeGlobalTransaction(); // pretend it went cross-process Parcel parcel; SurfaceControl::writeSurfaceToParcel(mpSurfaceControl, &parcel); parcel.setDataPosition(0); mpSurface = Surface::readFromParcel(parcel); mpWindow = mpSurface.get(); // /* printf("window=%p\n", mpWindow); native_window_api_connect(mpWindow, NATIVE_WINDOW_API_CAMERA); native_window_set_buffers_geometry(mpWindow, mpArgument->mPreviewSize.width, mpArgument->mPreviewSize.height, HAL_PIXEL_FORMAT_YV12); native_window_set_usage(mpWindow, GraphicBuffer::USAGE_SW_WRITE_OFTEN|GraphicBuffer::USAGE_HW_TEXTURE); native_window_set_scaling_mode(mpWindow, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); native_window_set_buffers_transform(mpWindow, HAL_TRANSFORM_ROT_90); native_window_set_buffer_count(mpWindow, 5); */ // CAM_LOGD("setupSurface: %p", mpSurface.get()); return (mpSurface != 0); }
// Test SharedRegionParcel. TEST(test_marshalling, aaudio_shared_region) { SharedMemoryParcelable sharedMemories[2]; SharedRegionParcelable sharedRegionA; SharedRegionParcelable sharedRegionB; const size_t memSizeBytes = 840; unique_fd fd(ashmem_create_region("TestMarshalling", memSizeBytes)); ASSERT_LE(0, fd); sharedMemories[0].setup(fd, memSizeBytes); int32_t regionOffset1 = 32; int32_t regionSize1 = 16; sharedRegionA.setup(0, regionOffset1, regionSize1); void *region1; EXPECT_EQ(AAUDIO_OK, sharedRegionA.resolve(sharedMemories, ®ion1)); int32_t *buffer1 = (int32_t *)region1; buffer1[0] = 336677; // arbitrary value Parcel parcel; size_t pos = parcel.dataPosition(); sharedRegionA.writeToParcel(&parcel); parcel.setDataPosition(pos); sharedRegionB.readFromParcel(&parcel); // should see same value void *region2; EXPECT_EQ(AAUDIO_OK, sharedRegionB.resolve(sharedMemories, ®ion2)); int32_t *buffer2 = (int32_t *)region2; EXPECT_EQ(buffer1[0], buffer2[0]); }
// Test SharedMemoryParcel. TEST(test_marshalling, aaudio_shared_memory) { SharedMemoryParcelable sharedMemoryA; SharedMemoryParcelable sharedMemoryB; const size_t memSizeBytes = 840; unique_fd fd(ashmem_create_region("TestMarshalling", memSizeBytes)); ASSERT_LE(0, fd); sharedMemoryA.setup(fd, memSizeBytes); void *region1; EXPECT_EQ(AAUDIO_OK, sharedMemoryA.resolve(0, 16, ®ion1)); // fits in region EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(-2, 16, ®ion1)); // offset is negative EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(0, memSizeBytes + 8, ®ion1)); // size too big EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(memSizeBytes - 8, 16, ®ion1)); // goes past the end int32_t *buffer1 = (int32_t *)region1; buffer1[0] = 98735; // arbitrary value Parcel parcel; size_t pos = parcel.dataPosition(); sharedMemoryA.writeToParcel(&parcel); parcel.setDataPosition(pos); sharedMemoryB.readFromParcel(&parcel); EXPECT_EQ(sharedMemoryA.getSizeInBytes(), sharedMemoryB.getSizeInBytes()); // should see same value at two different addresses void *region2; EXPECT_EQ(AAUDIO_OK, sharedMemoryB.resolve(0, 16, ®ion2)); int32_t *buffer2 = (int32_t *)region2; EXPECT_NE(buffer1, buffer2); EXPECT_EQ(buffer1[0], buffer2[0]); }
status_t BnMcuService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { ALOGI("BnMcuService::onTransact, code[%d]", code); switch (code) { case GET_TEST: { CHECK_INTERFACE(IMcuService, data, reply); int result = getTest(); reply->writeInt32(result); return NO_ERROR; } break; case obtain_info: { CHECK_INTERFACE(IMcuService, data, reply); int domain = data.readInt32(); int cmd = data.readInt32(); Parcel out; bool res = obtainInfo(domain, cmd, out); reply->appendFrom(&out, 0, out.dataSize()); reply->writeInt32(res?1:0); out.freeData(); return NO_ERROR; } break; case send_info: { CHECK_INTERFACE(IMcuService, data, reply); int domain = data.readInt32(); int cmd = data.readInt32(); Parcel in; if(data.dataAvail() >0) { in.appendFrom(&data, data.dataPosition(), data.dataSize()-data.dataPosition()); in.setDataPosition(0); } bool res = sendInfo(domain, cmd, in); reply->writeInt32(res?1:0); in.freeData(); return NO_ERROR; } break; case regist_data_changed_listener: { CHECK_INTERFACE(IMcuService, data, reply); int domain = data.readInt32(); sp<IDataChangedListener> client = interface_cast<IDataChangedListener>(data.readStrongBinder()); bool res = registDataChanagedListener(domain, client); reply->writeInt32((res?1:0)); return NO_ERROR; } break; case unregist_data_changed_listener: { CHECK_INTERFACE(IMcuService, data, reply); int domain = data.readInt32(); sp<IDataChangedListener> client = interface_cast<IDataChangedListener>(data.readStrongBinder()); bool res = unregistDataChanagedListener(domain, client); reply->writeInt32((res?1:0)); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } }
int MokoidSurface::clientInit(int x, int y, int w, int h, int *stride) { int depth = 16; int fmt; surfaceflinger_client = new SurfaceComposerClient; if (surfaceflinger_client == NULL) { LOGE("failed to create client\n"); return 0; } fmt = getFormat(depth); if (fmt == PIXEL_FORMAT_UNKNOWN) { LOGE("failed to find a format for depth %d\n", depth); return 0; } // Refactor in Android 4.0 surfaceflinger_surfaceControl = surfaceflinger_client->createSurface(getpid(), 0, w, h, fmt); if (surfaceflinger_surfaceControl == NULL) { LOGE("failed to create surfaceControl\n"); return 0; } // Refactor in Android 4.0 surfaceflinger_surface = surfaceflinger_surfaceControl->getSurface(); //surfaceflinger_client->openGlobalTransaction(); SurfaceComposerClient::openGlobalTransaction(); surfaceflinger_surfaceControl->setPosition(x, y); surfaceflinger_surfaceControl->setLayer(INT_MAX); //surfaceflinger_client->closeGlobalTransaction(); SurfaceComposerClient::closeGlobalTransaction(); if (stride) *stride = w * depth / 8; // Get native window Parcel parcel; SurfaceControl::writeSurfaceToParcel(surfaceflinger_surfaceControl, &parcel); parcel.setDataPosition(0); sp<Surface> surface = Surface::readFromParcel(parcel); ANativeWindow* window = surface.get(); LOGI("mokoid native window = %p", window); int err = native_window_set_buffer_count(window, 4); ANativeWindowBuffer* buffer; for (int i = 0; i < 4; i++) { window->dequeueBuffer(window, &buffer); LOGI("mokoid buffer %d: %p\n", i, buffer); } return 1; }
int PhoneMachine::incomingThread() { char boardname[PROPERTY_VALUE_MAX]; if (property_get("ro.product.board", boardname, "") > 0) { SLOGV("%s: -------------Board %s -----------------\n", __FUNCTION__, boardname); // QCOM Version 4.1.2 onwards, supports multiple clients and needs a SUB1/2 string to // identify client // For this example code we will just use "SUB1" for client 0 if ( !strcasecmp(boardname, "msm8960")) { char *sub = "SUB1"; int ret = ::send(mRILfd, sub, sizeof(sub), 0); if (ret != (int) sizeof(sub)) { perror("Socket write error when sending parcel"); return ret; } SLOGV("%s: sent SUB1\n", __FUNCTION__); } } else SLOGE("%s: could not get device name\n", __FUNCTION__); while (1) { uint32_t header; int ret = read(mRILfd, &header, sizeof(header)); if (ret != sizeof(header)) { SLOGW("Read %d bytes instead of %d\n", ret, sizeof(header)); perror("PhoneMachine::incomingThread read on header"); return ret; } int data_size = ntohl(header); Parcel data; ret = read(mRILfd, data.writeInplace(data_size), data_size); if (ret != data_size) { perror("PhoneMachine::incomingThread read on payload"); return ret; } if (mDebug & DEBUG_INCOMING) { SLOGV("<<<<<<< INCOMING <<<<<<<<<<\n"); const uint8_t *ptr = data.data(); for (int i = 0 ; i < data_size ; i++ ) { SLOGV("%02x ", *ptr++); if ((i+1) % 8 == 0 || (i+1 >= data_size)) SLOGV("\n"); } SLOGV("<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } data.setDataPosition(0); int type = data.readInt32(); // SLOGV("New message received: %d bytes type=%s\n", data_size, // (type ==RESPONSE_SOLICITED ? "solicited" : "unsolicited")); if (type == RESPONSE_SOLICITED) receiveSolicited(data); else receiveUnsolicited(data); } return NO_ERROR; }
// Test RingBufferParcelable. TEST(test_marshalling, aaudio_ring_buffer_parcelable) { SharedMemoryParcelable sharedMemories[2]; RingBufferParcelable ringBufferA; RingBufferParcelable ringBufferB; const size_t bytesPerFrame = 8; const size_t framesPerBurst = 32; const size_t dataSizeBytes = 2048; const int32_t counterSizeBytes = sizeof(int64_t); const size_t memSizeBytes = dataSizeBytes + (2 * counterSizeBytes); unique_fd fd(ashmem_create_region("TestMarshalling Z", memSizeBytes)); ASSERT_LE(0, fd); sharedMemories[0].setup(fd, memSizeBytes); int32_t sharedMemoryIndex = 0; // arrange indices and data in the shared memory int32_t readOffset = 0; int32_t writeOffset = readOffset + counterSizeBytes; int32_t dataOffset = writeOffset + counterSizeBytes; ringBufferA.setupMemory(sharedMemoryIndex, dataOffset, dataSizeBytes, readOffset, writeOffset, counterSizeBytes); ringBufferA.setFramesPerBurst(framesPerBurst); ringBufferA.setBytesPerFrame(bytesPerFrame); ringBufferA.setCapacityInFrames(dataSizeBytes / bytesPerFrame); // setup A RingBufferDescriptor descriptorA; EXPECT_EQ(AAUDIO_OK, ringBufferA.resolve(sharedMemories, &descriptorA)); descriptorA.dataAddress[0] = 95; descriptorA.dataAddress[1] = 57; descriptorA.readCounterAddress[0] = 17; descriptorA.writeCounterAddress[0] = 39; // write A to parcel Parcel parcel; size_t pos = parcel.dataPosition(); ringBufferA.writeToParcel(&parcel); // read B from parcel parcel.setDataPosition(pos); ringBufferB.readFromParcel(&parcel); RingBufferDescriptor descriptorB; EXPECT_EQ(AAUDIO_OK, ringBufferB.resolve(sharedMemories, &descriptorB)); // A and B should match EXPECT_EQ(descriptorA.dataAddress[0], descriptorB.dataAddress[0]); EXPECT_EQ(descriptorA.dataAddress[1], descriptorB.dataAddress[1]); EXPECT_EQ(descriptorA.readCounterAddress[0], descriptorB.readCounterAddress[0]); EXPECT_EQ(descriptorA.writeCounterAddress[0], descriptorB.writeCounterAddress[0]); EXPECT_EQ(ringBufferA.getFramesPerBurst(), ringBufferB.getFramesPerBurst()); EXPECT_EQ(ringBufferA.getBytesPerFrame(), ringBufferB.getBytesPerFrame()); EXPECT_EQ(ringBufferA.getCapacityInFrames(), ringBufferB.getCapacityInFrames()); }
/** * Go over all the records, collecting metadata keys and records' * type field offset in the Parcel. These are stored in * mKeyToPosMap for latter retrieval. * Format of a metadata record: <pre> 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | record size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | metadata key | // TITLE +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | metadata type | // STRING_VAL +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | .... metadata payload .... | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ </pre> * @param parcel With the serialized records. * @param bytesLeft How many bytes in the parcel should be processed. * @return false if an error occurred during parsing. */ bool CedarMetadata::scanAllRecords(Parcel& parcel, int bytesLeft) { int recCount = 0; bool error = false; mKeyToPosMap.clear(); while (bytesLeft > kRecordHeaderSize) { const int start = parcel.dataPosition(); const int size = parcel.readInt32(); if (size <= kRecordHeaderSize) { // at least 1 byte should be present. ALOGE("Record is too short"); error = true; break; } // Check the metadata key. static int metadataId = parcel.readInt32(); if (!checkMetadataId(metadataId)) { error = true; break; } // Store the record offset which points to the type // field so we can later on read/unmarshall the record // payload. if (mKeyToPosMap.indexOfKey(metadataId) >= 0) { ALOGE("Duplicate metadata ID found"); error = true; break; } mKeyToPosMap.add(metadataId, parcel.dataPosition()); // Check the metadata type. const int metadataType = parcel.readInt32(); if (metadataType <= 0 || metadataType > LAST_TYPE) { ALOGE("Invalid metadata type %d", metadataType); error = true; break; } // Skip to the next one. parcel.setDataPosition(start + size); bytesLeft -= size; ++recCount; } if (0 != bytesLeft || error) { ALOGE("Ran out of data or error on record %d", recCount); mKeyToPosMap.clear(); return false; } else { return true; } }
// Test adding one value. TEST(test_marshalling, aaudio_one_read_write) { Parcel parcel; size_t pos = parcel.dataPosition(); const int arbitraryValue = 235; parcel.writeInt32(arbitraryValue); parcel.setDataPosition(pos); int32_t y; parcel.readInt32(&y); EXPECT_EQ(arbitraryValue, y); }
bool obtainInfo(int domain, int cmd, Parcel& info) { //done in java client Parcel data, reply; data.writeInterfaceToken(IMcuService::getInterfaceDescriptor()); data.writeInt32(domain); data.writeInt32(cmd); remote()->transact(obtain_info, data, &reply); info.appendFrom(&reply, 0, reply.dataSize()-4); info.setDataPosition(0); return (reply.readInt32()==1); }
NS_IMETHOD Run() { assertIsNfcServiceThread(); Parcel parcel; parcel.writeInt32(0); // Parcel Size. mHandler->Marshall(parcel, mOptions); parcel.setDataPosition(0); uint32_t sizeBE = htonl(parcel.dataSize() - sizeof(int)); parcel.writeInt32(sizeBE); mConsumer->PostToNfcDaemon(parcel.data(), parcel.dataSize()); return NS_OK; }
TEST_F(MotionEventTest, Parcel) { Parcel parcel; MotionEvent inEvent; initializeEventWithHistory(&inEvent); MotionEvent outEvent; // Round trip. inEvent.writeToParcel(&parcel); parcel.setDataPosition(0); outEvent.readFromParcel(&parcel); ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent)); }
static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr, jbyteArray data, jint offset, jint length) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel == NULL || length < 0) { return; } jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0); if (array) { parcel->setDataSize(length); parcel->setDataPosition(0); void* raw = parcel->writeInplace(length); memcpy(raw, (array + offset), length); env->ReleasePrimitiveArrayCritical(data, array, 0); } }
status_t BBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { data.setDataPosition(0); status_t err = NO_ERROR; switch (code) { case PING_TRANSACTION: reply->writeInt32(pingBinder()); break; default: err = onTransact(code, data, reply, flags); break; } if (reply != NULL) { reply->setDataPosition(0); } return err; }
/** * Test if values from VendorTagDescriptor methods stay consistent after being * parcelled/unparcelled. */ TEST(VendorTagDescriptorTest, ConsistentAcrossParcel) { sp<VendorTagDescriptor> vDescOriginal, vDescParceled; const vendor_tag_ops_t *vOps = &fakevendor_ops; EXPECT_EQ(OK, VendorTagDescriptor::createDescriptorFromOps(vOps, /*out*/vDescOriginal)); ASSERT_TRUE(vDescOriginal != NULL); Parcel p; // Check whether parcel read/write succeed EXPECT_EQ(OK, vDescOriginal->writeToParcel(&p)); p.setDataPosition(0); ASSERT_EQ(OK, VendorTagDescriptor::createFromParcel(&p, vDescParceled)); // Ensure consistent tag count int tagCount = vDescOriginal->getTagCount(); ASSERT_EQ(tagCount, vDescParceled->getTagCount()); uint32_t descTagArray[tagCount]; uint32_t desc2TagArray[tagCount]; // Get all tag ids vDescOriginal->getTagArray(descTagArray); vDescParceled->getTagArray(desc2TagArray); ASSERT_NOT_NULL(descTagArray); ASSERT_NOT_NULL(desc2TagArray); uint32_t tag; for (int i = 0; i < tagCount; ++i) { // For each tag id, check consistency between the two vendor tag // descriptors for each type, section name, tag name tag = descTagArray[i]; EXPECT_CONTAINS_TAG(tag, desc2TagArray); EXPECT_EQ(vDescOriginal->getTagType(tag), vDescParceled->getTagType(tag)); EXPECT_STREQ(vDescOriginal->getSectionName(tag), vDescParceled->getSectionName(tag)); EXPECT_STREQ(vDescOriginal->getTagName(tag), vDescParceled->getTagName(tag)); } }
int main(int argc, char** argv) { // set up the thread-pool sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); // create a client to surfaceflinger sp<SurfaceComposerClient> client = new SurfaceComposerClient(); sp<SurfaceControl> surfaceControl = client->createSurface( String8("surface"), 160, 240, PIXEL_FORMAT_RGB_565, 0); SurfaceComposerClient::openGlobalTransaction(); surfaceControl->setLayer(100000); SurfaceComposerClient::closeGlobalTransaction(); // pretend it went cross-process Parcel parcel; SurfaceControl::writeSurfaceToParcel(surfaceControl, &parcel); parcel.setDataPosition(0); sp<Surface> surface = Surface::readFromParcel(parcel); ANativeWindow* window = surface.get(); printf("window=%p\n", window); int err = native_window_set_buffer_count(window, 8); ANativeWindowBuffer* buffer; for (int i=0 ; i<8 ; i++) { window->dequeueBuffer(window, &buffer); printf("buffer %d: %p\n", i, buffer); } printf("test complete. CTRL+C to finish.\n"); IPCThreadState::self()->joinThreadPool(); return 0; }
void CheckStartTimeMs(const Parcel& parcel, int32_t timeMs) { int32_t intval; parcel.setDataPosition(8); parcel.readInt32(&intval); EXPECT_EQ(timeMs, intval); }
status_t main(int argc, char** argv) { // set up the thread-pool sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); // create a client to surfaceflinger sp<SurfaceComposerClient> client = new SurfaceComposerClient(); // create surface sp<SurfaceControl> surfaceControl = client->createSurface( String8("test-resize2"), 0, LAYER_MIN_WIDTH, LAYER_MIN_HEIGHT, PIXEL_FORMAT_RGB_565); SurfaceComposerClient::openGlobalTransaction(); surfaceControl->setLayer(100000); SurfaceComposerClient::closeGlobalTransaction(); Parcel parcel; SurfaceControl::writeSurfaceToParcel(surfaceControl, &parcel); parcel.setDataPosition(0); sp<Surface> surface = Surface::readFromParcel(parcel); LOGD("RATIO:%f", RATIO); Surface::SurfaceInfo info; ssize_t bpr; while(true) { // zoom in { int width = LAYER_MIN_WIDTH, height; int x, y; Region *dirty = new Region(); while(width <= LAYER_MAX_WIDTH) { SurfaceComposerClient::openGlobalTransaction(); width = width + STEPPING; height = (int)(width * RATIO); surfaceControl->setSize(width, height); x = (int)((DISPLAY_WIDTH - width) / 2); y = (int)((DISPLAY_HEIGHT - height) / 2); surfaceControl->setPosition(x, y); SurfaceComposerClient::closeGlobalTransaction(); // set dirty region before lock dirty->set(Rect(x, y, x + width, y + height)); //surface->lock(&info); surface->lock(&info, dirty); bpr = info.s * bytesPerPixel(info.format); android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h); // LOGD("(w,h,x,y,s,h,bpr):(%d,%d,%d,%d,%d,%d,%d)", // width, height, // x, y, // info.s, info.h, (int)bpr); surface->unlockAndPost(); usleep(FPS); } delete dirty; } // zoom out { int width = LAYER_MAX_WIDTH, height; int x, y; Region *dirty = new Region(); while (width >= LAYER_MIN_WIDTH) { SurfaceComposerClient::openGlobalTransaction(); width = width - STEPPING; height = (int)(width * RATIO); surfaceControl->setSize(width, height); x = (int)((DISPLAY_WIDTH - width) / 2); y = (int)((DISPLAY_HEIGHT - height) / 2); surfaceControl->setPosition(x, y); SurfaceComposerClient::closeGlobalTransaction(); // set dirty region before lock dirty->set(Rect(x, y, x + width, y + height)); //surface->lock(&info); surface->lock(&info, dirty); bpr = info.s * bytesPerPixel(info.format); android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h); // LOGD("(w,h,x,y,s,h,bpr):(%d,%d,%d,%d,%d,%d,%d)", // width, height, // x, y, // info.s, info.h, (int)bpr); surface->unlockAndPost(); usleep(FPS); } delete dirty; } printf("\n... loop again ...\n"); } IPCThreadState::self()->joinThreadPool(); return NO_ERROR; } // main
status_t BnMediaPlayer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case DISCONNECT: { CHECK_INTERFACE(IMediaPlayer, data, reply); disconnect(); return NO_ERROR; } break; case SET_DATA_SOURCE_URL: { CHECK_INTERFACE(IMediaPlayer, data, reply); const char* url = data.readCString(); KeyedVector<String8, String8> headers; int32_t numHeaders = data.readInt32(); for (int i = 0; i < numHeaders; ++i) { String8 key = data.readString8(); String8 value = data.readString8(); headers.add(key, value); } reply->writeInt32(setDataSource(url, numHeaders > 0 ? &headers : NULL)); return NO_ERROR; } break; case SET_DATA_SOURCE_FD: { CHECK_INTERFACE(IMediaPlayer, data, reply); int fd = data.readFileDescriptor(); int64_t offset = data.readInt64(); int64_t length = data.readInt64(); reply->writeInt32(setDataSource(fd, offset, length)); return NO_ERROR; } case SET_DATA_SOURCE_STREAM: { CHECK_INTERFACE(IMediaPlayer, data, reply); sp<IStreamSource> source = interface_cast<IStreamSource>(data.readStrongBinder()); reply->writeInt32(setDataSource(source)); return NO_ERROR; } case SET_VIDEO_SURFACETEXTURE: { CHECK_INTERFACE(IMediaPlayer, data, reply); sp<ISurfaceTexture> surfaceTexture = interface_cast<ISurfaceTexture>(data.readStrongBinder()); reply->writeInt32(setVideoSurfaceTexture(surfaceTexture)); return NO_ERROR; } break; case PREPARE_ASYNC: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(prepareAsync()); return NO_ERROR; } break; case START: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(start()); return NO_ERROR; } break; case STOP: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(stop()); return NO_ERROR; } break; case IS_PLAYING: { CHECK_INTERFACE(IMediaPlayer, data, reply); bool state; status_t ret = isPlaying(&state); reply->writeInt32(state); reply->writeInt32(ret); return NO_ERROR; } break; case PAUSE: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(pause()); return NO_ERROR; } break; case SEEK_TO: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(seekTo(data.readInt32())); return NO_ERROR; } break; case GET_CURRENT_POSITION: { CHECK_INTERFACE(IMediaPlayer, data, reply); int msec; status_t ret = getCurrentPosition(&msec); reply->writeInt32(msec); reply->writeInt32(ret); return NO_ERROR; } break; case GET_DURATION: { CHECK_INTERFACE(IMediaPlayer, data, reply); int msec; status_t ret = getDuration(&msec); reply->writeInt32(msec); reply->writeInt32(ret); return NO_ERROR; } break; case RESET: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(reset()); return NO_ERROR; } break; case SET_AUDIO_STREAM_TYPE: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(setAudioStreamType(data.readInt32())); return NO_ERROR; } break; case SET_LOOPING: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(setLooping(data.readInt32())); return NO_ERROR; } break; case SET_VOLUME: { CHECK_INTERFACE(IMediaPlayer, data, reply); float leftVolume = data.readFloat(); float rightVolume = data.readFloat(); reply->writeInt32(setVolume(leftVolume, rightVolume)); return NO_ERROR; } break; case INVOKE: { CHECK_INTERFACE(IMediaPlayer, data, reply); status_t result = invoke(data, reply); return result; } break; case SET_METADATA_FILTER: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(setMetadataFilter(data)); return NO_ERROR; } break; case GET_METADATA: { CHECK_INTERFACE(IMediaPlayer, data, reply); bool update_only = static_cast<bool>(data.readInt32()); bool apply_filter = static_cast<bool>(data.readInt32()); const status_t retcode = getMetadata(update_only, apply_filter, reply); reply->setDataPosition(0); reply->writeInt32(retcode); reply->setDataPosition(0); return NO_ERROR; } break; case SET_AUX_EFFECT_SEND_LEVEL: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(setAuxEffectSendLevel(data.readFloat())); return NO_ERROR; } break; case ATTACH_AUX_EFFECT: { CHECK_INTERFACE(IMediaPlayer, data, reply); reply->writeInt32(attachAuxEffect(data.readInt32())); return NO_ERROR; } break; case SET_PARAMETER: { CHECK_INTERFACE(IMediaPlayer, data, reply); int key = data.readInt32(); Parcel request; if (data.dataAvail() > 0) { request.appendFrom( const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail()); } request.setDataPosition(0); reply->writeInt32(setParameter(key, request)); return NO_ERROR; } break; case GET_PARAMETER: { CHECK_INTERFACE(IMediaPlayer, data, reply); return getParameter(data.readInt32(), reply); } break; default: return BBinder::onTransact(code, data, reply, flags); } }