Service persistence

10 views
Skip to first unread message

Sean Eagan

unread,
Sep 26, 2011, 11:50:02 AM9/26/11
to web-i...@googlegroups.com

I think there are only two events which *may* indicate to the UA to close the service and/or picker for a given activity...

1) client closed prematurely (before postResult call):

Example - "pick" intent initiated, user closes client before postResult call.
Counter example - User reads article, clicks a button which initiates a "share" intent, closes article (since they are done with it), wants to be able to still complete the share workflow.

2) postResult call:

Example - Client initiates a "pick" intent, waits for a service to return picked content via postResult, at which point they want the service to be closed.
Counter example - Client initiates a "view" intent for a document, waits for the service to indicate success via a postResult call, the service browswing context should remain open after postResult so the user can view the document.

So currently there is not well defined criteria for the UA to use.  I think the criteria should be:

If the service's only purpose it to return data to the client, then close it anytime it calls postResult or the client is closed

The only question it how to inform the UA that a service has purpose other than returning data to the client.  The service will have the best insight into this, thus I propose allowing it to inform the UA by setting a "persistent" property on `window.intent` which defaults to false, that the UA will check when the client is closed or postResult is called.  However, if the client is closed before the service is opened (picker is still open), then the service will have not yet had a chance to inform the UA, so I propose letting the client set "persistent" as well.  Example code:

// share client
var intent = new Intent("http://webintents.org/share", "text/uri-list", url);
intent.persistent = true;
window.navigator.startActivity(intent);

// view service
var intent = window.intent;
if(intent.type = "http://webintents.org/view") {
  intent.persistent = true;
  var success = display(intent.data);
  window.intent.postResult(success);
}

Thanks,
Sean Eagan

James Hawkins

unread,
Sep 26, 2011, 4:08:45 PM9/26/11
to web-i...@googlegroups.com
On Mon, Sep 26, 2011 at 8:50 AM, Sean Eagan <seane...@gmail.com> wrote:

I think there are only two events which *may* indicate to the UA to close the service and/or picker for a given activity...

1) client closed prematurely (before postResult call):

Example - "pick" intent initiated, user closes client before postResult call.
Counter example - User reads article, clicks a button which initiates a "share" intent, closes article (since they are done with it), wants to be able to still complete the share workflow.


In this case, we envision letting the service continue it's business (for, e.g., your counter-example).  The call to postResult will silently be dropped on the floor.  From the perspective of the service, nothing different happens (since they are not notified on successful reception of postResult by the client).
 
2) postResult call:

Example - Client initiates a "pick" intent, waits for a service to return picked content via postResult, at which point they want the service to be closed.
Counter example - Client initiates a "view" intent for a document, waits for the service to indicate success via a postResult call, the service browswing context should remain open after postResult so the user can view the document.

So currently there is not well defined criteria for the UA to use.  I think the criteria should be:

If the service's only purpose it to return data to the client, then close it anytime it calls postResult or the client is closed

The only question it how to inform the UA that a service has purpose other than returning data to the client.  The service will have the best insight into this, thus I propose allowing it to inform the UA by setting a "persistent" property on `window.intent` which defaults to false, that the UA will check when the client is closed or postResult is called.  However, if the client is closed before the service is opened (picker is still open), then the service will have not yet had a chance to inform the UA, so I propose letting the client set "persistent" as well.  Example code:

// share client
var intent = new Intent("http://webintents.org/share", "text/uri-list", url);
intent.persistent = true;
window.navigator.startActivity(intent);

// view service
var intent = window.intent;
if(intent.type = "http://webintents.org/view") {
  intent.persistent = true;
  var success = display(intent.data);
  window.intent.postResult(success);
}


The counter-example is very compelling.  We could also provide a false-by-default parameter to postResult:

postResult(intent, persistent = false);

What are your thoughts on that solution?  Something about setting this signal on the intent payload itself seems not quite right.

Thanks,
James

Sean Eagan

unread,
Sep 27, 2011, 12:27:20 PM9/27/11
to web-i...@googlegroups.com
On Mon, Sep 26, 2011 at 3:08 PM, James Hawkins <jhaw...@chromium.org> wrote:
> On Mon, Sep 26, 2011 at 8:50 AM, Sean Eagan <seane...@gmail.com> wrote:
>>
>> I think there are only two events which *may* indicate to the UA to close
>> the service and/or picker for a given activity...
>>
>> 1) client closed prematurely (before postResult call):
>>
>> Example - "pick" intent initiated, user closes client before postResult
>> call.
>> Counter example - User reads article, clicks a button which initiates a
>> "share" intent, closes article (since they are done with it), wants to be
>> able to still complete the share workflow.
>
> In this case, we envision letting the service continue it's business (for,
> e.g., your counter-example)

But what about the "pick" example ? There is no reason for a "pick"
service picker or "pick" service to remain open after the client is
closed. Users would be confused and annoyed if they had to close
these themselves.

Also, it would be impossible to keep open "inline" pickers or
services. At the same time services with a "window" disposition would
be kept open. This would be inconsistent and unpredictable for the
user. This may be further reason to remove the "inline" disposition.

The following events can occur in an intent workflow:

1) startActivity call
2) service opened
3) postResult call
A) client closed

My thinking is that:

a) the client should decide whether the picker and/or service is
closed when A occurs between 1 and 3, basically whether to execute the
RPC for side effects, should probably remain open by default
b) the service should decide whether it is closed after 3, basically
whether to clean up the browsing context after the RPC call, should
close by default

I originally thought that the service should decide when A occurs
between 2 and 3, but I think it is more consistent to have the client
decide regardless of whether A occurs before or after 2.

Your false by default postResult argument seems to be the best solution for b).

For a) we could mirror the false by default postResult argument in
startActivity. The argument could be thought of as whether the
activity (RPC) is "dependent" on the client context remaining open.
One issue with this is that startActivity already has an optional
callback argument for which `undefined` would need to be passed.

What do you think ?

Thanks,
Sean Eagan

Tony Payne

unread,
Sep 27, 2011, 2:34:46 PM9/27/11
to web-i...@googlegroups.com
Comments inline

On Tue, Sep 27, 2011 at 9:27 AM, Sean Eagan <seane...@gmail.com> wrote:
On Mon, Sep 26, 2011 at 3:08 PM, James Hawkins <jhaw...@chromium.org> wrote:
> On Mon, Sep 26, 2011 at 8:50 AM, Sean Eagan <seane...@gmail.com> wrote:
>>
>> I think there are only two events which *may* indicate to the UA to close
>> the service and/or picker for a given activity...
>>
>> 1) client closed prematurely (before postResult call):
>>
>> Example - "pick" intent initiated, user closes client before postResult
>> call.
>> Counter example - User reads article, clicks a button which initiates a
>> "share" intent, closes article (since they are done with it), wants to be
>> able to still complete the share workflow.
>
> In this case, we envision letting the service continue it's business (for,
> e.g., your counter-example)

But what about the "pick" example ?  There is no reason for a "pick"
service picker or "pick" service to remain open after the client is
closed.  Users would be confused and annoyed if they had to close
these themselves.

There's no way to know that the service is still in the pick process. It's possible the user could navigate the service window away, in which case they would be quite annoyed (and surprised) when the client window forces the service window to close. Example: User chooses flickr to "pick" but instead gets distracted and starts uploading photos. Sure, a good picker service would make this impossible, but not every service will be "good" in this way.

I don't know if we want to expand the API surface, but I think a better solution to this use case is to allow the service to register a handler for a client-went-away event.
I don't think the client should ever decide when the service closes since the service window could have changed context. 
 
Your false by default postResult argument seems to be the best solution for b).

Another option is for the service window to just close itself after calling postResult.

Greg Billock

unread,
Sep 27, 2011, 2:43:49 PM9/27/11
to web-i...@googlegroups.com
It's probably easiest to think about three objects independently, the client page, the service page, and the connection (which you can think of as the picker page, although this is a bit misleading at some technical level).

