// Copyright 2025 Google LLC
//
// 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";

package google.devtools.testing.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/type/date.proto";

option go_package = "google.golang.org/genproto/googleapis/devtools/testing/v1;testing";
option java_multiple_files = true;
option java_outer_classname = "TestEnvironmentDiscoveryProto";
option java_package = "com.google.devtools.testing.v1";

// Service for discovering environments supported by the TestExecutionService.
//
// Over time the TestService may add or remove devices or configuration options
// (e.g., when new devices and APIs are released).  Clients should check here
// periodically to discover what options are supported.
//
// It defines the following resource model:
//
// - The API a collection of [TestEnvironmentCatalog]
//   [google.devtools.test.v1.TestEnvironmentCatalog] resources, named
//   `testEnvironmentCatalog/*`
//
// - Each TestEnvironmentCatalog resource describes a set of supported
//   environments.
//
// - An [AndroidDeviceCatalog][google.devtools.test.v1.AndroidDeviceCatalog]
//   describes supported Android devices. It contains lists of supported
//   [AndroidModels][google.devtools.test.v1.AndroidModel] and
//   [AndroidVersions][google.devtools.test.v1.AndroidVersion] along with a
//   [AndroidRuntimeConfiguration][google.devtools.test.v1.AndroidRuntimeConfiguration].
//   Each AndroidModel contains a list of Versions it supports. All
//   models support all locales and orientations described by the
//   AndroidRuntimeConfiguration
//
// - An [IosDeviceCatalog][google.devtools.test.v1.IosDeviceCatalog]
//   describes supported iOS devices. It contains lists of supported
//   [IosModels][google.devtools.test.v1.IosModel] and
//   [IosVersions][google.devtools.test.v1.IosVersion] along with a
//   [IosRuntimeConfiguration][google.devtools.test.v1.IosRuntimeConfiguration].
//   Each IosModel contains a list of Versions it supports. All
//   models support all locales and orientations described by the
//   IosRuntimeConfiguration.
service TestEnvironmentDiscoveryService {
  option (google.api.default_host) = "testing.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform,"
      "https://www.googleapis.com/auth/cloud-platform.read-only";

  // Gets the catalog of supported test environments.
  //
  // May return any of the following canonical error codes:
  //
  // - INVALID_ARGUMENT - if the request is malformed
  // - NOT_FOUND - if the environment type does not exist
  // - INTERNAL - if an internal error occurred
  rpc GetTestEnvironmentCatalog(GetTestEnvironmentCatalogRequest)
      returns (TestEnvironmentCatalog) {
    option (google.api.http) = {
      get: "/v1/testEnvironmentCatalog/{environment_type}"
    };
  }
}

// A single device IP block
message DeviceIpBlock {
  // An IP address block in CIDR notation eg: 34.68.194.64/29
  string block = 1;

  // Whether this block is used by physical or virtual devices
  DeviceForm form = 2;

  // The date this block was added to Firebase Test Lab
  google.type.Date added_date = 3;
}

// Request to list the currently supported values for an environment type.
message GetTestEnvironmentCatalogRequest {
  // Types of environments the Test API supports.
  enum EnvironmentType {
    // Do not use.  For proto versioning only.
    ENVIRONMENT_TYPE_UNSPECIFIED = 0;

    // A device running a version of the Android OS.
    ANDROID = 1;

    // A device running a version of iOS.
    IOS = 3;

    // A network configuration to use when running a test.
    NETWORK_CONFIGURATION = 4;

    // The software environment provided by TestExecutionService.
    PROVIDED_SOFTWARE = 5;

    // The IP blocks used by devices in the test environment.
    DEVICE_IP_BLOCKS = 6;
  }

  // Required. The type of environment that should be listed.
  EnvironmentType environment_type = 1;

  // For authorization, the cloud project requesting the TestEnvironmentCatalog.
  string project_id = 2;

  // Optional. Whether to include viewable only models in the response. This is
  // only applicable for Android models.
  bool include_viewable_models = 4 [(google.api.field_behavior) = OPTIONAL];
}

// A description of a test environment.
message TestEnvironmentCatalog {
  // Output only.
  oneof environment_catalog {
    // Supported Android devices.
    AndroidDeviceCatalog android_device_catalog = 1;

    // Supported iOS devices.
    IosDeviceCatalog ios_device_catalog = 3;

    // Supported network configurations.
    NetworkConfigurationCatalog network_configuration_catalog = 4;

    // The software test environment provided by TestExecutionService.
    ProvidedSoftwareCatalog software_catalog = 5;

    // The IP blocks used by devices in the test environment.
    DeviceIpBlockCatalog device_ip_block_catalog = 6;
  }
}

// List of IP blocks used by the Firebase Test Lab
message DeviceIpBlockCatalog {
  // The device IP blocks used by Firebase Test Lab
  repeated DeviceIpBlock ip_blocks = 1;
}

// The currently supported Android devices.
message AndroidDeviceCatalog {
  // The set of supported Android device models.
  repeated AndroidModel models = 1;

  // The set of supported Android OS versions.
  repeated AndroidVersion versions = 2;

  // The set of supported runtime configurations.
  AndroidRuntimeConfiguration runtime_configuration = 3;
}

// Android configuration that can be selected at the time a test is run.
message AndroidRuntimeConfiguration {
  // The set of available locales.
  repeated Locale locales = 1;

  // The set of available orientations.
  repeated Orientation orientations = 2;
}

// A description of an Android device tests may be run on.
message AndroidModel {
  // Reason for access denial.
  enum AccessDeniedReason {
    // Do not use. For proto versioning only.
    ACCESS_DENIED_REASON_UNSPECIFIED = 0;

    // The model is for viewing purposes only. Access and utilization require
    // acceptance of an End User License Agreement (EULA).
    EULA_NOT_ACCEPTED = 1;
  }

  // The unique opaque id for this model.
  // Use this for invoking the TestExecutionService.
  string id = 1;

  // The human-readable marketing name for this device model.
  // Examples: "Nexus 5", "Galaxy S5".
  string name = 2;

  // The manufacturer of this device.
  string manufacturer = 3;

  // The company that this device is branded with.
  // Example: "Google", "Samsung".
  string brand = 9;

  // The name of the industrial design.
  // This corresponds to android.os.Build.DEVICE.
  string codename = 10;

  // Whether this device is virtual or physical.
  DeviceForm form = 4;

  // Whether this device is a phone, tablet, wearable, etc.
  DeviceFormFactor form_factor = 16;

  // Version-specific information of an Android model.
  repeated PerAndroidVersionInfo per_version_info = 21;

  // Screen size in the horizontal (X) dimension measured in pixels.
  int32 screen_x = 5;

  // Screen size in the vertical (Y) dimension measured in pixels.
  int32 screen_y = 6;

  // Screen density in DPI.
  // This corresponds to ro.sf.lcd_density
  int32 screen_density = 12;

  // True if and only if tests with this model are recorded by stitching
  // together screenshots. See use_low_spec_video_recording in device config.
  bool low_fps_video_recording = 17;

  // The set of Android versions this device supports.
  repeated string supported_version_ids = 7;

  // The list of supported ABIs for this device.
  // This corresponds to either android.os.Build.SUPPORTED_ABIS (for API level
  // 21 and above) or android.os.Build.CPU_ABI/CPU_ABI2.
  // The most preferred ABI is the first element in the list.
  //
  // Elements are optionally prefixed by "version_id:" (where version_id is
  // the id of an AndroidVersion), denoting an ABI that is supported only on
  // a particular version.
  repeated string supported_abis = 11;

  // Tags for this dimension.
  // Examples: "default", "preview", "deprecated".
  repeated string tags = 8;

  // URL of a thumbnail image (photo) of the device.
  string thumbnail_url = 19;

  // Output only. Lab info of this device.
  LabInfo lab_info = 26 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Reasons for access denial. This model is accessible if this list is empty,
  // otherwise the model is viewable only.
  repeated AccessDeniedReason access_denied_reasons = 33;
}

// A version of the Android OS.
message AndroidVersion {
  // An opaque id for this Android version.
  // Use this id to invoke the TestExecutionService.
  string id = 1;

  // A string representing this version of the Android OS.
  // Examples: "4.3", "4.4".
  string version_string = 2;

  // The API level for this Android version.
  // Examples: 18, 19.
  int32 api_level = 3;

  // The code name for this Android version.
  // Examples: "JellyBean", "KitKat".
  string code_name = 4;

  // The date this Android version became available in the market.
  google.type.Date release_date = 5;

  // Market share for this version.
  Distribution distribution = 6;

  // Tags for this dimension.
  // Examples: "default", "preview", "deprecated".
  repeated string tags = 7;
}

