|
|
|
The IM framework is a component that provides an API to make applications aware of instant messaging presence information and interacts with instant messaging applications (like for example Wireless Village or ICQ). The presence information is provided by plugins to the framework. There will be one plugin for each IM application.
Example: The UIQ Contacts application is an IM aware application. An ICQ application would provide an IM plugin that would make it possible for Contacts and other IM aware applications to access presence information from the ICQ application.
This document has two parts. The first is about how you can use the framework to receive presence information in your IM aware application. The second part descibes how to implement a plugin for the framework.
There are two major classes you need to make your application IM aware. The first is CIMFramework which is the API to use when asking for information from the framework. The second is MIMObserver which is a mixin class used to get response from the framework.
Create an instance of the framework like this:
iIMFramework = CImFramework::NewL();
iIMFramework->SetImFwObserver(imObserver);
ImObserver is the class that will get callbacks from the framework. It needs to inherit from MIMObserver.
IM presence is another word for online status in an IM application. Examples could be “Available” or “Offline”.
If you want to know what online status someone has you can do like this:
_LIT(KIMIdentity,"john@hotmail.com");
TContactItemId cntId = 21;
imFramework->RequestContactNotificationL(serviceId, KIMIdentity, cntId);
serviceId is a UID that identifies a specific instant messaging application. You can get a list of available services (IM applications) by calling GetListOfServicesL. That will give you a list of TImServiceItem’s that contain name and UID of each installed IM application.
cntId can be used to remember what id this person has in the contact database. It can be set to zero if you don’t need it in your response later.
When the framework has discovered the presence of the contact (and each time the status of that contact changes) you will get a callback to PresenceStatusL(const TIndicationData& aIndicationData) in the observer. The indication data will contain the service Id, IM id and also an ID and text descriptions of the current presence of the contact. If you don’t want these callbacks anymore, you can cancel them using CancelContactNotificationL.
If you want the icon for this status you can do like this for example:
void CIMObserver::PresenceStatusL(const TIndicationData& aIndicationData)
{
CImStatusArray* array;
array = GetAvailableStatusesInServiceL(aIndicationData.iServiceId);
const TInt count = array->Count();
CImIcon* icon = NULL;
for(TInt i = 0; i < count; i++)
{
if(array->At(i)->StatusId() == aIndicationData.iStatusId)
{
icon = array->At(i)->Icon();
break;
}
} . . .
}
Getting the online status of the user (the person logged on to the IM network) is similar to getting the presence information from any other contact. You use RequestUsersPresenceStatusL in CIMFramework and will then get callbacks to UsersPresenceStatusL in the observer. If you want to change the online status of the user this can be done by calling SetUsersPresenceStatusL. There is one thing to keep in mind when setting the users presence: not every status returned by GetAvailableStatusesInServiceL can be set as the users status. The status needs to have the EUserAvailable flag set.
The framework provides a method that returns an IM identity (as a string) given some search parameters:
imIdentity = FindIMIdentityL(serviceId, firstName, lastName, mailAddress);
Service Id is the only required parameter, the others could be set to KNullDesC if not used.
The function of this method is somewhat unspecified. It is up to the IM plugin to define the behaviour. A typical thing would be to launch a dialog that would let the user select a IM identity from a list. When the dialog is closed, the selected identity is returned.
If your IM aware application is interested to know about all incoming IM messages, it should call RequestAnyMessageNotificationL() in CIMFramework. When you have done this, you will get callbacks to NewMessageL in the observer whenever a new IM message arrives in any IM application from any IM identity.
If you are only interested in notifications about incoming messages from individual IM identities in a specific IM application, you should use RequestContactNotificationL in the same way you do when requesting status information. You will then get callbacks to NewMessageContactL in the observer. If you want to stop getting these callbacks you can use CancelAnyMessageNotificationL. That will cancel message notifications from all services.
There is also a way to ask the framework for a list (CRequestedContacts) of all contacts that you have requested notifications about. This method in the framework is called RequestedContacts.
When you get a callback about a new message you will not receive the actual message itself, only who it came from and from what IM application it came (this is available in a TIndicationData as a parameter to the callback). This is enough information to DNL to the IM app and read the message there if desired.
Sometimes your IM aware application might want to know if there are any unread messages left. This could be useful if you for example want to display a flashing icon when you get an incoming message and then remove the icon when the message has been read. This can be done by the callbacks MessageReadContactL and AllMessageReadL to the observer. The first one is called when all new messages to a specific Contact has been read, and the second is called when all messages from a specific service has been read.
As the IM framwork only makes a very small part of the IM applications functions available to an IM aware application, there might sometimes be a need for quickly switching to an IM application. There are currently three such switches supported by the framework:
1. Read new messages (EImActionReadNew)
2. Compose a new message (EImActionComposeNew)
3. View detailed presence information (EImActionViewChatPresence)
You can use the GetViewUidForAction method to get the view UID and then perform a DNL to that view. If you want to read the incoming message of a contact, you can do like this for example:
_LIT(KIMIdentity,"john@hotmail.com");
TUid viewUid=iIMApi->GetViewUidForAction(serviceId, EImActionReadNew);
TUid actionUid = { EImActionReadNew };
CEikAppUi* eikAppUi = CEikonEnv::Static()->EikAppUi();
TUid appUid = {serviceId}; TVwsViewId id(appUid, viewUid);
if(viewUid.iUid != KNullUid)
{
TImDnlApplication dnl;
dnl.iActionId = EImActionReadNew;
dnl.iImUserId = KIMIdentity;
TImDnlApplicationBuf dnlBuf(dnl);
eikAppUi->ActivateViewL(id, actionUid, dnlBuf);
}
There are several icons that can be retrieved from the IM framework. All these icons are represented as CImIcon’s. A CImIcon consists of two CfbsBitmap’s (one small and one large) and their masks.
GetApplicationIconL(const TUint32& aServiceId) will return the icon that represents the IM application with that particular service id.
These can be retrieved from the framework by calling GetAvailableStatusesInServiceL. Each item (CImStatusItem) in the returned list will have an icon.
GetMessageIconL will return an icon from a specified service. This icon could be used to represent a new incoming message.
The difference between the default icons and the other icons is that the default icon is not unique for each IM service. Instead it is defined by the framework itself. This icon can be used whenever there is no other icon available.
As new IM applications may be installed and uninstalled at anytime, your IM aware application may need to adapt to this. That is why you will get callbacks to the observers InstallL and UninstallL methods when this happens.
If an IM identity is removed from an IM Application you will no longer get any presence updates from this identity, even if you had called RequestContactNotificationL for that identity. You will be notified about this by a call to the observers ImIdentityRemovedL method. You may still receive messages from this identity however.
When an IM application shuts down or otherwise logs off its online service, the OfflineL method in the observer will be called. This is an indication that the framework may no longer recieve any presence updates or any messages from that service. However, when the IM application goes online again, the observer is not directly notified about this. Presence notifications will simply start coming again.
The IM framework needs to communicate with IM applications. As IM applications can be installed at runtime, each IM application needs to implement a plugin to the IM framework that can also be installed at runtime.
The plugin is the component that handles the inter thread communication between IM framework and IM application. The plugin will run in the frameworks thread which is the same thread as the IM aware applications thread, while the IM application runs in its own thread. This document describes how to implement a plugin to the IM framework, but does not make any suggestions on how to handle the communication between IM application and plugin.
IM framework plugins are implemented as ECom plugins, using the ECom architecture. The mmp file must start something like this:
TARGET exampleplugin.dll
TARGETTYPE ECOMIIC
UID 0x10009D8D 0x101F61C8
0x101F61C8 is in this case the unique ID of this particular example plugin and needs to be replaced by the UID of your plugin. 0x10009D8D identifies this dll as an Ecom plugin.
The two major classes in the IM framework that you need to deal with when making a plugin are CImPlugin and MIMPluginObserver.
The class that needs to be implemented is the plugin class and it must inherit from CImPlugin. This class contain a set of virtual methods that must be implemented by your plugin. It also has a pointer to a plugin observer (MIMPluginObserver). The plugin observer is used by the plugin to send information to the framework.
A lot of the communication between the IM framework and the plugin uses the class TIndicationData as a parameter. This is a simple T-class with a number of public data members used to identify an IM notification:
iServiceId: Which service (IM application) the notification is sent from. This will be the “implementation_uid” from the resource file.
iImUserId: Which IM user this notification is associated with.
iCntId: Which contact id this IM user has.
iStatusId: The id of this particular status (this is only used for status notifications).
iViewUid: A uid that can be used to create a dnl to read the new message (this is only used in message notifications).
iDescription: A description of the new status (this is only used in status change notifications). Example: “Away”.
iAdditionalDescription: An additional description of the new status (this is only used in status change notifications). Example: “I am walking the dog”.
The following methods needs to be implemented by the plugin class.
When this method has been called the plugin is responsible for as soon as possible call PresenceStatusL in the plugin observer with the current status of the requested IM identity. It is also responsible for calling PresenceStatusL everytime the presence of this IM identity changes and it must call NewMessageContactL when a new message arrives from this IM identity.
Note that you can ask the plugin observer what contacts have requested notifcations by calling RequestedContacts().
When this method has been called, the plugin should no longer notify the plugin observer about status changes or incoming messages from this IM identity.
When this method has been called, the plugin should no longer notify the plugin observer about status changes or incoming messages from any IM identity.
When this method has been called the plugin is responsible for as soon as possible call UsersPresenceStatusL in the plugin observer with the user’s online status. It is also resonsible to call UsersPresenceStatusL everytime the online status of the user changes.
When this method has been called the plugin is responsible for calling NewMessageL in the plugin observer everytime the a new message arrive from any IM identity, even if notifications have not been requested for that particular IM identity.
When this method has been called, the plugin is no longer responsible for calling NewMessageL for any incoming messages. The plugin must however still call NewMessageContactL for those IM identities that has requested notifications.
This method should create and return a CImStatusArray. Each item (CImStatusItem) in this list contains:
StatusId: simply a number that is unique for this status. Used to identify this status in this service. It could for example be an index from 0 to n.
Description: A text with the name of the status. Example: “Away”.
Icon: A CImIcon that can be used to represent this status in IM aware applications.
Flags: There are two flags:
1. EUserAvailable. This indicates that the status is possible to use when changing the status of the user. Example: “Invisible”
2. EBuddyAvailable. This indicates that the status is possible as a status of any IM identity except the user. Example: “Offline”
Most statuses would have both flags set, Example “Away”.
When this method is called, the users presence should be changed to the status identified by the status id sent as a parameter. There is also a description text as a parameter. That is used for additional desription of the status (example: “I am walking the dog”).
This method could be implemented in many ways. The important thing is that it must return an IM identity as a text string. Preferably this method launch some kind of dialog that lets the user find an IM identity. The name and email adress sent as parameters may be used to help the user find IM identity he wants quicker, but they should not limit his search. In fact, they may only be empty stings sometimes, if that information is not available.
This method should return a view UID of the IM application that is suitable to make a DNL to for these actions:
1. Read new messages (EImActionReadNew)
2. Compose a new message (EImActionComposeNew)
3. View detailed presence information (EImActionViewChatPresence)
The method must always return a valid view UID, or return KNullUid if a DNL to the IM application is not recommended for some reason.
Returns the icon to represent a new message.
Returns the IM applications application icon (the icon visible in the application launcher).
The plugin should call UninstallL in the plugin observer when the IM application has been uninstalled. Note that there is also an InstallL method in the plugin observer, but this should not be used, as the framework handles that on its own.
When an IM identity has been removed from the IM applications and no longer recieves any presence updates from this identity, the plugin must inform the plugin observer about this by calling ImIdentityRemovedL. This only needs to be done if nofitifications from the removed identity had been requested.
The plugin needs to call OfflineL in the plugin observer when the IM application logs of its online service and no longer is able to respond to changes in presence. When the IM application goes online it should always send presence information about any requested Contacts (use RequestedContacts in the observer to ask for the list).
Please note that there is no connection between this offline and the status “Offline” that may be available in IM applications. This offline means that the user is not logged on to the IM network while the status “Offline” means that a particular IM identity in the users list of friends is not logged on (or perhaps “invisible”).
The plugin needs a resource file. This file must be named after the UID of the plugin. In this example (see 3.1) it must be named “101F61C8.dll”. Here is an example of what it could look like:
#include "registryinfo.rh"
RESOURCE REGISTRY_INFO theInfo
{
dll_uid = 0x101F61C8;
interfaces =
{
INTERFACE_INFO
{
interface_uid = 0x101F61A4;
implementations =
{
IMPLEMENTATION_INFO
{
implementation_uid = 0x101F61CB;
version_no = 1;
display_name = "IM example name";
default_data = "";
opaque_data = "";
}
};
}
};
}
Dll_uid is the UID of the plugin’s dll as specified in the mmp file.
Interface_uid should be 0x101F61A4 as this is what marks the plugin as a IM Framework plugin.
Implementation_uid must be the application UID of the IM application that this plugin belongs to.
Display_name is the name of the service you get from the IM framework when asking for available services, see 2.2. This will probably be visible in the UI and should be something that tells the user what IM app this plugin belongs to (for example “Wireless Village” or “AOL messager”).