The normal closing cases are these:

1. User closes entire client+picker+service context all at once. This is easy to do since inline services are displayed in the picker UI surface. In this case, there are some edge cases to worry about the destruction order to make sure that any events that need to be handled get handled. What we'll likely do is destruct the service with no particular special handling, then send an error callback to the client page if it exists, then close it down.

2. The user closes the picker + possibly inline service without closing the client. In this case, the client gets an error callback if it wants one.

3. The user closes the service page in a new-window context. In this case, the decision is whether to keep the picker active or just close all the way back down and signal the client page. There are other considerations here, chiefly whether the picker will remain visible after starting a new context. So we don't have that nailed down yet. On the other hand, we envision being able to drag the inline service window to tear it off and make a new window context, so it is likely that no matter what, this will be possible. The likely thing is that there'll be no picker, and that the client will get an error callback.

4. The user closes the whole browser window/process. This will likely be handled in the same way.

There are edge cases, such as the tab getting closed between the user picking a service and the service loading. These may not be so edge, esp. in cases of offline or slow services, or service unavailability. For edge cases such as these, we envision the picker remaining available and giving the user the opportunity to select another option.

Another edge case is if the user closes the client page without closing a new-window service page. In that case, I expect we'll almost certainly leave the service page open. We'll need to do some usability testing here -- perhaps a prompt about "you have an intent in progress, are you sure you want to close" will be nice to have. On the other hand, the page itself can present this, so it may be undesirable to force the issue in the UA.

Sean Eagan

unread,
Sep 30, 2011, 12:17:36 PM9/30/11
to web-i...@googlegroups.com
Good points. To summarize my thoughts on web intent browser context
close handling:

Clients should be allowed to register for an error callback which is
called anytime the UA determines that the result callback will not be
called.

Users should be allowed to go back and change their service
pre-postResult. This could manifest as a back button or a prompt upon
closing the service.

Services should be able to request to stay open after they call
postResult to handle such use cases as a "view" service wanting to
return a success indication but still remain open for content viewing
purposes. Implementation could be a false by default additional
postResult parameter.

Clients should be able to suggest to the UA whether an activity they
start is "dependent", if not then it should be canceled if the client
is closed pre-postResult. This prevents orphaned activities whose
only purpose was to return data to the client, such as"pick", as well
as user prompts as to whether they want to close the service upon
closing the client. Possibly let the service veto its dependency once
it is opened. Could be an optional boolean argument to startActivity
or a property on the intent instance.

--
Sean Eagan

James Hawkins

unread,
Sep 30, 2011, 1:59:58 PM9/30/11
to web-i...@googlegroups.com
On Fri, Sep 30, 2011 at 9:17 AM, Sean Eagan <seane...@gmail.com> wrote:
Good points.  To summarize my thoughts on web intent browser context
close handling:

Clients should be allowed to register for an error callback which is
called anytime the UA determines that the result callback will not be
called.


Agreed.
 
Users should be allowed to go back and change their service
pre-postResult.  This could manifest as a back button or a prompt upon
closing the service.


Agreed.
 
Services should be able to request to stay open after they call
postResult to handle such use cases as a "view" service wanting to
return a success indication but still remain open for content viewing
purposes.  Implementation could be a false by default additional
postResult parameter.


Agreed, though we need to figure out the best syntax.
 
Clients should be able to suggest to the UA whether an activity they
start is "dependent", if not then it should be canceled if the client
is closed pre-postResult.  This prevents orphaned activities whose
only purpose was to return data to the client, such as"pick", as well
as user prompts as to whether they want to close the service upon
closing the client.  Possibly let the service veto its dependency once
it is opened.  Could be an optional boolean argument to startActivity
or a property on the intent instance.


Hmm, not so sure about this one.  It seems to introduce a lot of complexity to the API for not much gain.

Thank you for your feedback; we'll take these notes as action items and make modifications to the draft.

James
Reply all
Reply to author
Forward
0 new messages