Sunday, June 14, 2009

Parameterized factory design pattern in Android Media Service Framework

As i was going through the Media framework of Android, i have found the implementation of a parameterized factory pattern in the way MediaPlayerService class creates the concrete media players.

Let me give an idea of the parameterized factory implementation as discussed in the GoF book. It goes like this.

class Creator {

public:

virtual Product* CreateProduct( ProductId id);

};

And the implementation will look like the following:

Product* Creator :: CreateProduct (ProductId id)
{

if (id == Product1) return new Product1;

if (id == Product2) return new Product2;

//repeat for the other products

return 0;

}

Product1, Product2 etc are all derived from the base class Product.

Now let us dissect the Media Framework of Android to see how this design pattern has been implemented to create the different Media players.

The base class of all the players are MediaPlayerInterface which is again derived from MediaPlayerBase.

MediaPlayerService has got a static function called

"static sp createPlayer(player_type playerType, void* cookie, notify_callback_f notifyFunc)"

which actually takes care of the creation of the concrete players namely PVPlayer, MidiFile and VorbisPlayer.

Hence the class MediaPlayerService works as the Factory class for creating the Concrete Players besides handling other responsibilities.

The class MediaPlayerService can be found at \base\media\libmediaplayerservice of the Android source code.

The createPlayer function goes like the following :

static sp(MediaPlayerBase) createPlayer(player_type playerType, void* cookie,
notify_callback_f notifyFunc)
{
sp(MediaPlayerBase) p;
switch (playerType) {
#ifndef NO_OPENCORE
case PV_PLAYER:
LOGV(" create PVPlayer");
p = new PVPlayer();
break;
#endif
case SONIVOX_PLAYER:
LOGV(" create MidiFile");
p = new MidiFile();
break;

case VORBIS_PLAYER:
LOGV(" create VorbisPlayer");
p = new VorbisPlayer();
break;
}
if (p != NULL) {
if (p->initCheck() == NO_ERROR) {
p->setNotifyCallback(cookie, notifyFunc);
} else {
p.clear();
}
}
if (p == NULL) {
LOGE("Failed to create player object");
}
return p;
}

As we can see from the above code that MediaPlayerBase here works as the base class Product. And we create different products (different concrete media players) through the function createPlayer which works as the CreateProduct function in the example at the beginning.

The above similarity shows how a Parameterized Factory Pattern has been implemented in the Android Media Framework by MediaService layer to create different Media Players.

No comments: