summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/Android.mk5
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp20
-rw-r--r--media/libmediaplayerservice/TestPlayerStub.cpp196
-rw-r--r--media/libmediaplayerservice/TestPlayerStub.h119
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java6
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java70
-rw-r--r--media/tests/players/Android.mk29
-rw-r--r--media/tests/players/README8
-rw-r--r--media/tests/players/invoke_mock_media_player.cpp118
9 files changed, 566 insertions, 5 deletions
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 6978b3d..f74ef3a 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \
MediaRecorderClient.cpp \
MediaPlayerService.cpp \
MetadataRetrieverClient.cpp \
+ TestPlayerStub.cpp \
VorbisPlayer.cpp \
MidiFile.cpp
@@ -28,6 +29,10 @@ LOCAL_SHARED_LIBRARIES := \
libmedia \
libandroid_runtime
+ifneq ($(TARGET_SIMULATOR),true)
+LOCAL_SHARED_LIBRARIES += libdl
+endif
+
LOCAL_C_INCLUDES := external/tremor/Tremor \
$(call include-path-for, graphics corecg) \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index c575f6c..02327d8 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -29,7 +29,7 @@
#include <string.h>
#include <cutils/atomic.h>
-#include <cutils/properties.h>
+#include <cutils/properties.h> // for property_get
#include <utils/misc.h>
@@ -58,6 +58,8 @@
#include "MidiFile.h"
#include "VorbisPlayer.h"
#include <media/PVPlayer.h>
+#include "TestPlayerStub.h"
+
#if USE_STAGEFRIGHT
#include "StagefrightPlayer.h"
#endif
@@ -68,6 +70,8 @@
#include <media/IOMX.h>
#endif
+
+
/* desktop Linux needs a little help with gettid() */
#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
#define __KERNEL__
@@ -656,6 +660,10 @@ static player_type getPlayerType(int fd, int64_t offset, int64_t length)
static player_type getPlayerType(const char* url)
{
+ if (TestPlayerStub::canBeUsed(url)) {
+ return TEST_PLAYER;
+ }
+
// use MidiFile for MIDI extensions
int lenURL = strlen(url);
for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
@@ -706,6 +714,10 @@ static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
"Should not be here, stagefright player not enabled.");
break;
#endif
+ case TEST_PLAYER:
+ LOGV("Create Test Player stub");
+ p = new TestPlayerStub();
+ break;
}
if (p != NULL) {
if (p->initCheck() == NO_ERROR) {
@@ -770,7 +782,11 @@ status_t MediaPlayerService::Client::setDataSource(const char *url)
// now set data source
LOGV(" setDataSource");
mStatus = p->setDataSource(url);
- if (mStatus == NO_ERROR) mPlayer = p;
+ if (mStatus == NO_ERROR) {
+ mPlayer = p;
+ } else {
+ LOGE(" error: %d", mStatus);
+ }
return mStatus;
}
}
diff --git a/media/libmediaplayerservice/TestPlayerStub.cpp b/media/libmediaplayerservice/TestPlayerStub.cpp
new file mode 100644
index 0000000..8627708
--- /dev/null
+++ b/media/libmediaplayerservice/TestPlayerStub.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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_NDEBUG 0
+#define LOG_TAG "TestPlayerStub"
+#include "utils/Log.h"
+
+#include "TestPlayerStub.h"
+
+#include <dlfcn.h> // for dlopen/dlclose
+#include <stdlib.h>
+#include <string.h>
+#include <cutils/properties.h>
+#include <utils/Errors.h> // for status_t
+
+#include "media/MediaPlayerInterface.h"
+
+
+namespace {
+using android::status_t;
+using android::MediaPlayerBase;
+
+const char *kTestUrlScheme = "test:";
+const char *kUrlParam = "url=";
+
+const char *kBuildTypePropName = "ro.build.type";
+const char *kEngBuild = "eng";
+const char *kTestBuild = "test";
+
+// @return true if the current build is 'eng' or 'test'.
+bool isTestBuild()
+{
+ char prop[PROPERTY_VALUE_MAX] = { '\0', };
+
+ property_get(kBuildTypePropName, prop, '\0');
+ return strcmp(prop, kEngBuild) == 0 || strcmp(prop, kTestBuild) == 0;
+}
+
+// @return true if the url scheme is 'test:'
+bool isTestUrl(const char *url)
+{
+ return url && strncmp(url, kTestUrlScheme, strlen(kTestUrlScheme)) == 0;
+}
+
+} // anonymous namespace
+
+namespace android {
+
+TestPlayerStub::TestPlayerStub()
+ :mUrl(NULL), mFilename(NULL), mContentUrl(NULL),
+ mHandle(NULL), mNewPlayer(NULL), mDeletePlayer(NULL),
+ mPlayer(NULL) { }
+
+TestPlayerStub::~TestPlayerStub()
+{
+ resetInternal();
+}
+
+status_t TestPlayerStub::initCheck()
+{
+ return isTestBuild() ? OK : INVALID_OPERATION;
+}
+
+// Parse mUrl to get:
+// * The library to be dlopened.
+// * The url to be passed to the real setDataSource impl.
+//
+// mUrl is expected to be in following format:
+//
+// test:<name of the .so>?url=<url for setDataSource>
+//
+// The value of the url parameter is treated as a string (no
+// unescaping of illegal charaters).
+status_t TestPlayerStub::parseUrl()
+{
+ if (strlen(mUrl) < strlen(kTestUrlScheme)) {
+ resetInternal();
+ return BAD_VALUE;
+ }
+
+ char *i = mUrl + strlen(kTestUrlScheme);
+
+ mFilename = i;
+
+ while (*i != '\0' && *i != '?') {
+ ++i;
+ }
+
+ if (*i == '\0' || strncmp(i + 1, kUrlParam, strlen(kUrlParam)) != 0) {
+ resetInternal();
+ return BAD_VALUE;
+ }
+ *i = '\0'; // replace '?' to nul-terminate mFilename
+
+ mContentUrl = i + 1 + strlen(kUrlParam);
+ return OK;
+}
+
+// Load the dynamic library.
+// Create the test player.
+// Call setDataSource on the test player with the url in param.
+status_t TestPlayerStub::setDataSource(const char *url)
+{
+ if (!isTestUrl(url) || NULL != mHandle) {
+ return INVALID_OPERATION;
+ }
+
+ mUrl = strdup(url);
+
+ status_t status = parseUrl();
+
+ if (OK != status) {
+ resetInternal();
+ return status;
+ }
+
+ ::dlerror(); // Clears any pending error.
+
+ // Load the test player from the url. dlopen will fail if the lib
+ // is not there. dls are under /system/lib
+ // None of the entry points should be NULL.
+ mHandle = ::dlopen(mFilename, RTLD_NOW | RTLD_GLOBAL);
+ if (!mHandle) {
+ LOGE("dlopen failed: %s", ::dlerror());
+ resetInternal();
+ return UNKNOWN_ERROR;
+ }
+
+ // Load the 2 entry points to create and delete instances.
+ const char *err;
+ mNewPlayer = reinterpret_cast<NEW_PLAYER>(dlsym(mHandle,
+ "newPlayer"));
+ err = ::dlerror();
+ if (err || mNewPlayer == NULL) {
+ // if err is NULL the string <null> is inserted in the logs =>
+ // mNewPlayer was NULL.
+ LOGE("dlsym for newPlayer failed %s", err);
+ resetInternal();
+ return UNKNOWN_ERROR;
+ }
+
+ mDeletePlayer = reinterpret_cast<DELETE_PLAYER>(dlsym(mHandle,
+ "deletePlayer"));
+ err = ::dlerror();
+ if (err || mDeletePlayer == NULL) {
+ LOGE("dlsym for deletePlayer failed %s", err);
+ resetInternal();
+ return UNKNOWN_ERROR;
+ }
+
+ mPlayer = (*mNewPlayer)();
+ return mPlayer->setDataSource(mContentUrl);
+}
+
+// Internal cleanup.
+status_t TestPlayerStub::resetInternal()
+{
+ if(mUrl) {
+ free(mUrl);
+ mUrl = NULL;
+ }
+ mFilename = NULL;
+ mContentUrl = NULL;
+
+ if (mPlayer) {
+ LOG_ASSERT(mDeletePlayer != NULL);
+ (*mDeletePlayer)(mPlayer);
+ mPlayer = NULL;
+ }
+
+ if (mHandle) {
+ ::dlclose(mHandle);
+ mHandle = NULL;
+ }
+ return OK;
+}
+
+/* static */ bool TestPlayerStub::canBeUsed(const char *url)
+{
+ return isTestBuild() && isTestUrl(url);
+}
+
+} // namespace android
diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h
new file mode 100644
index 0000000..80d53a8
--- /dev/null
+++ b/media/libmediaplayerservice/TestPlayerStub.h
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_BASE_MEDIA_LIBMEDIAPLAYERSERVICE_TESTPLAYERSTUB_H__
+#define ANDROID_FRAMEWORKS_BASE_MEDIA_LIBMEDIAPLAYERSERVICE_TESTPLAYERSTUB_H__
+
+#include <media/MediaPlayerInterface.h>
+#include <utils/Errors.h>
+
+namespace android {
+class MediaPlayerBase; // in media/MediaPlayerInterface.h
+
+// Wrapper around a test media player that gets dynamically loaded.
+//
+// The URL passed to setDataSource has this format:
+//
+// test:<name of the .so>?url=<url for the real setDataSource impl.>
+//
+// e.g:
+// test:invoke_test_media_player.so?url=http://youtube.com/
+// test:invoke_test_media_player.so?url=speedtest
+//
+// TestPlayerStub::setDataSource loads the library in the test url. 2
+// entry points with C linkage are expected. One to create the test
+// player and one to destroy it.
+//
+// extern "C" android::MediaPlayerBase* newPlayer();
+// extern "C" android::status_t deletePlayer(android::MediaPlayerBase *p);
+//
+// Once the test player has been loaded, its setDataSource
+// implementation is called with the value of the 'url' parameter.
+//
+// typical usage in a java test:
+// ============================
+//
+// MediaPlayer p = new MediaPlayer();
+// p.setDataSource("test:invoke_mock_media_player.so?url=http://youtube.com");
+// p.prepare();
+// ...
+// p.release();
+
+class TestPlayerStub : public MediaPlayerInterface {
+ public:
+ typedef MediaPlayerBase* (*NEW_PLAYER)();
+ typedef status_t (*DELETE_PLAYER)(MediaPlayerBase *);
+
+ TestPlayerStub();
+ virtual ~TestPlayerStub();
+
+ // Called right after the constructor. Check if the current build
+ // allows test players.
+ virtual status_t initCheck();
+
+ // @param url Should be a test url. See class comment.
+ virtual status_t setDataSource(const char* url);
+
+ // Test player for a file descriptor source is not supported.
+ virtual status_t setDataSource(int, int64_t, int64_t) {
+ return INVALID_OPERATION;
+ }
+
+
+ // All the methods below wrap the mPlayer instance.
+ virtual status_t setVideoSurface(const android::sp<android::ISurface>& s) {
+ return mPlayer->setVideoSurface(s);
+ }
+ virtual status_t prepare() {return mPlayer->prepare();}
+ virtual status_t prepareAsync() {return mPlayer->prepareAsync();}
+ virtual status_t start() {return mPlayer->start();}
+ virtual status_t stop() {return mPlayer->stop();}
+ virtual status_t pause() {return mPlayer->pause();}
+ virtual bool isPlaying() {return mPlayer->isPlaying();}
+ virtual status_t seekTo(int msec) {return mPlayer->seekTo(msec);}
+ virtual status_t getCurrentPosition(int *p) {
+ return mPlayer->getCurrentPosition(p);
+ }
+ virtual status_t getDuration(int *d) {return mPlayer->getDuration(d);}
+ virtual status_t reset() {return mPlayer->reset();}
+ virtual status_t setLooping(int b) {return mPlayer->setLooping(b);}
+ virtual player_type playerType() {return mPlayer->playerType();}
+ virtual status_t invoke(const android::Parcel& in, android::Parcel *out) {
+ return mPlayer->invoke(in, out);
+ }
+
+
+ // @return true if the current build is 'eng' or 'test' and the
+ // url's scheme is 'test:'
+ static bool canBeUsed(const char *url);
+
+ private:
+ // Release the player, dlclose the library.
+ status_t resetInternal();
+ status_t parseUrl();
+
+ char *mUrl; // test:foo.so?url=http://bar
+ char *mFilename; // foo.so
+ char *mContentUrl; // http://bar
+ void *mHandle; // returned by dlopen
+ NEW_PLAYER mNewPlayer;
+ DELETE_PLAYER mDeletePlayer;
+ MediaPlayerBase *mPlayer; // wrapped player
+};
+
+} // namespace android
+
+#endif
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
index 6edc2cc..2a4e9a0 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
@@ -23,6 +23,7 @@ import com.android.mediaframeworktest.functional.MediaMimeTest;
import com.android.mediaframeworktest.functional.MediaPlayerApiTest;
import com.android.mediaframeworktest.functional.MediaRecorderTest;
import com.android.mediaframeworktest.functional.SimTonesTest;
+import com.android.mediaframeworktest.functional.MediaPlayerInvokeTest;
import junit.framework.TestSuite;
@@ -32,7 +33,7 @@ import android.test.InstrumentationTestSuite;
/**
* Instrumentation Test Runner for all MediaPlayer tests.
- *
+ *
* Running all tests:
*
* adb shell am instrument \
@@ -52,6 +53,7 @@ public class MediaFrameworkTestRunner extends InstrumentationTestRunner {
suite.addTestSuite(MediaRecorderTest.class);
suite.addTestSuite(MediaAudioTrackTest.class);
suite.addTestSuite(MediaMimeTest.class);
+ suite.addTestSuite(MediaPlayerInvokeTest.class);
return suite;
}
@@ -60,5 +62,3 @@ public class MediaFrameworkTestRunner extends InstrumentationTestRunner {
return MediaFrameworkTestRunner.class.getClassLoader();
}
}
-
-
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java
new file mode 100644
index 0000000..ab8b311
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package com.android.mediaframeworktest.functional;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
+
+import android.media.MediaPlayer;
+import android.os.Parcel;
+
+import java.util.Calendar;
+import java.util.Random;
+
+// Tests for the invoke method in the MediaPlayer.
+public class MediaPlayerInvokeTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private static final String TAG = "MediaPlayerInvokeTest";
+ private MediaPlayer mPlayer;
+ private Random rnd;
+
+ public MediaPlayerInvokeTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ rnd = new Random(Calendar.getInstance().getTimeInMillis());
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mPlayer = new MediaPlayer();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mPlayer.release();
+ super.tearDown();
+ }
+
+ // Generate a random number, sends it to the ping test player.
+ @MediumTest
+ public void testPing() throws Exception {
+ mPlayer.setDataSource("test:invoke_mock_media_player.so?url=ping");
+
+ Parcel request = mPlayer.newRequest();
+ Parcel reply = Parcel.obtain();
+
+ int val = rnd.nextInt();
+ request.writeInt(val);
+ assertEquals(0, mPlayer.invoke(request, reply));
+ assertEquals(val, reply.readInt());
+ }
+}
diff --git a/media/tests/players/Android.mk b/media/tests/players/Android.mk
new file mode 100644
index 0000000..eb50a51
--- /dev/null
+++ b/media/tests/players/Android.mk
@@ -0,0 +1,29 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= invoke_mock_media_player.cpp
+
+LOCAL_SHARED_LIBRARIES:= \
+ libbinder \
+ libutils
+
+LOCAL_MODULE:= invoke_mock_media_player
+LOCAL_MODULE_TAGS := test eng
+LOCAL_PRELINK_MODULE:= false
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/tests/players/README b/media/tests/players/README
new file mode 100644
index 0000000..edf9bd6
--- /dev/null
+++ b/media/tests/players/README
@@ -0,0 +1,8 @@
+Native test players for system tests.
+
+For functional/system/performance tests, a native test player can be used.
+This directory contains the sources of such players.
+The class TestPlayerStub uses the dynamic loader to load any of them.
+
+
+
diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp
new file mode 100644
index 0000000..f02298d
--- /dev/null
+++ b/media/tests/players/invoke_mock_media_player.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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_NDEBUG 0
+#define LOG_TAG "TestPlayerStub"
+#include "utils/Log.h"
+
+#include <string.h>
+
+#include "binder/Parcel.h"
+#include "media/MediaPlayerInterface.h"
+#include "utils/Errors.h"
+
+using android::ISurface;
+using android::MediaPlayerBase;
+using android::OK;
+using android::Parcel;
+using android::TEST_PLAYER;
+using android::UNKNOWN_ERROR;
+using android::player_type;
+using android::sp;
+using android::status_t;
+
+// This file contains a test player that is loaded via the
+// TestPlayerStub class. The player contains various implementation
+// of the invoke method that java tests can use.
+
+namespace {
+const char *kPing = "ping";
+
+class Player: public MediaPlayerBase
+{
+ public:
+ enum TestType {TEST_UNKNOWN, PING};
+ Player() {}
+ virtual ~Player() {}
+
+ virtual status_t initCheck() {return OK;}
+ virtual bool hardwareOutput() {return true;}
+
+ virtual status_t setDataSource(const char *url) {
+ LOGV("setDataSource %s", url);
+ mTest = TEST_UNKNOWN;
+ if (strncmp(url, kPing, strlen(kPing)) == 0) {
+ mTest = PING;
+ }
+ return OK;
+ }
+
+ virtual status_t setDataSource(int fd, int64_t offset, int64_t length) {return OK;}
+ virtual status_t setVideoSurface(const sp<ISurface>& surface) {return OK;}
+ virtual status_t prepare() {return OK;}
+ virtual status_t prepareAsync() {return OK;}
+ virtual status_t start() {return OK;}
+ virtual status_t stop() {return OK;}
+ virtual status_t pause() {return OK;}
+ virtual bool isPlaying() {return true;}
+ virtual status_t seekTo(int msec) {return OK;}
+ virtual status_t getCurrentPosition(int *msec) {return OK;}
+ virtual status_t getDuration(int *msec) {return OK;}
+ virtual status_t reset() {return OK;}
+ virtual status_t setLooping(int loop) {return OK;}
+ virtual player_type playerType() {return TEST_PLAYER;}
+ virtual status_t invoke(const Parcel& request, Parcel *reply);
+ private:
+ // Take a request, copy it to the reply.
+ void ping(const Parcel& request, Parcel *reply);
+
+ status_t mStatus;
+ TestType mTest;
+};
+
+status_t Player::invoke(const Parcel& request, Parcel *reply)
+{
+ switch (mTest) {
+ case PING:
+ ping(request, reply);
+ break;
+ default: mStatus = UNKNOWN_ERROR;
+ }
+ return mStatus;
+}
+
+void Player::ping(const Parcel& request, Parcel *reply)
+{
+ const size_t len = request.dataAvail();
+
+ reply->setData(static_cast<const uint8_t*>(request.readInplace(len)), len);
+ mStatus = OK;
+}
+
+}
+
+extern "C" android::MediaPlayerBase* newPlayer()
+{
+ LOGD("New invoke test player");
+ return new Player();
+}
+
+extern "C" android::status_t deletePlayer(android::MediaPlayerBase *player)
+{
+ LOGD("Delete invoke test player");
+ delete player;
+ return OK;
+}