// 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;

/// This file has interfaces for 2 pieces of information: (1) The story
/// that is currently in focus and (2) stories that are visible to the
/// user. Names of interfaces follow the usual patterns:
///
/// {Focus,VisibleStories}Controller is used by session shell to update
/// information whenever changes take place.
///
/// FocusProvider is used by maxwell and session shell to
/// query and get updates on which story is in focus on which device
/// and visible stories on this device.
///
// NOTE(alhaad): The information about visible stories can be used by
// sessionmgr to stop / pause stories that are not visible to the
// user.

/// Implemented by sessionmgr. Given to session shell through its namespace.
protocol FocusController {
    // Sets the focus on this device.
    Set(string? focused_story_id);
    WatchRequest(FocusRequestWatcher watcher);
};

/// Implemented by session shell. OnFocusRequest() gets called whenever there
/// is a new request to change focus on this device. Requests can be
/// made via FocusProvider.Request().
protocol FocusRequestWatcher {
    OnFocusRequest(string story_id);
};

/// Implemented by sessionmgr. Given to session shell and session agents through
/// their namespace. Focus is persisted on the ledger.
[Discoverable]
protocol FocusProvider {
    /// Returns the stories that are focused across all devices.
    Query() -> (vector<FocusInfo> focused_stories);

    /// Watches for change in focus on any of the user's devices.
    Watch(FocusWatcher watcher);

    /// Requests session shell to change focus on this device. If session shell
    /// responds to this request, focus shall be taken away from
    /// previously focused story and an update will be sent on
    /// FocusWatcher.OnFocusChange(). If |story_id| is NULL, the timeline
    /// is brought back into focus.
    ///
    // TODO(alhaad): Consider making this available for remote devices as
    // well.
    Request(string? story_id);
};

/// Implemented by anyone who is interested in getting updates when focus
/// changes.
protocol FocusWatcher {
    OnFocusChange(FocusInfo? focus_info);
};

/// Specifies the focused story of a device.
struct FocusInfo {
    /// The id of the device.
    string device_id;

    /// The id of the focused story.  If null, no stories are focused.
    string? focused_story_id;

    /// The time the focused story on the device |device_id| was last
    /// changed. 0 if no focus has ever been set for device |device_id|.
    uint64 last_focus_change_timestamp;
};

/// Implemented by sessionmgr. Given to session shell through its namespace.
protocol VisibleStoriesController {
    Set(vector<string>? visible_story_ids);
};
