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

using fuchsia.modular;
using fuchsia.ui.policy;
using fuchsia.ui.views;

/// The basemgr application (there is no `Basemgr` service) requests
/// an instance of this service in order to launch and display a `Sessionmgr`.
[Discoverable] // Created by sessionmgr application.
protocol Sessionmgr {
    /// Launches a sessionmgr instance identified by a unique device-local
    /// `session_id`. The uniqueness of `session_id` must be guaranteed by the
    /// caller, because `sessionmgr` creates an Environment namespace with the
    /// given `session_id`, and this will crash if we try to create an
    /// environment with a pre-existing name, because the services sessionmgr
    /// tries to access won't be available.
    ///
    // TODO(MF-287): Address issues around client-generated session_id and
    // initialization pattern of sessionmgr.
    Initialize(string session_id,
               fuchsia.modular.AppConfig session_shell,
               fuchsia.modular.AppConfig story_shell,
               bool use_session_shell_for_story_shell_factory,
               SessionContext session_context,
               fuchsia.ui.views.ViewToken view_token);
};

/// This interface is provided by basemgr to `Sessionmgr`.
protocol SessionContext {
    /// Restarts the session.
    Restart();

    /// Restarts the session due to an unrecoverable error. This may reboot the
    /// device.
    RestartDueToCriticalFailure();

    GetPresentation(request<fuchsia.ui.policy.Presentation> presentation);
};
