// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.modular;

// Sessionmgr passes a connection to this service to the SessionShell so it can
// operate on stories for the user. It is also passed to other services that
// monitor or manipulate stories, specifically the maxwell services.
//
// Closing a |StoryProvider| connection has no effect on the state of the
// framework.
[Discoverable]
interface StoryProvider {
    // Deletes an existing story from the list of known stories. Returns when the
    // delete notification is received from the Ledger. If the story to be deleted
    // is running, it is first stopped and its story controller disconnected. If
    // the story ID doesn't exist, it silently does nothing and returns.
    //
    // DEPRECATED: To delete stories, use PuppetMaster.
    3: DeleteStory(string story_id) -> ();

    // Returns a list of existing stories. If |watcher| is provided, the client will
    // be notified of story changes (new stories, deleted stories, runtime
    // state changes).
    4: GetStories(StoryProviderWatcher? watcher) -> (vector<StoryInfo> story_infos);

    // Requests detailed information about the given story. If the story doesn't
    // exist, returns null. GetStoryInfo() called immediately after DeleteStory()
    // (even before DeleteStory() returns) returns null.
    5: GetStoryInfo(string story_id) -> (StoryInfo? story_info);

    // Obtains a controller for a previously created story identified by its story
    // ID. Obtaining the controller doesn't run it yet. If the story doesn't
    // exist, the interface request is closed.
    6: GetController(string story_id, request<StoryController> request);

    // Returns info of known stories.
    // DEPRECATED: In favor of GetStories().
    7: PreviousStories() -> (vector<StoryInfo> story_infos);

    // Returns IDs of stories on the current device that are not STOPPED. More
    // information about the stories can be retrieved using GetStoryInfo(), or by
    // GetController(), then StoryController.GetInfo().
    // DEPRECATED: Use GetStories() and examine StoryInfo for running state.
    8: RunningStories() -> (vector<string> story_ids);

    // Registers a watcher for changes in the story collection.
    // DEPRECATED: In favor of GetStories().
    9: Watch(StoryProviderWatcher watcher);

    // Registers a watcher for ongoing story activity. Upon registration,
    // StoryActivityWatcher.OnStoryActivity() will be called to update clients
    // with the initial data. See StoryActivityWatcher for motivations.
    10: WatchActivity(StoryActivityWatcher watcher);
};

// Implemented by clients of StoryProvider.
interface StoryProviderWatcher {
    // Called in three different situations:
    //
    //  * Immediately when a new watcher is registered with one OnChange()
    //    invocation with the current infor and state of each story known on the
    //    current device.
    //
    //  * Every time a change to StoryInfo is applied to the record of the story
    //    kept on the current device, including a new story created on another
    //    device becoming known on this device for the first time.
    //
    //  * Every time the StoryState of the story changes on this device. The
    //    StoryState on another device of a story known on this device is not made
    //    known on this device.
    //
    //  * Every time the StoryVisibilityState of the story changes on this device.
    //    The StoryVisibilityState on another device of a story known on this
    //    device is not made known on this device.
    //
    //    I.e. if the story is started or stopped on *another* device, it does
    //    *not* cause an OnChange() call on *this* device. Cf. OnDelete() below.
    //
    // The ID of the story the notifications are about are part of StoryInfo.
    //
    // |story_state| is STOPPED if the story was just created or just became known
    // on this device and was not yet started on the current device. It's RUNNING
    // when the story is started on the current device.
    //
    // |story_visibility_state| is DEFAULT until a mod on the current device
    // requests for the visibility state to be changed.
    1: OnChange(StoryInfo story_info, StoryState story_state,
                StoryVisibilityState story_visibility_state);

    // Called in two different situations:
    //
    // * After the story record of a story is deleted from the current device by
    //   an invocation of StoryProvider.DeleteStory() on the current device.
    //
    // * When the information reaches the current device through Ledger
    //   synchronization that the story record of a story was deleted from another
    //   device by an invocation by StoryProvider.DeleteStory() there.
    //
    //   I.e. if the story is deleted on *another* device, it eventually *does*
    //   cause an OnDelete() call on *this* device. Cf. OnChange() above.
    //
    // Either way, if the story is running on this device at the time the deletion
    // becomes known to this device on this device, it is also stopped first. This
    // stopping of the story does not cause an OnChange() callback, only the
    // OnDelete() here.
    //
    // The OnDelete() call also happen when the story record is deleted while the
    // story is not running.
    2: OnDelete(string story_id);
};

// Implemented by clients of StoryProvider in order to inform them about ongoing
// activities in stories. |activities| is the entire list of ongoing activities
// (represented by its type) within the story by the given |story_id|. If
// |activities| is empty, it means that there is no ongoing activity within the
// story.
//
// Clients can expect this event whenever there is a newly started/stopped
// ongoing activity, as well as when the client first registers for updates
// via StoryProvider.WatchActivity(). |activities| can contain duplicate
// OngoingActivityType's, ex. if a story is playing 2 videos at once.
interface StoryActivityWatcher {
    1: OnStoryActivityChange(string story_id,
                             vector<OngoingActivityType> activities);
};
