// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

edition = "2023";

package optimization_guide.proto;

import "components/optimization_guide/proto/features/common_quality_data.proto";

option java_outer_classname = "ActionsProto";

option java_package = "org.chromium.components.optimization_guide.features.proto";

option optimize_for = LITE_RUNTIME;

// DO NOT EDIT THIS FILE DIRECTLY!
//
// This file is generated in g3 and then synced to Chrome. Instead, please refer to
// http://go/chrome-mqls-onboarding (Google-internal link), and then changes will
// be synced with Chrome automatically.

// The target of an action.
// Next ID: 4
message ActionTarget {
  // Id of the content node within the frame. Same as
  // ContentNode.common_ancestor_dom_node_id.
  int32 content_node_id = 1 [features = { field_presence: EXPLICIT }];

  Coordinate coordinate = 2 [features = { field_presence: EXPLICIT }];

  // Which document in a frame the action should be taken in.
  DocumentIdentifier document_identifier = 3 [features = { field_presence: EXPLICIT }];
}

// Mouse click action.
// Next ID: 5
message ClickAction {
  ActionTarget target = 1 [features = { field_presence: EXPLICIT }];

  ClickType click_type = 2 [features = { field_presence: EXPLICIT }];

  ClickCount click_count = 3 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 4 [features = { field_presence: EXPLICIT }];

  enum ClickType {
    // Unknown click type. This should not be used.
    UNKNOWN_CLICK_TYPE = 0;

    // Left mouse click.
    LEFT = 1;

    // Right mouse click.
    RIGHT = 2;
  }

  // Represents the number of times the target was clicked, for now only
  // supports single and double clicks.
  enum ClickCount {
    // Unknown click count. This should not be used.
    UNKNOWN_CLICK_COUNT = 0;

    // Single click.
    SINGLE = 1;

    // Double click.
    DOUBLE = 2;
  }
}

// Type text action.
// Next ID: 6
message TypeAction {
  ActionTarget target = 1 [features = { field_presence: EXPLICIT }];

  // The text to type.
  string text = 2 [features = { field_presence: EXPLICIT }];

  // After Typing the text, press enter.
  bool follow_by_enter = 3 [features = { field_presence: EXPLICIT }];

  TypeMode mode = 4 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 5 [features = { field_presence: EXPLICIT }];

  // How the text should be inserted into the target.
  enum TypeMode {
    UNKNOWN_TYPE_MODE = 0;

    DELETE_EXISTING = 1;

    PREPEND = 2;

    APPEND = 3;
  }
}

// Scroll action.
// Next ID: 5
message ScrollAction {
  ActionTarget target = 1 [features = { field_presence: EXPLICIT }];

  ScrollDirection direction = 2 [features = { field_presence: EXPLICIT }];

  // The distance to scroll in DIPs.
  float distance = 3 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 4 [features = { field_presence: EXPLICIT }];

  enum ScrollDirection {
    // Unknown scroll direction. This should not be used.
    UNKNOWN_SCROLL_DIRECTION = 0;

    // Scroll left.
    LEFT = 1;

    // Scroll right.
    RIGHT = 2;

    // Scroll up.
    UP = 3;

    // Scroll down.
    DOWN = 4;
  }
}

// Move mouse action.
// This is considered a low-level building block for more complex actions, e.g.
// scroll_at can be mouse_move + scroll action.
// This action also covers hovering, equivalent to "hovering at" when used in
// isolation.
// Next ID: 3
message MoveMouseAction {
  ActionTarget target = 1 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 2 [features = { field_presence: EXPLICIT }];
}

// Drag and release mouse action.
// Next ID: 4
message DragAndReleaseAction {
  ActionTarget from_target = 1 [features = { field_presence: EXPLICIT }];

  ActionTarget to_target = 2 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 3 [features = { field_presence: EXPLICIT }];
}

// Select dropdown action.
// Next ID: 4
message SelectAction {
  ActionTarget target = 1 [features = { field_presence: EXPLICIT }];

  // The value of the option to select.
  string value = 2 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 3 [features = { field_presence: EXPLICIT }];
}

// Navigate the page to a URL action.
// Next ID: 3
message NavigateAction {
  string url = 1 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 2 [features = { field_presence: EXPLICIT }];
}

// Wait action waits the specified milliseconds.
// Next ID: 3
message WaitAction {
  int32 wait_time_ms = 1 [features = { field_presence: EXPLICIT }];

  // If provided, the given tab will be included in the returned observations
  // (along with tabs in the actuating set), regardless of whether the tab is in
  // the actuating set. This will not cause the tab to be added to the actuating
  // set.
  int32 observe_tab_id = 2 [features = { field_presence: EXPLICIT }];
}

// Navigate the page Back action.
// Next ID: 2
message HistoryBackAction {
  int32 tab_id = 1 [features = { field_presence: EXPLICIT }];
}

// Navigate the page Forward action.
// Next ID: 2
message HistoryForwardAction {
  int32 tab_id = 1 [features = { field_presence: EXPLICIT }];
}

// Creates a new tab
// Next ID: 3
message CreateTabAction {
  // The id of the window to create the tab in. Passing in invalid window id
  // will cause the action to fail.
  int32 window_id = 1 [features = { field_presence: EXPLICIT }];

  // When set to true, the new tab will be visible within the window, although
  // the window itself may not be visible.
  bool foreground = 2 [features = { field_presence: EXPLICIT }];
}

// Closes an existing tab.
// Next ID: 2
message CloseTabAction {
  // The id of the tab to close. Passing in invalid tab id will cause the action
  // to fail.
  int32 tab_id = 1 [features = { field_presence: EXPLICIT }];
}

// Activates an existing tab. This does not affect window visibility or
// activation.
// Next ID: 2
message ActivateTabAction {
  // The id of the tab to activate. Passing in invalid tab id will cause the
  // action to fail.
  int32 tab_id = 1 [features = { field_presence: EXPLICIT }];
}

// Creates a new window.
// Next ID: 1
message CreateWindowAction {
}

// Closes an existing window.
// Next ID: 2
message CloseWindowAction {
  // The id of the window to close. Passing in invalid window id will cause the
  // action to fail.
  int32 window_id = 1 [features = { field_presence: EXPLICIT }];
}

// Activates an existing window. This does not move the window, but it brings it
// to the front of the z-order, and gives it OS-activation, which means the
// window will receive keyboard events.
// Next ID: 2
message ActivateWindowAction {
  // The id of the window to activate. Passing in invalid window id will cause
  // the action to fail.
  int32 window_id = 1 [features = { field_presence: EXPLICIT }];
}

// Yields control to the user.
// Next ID: 1
message YieldToUserAction {
}

// Attempts to log in to the website.
// Next ID: 3
message AttemptLoginAction {
  int32 tab_id = 1 [features = { field_presence: EXPLICIT }];

  // All of the login methods that the model knows about for this page.
  // As it does not know in advance which account type will be selected by the
  // user, the model provides everything it recognizes.
  // If a password form target is not provided (or if no targets are provided at
  // all), password form filling will still be done if a password credential is
  // selected by the user, but submitting the form will need to be done by a
  // follow up action.
  repeated LoginTarget login_targets = 2;

  // A target along with a type indicating how it is used to log in.
  // Next ID: 3
  message LoginTarget {
    LoginType login_type = 1 [features = { field_presence: EXPLICIT }];

    ActionTarget target = 2 [features = { field_presence: EXPLICIT }];

    // Indicates how the target is used to log in.
    enum LoginType {
      // Unknown login type. This should not be used.
      UNKNOWN_LOGIN_TYPE = 0;

      // The target is used to submit a username/password form.
      PASSWORD_FORM_SUBMIT = 1;

      // The target is a "Sign in with Google" button.
      FEDERATED_GOOGLE_SIGNIN = 2;
    }
  }
}