// A version-specific information of an Android model.
message PerAndroidVersionInfo {
  // An Android version.
  string version_id = 1;

  // The number of online devices for an Android version.
  DeviceCapacity device_capacity = 2;

  // Output only. The estimated wait time for a single interactive device
  // session using Direct Access.
  google.protobuf.Duration interactive_device_availability_estimate = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Identifies supported clients for DirectAccess for this Android
  // version.
  DirectAccessVersionInfo direct_access_version_info = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Denotes whether Direct Access is supported, and by which client versions.
//
// DirectAccessService is currently available as a preview to select developers.
// You can register today on behalf of you and your team at
// https://developer.android.com/studio/preview/android-device-streaming
message DirectAccessVersionInfo {
  // Whether direct access is supported at all. Clients are expected to
  // filter down the device list to only android models and versions which
  // support Direct Access when that is the user intent.
  bool direct_access_supported = 1;

  // Output only. Indicates client-device compatibility, where a device is known
  // to work only with certain workarounds implemented in the Android Studio
  // client. Expected format "major.minor.micro.patch", e.g.
  // "5921.22.2211.8881706".
  string minimum_android_studio_version = 2;
}

// Data about the relative number of devices running a
// given configuration of the Android platform.
message Distribution {
  // Output only. The time this distribution was measured.
  google.protobuf.Timestamp measurement_time = 1;

  // Output only. The estimated fraction (0-1) of the total market with this
  // configuration.
  double market_share = 2;
}

// Lab specific information for a device.
message LabInfo {
  // Lab name where the device is hosted.
  // If empty, the device is hosted in a Google owned lab.
  string name = 1;

  // The Unicode country/region code (CLDR) of the lab where the device is
  // hosted. E.g. "US" for United States, "CH" for Switzerland.
  string region_code = 2;
}

// The currently supported iOS devices.
message IosDeviceCatalog {
  // The set of supported iOS device models.
  repeated IosModel models = 1;

  // The set of supported iOS software versions.
  repeated IosVersion versions = 2;

  // The set of supported Xcode versions.
  repeated XcodeVersion xcode_versions = 4;

  // The set of supported runtime configurations.
  IosRuntimeConfiguration runtime_configuration = 3;
}

// iOS configuration that can be selected at the time a test is run.
message IosRuntimeConfiguration {
  // The set of available locales.
  repeated Locale locales = 1;

  // The set of available orientations.
  repeated Orientation orientations = 2;
}

// A description of an iOS device tests may be run on.
message IosModel {
  // The unique opaque id for this model.
  // Use this for invoking the TestExecutionService.
  string id = 1;

  // The human-readable name for this device model.
  // Examples: "iPhone 4s", "iPad Mini 2".
  string name = 2;

  // The set of iOS major software versions this device supports.
  repeated string supported_version_ids = 3;

  // Tags for this dimension.
  // Examples: "default", "preview", "deprecated".
  repeated string tags = 4;

  // Device capabilities.
  // Copied from
  // https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html
  repeated string device_capabilities = 5;

  // Screen size in the horizontal (X) dimension measured in pixels.
  int32 screen_x = 7;

  // Screen size in the vertical (Y) dimension measured in pixels.
  int32 screen_y = 8;

  // Screen density in DPI.
  int32 screen_density = 9;

  // Whether this device is a phone, tablet, wearable, etc.
  DeviceFormFactor form_factor = 6;

  // Version-specific information of an iOS model.
  repeated PerIosVersionInfo per_version_info = 14;
}

// An iOS version.
message IosVersion {
  // An opaque id for this iOS version.
  // Use this id to invoke the TestExecutionService.
  string id = 1;

  // An integer representing the major iOS version.
  // Examples: "8", "9".
  int32 major_version = 2;

  // An integer representing the minor iOS version.
  // Examples: "1", "2".
  int32 minor_version = 4;

  // Tags for this dimension.
  // Examples: "default", "preview", "deprecated".
  repeated string tags = 3;

  // The available Xcode versions for this version.
  repeated string supported_xcode_version_ids = 5;
}

// A version-specific information of an iOS model.
message PerIosVersionInfo {
  // An iOS version.
  string version_id = 1;

  // The number of online devices for an iOS version.
  DeviceCapacity device_capacity = 2;
}

// A location/region designation for language.
message Locale {
  // The id for this locale.
  // Example: "en_US".
  string id = 1;

  // A human-friendly name for this language/locale.
  // Example: "English".
  string name = 2;

  // A human-friendly string representing the region for this
  // locale. Example: "United States". Not present for every locale.
  string region = 3;

  // Tags for this dimension.
  // Example: "default".
  repeated string tags = 4;
}

// Screen orientation of the device.
message Orientation {
  // The id for this orientation.
  // Example: "portrait".
  string id = 1;

  // A human-friendly name for this orientation.
  // Example: "portrait".
  string name = 2;

  // Tags for this dimension.
  // Example: "default".
  repeated string tags = 3;
}

// An Xcode version that an iOS version is compatible with.
message XcodeVersion {
  // The id for this version.
  // Example: "9.2".
  string version = 1;

  // Tags for this Xcode version.
  // Example: "default".
  repeated string tags = 2;
}

message NetworkConfigurationCatalog {
  repeated NetworkConfiguration configurations = 1;
}

message NetworkConfiguration {
  // The unique opaque id for this network traffic configuration.
  string id = 1;

  // The emulation rule applying to the upload traffic.
  TrafficRule up_rule = 2;

  // The emulation rule applying to the download traffic.
  TrafficRule down_rule = 3;
}

// Network emulation parameters.
message TrafficRule {
  // Packet delay, must be >= 0.
  google.protobuf.Duration delay = 1;

  // Packet loss ratio (0.0 - 1.0).
  float packet_loss_ratio = 2;

  // Packet duplication ratio (0.0 - 1.0).
  float packet_duplication_ratio = 3;

  // Bandwidth in kbits/second.
  float bandwidth = 4;

  // Burst size in kbits.
  float burst = 5;
}

// The currently provided software environment on the devices under test.
message ProvidedSoftwareCatalog {
  // Deprecated: Use AndroidX Test Orchestrator going forward.
  //
  // A string representing the current version of Android Test Orchestrator
  // that is used in the environment. The package is available at
  // https://maven.google.com/web/index.html#com.android.support.test:orchestrator.
  string orchestrator_version = 1 [deprecated = true];

  // A string representing the current version of AndroidX Test Orchestrator
  // that is used in the environment. The package is available at
  // https://maven.google.com/web/index.html#androidx.test:orchestrator.
  string androidx_orchestrator_version = 2;
}

// Whether the device is physical or virtual.
enum DeviceForm {
  // Do not use.  For proto versioning only.
  DEVICE_FORM_UNSPECIFIED = 0;

  // Android virtual device using Compute Engine native virtualization. Firebase
  // Test Lab only.
  VIRTUAL = 1;

  // Actual hardware.
  PHYSICAL = 2;

  // Android virtual device using emulator in nested virtualization. Equivalent
  // to Android Studio.
  EMULATOR = 3;
}

// The form factor of a device.
enum DeviceFormFactor {
  // Do not use. For proto versioning only.
  DEVICE_FORM_FACTOR_UNSPECIFIED = 0;

  // This device has the shape of a phone.
  PHONE = 1;

  // This device has the shape of a tablet.
  TABLET = 2;

  // This device has the shape of a watch or other wearable.
  WEARABLE = 3;
}

// Capacity based on the number of online devices in the lab.
//
// Important: device capacity does not directly reflect the length of the
// queue at a moment in time. It does not take into account current traffic or
// the state of the devices.
//
// For physical devices, the number is the average of online devices in the last
// 30 days.
enum DeviceCapacity {
  // The value of device capacity is unknown or unset.
  DEVICE_CAPACITY_UNSPECIFIED = 0;

  // Devices that are high in capacity (The lab has a large number of these
  // devices).
  //
  // These devices are generally suggested for running a large number of
  // simultaneous tests (e.g. more than 100 tests).
  //
  // Please note that high capacity devices do not guarantee short wait times
  // due to several factors:
  // 1. Traffic (how heavily they are used at any given moment)
  // 2. High capacity devices are prioritized for certain usages, which may
  // cause user tests to be slower than selecting other similar device types.
  DEVICE_CAPACITY_HIGH = 1;

  // Devices that are medium in capacity (The lab has a decent number of these
  // devices, though not as many as high capacity devices).
  //
  // These devices are suitable for fewer test runs (e.g. fewer than 100 tests)
  // and only for low shard counts (e.g. less than 10 shards).
  DEVICE_CAPACITY_MEDIUM = 2;

  // Devices that are low in capacity (The lab has a small number of these
  // devices).
  //
  // These devices may be used if users need to test on this specific device
  // model and version. Please note that due to low capacity, the tests may take
  // much longer to finish, especially if a large number of tests are invoked at
  // once. These devices are not suitable for test sharding.
  DEVICE_CAPACITY_LOW = 3;

  // Devices that are completely missing from the lab.
  //
  // These devices are unavailable either temporarily or permanently and should
  // not be requested. If the device is also marked as deprecated, this state
  // is very likely permanent.
  DEVICE_CAPACITY_NONE = 4;
}
