@cmarcelo, Hi, thanks for pointing this out, this is also a controversial part for myself. Things would be more difficult if we add the implementation of 'onInstalled' event API into consideration. 

How do you think of the following proposal?
1. We add a new parameter named 'launch_type' in ApplicationService::Launch(),  the launch_type is the reason of running the main document. It could be 'INSTALL' & 'REAL_LAUNCH'. Also ApplicationProcessManager will maintain a member variable named launch_type_ to track whether RunMainDocument() is called by install or real lauch.
2. After ApplicationSystem calls ApplicationService::Install(), it calls ApplicationService::Launch(id, launch_type), then pass the 'lauch_type' parameter to ApplicationProcessManager::launch_type_.
3. The ApplicationProcessManager is a webcontent observer of the main page, it is notified when main page finishes loading.  Then ApplicationProcessManager checks whether ‘onInstall’ event is registered in system database(the event should be registered before main page loading finish, at least we should have a copy of the event list in the memory). 
4. If the ‘onInstalled’ event is not registered in database, ApplicationProcessManager checks about the ‘launch_type_’, if is ‘INSTALL’, it closes the main loop and exit. Otherwise, it is a normal launch, nothing happens.
5. If the ‘onInstalled’ event is registered in database, ApplicationProcessManager sends ‘onInstalled’ event to render process and wait the event finish ack event is sent back. Note that ApplicationProcessManager is an ACK event observer. Therefore, ApplicationProcessManager is able to check the ACK event type. If event type is ‘onInstalled’, we check if there is still only main runtime object(because onInstalled event handler may open new windows) . If yes, we close main document and exit.
@pozdnyakov @seanlong