// Specifies a form by a set of fields (from different autofill sections) and
// the kind of data to fill in these sections. See AttemptFormFillingAction.
//
// If a form consists of multiple autofill sections, only fields from the
// section corresponding to the trigger field will be filled.
//
// This FormFillingRequest in development and future changes are possible once
// the model constraings/performance are understood.
//
// Next ID: 3
message FormFillingRequest {
  // Specifies a field that is part of the form. Autofill will be triggered from
  // this field, but will fill other fields of the same autofill section with
  // the available data.
  //
  // TODO(crbug.com/452946211): This field is repeated to be able to support a form that
  // is spread over multiple autofill sections.
  repeated ActionTarget trigger_fields = 1;

  // Specifies which data is requested. The requested data type will be
  // presented in the UI to the user (e.g. a user chooses an address for the
  // "shipping address").
  RequestedData requested_data = 2 [features = { field_presence: EXPLICIT }];

  // Enumerates the purposes for forms. Note that although the type of data
  // (address or credit card) is encoded that autofill already detects the type,
  // but does not detect the purpose (e.g. shipping v.s. billing address)
  // provide here.
  enum RequestedData {
    // The requested data is not specified.
    REQUESTED_DATA_UNKNOWN = 0;

    // An address should be filled. This value can be used as a catch-all when
    // the more specific address options below do not fit.
    ADDRESS = 1;

    // A shipping address should be filled.
    SHIPPING_ADDRESS = 2;

    // A billing address should be filled.
    BILLING_ADDRESS = 3;

    // A home address should be filled.
    HOME_ADDRESS = 4;

    // A work address should be filled.
    WORK_ADDRESS = 5;

    // A credit card should be filled.
    CREDIT_CARD = 6;

    // Contact information should be filled. Contact information includes name,
    // email, phone number, but not postal address information (street, city,
    // etc.)
    CONTACT_INFORMATION = 7;
  }
}

// Attempts to fill forms on the website.
//
// This AttemptFormFillingAction in development and future changes are possible
// once the model constraings/performance are understood.
//
// Next ID: 3
message AttemptFormFillingAction {
  int32 tab_id = 1 [features = { field_presence: EXPLICIT }];

  repeated FormFillingRequest form_filling_requests = 2;
}

// Attempts to fill One-Time Password (OTP) /verification codes in the tab. This
// action is used for OTP filling, which is different from the general form
// filling action above. Next ID: 4
message AttemptOtpFillingAction {
  // The tab ID in which to attempt OTP filling.
  int32 tab_id = 1 [features = { field_presence: EXPLICIT }];

  // The input field elements where the OTP/verification code should be filled.
  repeated ActionTarget target_fields = 2;

  // Indicates whether this operation call is needed for a signin.
  // This field determines whether a user confirmation dialog is shown before
  // filling the OTP/verification code. A dialog is shown only when
  // `for_signin` is false.
  bool for_signin = 3 [features = { field_presence: EXPLICIT }];
}

// Scrolls the DOM element into viewport.
// Next ID: 5
message ScrollToAction {
  ActionTarget target = 3 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 4 [features = { field_presence: EXPLICIT }];

  reserved 1, 2;
}

// Executes a script tool.
// Next ID: 5
message ScriptToolAction {
  // The Document which provides the associated Tool.
  DocumentIdentifier document_identifier = 1 [features = { field_presence: EXPLICIT }];

  int32 tab_id = 2 [features = { field_presence: EXPLICIT }];

  // The name of the tool to execute.
  string tool_name = 3 [features = { field_presence: EXPLICIT }];

  // A serialized JSON string containing the arguments to pass to the tool.
  string input_arguments = 4 [features = { field_presence: EXPLICIT }];
}

// Play media action plays the media session.
// Next ID: 1
message PlayMediaAction {
}

// Pause media action pauses the media session.
// Next ID: 1
message PauseMediaAction {
}

// Seek media action seeks the media session to the given seek time in
// milliseconds from the beginning of the media. The seek time should be
// non-negative.
// Next ID: 3
message SeekMediaAction {
  // TODO(crbug.com/490195093): Remove this field.
  int64 seek_time_microseconds = 1 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  int64 seek_time_milliseconds = 2 [features = { field_presence: EXPLICIT }];
}

// Controls media session in a tab.
// Next ID: 6
message MediaControlAction {
  oneof media_control_action {
    PlayMediaAction play = 3;

    PauseMediaAction pause = 4;

    SeekMediaAction seek = 5;
  }

  // The id of the tab which contains the media session.
  int32 tab_id = 2 [features = { field_presence: EXPLICIT }];

  reserved 1;
}

// Loads the given URLs and extracts content from them.
message LoadAndExtractContentAction {
  repeated string urls = 1;
}

