December 20, 2014
Hot Topics:

How Palm OS Expands Your Applications: Expansion Manager

  • June 23, 2005
  • By Alex Gusev
  • Send Email »
  • More Articles »

Inserting and Removing Cards

When expansion cards are inserted to or removed from a slot, Palm OS sends several broadcast notifications to inform all interested parties about the event that occured. Usually, Expansion and VFS Managers register several events on the card's insertion/removal, volume mounting, and so forth. Your application may be required to intercept default handlers. Palm OS gives you a simple way to do it: using notification handlers. A common practice here is to register for desired notifications at program startup and then unregister when it is no longer needed, usually at the exit from the application.

The default sequence of broadcasted events and related stuff upon card insertion are listed below:

  1. The sysNotifyCardInsertedEvent is broadcast by the slot driver
  2. Expansion Manager, registered for this event with priority 20, tries to mount volumes on inserted card with VFSVolumeMount
  3. VFSVolumeMount broadcasts sysNotifyVolumeMountedEvent for each mounted volume
  4. Expansion Manager, registered for this event with priority -20, does its job before any other application with normal priority
  5. VFS Manager, registered with priority 10, handles next two steps
  6. VFS Manager copies start.prc (if such an application exists in the /PALM folder)
  7. sysAppLaunchCmdCardLaunch is sent to start.prc and then sysAppLaunchCmdNormalLaunch
  8. Expansion Manager plays a sound indicating card insertion

Looking at the above list, let me point to where your application can intercept a default flow. There are two main spots. When the user inserts a card into expansion slot, sysNotifyCardInsertedEvent is broadcast. By default, Expansion Manager registers itself to get it with priority 20. This is done to ensure that Expansion Manager will get notified after all other applications registered for the same event with normal priority (sysNotifyNormalPriority). Your new handler should set the appropriate bits in the SysNotifyParamType.handled member:

  • expHandledVolume to prevent Expansion Manager; to deal with volume mounting and unmounting
  • expHandledSound to prevent Expansion Manager; to deal with sound indication on card insertion/removal

If you need only to be notified about these events without any influence on the default flow, just don't set up these two bits, that's all. Applications usually register themselves to volume mount/unmount events rather than to card related stuff, which was initially intended for system use. Nevetherless, sometimes you can be required to handle such kind of events as well.

A similar event chain happens in the case of sysNotifyVolumeMountedEvent. As you have seen already, VFS Manager registers itself to receive volume-related notifications with priority 10. So, if your application was registered for such notifications with normal priority, you always will be able to change the default flow of event handling. Saying so, you might be setting the following bits in the SysNotifyParamType.handled member:

  • vfsHandledUIAppSwitch to prevent VFS Manager from performing an UI switch to start.prc
  • vfsHandledStartPrc to prevent VFS Manager from running start.prc automatically

The volume unmounting and card removal processes flow is similar to insertion, but with several differences. Upon card removal, Expansion Manager informs all subscribers by broadcasting sysNotifyCardRemovedEvent, unmounts all its volumes, and plays a sound to indicate removal. Volume unmounting causes VFS Manager to remove start.prc from heap and send sysNotifyVolumeUnmountedEvent. Your application can be interested to be notified about such events.

The last, but not the least thing, is the security issues here. You should keep in mind one very simple scenario. If the PDA was locked at the time of insertion/mounting notification, your application has not run anything, thus keeping the PDA locked.

Finally, after such a long discussion about different notification codes, let me place a simple schematical code snippet here to illustrate all the things you have learrned:


...
static Err AppStart(void)
{
   UInt16 cardNo;
   LocalID dbID;
   // Get the current application path
   SysCurAppDatabase(&cardNo, &dbID);
   // Register for desired notifications, they will be sent as
   // launch codes (the fourth parameter is NULL)
   SysNotifyRegister(cardNo, dbID, sysNotifyCardInsertedEvent,
                     NULL, sysNotifyNormalPriority, NULL);
   SysNotifyRegister(cardNo, dbID, sysNotifyCardRemovedEvent,
                     NULL, sysNotifyNormalPriority, NULL);
   SysNotifyRegister(cardNo, dbID, sysNotifyVolumeMountedEvent,
                     NULL, sysNotifyNormalPriority, NULL);
   SysNotifyRegister(cardNo, dbID, sysNotifyVolumeUnmountedEvent,
                     NULL, sysNotifyNormalPriority, NULL);
   ...
   return errNone;
}
static void AppStop(void)
{
   UInt16 cardNo;
   LocalID dbID;
   // Get the current application path
   SysCurAppDatabase(&cardNo, &dbID);
   // Unregister for all notifications
   SysNotifyUnregister(cardNo, dbID, sysNotifyCardInsertedEvent,
                       sysNotifyNormalPriority);
   SysNotifyUnregister(cardNo, dbID, sysNotifyCardRemovedEvent,
                       sysNotifyNormalPriority);
   SysNotifyUnregister(cardNo, dbID, sysNotifyVolumeMountedEvent,
                       sysNotifyNormalPriority);
   SysNotifyUnregister(cardNo, dbID, sysNotifyVolumeUnmountedEvent,
                       sysNotifyNormalPriority);
   ...
   /* Close all the open forms. */
   FrmCloseAllForms();
}
...
UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
   Err error;
   UInt32 locked = 0;
   SysNotifyParamType *notifyParamP = NULL;
   UInt16 nSlotNumber = 0;
   error = RomVersionCompatible (ourMinVersion, launchFlags);
   if (error) return (error);
   switch (cmd)
   {
      case sysAppLaunchCmdNormalLaunch:
         error = AppStart();
         if (error)
            return error;
         /*
          * start application by opening the main form
          * and then entering the main event loop
          */
         FrmGotoForm(MainForm);
         AppEventLoop();
         AppStop();
         break;
      case sysAppLaunchCmdNotify:
         notifyParamP = (SysNotifyParamType *)cmdPBP;
         switch(notifyParamP->notifyType)
                        {
            case sysNotifyCardInsertedEvent:
               nSlotNumber = (UInt16)notifyParamP->notifyDetailsP;
               // do whatever you need to
               break;
            case sysNotifyCardRemoveEvent:
               nSlotNumber = (UInt16)notifyParamP->notifyDetailsP;
               // do whatever you need to
               break;
            case sysNotifyVolumeMountedEvent:
               nSlotNumber = (UInt16)notifyParamP->notifyDetailsP;
               // do whatever you need to
               break;
            case sysNotifyVolumeUnmountedEvent:
               nSlotNumber = (UInt16)notifyParamP->notifyDetailsP;
               // do whatever you need to
               break;
            ...
         }
         break;
   }
   return errNone;
}

Conclusion

Palm OS Expansion and VFS Managers working together give additional power to your application. You now can use their APIs to handle data stored on various expansion cards and similar peripheral devices. I hope that this article series has helped you in getting a general picture of what's going on in this area. Definitely some cards can behave weirdly, but I hope you will successfully conquer all possible issues....

About the Author

Alex Gusev started to play with mainframes at the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers lives in the mobile jungles a little bit simpler.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel