blob: 8cec33c9a1efecfb6709fc94fd9f0d9fa0172dcb [file] [log] [blame]
// Copyright 2018 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;
type ExecuteStatus = strict enum {
OK = 0;
// Encountered an invalid command.
INVALID_COMMAND = 1;
// The `story_id` provided does not exist or is not visible
// to this client.
INVALID_STORY_ID = 2;
// A story must contain at least one mod, and the commands given
// either don't add one, or remove the last one.
STORY_MUST_HAVE_MODS = 3;
// The mod name specified in AddMod, RemoveMod or SendModCommand
// was not found, or is invalid.
INVALID_MOD = 4;
// Resolution of the intent provided in AddMod returned zero results.
NO_MODULES_FOUND = 5;
// Some error happened while executing the command.
INTERNAL_ERROR = 6;
};
type ConfigureStoryError = strict enum : int32 {
/// The story cannot be (re)configured because it was already created.
ERR_STORY_ALREADY_CREATED = 1;
};
type ExecuteResult = struct {
status ExecuteStatus;
story_id string:<MAX, optional>;
error_message string:<MAX, optional>;
};
// Enables control of a session. A session, conceptually, is a single
// full-screen experience of a Fuchsia device. A device can run multiple
// sessions (ie, when one device powers multiple kiosks); that said, sessions
// are siloed from each other.
//
// A session, concretely, is a collection of stories, their state, the modules
// within them, any agents that run to support the mods and the various UI
// shells (session and story shells).
@discoverable
protocol PuppetMaster {
// Requests a capability to control a story by name. The name acts as the
// story's unique ID. Calling ControlStory() for the same story name will
// control the same story.
//
// The story name, as well as modification to the story, are durable and
// persist across device reboots. This allows the client to assign its own
// identifiers to stories. Clients wishing to guarantee a new story is
// created should generate a UUIDv4 or similar.
//
// `request` is closed if control cannot be granted.
//
// TODO(thatguy): We want story names to be scoped to the client's namespace.
ControlStory(resource struct {
story_name string:MAX;
request server_end:StoryPuppetMaster;
});
// Deletes a story associated to `story_name`.
// Any active StoryPuppetMaster connections to the Story will be closed.
DeleteStory(struct {
story_name string:MAX;
}) -> ();
// Returns a list of all the names of stories in the session.
GetStories() -> (struct {
story_names vector<string:MAX>:MAX;
});
};
protocol StoryPuppetMaster {
// Enqueues the given `commands` in the order they are given.
// Can be called as many times as necessary to specify the full
// set of changes to the story.
//
// To execute all enqueued commands, call Execute().
Enqueue(resource struct {
commands vector<StoryCommand>:MAX;
});
// Executes the commands enqueued so far by Enqueue() in order and as
// a batch: no other commands from other clients will be interleaved.
//
// If an error occurs, execution is stopped and an error code
// and message are returned in `result`.
Execute() -> (struct {
result ExecuteResult;
});
/// Attach the `annotations` to the story. If the story does not yet exist,
/// it will be created.
///
/// Existing annotations with the same key will be overwritten, or
/// deleted if new value is null.
Annotate(resource struct {
annotations vector<Annotation>:MAX_ANNOTATIONS_PER_UPDATE;
}) -> (struct {}) error AnnotationError;
/// Returns the annotations attached to this story.
///
/// This is a "hanging get" that returns the current annotations on
/// first call, and on subsequent calls returns the full set of
/// annotations once they are updated.
///
/// Returns AnnotationError.NOT_FOUND if the story does not exist.
WatchAnnotations() -> (resource struct {
annotations vector<Annotation>:MAX_ANNOTATIONS_PER_STORY;
}) error AnnotationError;
};