// All of the actions that can be taken.
// Only one of these is allowed per action.
// Next ID: 25
message Action {

  oneof action {
    ClickAction click = 1;

    TypeAction type = 2;

    ScrollAction scroll = 3;

    MoveMouseAction move_mouse = 4;

    DragAndReleaseAction drag_and_release = 5;

    SelectAction select = 6;

    NavigateAction navigate = 7;

    HistoryBackAction back = 8;

    HistoryForwardAction forward = 9;

    WaitAction wait = 10;

    CreateTabAction create_tab = 11;

    CloseTabAction close_tab = 12;

    ActivateTabAction activate_tab = 13;

    CreateWindowAction create_window = 14;

    CloseWindowAction close_window = 15;

    ActivateWindowAction activate_window = 16;

    YieldToUserAction yield_to_user = 17;

    AttemptLoginAction attempt_login = 18;

    ScrollToAction scroll_to = 19;

    ScriptToolAction script_tool = 20;

    MediaControlAction media_control = 21;

    AttemptFormFillingAction attempt_form_filling = 22;

    LoadAndExtractContentAction load_and_extract_content = 23;

    AttemptOtpFillingAction attempt_otp_filling = 24;
  }
}

// Container for any type of metadata that is associated with a task.
// Next ID: 2
message TaskMetadata {
  SecurityMetadata security = 1 [features = { field_presence: EXPLICIT }];
}

// Metadata related to action security.
// Next ID: 3
message SecurityMetadata {
  // If the server predicted that new mainframe origins may be navigated to as a
  // result of the current task turn, those are given here.
  //
  // These origins, if any, are added to the set of all writeable origins kept
  // by the Chrome browser process.
  repeated string added_writable_mainframe_origins = 1;

  // If set, this config will be used to determine which locations the agent
  // may visit and what resources and capabilities are available.
  // This field is only respected the first turn if it is received; any
  // subsequent turns' values are ignored.
  AgentContainerConfig agent_container_config = 2 [features = { field_presence: EXPLICIT }];
}

// Options for screenshot collection.
// Next ID: 5
message ScreenshotCollectionOptions {
  // The maximum width of the screenshot. If 0, the screenshot will be returned
  // at the natural width of the screen.
  // Screenshot will be scaled to fit the max width and height while
  // maintaining the aspect ratio.
  int32 max_width = 1 [features = { field_presence: EXPLICIT }];

  // The maximum height of the screenshot. If 0, the screenshot will be returned
  // at the natural height of the screen.
  // Screenshot will be scaled to fit the max width and height while maintaining
  // the aspect ratio.
  int32 max_height = 2 [features = { field_presence: EXPLICIT }];

  // The format of the screenshot. If not set, the screenshot will be returned
  // as a jpeg image.
  ScreenshotImageFormat screenshot_format = 3 [features = { field_presence: EXPLICIT }];

  // The compression quality of the screenshot. If not set, the screenshot will
  // be returned with medium compression quality.
  CompressionQuality compression_quality = 4 [features = { field_presence: EXPLICIT }];
}

// A single set of actions to be taken by Chrome. The response is ActionsResult.
// Next ID: 6
message Actions {
  // The actions to be taken by Chrome.
  repeated Action actions = 1;

  // The task id of the action.
  int32 task_id = 2 [features = { field_presence: EXPLICIT }];

  // Whether to skip APC and screenshot (i.e., async) observation collections
  // when building the ActionsResult. Tab Observation will still be collected,
  // but will be missing APC and screenshot. Tab ID will be populated in the
  // TabObservation.
  // We may want more sophisticated control over which observations are
  // collected in the future.
  bool skip_async_observation_collection = 3 [features = { field_presence: EXPLICIT }];

  // Metadata that is associated with a task.
  TaskMetadata task_metadata = 4 [features = { field_presence: EXPLICIT }];

  // Options for screenshot collection.
  ScreenshotCollectionOptions screenshot_options = 5 [features = { field_presence: EXPLICIT }];
}

// Information about a chrome window.
// Next ID: 5
message WindowObservation {
  // Unique id
  int32 id = 1 [features = { field_presence: EXPLICIT }];

  // id of the activated tab. There may be multiple tabs visible at the same
  // time.
  int32 activated_tab_id = 2 [features = { field_presence: EXPLICIT }];

  // The active window is defined as the most recently used chrome browser
  // window.
  bool active = 3 [features = { field_presence: EXPLICIT }];

  // All tabs. The order is not meaningful.
  repeated int32 tab_ids = 4;
}

