Ejemplo n.º 1
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);
    }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
/**
 * 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;
	}
}
Ejemplo n.º 4
0
status_t BnHDCPObserver::onTransact(
        uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
    switch (code) {
        case OBSERVER_NOTIFY:
        {
            CHECK_INTERFACE(IHDCPObserver, data, reply);

            int msg = data.readInt32();
            int ext1 = data.readInt32();
            int ext2 = data.readInt32();

            Parcel obj;
            if (data.dataAvail() > 0) {
                obj.appendFrom(
                        const_cast<Parcel *>(&data),
                        data.dataPosition(),
                        data.dataAvail());
            }

            notify(msg, ext1, ext2, &obj);

            return OK;
        }

        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}
Ejemplo n.º 5
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, &region1));
    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, &region2));
    int32_t *buffer2 = (int32_t *)region2;
    EXPECT_EQ(buffer1[0], buffer2[0]);
}
Ejemplo n.º 6
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, &region1)); // fits in region
    EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(-2, 16, &region1)); // offset is negative
    EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(0, memSizeBytes + 8, &region1)); // size too big
    EXPECT_NE(AAUDIO_OK, sharedMemoryA.resolve(memSizeBytes - 8, 16, &region1)); // 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, &region2));
    int32_t *buffer2 = (int32_t *)region2;
    EXPECT_NE(buffer1, buffer2);
    EXPECT_EQ(buffer1[0], buffer2[0]);
}
Ejemplo n.º 7
0
/**
 * 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;
}
Ejemplo n.º 8
0
// 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());
}
Ejemplo n.º 9
0
// 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);
}
Ejemplo n.º 10
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;
}
status_t BnListenReceiver::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {
        case NOTIFY: {
            ALOGI("BnListenReceiver::onTransact received NOTIFY");
            CHECK_INTERFACE(IListenReceiver, data, reply);
            int msg = data.readInt32();
            Parcel obj;
            if (data.dataAvail() > 0) {
                ALOGI("append %d bytes available at pos %d",
                      data.dataAvail(), data.dataPosition());
                obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
            }

            notify(msg, &obj);
            return NO_ERROR;
        } break;
        default:
            ALOGI("BnListenReceiver::onTransact received unknown msg %d", code);
            return BBinder::onTransact(code, data, reply, flags);
    }
}
status_t BnDrmClient::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {
        case NOTIFY: {
            CHECK_INTERFACE(IDrmClient, data, reply);
            int eventType = data.readInt32();
            int extra = data.readInt32();
            Parcel obj;
            if (data.dataAvail() > 0) {
                obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
            }

            notify((DrmPlugin::EventType)eventType, extra, &obj);
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}
status_t BnMediaPlayerClient::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {
        case NOTIFY: {
            CHECK_INTERFACE(IMediaPlayerClient, data, reply);
            int msg = data.readInt32();
            int ext1 = data.readInt32();
            int ext2 = data.readInt32();
            Parcel obj;
            if (data.dataAvail() > 0) {
                obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(), data.dataAvail());
            }

            notify(msg, ext1, ext2, &obj);
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}
static jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    return parcel ? parcel->dataPosition() : 0;
}
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);
    }
}