Clarifying the MIDP3 pauseApp proposal
The intent of this post is to summarize and address the developer comments regarding the MIDP3 proposal to deprecate
pauseApp, and hopefully clarify some misconceptions about the proposal. I want to thank Enrique Ortiz for using his position in the industry to help get the message on this topic out to developers via his blog and post to KVM-INTEREST which is reflected in the Mobile & Embedded forums at java.net.
Mike Milikich, the MIDP3 EG lead, has asked for developer input on two specific questions:
- What percentage of your applications implement pauseApp, and for the ones that do, what functionality is present in pauseApp?
- For any applications that implement pauseApp, what would be the effect of running that application in an environment in which pauseApp was never called?
If you don't make it through this rather long post, these are the two most pressing questions at this point.
Also, I will be going to next week's MIDP3 face-to-face meeting. If there is a particular aspect of this topic or any other you would like me to emphasize, post a reply, or call me at +1-703-771-8527. The developer community is underrepresented in face-to-face meetings because of the substantial time and financial burden that attending these presents, and frankly we need more of the "street smarts" experience of developers.
What is driving the proposal?
pauseApp proposal revolves around these points:
- MIDP3 is introducing new APIs to provide better homes for the functionality that implementers have burdened
pauseAppwith in non-portable ways.
- MIDP3 is also introducing concurrency, and is trying to eliminate the ability of a platform to place a MIDlet into a PAUSED state (that is, cease providing CPU time to threads, or arbitrarily pull resources).
- The proposal proponents wish to force implementers to stop the overloading of
pauseApp, which is creating fragmentation between devices, by closing this loophole, while providing standardized methods to accomplish the same tasks.
- The Expert Group wishes to learn all the different ways that developers have been using
pauseAppso that no one gets left out in the cold, either by addressing concerns through these new APIs, or if the impact is severe enough, dropping the proposal.
The EG literally realized that when these were accomplished, there would be nothing left for
pauseApp or the related methods to do. Therefore,
notifyPaused would essentially have nothing but a legacy purpose, and could become no-ops for applications written for MIDP3.
And to the legacy point, the EG has discussed whether or not implementations should be allowed to continue to provide legacy functionality for these APIs, if the MIDlet is labeled "MIDP-2.x" or earlier. It's totally legal by the MIDP1/2 spec and TCK to make these methods no-ops (and this is what Nokia does); if MIDP3 mandates this for ALL implementations, how much of a problem will it be for you to port your application to a MIDP3 device?
Is the EG "removing" pauseApp?
No! The interpretation of the word "deprecate" has turned this into a real debate. The proposal includes the use of the deprecation as a tool to remind people that this has occurred via compiler warnings - not to remove the API. We're thinking more along the lines of this definition, keeping in mind that eventual removal of the API is not going to happen any time soon because of the huge impact this would have on existing applications.
I'm afraid that I inadvertently started the idea that the EG was removing
pauseApp with the title of my original post (Message from MIDP3: Goodbye pauseApp!) What I meant was, goodbye to all the issues it has caused, and I'll be happy never to have to include an empty
pauseApp method in my MIDlets again. (The new API is removing the
abstract modifier to make that possible.)
What is replacing the functionality that
pauseApp is overloaded with?
The MIDP1/2 specification provides the
resumeRequest methods for the following purposes:
- To allow a MIDlet to be signaled that the implementation has placed it into the PAUSED state
- To allow a MIDlet to signal that is wishes to be placed into the PAUSED state
- To allow a MIDlet to signal that it wishes to be removed from the PAUSED state
This begs the question, what exactly does it mean to be PAUSED. The answer has been subject to different interpretations since MIDP 1.0. In my original post, I pointed out that the PAUSED state existed so that early implementers would be better able to use MIDP on platforms not originally designed for it. If an implementation being built in 2000 really needed CPU time for a phone call, it could simply call
pauseApp, halt execution, take back memory and other resources, and handle the phone call.
In 2007, handsets are designed with Java ME in mind, and many implementers have solutions to the phone call problem. MIDP3 is introducing concurrency so a MIDlet's thread can execute even when it does not have the display and other MIDlets are running.
There is an argument that the PAUSED state must exist to allow MIDP3 to run on the lowest common denominator of devices, but if you look at where MIDP has gone since MIDP1, it has basically priced itself out of that market. MIDP has found its niche and it is not at the bottom of the market. New VMs such as the Squawk VM are filling that gap. I'd be happy to argue about this in a different thread.
So with no PAUSED state (outside of that prior to the first call of
startApp), that leaves us with the ways
pauseApp has been overloaded by implementers in non-portable ways:
- As a signal that the app is about to lose the UI, as during an incoming phone call
- And in other ways that implementations are leveraging
pauseApp. This is a key area where the EG is trying to find out if the APIs in MIDP3 are covering these cases sufficiently - please provide these cases!
pauseApp provided me with a way of doing (x) - how can I do that in MIDP3?
The signal that the app is about to lose the display for a phone call is one interpretation that permeates the iDEN platform, which was the first US Java ME platform launched in 2001. The low level lcdui class
hideNotify as a notification that you've lost the display, but there was no equivalent high level API notification - you had to poll
Screen.isShown, which was possible in the PAUSED state on the iDEN platform (iDEN has allowed threads to run in PAUSED state since alpha in 2000) but this is kind of hard to do when threads are stopped in other platforms. Providing a way to be notified of display state changes is a major feature addition in MIDP3 that was not ready in time for the early draft review, but is planned for the upcoming public review. This is one area where MIDP3 is replacing functionality in
pauseApp that is not implemented consistently across the ME universe.
As far as detecting an incoming phone call, on iDEN that was a guess, because
pauseApp could be called for a number of reasons, including when the user actually paused the application through the device's application manager.
As noted in the discussion, there are many other reasons that a phone may lose control of the display. Some of these can be handled through the new mechanisms in MIDP3 or existing mechanisms in other JSRs (Bluetooth, etc) and hopefully (a point for another entire debate!) these implementers get it right and the TCKs catch where they got it wrong. The new
javax.microedition.event package should be of great help here. The
EventData class includes things like
BATTERY_LEVEL, EXTERNAL_POWER, and VOICE_CALL (events outside of MIDP's purview, such as those related to SMS, are the domain of other JSRs.) Developers should look at other fields in this class by downloading the early draft review from the JSR-271 page at JCP.org, and let the EG know what else they'd like to see.
Won't this break compatibility between MIDP 1/2 and MIDP3?
Actually, the way pauseApp is currently defined and implemented, we have incompatibility today between platforms, with developers creating porting layers run by porting teams to deal with these incompatibilities whenever a new device comes out. Defining new APIs that replace the non-portable behaviors in
pauseApp with standardized behavior is the whole point of this.
pauseApp mechanism is so loosely defined that nothing today is preventing an implementer from changing their
pauseApp behavior when they move to a new platform (and I know cases where this has happened.) They will still pass the TCK with flying colors. There is no way to bolster the TCK the way these APIs are currently defined - they were deliberately left open to allow the widest range of platforms to implement MIDP, back at the turn of the century.
There is a question that developers need to weigh in on, and that is whether or not implementers of MIDP3 would be allowed (or forced) to retain compatibility with applications written for MIDP 1/2 platforms. In other words, if an app was written to deal with a specific platform's implementation of pauseApp, it might have a chance of running on a new MIDP3 platform without modification.
While this sounds good on the outside, there are several major issues with this, including:
- This requirement could greatly increase the complexity of certain MIDP3 implementations and emulators.
- The requirement for apps to work in MIDP3 as they did in MIDP2 is not testable by a TCK.
- A particular implementer may have several implementations that are legal but incompatible, so the requirement would be impossible to comply with.
The EG is strongly leaning towards the simpler solution of making this change apply regardless of how a MIDlet is labeled. This means that if your existing application is, for example, counting on
pauseApp for a particular notification and will misbehave if
pauseApp is not called when that behavior occurs, then your application will need to be rewritten before it will run on that new device.
It would be good to know the extent of this issue, and how bad it really is given that many apps (unfortunately) need to be touched whenever a new version of a device comes out. Some posters commented that a
pauseApp-related change was relatively minor compared to some of the other porting issues they encounter when bringing a new device onboard.
What areas has this thread suggested that the EG has to look into more/respond to?
One area is the interruption of MIDlets (loss of display and/or keyboard) to various notifications by the platform:
- Presentation of a permissions request
- Low battery
- Out of coverage
- Incoming call - request to accept it
- Incoming notifications
- Bluetooth and other device changes
MIDP3 does provide the
javax.microedition.event API for notification of events, but there is no coupling between the new Display notifications to allow a MIDlet to determine why they were interrupted.
I feel that trying to find a cause for every interruption leads an exercise in boiling the ocean. Still, it is useful to provide some coupling between the
DisplayListener API and the
event mechanism if for no other reason than knowing that it is the same event coming from two different perspectives, possibly in different order on different platforms.
How to couple events from other JSRs that also lead to a DisplayListener event is another question.
In conclusion... isn't this a minor issue in the bigger fragmentation picture?
Simon Maspero's response to Hartti Suomela's Forum Nokia Blog on this topic summed it up well:
...the point is not really to know if pauseApp is necessary or not, but to make sure that every device will behave the same.
Fragmentation spans many areas of the Java ME ecosystem and needs to be addressed in a coordinated way. This will help in one small way, but there are many other points of fragmentation, including broken behavior, operator certification hurdles, barriers to certain APIs, user interface differences between MIDlet and native, phones interrupting apps for who knows what, etc. And, many people will tell you that not all fragmentation is bad. Some of it comes from the necessity of providing new features before a standard can be wrapped around them. Some of it comes from the need to provide flexibility to allow implementations to flourish.
pauseApp is an example of the latter whose time has passed and is no longer needed.
MSA addresses certain points of fragmentation but only a subset of those encountered. Individual companies like Sun, every company who is on MSA, and other standards organizations like 3G Americas are also very concerned and making progress.
But the largest fragmentation issues cannot be solved by a single company or JSR. The issue of fragmentation must be taken up at the industry level and be a legitimate coordinated effort involving all in the Java ME ecosystem. It especially needs to involve developers who don't have time to participate in EGs because they are too busy getting code out the door. It needs to solve the problem of getting input from these key people, who can't afford to fly around the world to meetings on their own dime.
It cannot be solved in closed JSRs where none of the members are developers working at the street level where these issues are encountered. It is the biggest threat to Java ME because it stops budding developers in their tracks and eats away at the investment we've made into Java ME.
Finally, I want to say that actively bringing dialog from an active JSR expert group, which is closed, out to the community in order to get feedback, is something that MIDP has done before, and is an experiment that should happen more often. Thanks to Mike Milikich, the 271 spec lead, for opening this up and letting us bypass the normal JCP rules that allow JSRs to operate in a closed manner.