This chapter provides instructions for developing a plug-in application. A sample plug-in application may be found in Reference 4 on page 63.
When the browser starts up, it queries the ECom framework to get a list
of all of the Symbian-registered plug-ins whose UIDs match the
KBrowserPluginInterfaceUid
.
The browser identifies the following information for each Netscape ECom plug-in:
File name
Plug-in name
Plug-in description
MIME type supported
MIME file extensions supported
MIME type description
When the browser needs to display data of a particular MIME type, it finds a plug-in registered to that type and loads the plug-in.
The browser employs a common Netscape Plug-in ECom interface to interact with any number of Netscape plug-in ECom implementations. This interface has two abstract methods that closely map to the following Netscape plug-in DLL-level methods:
InitializeFuncs
—initializes the plug-in
NPP_Shutdown
—shuts the plug-in down
Each ECom implementation derives from this interface and implements these two abstract methods to initialize and shutdown the plug-in. When the plug-in is initialized, the browser and the plug-in exchange function tables.
The Netscape Plug-in API defines two additional DLL-level methods:
NPP_GetMIMEDescription
NPP_GetValue
The NPP_GetMIMEDescription
method
returns the following information:
MIME types supported by the plug-in
File extensions supported by the plug-in
Brief description of the file type
The NPP_GetValue
method
is no longer needed because the ECom resource file can contain the display
name and description of the plug-in. The
Sample resource file for an ECom plug-in example
shows a sample ECom plug-in resource file:
/* Description : Resource file for the test Interface Implementation plug-in */ // INCLUDES #include "RegistryInfo.rh" // RESOURCE DEFINITIONS // Registry info // The UIDs for the filters implemented in this DLL RESOURCE_REGISTRY_INFO theInfo { dll_uid = 0x101F8756; // Should match the name of the file. // 3-d UID of the associated plug-in DLL (declared in the // mmp file of the plug-in’s DLL) interfaces= { INTERFACE_INFO { interface_uid = 0x101F8810; // identifies plug-in type (used by ECom) // interface_uid = KBrowserPluginInterfaceUid; implementations = { IMPLEMENTATION_INFO { implementation_uid = 0x101F8757; // Specify specific implementation //(must match an implementation entry in the DLL version_no = 1; display_name = "np.dll;S60 Test Plugin"; // file name and name of the plug-in default_data = "application/pdf;pdf;|app/pdf;abc;|application/x-shockwave-flash;plg,xplg,swf;My plugin;|txt/plg;txt|"; // Supported MIME types (application/pdf, // application/x-shockwave-flash ..), // MIME Extensions (pdf, plg, xplg ..), // and MIME descriptions (My plugin) opaque_data = "Plugin to test Browser support"; // Description of the plug-in } }; } }; } // End of File
Example 1: Sample resource file for an ECom plug-in
This section describes the initialization and destruction of ECom plug-in applications.
When a Netscape ECom plug-in is initialized, the browser saves the following data:
Plug-in name
Plug-in description
File name
MIME type
MIME file extension
MIME description
The browser passes a table of function pointers to the plug-in. This table is an allocated but uninitialized structure that contains the API that the plug-in provides to the browser. The plug-in fills out this table during the initialization call.
The browser calls the
NPP_New
function
to
create a plug-in instance. Instance-specific private data can be allocated
at this time. This call does not pass windowing information to the plug-in
constructor. The browser then calls the
NPP_SetWindow
function
to provide the windowing information required to embed the plug-in within
the parent Web page.
The browser calls the
NPP_Destroy
function to destroy
a plug-in instance. The browser application calls the
NPP_Destroy
function
when the user performs any of the
following actions:
Navigates away from the page containing the instance
Quits the application
If this is the last instance created by a plug-in, the browser calls the
NPP_Shutdown
function
.
It is important that the plug-in developer deletes all the resources, such
as the memory, files, and sockets allocated by the browser (such as streams)
before calling the
NPP_Destroy
function
. NPP_Destroy
does not track
or delete browser-created objects.
The
NPP_Shutdown
function does the
following:
Informs the plug-in that its library is about to be unloaded
Gives the plug-in a chance to perform closing tasks such as:
Cancel any outstanding I/O requests
Delete threads it created
Free any memory it allocated
This function is not called if any existing plug-in instances or plug-in stream instances are open.
All plug-in data should be deleted before this call is made. This call
is useful when data allocated by the
NPP_Initialize
function
needs to be cleaned up.
The S60 platform supports only windowed plug-ins, in which the plug-in
is drawn inside its own native window on a Web page. The
NPWindow
structure
represents the native window. This structure contains information about coordinate
position, size, the state of the plug-in, and a handle to the window.
typedef struct _NPWindow { void* window; // Platform-specific window handle int32 x; // Position of top left corner relative int32 y; // to a Web page. uint32 width; // Maximum window size uint32 height; NPRect clipRect; // MAC - Clipping rectangle in port coordinates NPWindowType type;// Only WindowType Window is supported NPWindow; }
Using the
NPP_SetWindow
function, the plug-in constructs a
CCoeControl
object
(or an object that inherits from
CCoeControl
) that is parented
to the Web page. The plug-in also gets a pointer to an object that implements
the PluginAdapter
interface.
The plug-in control should inherit from the following classes:
|
public |
#include <coecntrl.h> |
|
public |
#include <coecntrl.h> |
public |
#include " Pluginadapterinterface.h" from the plug-in adapter utility |
The parameters, plug-in instance, and the
NPWindow
structure
provide all the necessary information to the
NPP_SetWindow
function
call to create a control instance. The
NPWindow
argument
contains information pertaining to the window. The most important data is:
The bounds of the window
A pointer to a platform-specific window object. From this object, a pointer to the adapter interface can be obtained, which makes control-specific calls into the browser from the plug-in.
For more information on these functions, see the
MPluginAdapter class section.
The most important ones are the
PluginCreatedL
and the
PluginDeletedL
functions,
which inform the browser object of new and deleted plug-in child objects.
The following code example shows the implementation of the
NPP_SetWindow
function.
The CPluginAdapterUtil
::ExtractParentControlAndApiL
function is called
to get the parent control. The
adapter
object calls the Symbian
Window APIs.
/** * The browser calls the PluginSetWindow function to set the * control parent and the coordinates for the plug-in. * The first time this function is called, it * is important to construct the corresponding plug-in control. * The other times this call is made, it is expected that the * function simply updates the bounds of the control. * * @param instance − the plug-in instance originally used in * NPP_New(). * * @param window - a plug-in window structure that contains * window coordinates and platform-specific window information. * * @return - an error code, on success returns NPERR_NO_ERROR. */ NPError PluginSetWindow(NPP instance, NPWindow* window) { return Inst(instance)->PluginSetWindow(window); } NPError CNpInst::PluginSetWindow(NPWindow* window) { MPluginAdapterPTR pPluginAdapter = NULL; CCoeControlPTR pParentCoeControl = NULL; TRAPD(error, CPluginAdapterUtil::ExtractParentControlAndApiL( window, pPluginAdapter, pParentCoeControl)); if (error) return NPERR_GENERIC_ERROR; if (iFirstTime) { CreateWindowL(pParentCoeControl); pPluginAdapter->SetPluginNotifier(this); pPluginAdapter->PluginConstructedL(this); } TPoint point (window->x, window->y); TSize size(window->width, window->height); SetExtent(point, size); if (iFirstTime) { ActivateL(); iFirstTime = EFalse; } return NPERR_NO_ERROR; }
The plug-in calls the
NPN_MemAlloc
function to dynamically allocate
a specified amount of memory. The plug-in calls the
NPN_MemFree
function
to de-allocate a block of memory.
Streams are objects that represent data generated from a URL, or data sent by a plug-in without an associated URL. Streams can be produced by the browser and consumed by a plug-in instance, or produced by a plug-in instance and consumed by the browser. A stream object has an associated MIME type, which identifies the format of the data in the stream. Each stream object is associated with a single plug-in, and a plug-in can hold multiple stream objects.
The browser performs the following tasks when sending a data stream to the plug-in:
Creates a stream and informs the plug-in
To inform a plug-in when a new stream is created,
the browser calls the
NPP_NewStream
function.
This function also determines which mode the browser should use to send data
to the plug-in. The browser can create a stream for the following types of
data:
File
specified in the
src
attribute
of the
embed
tag
Data file
Full-page instance
Finds out from the plug-in how much data it can accept
After calling the
NPP_NewStream
function
and before writing data to the plug-in, the browser
calls the
NPP_WriteReady
function
to determine the maximum number
of bytes that the plug-in can accept. This function allows the browser to
send only as much data to the plug-in as it can handle at one time, and it
helps both the browser and the plug-in to use their resources efficiently.
Writes data to the stream object
The browser pushes data into the stream by using
a series of calls to the
NPP_WriteReady
and the
NPP_Write
functions
. The
NPP_Write
function returns the number of bytes
consumed by the plug-in instance. If this is a negative number, the browser
calls the
NPP_DestroyStream
function
to destroy the stream. If
the number returned is smaller than the size of the buffer, the browser sends
the remaining data in the buffer to the plug-in through repeated calls to
the
NPP_WriteReady
and
NPP_Write
functions
.
Notifies the plug-in and deletes the stream
After it sends the stream to the plug-in, the browser
calls the
NPP_DestroyStream
function
whether or not the stream arrived successfully. After the plug-in returns
from this function, the browser deletes the
NPStream
object.
The plug-in stores private
data associated with the stream in
stream ->pdata
.
Any resources that the plug-in allocated
for that stream
should be deleted when the stream is destroyed.
The browser stores private data in
stream->ndata.
T
he
plug-in should not change the value of
ndata
.
Figure 1: |
Note: It is not possible to send a data stream from the plug-in to the browser. |
A plug-in can request and receive the data associated with any type of URL that the browser can handle.
The plug-in calls the
NPN_GetURL
function to ask
the browser to do one of the following:
Display data retrieved from a URL in a specified target window or frame
Deliver the data to the plug-in instance in a new stream
If the browser cannot locate the URL or retrieve the data, it does not
create a stream for the plug-in. The developer can call the
NPN_GetURLNotify
function
to notify the plug-in that the data was not retrieved.
The browser calls the
NPP_URLNotify
function to
notify the plug-in. The browser then passes the
notifyData
value
to the plug-in. The
notifyData
parameter contains the
private plug-in data passed to the corresponding call to the
NPN_GetURLNotify
function
. The value of
notifyData
may
be used to track multiple requests.
The
NPN_GetURLNotify
function handles the URL request
asynchronously. It returns immediately and only later handles the request
and calls the
NPP_URLNotify
function
.
The plug-in must receive this notification in order to determine whether a
request with a null target failed or whether a request with a non-null target
completed successfully.
The plug-in calls the
NPN_PostURL
function to post
data from a file or buffer to a URL. After posting the data, the
NPN_PostURL
function
either displays the server response in the target window or delivers it to
the plug-in.
The
NPN_PostURLNotify
function has the same capabilities
as the
NPN_PostURL
function, with the following exceptions:
NPN_PostURLNotify
supports specifying
headers when posting a memory buffer
NPN_PostURLNotify
calls the
NPP_URLNotifyfunction
upon successful
or unsuccessful completion of the request. The
NPN_PostURLNotify function
is asynchronous; it returns
immediately and only later handles the request and calls the
NPP_URLNotify
function
.
The browsers for the S60 platform does not support Java communication functions.
The following utility functions enable a plug-in to display the current version of the Browser Plug-in API, the current browser status, the current User Agent, and any newly installed plug- ins:
|
Returns version information for the plug-in API. The browser does not support the
|
|
Returns the current browser status by displaying a message window in the top right corner of the screen |
|
Returns information about the currently configured User Agent to the plug-in. This information includes the name, version, and operating system on which the UA runs. The HTTP servers with which the browser communicates may require this information. |
|
Sends a request to the browser to reload all
plug-ins in the
The browser searches all drives from A: to Z: for new plug-ins. The browser installs any new plug-ins it finds into that directory and loads them without restarting. |
For more information on these functions, see the Utility functions section.
In order to build the plug-in component, follow these steps:
Add the following to the plug-in
mmp
file:
USERINCLUDE \epoc32\include\BrowserInterfaces\pluginInterface LIBRARY PluginAdapterUtil.lib
The
NPP_SetWindow
function
must make a call to the
ExtractParentControlAndApiL
function
API to extract
the platform-dependent window:
NPError NPP_SetWindow(NPP instance, NPWindow* window) { TRAPD(error, CPluginAdapterUtil::ExtractParentControlAndApiL( /*in*/ window, /*out*/iAdaptor, /*out*/iParentControl)); //Error processing based on error //…and so on… }