Interapplication Communication with Qualcomm Brew

Interapplication Communication with Qualcomm Brew

wo heads are better than one, goes the old saying, and that can be as true for mobile applications as it is the people who write them. Whether you’re looking to partition functionality between related applications, or integrate two applications to work together to share data, if you’re working in the mobile space, you should understand Brew’s interapplication paradigm. This article willshow you how to have applications communicate via launch arguments, events, URLs, and Brew’s IFIFO, a kernel-level pipe interface you can establish between applications.

Brew Interprocess Communications Overview
As you already know, Brew provides a single-process execution environment with an application stack. The frontmost application?that’s the one you’re interacting with?is at the top of the stack, and other applications that have been previously launched and are suspended are at lower levels of the stack. An application may also run in the background, in which case its context remains loaded and it can receive events from the system or other applications, but shouldn’t draw to the screen.

All of these applications can communicate in four different ways:

  • Applications may pass events to each other.
  • One application may start another and include launch arguments for the started application to process as it begins execution.
  • Applications can pass URLs anonymously to other applications (this is a specialized form of launch argument handling).
  • An application can establish a fifo to which other applications can write.

Events in Brew
The Brew Application Execution Environment (AEE) includes an event pump that accepts events from the system and other sources and directs them to applications. Using the twin methods ISHELL_SendEvent and ISHELL_PostEvent, your application can direct an event to any other application resident on the device. With the event?a thirty-two bit integer?you can send two arguments: a sixteen bit integer and a thirty-two bit integer, collectively called the event arguments. The system reserves a range of events for system notifications such as incoming keystrokes, alarms, and SMS messages; any event numbered greater than the Brew-defined constant EVT_USER is fair game.

When sending an event to another application, it’s important to know the difference between ISHELL_SendEvent and ISHELL_PostEvent. The former is synchronous, that is, the recipient’s event handler is invoked before ISHELL_SendEvent returns. ISHELL_PostEvent, on the other hand, is asynchronous; your event is queued and will be sent to the recipient application after ISHELL_PostEvent returns. Which you choose to use is largely up to you, but you should be aware of two things:

  • Because ISHELL_SendEvent is synchronous, the amount of stack space available to the recipient may be significantly less than if you use ISHELL_PostEvent.
  • Anything you’re signalling about using ISHELL_PostEvent must persist beyond the lifetime of the calling function, because it’s asynchronous and the receiver won’t receive the event until your application has yielded control to the Brew run time.

An obvious mode of interapplication communication, then, is to agree on event code and argument syntax, and just have two applications pass events around. If you and I agree that EVT_USER+1 means something?say, for my application to show a particular screen?your application can invoke mine by sending me that event, and I can handle it by launching using ISHELL_StartApplet and going to that screen.

This is unnecessarily brittle, however. Brew provides the ISHELL_RegisterEvent call, which takes a character string and returns a unique event associated with that character string. If more than one application invokes this API with the same character string, the same event is returned. Thus, instead of agreeing on a specific constant (EVT_USER+1) it’s better for us to agree on a well-defined character string, such as com.rocketmobile.myapp.launchtolistview, and let Brew handle the event code mapping under the hood. On boot, my application can register this event, and your application can register the same event when it needs to invoke mine, and Brew will handle the string-to-event code mechanism.

A word about the event arguments is in order. Because one of the event arguments is a thirty-two-bit integer, it’s very tempting to overload this integer and use it as a pointer, as Brew does with many events such as EVT_APP_MESSAGE. As I write this, this actually works?an application can use ISHELL_SendEvent to send an event and a pointer to its private data to another application, and another application can accept the integer, cast it to a pointer of the appropriate type, and dereference the pointer in the first application’s heap. This is a particularly nasty solution to passing large quantities of data between two applications for at least three reasons:

  • There is no type safety in this transaction. If the sending or receiving application mis-casts the pointer, the data will not be interpreted correctly and one or more applications may crash as a result.
  • Qualcomm has indicated that in future versions of Brew, each application will run in its own memory space, so that applications cannot share pointers to the same data.
  • There are bettter ways to do it, which is what the rest of this article is about.

For these reasons, I strongly recommend using one of the following means to pass anything more than a sixteen or thirty-two bit integer between two applications.

Starting an Application with Arguments
Most of the time, starting an applet is as easy as calling ISHELL_StartApplet with the class ID of the application to start. But there’s also ISHELL_StartAppletArgs, which takes an additional character string. When Brew handles this API, it makes a copy of the character string you provide, and sends it to the application being started as the pszArgs element of the AEEAppStart structure pointed to by the dwParam argument of the EVT_APP_START or EVT_APP_RESUME event. Thus, if your application invokes the following:

