/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto3";
option optimize_for = LITE_RUNTIME;

import "tracing/src/ipc/data_source_config.proto";
import "tracing/src/ipc/data_source_descriptor.proto";

package perfetto;

// IPC interface definition for the producer port of the tracing service.
service ProducerPort {
  // Called once only after establishing the connection with the Service.
  // The service replies sending the shared memory file descriptor in reply.
  rpc InitializeConnection(InitializeConnectionRequest)
      returns (InitializeConnectionResponse) {}

  // Advertises a data source.
  rpc RegisterDataSource(RegisterDataSourceRequest)
      returns (RegisterDataSourceResponse) {}

  // Unregisters a previously registered data source.
  rpc UnregisterDataSource(UnregisterDataSourceRequest)
      returns (UnregisterDataSourceResponse) {}

  // Sent by the client whenever it the state of one or more pages in the shared
  // memory buffer have been changed. This is used to kick the tracing service
  // and let it move filled pages from the staging shared memory buffer into the
  // actual (non-shared) trace buffer.
  rpc NotifySharedMemoryUpdate(NotifySharedMemoryUpdateRequest)
      returns (NotifySharedMemoryUpdateResponse) {}

  // This is a backchannel to get asynchronous commands / notifications back
  // from the Service.
  rpc GetAsyncCommand(GetAsyncCommandRequest)
      returns (stream GetAsyncCommandResponse) {}
}

// Arguments for rpc InitializeConnection().
message InitializeConnectionRequest {
  // Optional. Provides a hint to the tracing service about the suggested size
  // of the shared memory buffer. The service is not required to respect this
  // and might return a smaller buffer.
  uint32 shared_buffer_size_hint_bytes = 1;
}

message InitializeConnectionResponse {
  // This message provides the shared memory buffer FD (not a proto field).
}

// Arguments for rpc RegisterDataSource().

message RegisterDataSourceRequest {
  proto.DataSourceDescriptor data_source_descriptor = 1;
}

message RegisterDataSourceResponse {
  // The ID assigned by the service to this data source. 0 in case of errors.
  uint64 data_source_id = 1;

  // Only set in case of errors, when |data_source_id| == 0.
  string error = 2;
};

// Arguments for rpc UnregisterDataSource().

message UnregisterDataSourceRequest {
  // The ID of the data source to unregister, as previously returned in
  // |RegisterDataSourceResponse.data_source_id|.
  uint64 data_source_id = 1;
}

message UnregisterDataSourceResponse {}

// Arguments for rpc NotifySharedMemoryUpdate().

message NotifySharedMemoryUpdateRequest {
  repeated uint32 changed_pages = 1;
}

message NotifySharedMemoryUpdateResponse {}

// Arguments for rpc GetAsyncCommand().

message GetAsyncCommandRequest {}

message GetAsyncCommandResponse {
  message StartDataSource {
    uint64 new_instance_id = 1;
    proto.DataSourceConfig config = 2;
  }

  message StopDataSource { uint64 instance_id = 1; }

  oneof cmd {
    StartDataSource start_data_source = 1;
    StopDataSource stop_data_source = 2;
  }
}
