/*
 * 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 = "proto2";

import "protos/perfetto/common/commit_data_request.proto";
import "protos/perfetto/config/data_source_config.proto";
import "protos/perfetto/common/data_source_descriptor.proto";

package perfetto.protos;

// 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 new data source.
  rpc RegisterDataSource(RegisterDataSourceRequest)
      returns (RegisterDataSourceResponse) {}

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

  // Sent by the client to request the service to:
  // 1) Move some chunks from the shmem buffer into the logging buffer.
  // 2) Patch the content of some chunks previously moved.
  // 3) Acknowledge a Flush() request.
  rpc CommitData(protos.CommitDataRequest) returns (CommitDataResponse) {}

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

  // ----------------------------------------------------
  // All methods below have been introduced in Android Q.
  // ----------------------------------------------------

  // Associates a trace writer with its target buffer.
  rpc RegisterTraceWriter(RegisterTraceWriterRequest)
      returns (RegisterTraceWriterResponse) {}

  // Removes a trace writer association previously added by
  // RegisterTraceWriter.
  rpc UnregisterTraceWriter(UnregisterTraceWriterRequest)
      returns (UnregisterTraceWriterResponse) {}

  // Sent by the client in response to a StartDataSource message, when a data
  // source is successfully started. This is expected only for data sources that
  // set the DataSourceDescriptor.will_notify_on_start flag when registering.
  rpc NotifyDataSourceStarted(NotifyDataSourceStartedRequest)
      returns (NotifyDataSourceStartedResponse) {}

  // Sent by the client in response to a StopDataSource message, when a data
  // source is successfully stopped. This is expected only for data sources that
  // set the DataSourceDescriptor.will_notify_on_stop flag when registering.
  rpc NotifyDataSourceStopped(NotifyDataSourceStoppedRequest)
      returns (NotifyDataSourceStoppedResponse) {}

  // Sent by the client to request the service to:
  // 1) Find all sessions which define these triggers
  // 2) Perform an action as defined in those sessions configs.
  rpc ActivateTriggers(ActivateTriggersRequest)
      returns (ActivateTriggersResponse) {}

  // ----------------------------------------------------
  // All methods below have been introduced in Android R.
  // ----------------------------------------------------

  // This is used to linearize the producer with the service and to guarantee
  // that all IPCs prior to this call have been seen and processed by the
  // service. Example:
  //   - RegisterDataSource(A)
  //   - RegisterDataSource(B)
  //   - Sync()
  // When the Sync() response is received, the producer is guaranteed that the
  // service has seen both data source registrations.
  rpc Sync(SyncRequest) returns (SyncResponse) {}

  // ----------------------------------------------------
  // All methods below have been introduced in Android T.
  // ----------------------------------------------------

  // Updates the data source descriptor for an already-registered data source.
  // This can be used to update the list of features supported.
  // Only the data source with a matching data_source_descriptor.id is updated.
  // The data_source_descriptor.name cannot be changed.
  rpc UpdateDataSource(UpdateDataSourceRequest)
      returns (UpdateDataSourceResponse) {}
}

// Arguments for rpc InitializeConnection().
message InitializeConnectionRequest {
  // Optional. Provides a hint to the tracing service about the suggested size
  // of the shared memory buffer pages. The service is not required to respect
  // this if it has already another value in the configuration or if the hint
  // is unreasonably large. Must be an integer multiple of 4096. See tradeoff
  // considerations in shared_memory_abi.h.
  optional uint32 shared_memory_page_size_hint_bytes = 1;

  // 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.
  optional uint32 shared_memory_size_hint_bytes = 2;

  // Required to match the producer config set by the service to the correct
  // producer.
  optional string producer_name = 3;

  enum ProducerSMBScrapingMode {
    // Use the service's default setting for SMB scraping.
    SMB_SCRAPING_UNSPECIFIED = 0;

    // Enable scraping of uncommitted chunks from the producer's shared memory
    // buffer.
    SMB_SCRAPING_ENABLED = 1;

    // Disable scraping of uncommitted chunks from the producer's shared memory
    // buffer.
    SMB_SCRAPING_DISABLED = 2;
  }

  // If provided, overrides the service's SMB scraping setting for the producer.
  optional ProducerSMBScrapingMode smb_scraping_mode = 4;

  // Was build_flags = BUILD_FLAGS_DCHECKS_ON|OFF. It was used to emit an error
  // when DCHECKs level didn't match between service and producer (in turn that
  // would crash the service when applying patches).
  // Removed in v20 as part of b/197340286.
  reserved 5;

  // ---------------------------------------------------
  // All fields below have been introduced in Android R.
  // ---------------------------------------------------

  // Since Android R, this request can also transport an FD for the producer's
  // shared memory buffer, if allocated by the producer (e.g. for startup
  // tracing). In this case, |shared_memory_page_size_hint_bytes| is a required
  // field, and describes the SMB's page size. Note that the service may not
  // accept this SMB (e.g. because it is too old or its size / page size are
  // invalid) and instead allocate a new SMB which is provided in the
  // SetupTracing response. See TracingService::ConnectProducer() and
  // |using_shmem_provided_by_producer| in InitializeConnectionResponse.
  optional bool producer_provided_shmem = 6;

  // ---------------------------------------------------
  // All fields below have been introduced in Android S.
  // ---------------------------------------------------

  // The version of the client library used by the producer.
  // This is a human readable string with and its format varies depending on
  // the build system that is used to build the code and the repo (standalone
  // vs AOSP). This is intended for human debugging only.
  optional string sdk_version = 8;

  // On Windows, when producer_provided_shmem = true, the client creates a named
  // SHM region and passes the name (an unguessable token) back to the service.
  // Introduced in v13.
  optional string shm_key_windows = 7;
}

message InitializeConnectionResponse {
  // Indicates whether the service accepted the SMB provided by the producer in
  // InitializeConnectionRequest (if any). If false, the shared memory buffer FD
  // will provided by the service via the SetupTracing async command.
  optional bool using_shmem_provided_by_producer = 1;

  // Indicates to the producer that the service allows direct SMB patching of
  // chunks that have not yet been committed to it.
  // This field has been introduced in Android S.
  optional bool direct_smb_patching_supported = 2;

  // Indicates whether the service would like to use SMB emulation for the
  // connection, and request the client to send chunk data over the socket e.g.
  // for remote connection from a VM guest.
  optional bool use_shmem_emulation = 3;
}

// Arguments for rpc RegisterDataSource().

message RegisterDataSourceRequest {
  optional protos.DataSourceDescriptor data_source_descriptor = 1;
}

message RegisterDataSourceResponse {
  // Only set in case of errors, when |data_source_id| == 0.
  optional string error = 1;
};

// Arguments for rpc UpdateDataSource().

message UpdateDataSourceRequest {
  // The new data_source_descriptor.{id, name} must match {id, name} of a
  // data source previously registered via RegisterDataSource().
  optional protos.DataSourceDescriptor data_source_descriptor = 1;
}

message UpdateDataSourceResponse {};

// Arguments for rpc UnregisterDataSource().

message UnregisterDataSourceRequest {
  // The name of the data source to unregister, as previously passed in
  // |RegisterDataSourceRequest.name|.
  optional string data_source_name = 1;
}

message UnregisterDataSourceResponse {}

// Arguments for rpc RegisterTraceWriter().

message RegisterTraceWriterRequest {
  // The ID of a producer's trace writer.
  optional uint32 trace_writer_id = 1;

  // The ID of the target buffer that the trace writer commits its chunks to.
  optional uint32 target_buffer = 2;
}

message RegisterTraceWriterResponse {}

// Arguments for rpc UnregisterTraceWriter().

message UnregisterTraceWriterRequest {
  // The ID of a producer's trace writer.
  optional uint32 trace_writer_id = 1;
}

message UnregisterTraceWriterResponse {}

// Arguments for rpc CommitData().
// See commit_data_request.proto for CommitDataRequest. That has its own file
// because it is used also as input to generate C++ classes (xxx.gen.h).

message CommitDataResponse {}

// Arguments for rpc NotifyDataSourceStarted().

message NotifyDataSourceStartedRequest {
  // ID of the data source that has successfully started.
  optional uint64 data_source_id = 1;
}

message NotifyDataSourceStartedResponse {}

// Arguments for rpc NotifyDataSourceStopped().

message NotifyDataSourceStoppedRequest {
  // ID of the data source that has successfully stopped.
  optional uint64 data_source_id = 1;
}

message NotifyDataSourceStoppedResponse {}

// Arguments for rpc ActivateTriggersRequest().

message ActivateTriggersRequest {
  repeated string trigger_names = 1;
}

message ActivateTriggersResponse {}

// Arguments for rpc GetAsyncCommand().

message GetAsyncCommandRequest {}

message GetAsyncCommandResponse {
  // Called after SetupTracing and before StartDataSource.
  // This message was introduced in Android Q.
  message SetupDataSource {
    optional uint64 new_instance_id = 1;
    optional protos.DataSourceConfig config = 2;
  }

  message StartDataSource {
    optional uint64 new_instance_id = 1;

    // For backwards compat reasons (with Android P), the config passed here
    // is identical to the one passed to SetupDataSource.config.
    optional protos.DataSourceConfig config = 2;
  }

  message StopDataSource { optional uint64 instance_id = 1; }

  // On Android/Linux/Mac this message also transports the file descriptor for
  // the shared memory buffer (not a proto field).
  message SetupTracing {
    optional uint32 shared_buffer_page_size_kb = 1;

    // On Windows, instead, we pass the name (an unguessable token) of a shared
    // memory region that can be attached by the other process by name.
    // Introduced in v13.
    optional string shm_key_windows = 2;
  }

  message Flush {
    // The instance id (i.e. StartDataSource.new_instance_id) of the data
    // sources to flush.
    repeated uint64 data_source_ids = 1;

    // A monotonic counter generated by the service. The producer is simply
    // expected to copy this value back into the CommitDataRequest, so the
    // service can tell when the data for this flush has been committed.
    optional uint64 request_id = 2;

    // More details such as flush reason and originator. Introduced in v38 / V.
    // See FlushFlags in include/perfetto/ext/tracing/core/flush_flags.h.
    optional uint64 flags = 3;
  }

  // Instructs the given data sources to stop referring to any trace contents
  // emitted so far. Sent only to active data sources that set
  // |handles_incremental_state_clear| in their DataSourceDescriptor.
  //
  // Added to perfetto tree in May 2019.
  message ClearIncrementalState {
    // The instance id (i.e. StartDataSource.new_instance_id) of the data
    // sources that should clear their incremental state.
    repeated uint64 data_source_ids = 1;
  }

  // Next id: 8.
  oneof cmd {
    SetupTracing setup_tracing = 3;
    SetupDataSource setup_data_source = 6;
    StartDataSource start_data_source = 1;
    StopDataSource stop_data_source = 2;
    // id == 4 was teardown_tracing, never implemented.
    Flush flush = 5;
    ClearIncrementalState clear_incremental_state = 7;
  }
}

// Arguments for rpc Sync().
message SyncRequest {}
message SyncResponse {}