ISHELL_StartAppletArgs( pMe->a.,m_pIShell,                         AEECLSID_MYAPP, "listview" );

and my application’s class ID is AEECLSID_MYAPP is found on the device, it will be created and sent an EVT_APP_START (or, if it’s already running, it will receive EVT_APP_RESUME), and I can get the arguments you pass me with code such as the following in my event handler: EVT_APP_START:case EVT_APP_RESUME:{	AEEAppStart *pArgs = (AEEAppStart *)dwParam;	if ( pArgs && pArgs->pszArgs &&         0==STRCMP(pArgs->pszArgs, "listview" )		ShowListView( pMe );	else		ShowNormalView( pMe );	bHandled = TRUE;}break;...return bHandled;

The beauty of ISHELL_StartAppletArgs is that anything can be passed, so long as it’s a reasonable-length string. It’s an excellent means of chaining one application to another, so that one application can offer a particular feature such as media download, while another application offers a related feature, such as content search. It does have its drawbacks, however.

First, the data you pass must be a null-terminated string of reasonable length, because the Brew runtime is going to use some equivalent of STRDUP() to make a copy of the arguments you provide before passing it to the receiving application. If you’re looking to pass a large blob of binary data, a FIFO is a better choice, as shown in a subsequent section of this article.

Second, there’s no format imposed on the character string you pass. This is both good and bad. It gives you the freedom to use whatever you want, but at the same time, it’s up to you to create a parser to interpret the string you’re receiving. There’s no equivalent to the UNIX getopt for Brew; over the years I’ve seen some pretty esoteric means of getting arguments from one application to another as a result.

Third, you have to know the class ID of the receiving application. It’s not enough to know what to say, but you have to know to whom your message is being sent. While this usually isn’t a problem?interapplication communication is usually used by closely coupled parties such as two development teams at one firm or two firms working together?it imposes unnecessary coupling between the two applications.

To address these concerns?the format of the arguments and the coupling of between applications?you should use ISHELL_BrowseURL or ISHELL_PostURL instead.

Passing an Application to a URL
Any Brew application can request another application to handle URLs using the ISHELL_BrowseURL or ISHELL_PostURL functions through the Brew AEE’s URL and MIME type handling registries. Using this mechanism:

  • Applications that can handle specific Web protocols register their ability in their Module Information File.
  • A client application requesting a service creates a URL for the specific Web protocol, embedding the arguments to the request in the URL using the standard mechanism used by Web servers handling GET requests.
  • The client application invokes ISHELL_BrowseURL to launch the application associated with the desired protocol, or ISHELL_PostURL to request a service without launching the application that handles the desired protocol.
  • The Brew AEE searches its registry of Web protocol and MIME handlers for a class ID that can handle the protocol in the URL you pass.
  • The Brew AEE sends the URL to the handling application via either the EVT_BROWSE_URL (if you used ISHELL_BrowseURL) or the EVT_APP_POST_URL (if you used ISHELL_PostURL).

To use one of these APIs to launch the hypothetical application to the list view, you might write:

ISHELL_LaunchURL( pMe->a.m_pIShell,                   "rayapp://listview" );

The application here would need to add the rayapp protocol to the list of handled protocols in the module information file, and then use IWEBUtil to crack the incoming URL in the event handler, like this:

case EVT_BROWSE_URL:{	char *pszUrl = (char *)dwParam;	UrlParts sParts = {};	IWEBUTIL_ParseUrl( pMe->piwu, pszUrl, &sParts );		if ( sParts.cpcPath &&         0 == STRCMP( sParts.cpcPath, "listview" ) )		ShowListView( pMe );	else		ShowNormalView( pMe );	bHandled = TRUE;}break;

Of course, the URL you pass to me might have arguments, too; you could pass something like rayapp://listview?style=fancy;items=one,two,three, and I can parse the URL arguments starting from the UrlPart’s cpcSrch pointer.

As I hinted previously, ISHELL_LaunchURL launches the registered application to the foreground; if what you want is background processing of the content, use ISHELL_PostURL instead. From there, your application can process the URL and even start itself in the foreground or background as appropriate.

URLs are excellent containers for small parcels of data like launch parameters, but sometimes you need something bigger. For this, there’s IFIFO.

Since Brew 1.x, applications have been able to share data via the file system by putting files in the shared directory. Later versions of Brew improve upon this convention by providing access control lists (ACLs), permitting modules to share access to their private directories. While this has been an acceptable means to share large quantities of data between applications, it can have stiff performance penalties, as applications must read and write the data being shared to the flash file system.

In Brew 3.x, Qualcomm introduced the IFIFO interface, which as its name suggests, is a first-in-first-out queue for interapplication communication. Applications using IFIFO specify the location of the fifo as they open it using a file path preceded by the string fifo:/, i.e., fifo:/shared/rayapp or fifo:/~0x123456/rayapp. The first example denotes a fifo in the shared file system that can be accesed by any application; the latter a fifo in a specific module’s directory that can only be accessed by applications that have the appropriate entry in their ACL.

Once a FIFO is opened, it can can be read from or written to depending on the access mode they specify when opening the fifo. For example, to open the fifo located at /shared/rayapp for reading and writing, I would refer to the fifo as fifo:/shared/rayapp?mode=rw, like this:

result = ISHELL_CreateInstance( pMe->a.m_pIShell, AEECLSID_FIFO, (void **)&pMe->pififo );if ( result == SUCCESS ){	result = IFIFO_Open( pMe-

Once open, the using the fifo is just like using any other Brew socket. You must see if you can write to the fifo by calling IFIFO_Writable with a callback, and in your callback, invoke IFIFO_Write. Similarly, to read data, set a callback using IFIFO_Readable and read the data using IFIFO_Read, looking for ISOURCE_WAIT, ISOURCE_ERROR, and ISOURCE_END values, indicating that all of the data has been read, an error has occured, or the writer has closed the fifo, respectively.

You can also set and query the fifo's buffer size (within reason) using IFIFO_SetBufSize and IFIFO_GetBufSize. Equally useful is IFIFO_GetBufUsed, which returns the number of bytes used in the buffer.

When using a fifo, two questions come to mind: in what format should the data be, and how should listeners wait for the data? The answer to the former is largely application-dependent, but of course you should consider platform-agnostic types such as media types, XML, and YAML, to make the most of decoupling between your applications.

Figure 1. Picture This: Drawing lines using different Pens.

The second question also depends on the nature of your application, but in practice an approach coupling an event with a specific fifo can work well. When a client application needs to request a service of the serving application, it registers an event and invokes ISHELL_SendEvent to the serving application. The serving application registers the same event on module load, then responds to the event by opening the established fifo for reading and launches to the background. The client application is then free to write its request to the fifo, and the serving application can respond via events or a second fifo as appropriate (see Figure 1).

Brew's Come a Long Way, Baby
Interapplication communication has come a long way since the lowly shared file and mutually agreed upon event found in the first versions of Brew. Using either URLs for simple data types or fifos for complex data blocks, it's now possible to create sophisticated client-server relationships between applications in Brew.



Share the Post:
Poland Energy Future

Westinghouse Builds Polish Power Plant

Westinghouse Electric Company and Bechtel have come together to establish a formal partnership in order to design and construct Poland’s inaugural nuclear power plant at

EV Labor Market

EV Industry Hurting For Skilled Labor

The United Auto Workers strike has highlighted the anticipated change towards a future dominated by electric vehicles (EVs), a shift which numerous people think will

Soaring EV Quotas

Soaring EV Quotas Spark Battle Against Time

Automakers are still expected to meet stringent electric vehicle (EV) sales quotas, despite the delayed ban on new petrol and diesel cars. Starting January 2023,

Affordable Electric Revolution

Tesla Rivals Make Bold Moves

Tesla, a name synonymous with EVs, has consistently been at the forefront of the automotive industry’s electric revolution. The products that Elon Musk has developed

Poland Energy Future

Westinghouse Builds Polish Power Plant

Westinghouse Electric Company and Bechtel have come together to establish a formal partnership in order to design and construct Poland’s inaugural nuclear power plant at the Lubiatowo-Kopalino site in Pomerania.

EV Labor Market

EV Industry Hurting For Skilled Labor

The United Auto Workers strike has highlighted the anticipated change towards a future dominated by electric vehicles (EVs), a shift which numerous people think will result in job losses. However,

Soaring EV Quotas

Soaring EV Quotas Spark Battle Against Time

Automakers are still expected to meet stringent electric vehicle (EV) sales quotas, despite the delayed ban on new petrol and diesel cars. Starting January 2023, more than one-fifth of automobiles

Affordable Electric Revolution

Tesla Rivals Make Bold Moves

Tesla, a name synonymous with EVs, has consistently been at the forefront of the automotive industry’s electric revolution. The products that Elon Musk has developed are at the forefront because

Sunsets' Technique

Inside the Climate Battle: Make Sunsets’ Technique

On February 12, 2023, Luke Iseman and Andrew Song from the solar geoengineering firm Make Sunsets showcased their technique for injecting sulfur dioxide (SO₂) into the stratosphere as a means

AI Adherence Prediction

AI Algorithm Predicts Treatment Adherence

Swoop, a prominent consumer health data company, has unveiled a cutting-edge algorithm capable of predicting adherence to treatment in people with Multiple Sclerosis (MS) and other health conditions. Utilizing artificial

Personalized UX

Here’s Why You Need to Use JavaScript and Cookies

In today’s increasingly digital world, websites often rely on JavaScript and cookies to provide users with a more seamless and personalized browsing experience. These key components allow websites to display

Geoengineering Methods

Scientists Dimming the Sun: It’s a Good Thing

Scientists at the University of Bern have been exploring geoengineering methods that could potentially slow down the melting of the West Antarctic ice sheet by reducing sunlight exposure. Among these

why startups succeed

The Top Reasons Why Startups Succeed

Everyone hears the stories. Apple was started in a garage. Musk slept in a rented office space while he was creating PayPal with his brother. Facebook was coded by a

Bold Evolution

Intel’s Bold Comeback

Intel, a leading figure in the semiconductor industry, has underperformed in the stock market over the past five years, with shares dropping by 4% as opposed to the 176% return

Semiconductor market

Semiconductor Slump: Rebound on the Horizon

In recent years, the semiconductor sector has faced a slump due to decreasing PC and smartphone sales, especially in 2022 and 2023. Nonetheless, as 2024 approaches, the industry seems to

Elevated Content Deals

Elevate Your Content Creation with Amazing Deals

The latest Tech Deals cater to creators of different levels and budgets, featuring a variety of computer accessories and tools designed specifically for content creation. Enhance your technological setup with

Learn Web Security

An Easy Way to Learn Web Security

The Web Security Academy has recently introduced new educational courses designed to offer a comprehensible and straightforward journey through the intricate realm of web security. These carefully designed learning courses

Military Drones Revolution

Military Drones: New Mobile Command Centers

The Air Force Special Operations Command (AFSOC) is currently working on a pioneering project that aims to transform MQ-9 Reaper drones into mobile command centers to better manage smaller unmanned

Tech Partnership

US and Vietnam: The Next Tech Leaders?

The US and Vietnam have entered into a series of multi-billion-dollar business deals, marking a significant leap forward in their cooperation in vital sectors like artificial intelligence (AI), semiconductors, and

Huge Savings

Score Massive Savings on Portable Gaming

This week in tech bargains, a well-known firm has considerably reduced the price of its portable gaming device, cutting costs by as much as 20 percent, which matches the lowest

Cloudfare Protection

Unbreakable: Cloudflare One Data Protection Suite

Recently, Cloudflare introduced its One Data Protection Suite, an extensive collection of sophisticated security tools designed to protect data in various environments, including web, private, and SaaS applications. The suite

Drone Revolution

Cool Drone Tech Unveiled at London Event

At the DSEI defense event in London, Israeli defense firms exhibited cutting-edge drone technology featuring vertical-takeoff-and-landing (VTOL) abilities while launching two innovative systems that have already been acquired by clients.

2D Semiconductor Revolution

Disrupting Electronics with 2D Semiconductors

The rapid development in electronic devices has created an increasing demand for advanced semiconductors. While silicon has traditionally been the go-to material for such applications, it suffers from certain limitations.

Cisco Growth

Cisco Cuts Jobs To Optimize Growth

Tech giant Cisco Systems Inc. recently unveiled plans to reduce its workforce in two Californian cities, with the goal of optimizing the company’s cost structure. The company has decided to

FAA Authorization

FAA Approves Drone Deliveries

In a significant development for the US drone industry, drone delivery company Zipline has gained Federal Aviation Administration (FAA) authorization, permitting them to operate drones beyond the visual line of

Mortgage Rate Challenges

Prop-Tech Firms Face Mortgage Rate Challenges

The surge in mortgage rates and a subsequent decrease in home buying have presented challenges for prop-tech firms like Divvy Homes, a rent-to-own start-up company. With a previous valuation of

Lighthouse Updates

Microsoft 365 Lighthouse: Powerful Updates

Microsoft has introduced a new update to Microsoft 365 Lighthouse, which includes support for alerts and notifications. This update is designed to give Managed Service Providers (MSPs) increased control and

Website Lock

Mysterious Website Blockage Sparks Concern

Recently, visitors of a well-known resource website encountered a message blocking their access, resulting in disappointment and frustration among its users. While the reason for this limitation remains uncertain, specialists