New test player stub to load mock native players.

Added a new class TestPlayerStub that takes a magic url in the setDataSource call.
Based on the value of the url, the stub is going to load a DL and create the concrete
player used during the test.
After these initialization steps TestPlayerStub is just a wrapper.

Added a new functional test MediaPlayerInvokeTest to demonstrate how a new
mock player to test the invoke method can be loaded.

Added a new mock player for the invoke test: invoke_mock_media_player.cpp.
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