// Information about a chrome tab.
// Next ID: 9
message TabObservation {
  // Unique id
  int32 id = 1 [features = { field_presence: EXPLICIT }];

  // The page content at the observation time.
  // This field is only populated if skip_async_observation_collection is false
  // in the Actions message.
  AnnotatedPageContent annotated_page_content = 2 [features = { field_presence: EXPLICIT }];

  // The screenshot of the page at the time after the action.
  // This field is only populated if skip_async_observation_collection is false
  // in the Actions message.
  bytes screenshot = 3 [features = { field_presence: EXPLICIT }];

  // The mime type of the |screenshot|.
  // This field is only populated if skip_async_observation_collection is false
  // in the Actions message.
  string screenshot_mime_type = 4 [features = { field_presence: EXPLICIT }];

  // The result of the tab observation.
  TabObservationResult result = 5 [features = { field_presence: EXPLICIT }];

  // Metadata about the page content.
  // The number of meta tags returned is limited to 32.
  // This field is only populated if skip_async_observation_collection is false
  // in the Actions message.
  PageMetadata metadata = 6 [features = { field_presence: EXPLICIT }];

  AnnotatedPageContentResult annotated_page_content_result = 7 [features = { field_presence: EXPLICIT }];

  ScreenshotResult screenshot_result = 8 [features = { field_presence: EXPLICIT }];

  // Result codes of a tab observation as a whole. It may be possible to retry
  // an observation given specific error codes.
  enum TabObservationResult {
    // The tab was observed successfully.
    TAB_OBSERVATION_OK = 0;

    // The tab is not available because it went away.
    TAB_OBSERVATION_TAB_WENT_AWAY = 1;

    // The screenshot of the tab timed out.
    // TODO: crbug.com/462190108 - Deprecate, this should be a screenshot error code.
    TAB_OBSERVATION_SCREENSHOT_TIMEOUT = 2;

    // The page crashed.
    TAB_OBSERVATION_PAGE_CRASHED = 3;

    // A generic error has occurred.
    TAB_OBSERVATION_UNKNOWN_ERROR = 4;

    // The web contents of the tab changed so the tab observation was abandoned.
    TAB_OBSERVATION_WEB_CONTENTS_CHANGED = 5;

    // The page is not eligible for tab observation.
    TAB_OBSERVATION_PAGE_CONTEXT_NOT_ELIGIBLE = 6;

    // Fetching context encountered an error. The details are in the APC or
    // Screenshot specific fields below.
    TAB_OBSERVATION_FETCH_ERROR = 7;
  }

  enum AnnotatedPageContentResult {
    // The annotated page content was observed successfully.
    ANNOTATED_PAGE_CONTENT_OK = 0;

    // Fetching annotated page content timed out.
    ANNOTATED_PAGE_CONTENT_TIMEOUT = 1;

    // Fetching annotated page content encountered an unspecified error.
    ANNOTATED_PAGE_CONTENT_ERROR = 2;
  }

  enum ScreenshotResult {
    // The screenshot was observed successfully.
    SCREENSHOT_OK = 0;

    // Fetching the screenshot timed out.
    SCREENSHOT_TIMEOUT = 1;

    // Fetching the screenshot encountered an unspecified error.
    SCREENSHOT_ERROR = 2;
  }
}

// All relevant state in chrome after the actions are taken or an error has
// occurred.
// Next ID: 8
message ActionsResult {
  // The result of the actions. See
  // https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/actor.mojom
  // for definition.
  int32 action_result = 1 [features = { field_presence: EXPLICIT }];

  // If a specific action failed, the index of the failed action. -1 for no
  // failure.
  int32 index_of_failed_action = 2 [features = { field_presence: EXPLICIT }];

  // A human-readable error message from first failed action, if any.
  string error_message = 7 [features = { field_presence: EXPLICIT }];

  // Observations after all actions are finished or an error has occurred. The
  // client will determine the relevant windows and tabs.
  repeated WindowObservation windows = 3;

  // Observations after all actions are finished or an error has occurred. The
  // client will determine the relevant windows and tabs.
  repeated TabObservation tabs = 4;

  // The results of executing script tools.
  repeated ScriptToolResult script_tool_results = 5;

  LatencyInformation latency_information = 6 [features = { field_presence: EXPLICIT }];

  // Chrome reported information about the latency of steps while performing the
  // actions.
  // Next ID: 4
  message LatencyInformation {
    // All steps that Chrome reported latency for. These steps can overlap due
    // to parallel execution.
    repeated LatencyStep latency_steps = 1;

    // Latency of a single step.
    // Next ID: 7
    message LatencyStep {
      oneof step {
        ActionLatency action = 3;

        PageStabilizationLatency page_stabilization = 4;

        AnnotatedPageContentLatency annotated_page_content = 5;

        ScreenshotLatency screenshot = 6;
      }

      // The latency since the time that Chrome received the Actions request.
      // Time from request to step start.
      int32 latency_start_ms = 1 [features = { field_presence: EXPLICIT }];

      // Time from request to step stop.
      int32 latency_stop_ms = 2 [features = { field_presence: EXPLICIT }];

      message ActionLatency {
        // The index of the action that triggered the latency step.
        int32 action_index = 1 [features = { field_presence: EXPLICIT }];
      }

      message PageStabilizationLatency {
        // The index of the action that triggered the page stabilization.
        int32 action_index = 1 [features = { field_presence: EXPLICIT }];
      }

      // The latency of the annotated page content step.
      message AnnotatedPageContentLatency {
        // The id of the tab that was observed.
        int32 id = 1 [features = { field_presence: EXPLICIT }];
      }

      // The latency of the screenshot step.
      message ScreenshotLatency {
        // The id of the tab that was observed.
        int32 id = 1 [features = { field_presence: EXPLICIT }];
      }
    }
  }
}

// A request to start a task.
// Next ID: 2
message BrowserStartTask {
  // The id of the tab the task should be started in. If not set, the task
  // will be started in a new tab.
  // TODO(crbug.com/421441072): Remove this field. This is only needed in the short term
  // since we need a mechanism to start tasks in a new tab, and the model has
  // not yet been trained to use CreateTabAction.
  int32 tab_id = 1 [features = { field_presence: EXPLICIT }];
}

// The response to a request to start a task.
// Next ID: 4
message BrowserStartTaskResult {
  // The id of the task that was created.
  int32 task_id = 1 [features = { field_presence: EXPLICIT }];

  // The id of the tab the action will be taken in.
  int32 tab_id = 2 [features = { field_presence: EXPLICIT }];

  // The status of the start task request. If not SUCCESS, the task_id and
  // tab_id may not be set.
  StartTaskStatus status = 3 [features = { field_presence: EXPLICIT }];

  enum StartTaskStatus {
    // Unknown start task status. This should not be used.
    START_TASK_STATUS_UNKNOWN = 0;

    // The task was started successfully.
    SUCCESS = 1;

    // The task was not started because there were too many tasks already
    // running.
    OVER_TASK_LIMIT = 2;
  }
}

enum ScreenshotImageFormat {
  // Unknown screenshot format. This should not be used.
  SCREENSHOT_IMAGE_FORMAT_UNKNOWN = 0;

  // JPEG screenshot format. This is the default format.
  SCREENSHOT_IMAGE_FORMAT_JPEG = 1;

  // PNG screenshot format.
  SCREENSHOT_IMAGE_FORMAT_PNG = 2;

  // WEBP screenshot format.
  SCREENSHOT_IMAGE_FORMAT_WEBP = 3;
}

// The compression quality of the screenshot. Depending on screenshot format,
// the compression quality may not be respected or may mean something different.
// The default value is MEDIUM.
enum CompressionQuality {
  // Unknown compression quality. This should not be used.
  COMPRESSION_QUALITY_UNKNOWN = 0;

  // Low compression quality.
  COMPRESSION_QUALITY_LOW = 1;

  // Medium compression quality.
  COMPRESSION_QUALITY_MEDIUM = 2;

  // High compression quality.
  COMPRESSION_QUALITY_HIGH = 3;

  // No compression.
  COMPRESSION_QUALITY_NONE = 4;
}
