/*
 * Copyright (C) 2023 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";

package android.os.statsd.appsearch;

import "frameworks/proto_logging/stats/atom_field_options.proto";
import "frameworks/proto_logging/stats/atoms.proto";
import "frameworks/proto_logging/stats/enums/appsearch/enums.proto";

option java_package = "com.android.os.appsearch";
option java_multiple_files = true;

extend Atom {
  // Pushed atoms
  optional AppSearchSetSchemaStatsReported app_search_set_schema_stats_reported = 385 [(module) = "appsearch"];
  optional AppSearchSchemaMigrationStatsReported
          app_search_schema_migration_stats_reported = 579 [(module) = "appsearch"];

  optional AppSearchUsageSearchIntentStatsReported
          app_search_usage_search_intent_stats_reported = 825 [(module) = "appsearch"];

  optional AppSearchUsageSearchIntentRawQueryStatsReported
          app_search_usage_search_intent_raw_query_stats_reported = 826
          [(module) = "appsearch", (restriction_category) = RESTRICTION_SYSTEM_INTELLIGENCE];

  optional AppSearchAppsIndexerStatsReported
          app_search_apps_indexer_stats_reported = 909 [(module) = "appsearch"];

  optional AppSearchAppOpenEventIndexerStatsReported
          app_search_app_open_event_indexer_stats_reported = 1050 [(module) = "appsearch"];

  optional AppSearchVmPayloadStatsReported
          app_search_vm_payload_stats_reported = 1047 [(module) = "appsearch"];

  optional AppSearchVmInitializationStatsReported
          app_search_vm_initialization_stats_reported = 1127 [(module) = "appsearch"];

  optional AppSearchPersistToDiskStatsReported
          app_search_persist_to_disk_stats_reported = 1153 [(module) = "appsearch"];
}

// Keep in sync with
// packages/modules/AppSearch/framework/java/external/android/app/appsearch/stats/BaseStats.java
enum AppSearchEnabledFeatures {
    APP_SEARCH_ENABLED_UNKNOWN = 0;
    APP_SEARCH_ENABLED_LAUNCH_VM = 0x0001; // 1 << 0
}

/**
 * Logs detailed stats for setting schema in AppSearch.
 *
 * stats pushed from:
 *   frameworks/base/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
 *
 * Next tag: 45
 */
message AppSearchSetSchemaStatsReported {
    // The sampling interval for this specific type of stats
    // For example, sampling_interval=10 means that one out of every 10 stats was logged.
    optional int32 sampling_interval = 1;

    // # of previous skipped sample for this specific type of stats
    // We can't push atoms too closely, so some samples might be skipped
    // In order to extrapolate the counts, we need to save the number of skipped stats and add it back
    // For example, the true count of an event could be estimated as:
    //   SUM(sampling_interval * (num_skipped_sample + 1)) as est_count
    optional int32 num_skipped_sample = 2;

    // Package UID of the application.
    optional int32 uid = 3 [(is_uid) = true];

    // Hash of the database name within AppSearch
    optional int32 database = 4;

    // Needs to be sync with AppSearchResult#ResultCode in
    // frameworks/base/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
    optional int32 status_code = 5;

    // Overall time used for setting schema including the binder latency
    optional int32 total_latency_millis = 6;

    // Number of newly added schema types
    optional int32 new_type_count = 7;

    // Number of deleted schema types
    optional int32 deleted_type_count = 8;

    // Number of compatible schema type changes
    optional int32 compatible_type_change_count = 9;

    // Number of index-incompatible schema type changes
    optional int32 index_incompatible_type_change_count = 10;

    // Number of backwards-incompatible schema type changes
    optional int32 backwards_incompatible_type_change_count = 11;

    // Time used for verifying the incoming call.
    optional int32  verify_incoming_call_latency_millis = 12;

    // Time used for creating or waiting the user executor.
    optional int32  executor_acquisition_latency_millis = 13;

    // Time used for rebuilding objects from bundles.
    optional int32  rebuild_from_bundle_latency_millis = 14;

    // Time passed while waiting to acquire the lock during Java function calls.
    optional int32  java_lock_acquisition_latency_millis = 15;

    // Time used for the rewrite schema to proto.
    optional int32  rewrite_schema_latency_millis = 16;

    // Overall time used for the native function call.
    optional int32  total_native_latency_millis = 17;

    // Time used for the apply visibility settings function call.
    optional int32  visibility_setting_latency_millis = 18;

    // Time used for the dispatch change notification function call.
    optional int32  dispatch_change_notifications_latency_millis = 19;

    // Time used for the optimization function call.
    optional int32  optimize_latency_millis = 20;

    /** Whether this package is observed. */
    optional bool is_package_observed = 21;

    /** Time used for the get old schema. */
    optional int32  get_old_schema_latency_millis = 22;

    /** Time used for the get registered observer function call. */
    optional int32  get_observer_latency_millis = 23;

    /** Time used for the preparing change notification action. */
    optional int32  preparing_change_notification_latency_millis = 24;

    // Type of the SetSchema call relative to SchemaMigration case.
    // This is in sync with
    // packages/modules/AppSearch/service/java/com/android/server/appsearch/external/localstorage/stats/SetSchemaStats.java
    optional int32 schema_migration_call_type = 25;

    // The bitmask for all enabled features on this device. Must be one or a combination of the
    // types AppSearchEnabledFeatures.
    optional int64 enabled_features = 26;

    // The last blocking operation call type.
    optional int32 last_blocking_operation = 27;

    // The latency for last blocking operation which hold the write lock in milliseconds.
    optional int32 last_blocking_operation_latency_millis = 28;

    // The time passed while get the vm instance.
    optional int32 get_vm_latency_millis = 29;

    // Time passed while the task is running in AppSearch without any waiting time.
    optional int32 unblocked_appsearch_latency_millis = 30;

    // Number of join index-incompatible schema type changes
    optional int32 join_index_incompatible_type_change_count = 31;

    // Number of scorable property-incompatible schema type changes
    optional int32 scorable_property_incompatible_type_change_count = 32;

    // Number of documents deleted.
    optional int32 deleted_documents_count = 33;

    // Whether the term index is restored.
    optional bool is_term_index_restored = 34;

    // Whether the integer index is restored.
    optional bool is_integer_index_restored = 35;

    // Whether the embedding index is restored.
    optional bool is_embedding_index_restored = 36;

    // Whether the qualified-id join index is restored.
    optional bool is_qualified_id_join_index_restored = 37;

    // Latency for setting the schema in the schema store.
    optional int32 native_schema_store_set_schema_latency_millis = 38;

    // Latency for updating the document store's derived data using
    // DocumentStore::UpdateSchemaStore.
    optional int32 native_document_store_update_schema_latency_millis = 39;

    // Latency for updating the document store's derived data using
    // DocumentStore::OptimizedUpdateSchemaStore.
    optional int32 native_document_store_optimized_update_schema_latency_millis = 40;

    // Latency for rebuilding the index following an index-incompatible schema change.
    optional int32 native_index_restoration_latency_millis = 41;

    // Latency for regenerating the scorable property cache.
    optional int32 native_scorable_property_cache_regeneration_latency_millis = 42;

    // Whether or not AppSearch skipped sending the schema to Icing because it didn't change.
    optional bool skipped_icing_interaction = 43;

    // The number of times that we called icing.
    optional int32 num_icing_calls = 44;
}

/**
 * Logs detailed stats for schema migration in AppSearch.
 *
 * stats pushed from:
 *   packages/modules/AppSearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
 *
 * Next tag: 16
 */
message AppSearchSchemaMigrationStatsReported {
    // The sampling interval for this specific type of stats
    // For example, sampling_interval=10 means that one out of every 10 stats was logged.
    optional int32 sampling_interval = 1;

    // # of previous skipped sample for this specific type of stats
    // We can't push atoms too closely, so some samples might be skipped
    // In order to extrapolate the counts, we need to save the number of skipped stats and add it back
    // For example, the true count of an event could be estimated as:
    //   SUM(sampling_interval * (num_skipped_sample + 1)) as est_count
    optional int32 num_skipped_sample = 2;

    // Package UID of the application.
    optional int32 uid = 3 [(is_uid) = true];

    // Hash of the database name within AppSearch
    optional int32 database = 4;

    // Needs to be sync with AppSearchResult#ResultCode in
    // packages/modules/AppSearch/framework/java/external/android/app/appsearch/AppSearchResult.java
    optional int32 status_code = 5;

    // Overall time used for setting schema including the binder latency
    optional int32 total_latency_millis = 6;

    // Overall time used for getting schema during schema migration
    optional int32 schema_migration_get_schema_latency_millis = 7;

    // Overall time used for querying and transforming documents during schema migration
    optional int32 schema_migration_query_and_transform_latency_millis = 8;

    // Overall time used for first setSchema during schema migration
    optional int32 schema_migration_first_set_schema_latency_millis = 9;

    // Overall time used for second setSchema during schema migration
    optional int32 schema_migration_second_set_schema_latency_millis = 10;

    // Overall time used for saving documents during schema migration
    optional int32 schema_migration_save_document_latency_millis = 11;

    // Number of document that need to be migrated to another version
    optional int32 total_need_migrated_document_count = 12;

    // Number of successfully migrated and saved in Icing
    optional int32 total_success_migrated_document_count = 13;

    // Number of migration failure during schema migration
    optional int32 schema_migration_failure_count = 14;

    // The bitmask for all enabled features on this device. Must be one or a combination of the
    // types AppSearchEnabledFeatures.
    optional int64 enabled_features = 15;
}

/**
 * Usage detailed stats (excluding raw query string) for search intent in AppSearch.
 *
 * stats pushed from:
 *   frameworks/base/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
 *
 * Next tag: 11
 */
message AppSearchUsageSearchIntentStatsReported {
    // Package UID of the application.
    optional int32 uid = 1 [(is_uid) = true];

    // Hash of the database name within AppSearch.
    optional int32 database = 2;

    // Timestamp of search request issued by the client.
    optional int64 search_intent_timestamp_millis = 3;

    // How many result documents being fetched in this search intent.
    optional int32 num_results_fetched = 4;

    // The correction type of the query in this search intent compared with the previous search
    // intent.
    optional android.appsearch.QueryCorrectionType query_correction_type = 5;

    // The following fields with prefix "clicks_" contain numbers (e.g. timestamp, rank) for all
    // clicks associated with the search intent.
    // Due to statsd restriction, we have to separate them into multiple repeated fields with
    // primitive type.
    repeated int64 clicks_timestamp_millis = 6;
    repeated int64 clicks_time_stay_on_result_millis = 7;
    repeated int32 clicks_result_rank_in_block = 8;
    repeated int32 clicks_result_rank_global = 9;

    // The bitmask for all enabled features on this device. Must be one or a combination of the
    // types AppSearchEnabledFeatures.
    optional int64 enabled_features = 10;
}

/**
 * Privacy preserved usage detailed stats (including raw query strings) for search intent in
 * AppSearch.
 *
 * stats pushed from:
 *   frameworks/base/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
 *
 * Next tag: 10
 */
message AppSearchUsageSearchIntentRawQueryStatsReported {
    // Package name of the application.
    optional string package_name = 1;

    // Hash of the database name within AppSearch.
    optional int32 database = 2;

    // Raw query string of the previous search intent.
    optional string prev_query = 3 [(field_restriction_option).system_search = true];

    // Raw query string of the current search intent.
    optional string curr_query = 4 [(field_restriction_option).system_search = true];

    // How many result documents being fetched in this search intent.
    optional int32 num_results_fetched = 5;

    // How many click actions being taken in this search intent.
    optional int32 num_clicks = 6;

    // How many good click actions (i.e. the user stays on the clicked results for reasonable time)
    // being taken in this search intent.
    optional int32 num_good_clicks = 7;

    // The correction type of the query in this search intent compared with the previous search
    // intent.
    optional android.appsearch.QueryCorrectionType query_correction_type = 8;

    // The bitmask for all enabled features on this device. Must be one or a combination of the
    // types AppSearchEnabledFeatures.
    optional int64 enabled_features = 9;
}

/**
 * Reported when AppSearch Apps Indexer syncs apps from PackageManager to AppSearch.
 *
 * Logged from:
 *   packages/modules/AppSearch/service/java/com/android/server/appsearch/appsindexer/AppsIndexerManagerService.java
 * Estimated Logging Rate:
 *    Peak: 20 times in 10*1000 ms | Avg: 1 per device per day
 *
 * Next tag: 20
 */
message AppSearchAppsIndexerStatsReported {
  enum UpdateType {
    UNKNOWN = 0;
    FULL = 1;
  }

  // Type of the update. An additional "package intent" update type may be added
  optional UpdateType update_type = 1;

  // Status codes for inserting/updating apps. If everything succeeds, this only contains [0]. If
  // something fails, this contains all the error codes we got.
  repeated int32 update_status_codes = 2;

  // Update counts
  optional int32 number_of_apps_added = 3;
  optional int32 number_of_apps_removed = 4;
  optional int32 number_of_apps_updated = 5;
  optional int32 number_of_apps_unchanged = 6;

  // Latencies
  optional int64 total_latency_millis = 7;
  optional int64 package_manager_latency_millis = 8;
  optional int64 get_all_apps_from_appsearch_latency_millis = 9;
  optional int64 set_schema_for_all_apps_latency_millis = 10;
  optional int64 index_all_apps_to_appsearch_latency_millis = 11;

  // Timestamps
  optional int64 update_start_wallclock_timestamp_millis = 12;
  optional int64 last_app_updated_wallclock_timestamp_millis = 13;

  // App Function counts
  optional int32 number_of_functions_added = 14;
  optional int32 number_of_functions_removed = 15;
  optional int32 number_of_functions_updated = 16;
  optional int32 number_of_functions_unchanged = 17;

  // App Function removal latency
  optional int64 remove_functions_from_appsearch_appsearch_latency_millis = 18;

  // Flag indicating if Emergency Update has been triggered for Apps Indexer User Instance.
  // This field is meant to be false until a Force Update is manually triggered
  optional bool force_update_triggered = 19;
}

/**
 * Reported when AppSearch App Open Event Indexer syncs apps from UsageStatsManager to AppSearch.
 *
 * Logged from:
 *   packages/modules/AppSearch/service/java/com/android/server/appsearch/appsindexer/AppOpenEventIndexerUserInstance.java
 * Estimated Logging Rate: once per device per day
 *
 * Next tag: 10
 */
message AppSearchAppOpenEventIndexerStatsReported {

  // Status codes for inserting/updating apps. If everything succeeds, this only contains [0]. If
  // something fails, this contains all the error codes we got.
  repeated int32 update_status_codes = 1;

  // Update counts
  optional int32 number_of_app_open_events_added = 2;

  // Latencies
  optional int64 total_latency_millis = 3;
  optional int64 usage_stats_manager_read_latency_millis = 4;
  optional int64 appsearch_set_schema_latency_millis = 5;
  optional int64 appsearch_put_latency_millis = 6;

  // Timestamps
  optional int64 update_start_wallclock_timestamp_millis = 7;
  optional int64 last_app_update_wallclock_timestamp_millis = 8;

  // Flag indicating if Emergency Update has been triggered for AppOpenEvent Indexer User Instance.
  // This field is meant to be false until a Force Update is manually triggered
  optional bool force_update_triggered = 9;
}

/**
 * Reported when AppSearch VM payload statistics are collected and reported.
 *
 * This message encapsulates various metrics related to the execution and outcome of
 * a pVM payload.
 *
 * Next tag: 7
 */
message AppSearchVmPayloadStatsReported {

  // The sampling interval for this specific type of stats
  // For example, sampling_interval=10 means that one out of every 10 stats was logged.
  optional int32 sampling_interval = 1;

  // # of previous skipped sample for this specific type of stats
  // We can't push atoms too closely, so some samples might be skipped
  // In order to extrapolate the counts, we need to save the number of skipped stats and add it back
  // For example, the true count of an event could be estimated as:
  //   SUM(sampling_interval * (num_skipped_sample + 1)) as est_count
  optional int32 num_skipped_sample = 2;

  /**  The type of VMCallback that triggered this report.  */
  optional int32 callback_type = 3;

  /**
   * The exit code of the AppSearch {@code IsolateStorageService.VMCallback#onPayloadFinished()}
   * call.
   */
  optional int32 exit_code = 4;

  /**
   * The error code associated with the AppSearch {@code IsolateStorageService.VMCallback.onError()}
   * call.
   */
  optional int32 error_code = 5;

  /**
   * The reason for stopping the AppSearch {@code IsolateStorageService.VMCallback.onStopped()}
   * call.
   */
  optional int32 stop_reason = 6;
}

/**
 * Statistics for multiple AppSearch VM start attempts in MODE_BYTES. It is reported under
 * AppSearchVmInitializationStatsReported.
 *
 * Next tag: 2
 */
message AppSearchVmStartAttempts {
  /**
   * Statistics for a single VM start attempt.
   *
   * Next tag: 3
   */
  message Stats {
    /** The enum class of AppSearch VM start status code. */
    message Status {
      // Next tag: 4
      enum Code {
        UNKNOWN = 0;

        // Indicates that the VM starts successfully.
        SUCCESS = 1;

        // Indicates that timeout occurs when attempting to start the VM.
        TIMEOUT = 2;

        // Indicates that an error occurs when attempting to start the VM.
        ERROR = 3;
      }
    }
    optional Status.Code status_code = 1;

    /** Overall time for a single VM start attempt in milliseconds. */
    optional int64 latency_millis = 2;
  }
  repeated Stats stats = 1;
}

/**
 * Statistics for AppSearch VM initialization. It may contain multiple start attempts (i.e. retries)
 * due to errors.
 *
 * Logged from:
 *   packages/modules/AppSearch/service/java/com/android/server/appsearch/isolated_storage_service/IsolatedStorageServiceManager.java
 * Estimated Logging Rate:
 *    Peak: 5 times in 10*1000 ms | Avg: 10 per device per day
 *
 * Next tag: 3
 */
message AppSearchVmInitializationStatsReported {
  /** The enum class of AppSearch VM initialization type. */
  message VmInitializationType {
    // Next tag: 3
    enum Code {
      UNKNOWN = 0;

      BOOTING = 1;

      RECONNECTING = 2;
    }
  }
  optional VmInitializationType.Code vm_init_type = 1;

  optional AppSearchVmStartAttempts vm_start_attempts = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
}

/**
 * Stats for persist-to-disk operations in AppSearch.

 * Next tag: 27
 */
message AppSearchPersistToDiskStatsReported {

  // The sampling interval for this specific type of stats
  // For example, sampling_interval=10 means that one out of every 10 stats was logged.
  optional int32 sampling_interval = 1;

  // # of previous skipped sample for this specific type of stats
  // We can't push atoms too closely, so some samples might be skipped
  // In order to extrapolate the counts, we need to save the number of skipped stats and add it back
  // For example, the true count of an event could be estimated as:
  //   SUM(sampling_interval * (num_skipped_sample + 1)) as est_count
  optional int32 num_skipped_sample = 2;

  // Package UID of the application.
  optional int32 uid = 3 [(is_uid) = true];

  // Needs to be sync with AppSearchResult#ResultCode in
  // packages/modules/AppSearch/framework/java/external/android/app/appsearch/AppSearchResult.java
  optional int32 status_code = 4;

  // The bitmask for all enabled features on this device. Must be one or a combination of the
  // types AppSearchEnabledFeatures.
  optional int64 enabled_features = 5;

  // The call type that trigger this persist to disk call.
  optional int32 trigger_call_type = 6;

  // The last blocking operation call type.
  optional int32 last_blocking_operation = 7;

  // The latency for last blocking operation which hold the write lock in milliseconds.
  optional int32 last_blocking_operation_latency_millis = 8;

  // The time passed while waiting to acquire the lock during Java function calls
  optional int32 java_lock_acquisition_latency_millis = 9;

  // The time passed while get the vm instance.
  optional int32 get_vm_latency_millis = 10;

  // Overall time used for setting schema including the binder latency
  optional int32 total_latency_millis = 11;

  // The type of persist operation.
  optional int32 persist_type = 12;

  // The latency of the native persist operation (excluding Java overhead) in milliseconds.
  optional int32 native_latency_millis = 13;

  // The latency of persisting the blob store in milliseconds.
  optional int32 native_blob_store_persist_latency_millis = 14;

  // The total latency of persisting the document store in milliseconds.
  optional int32 native_document_store_total_persist_latency_millis = 15;

  // The latency of persisting individual components of the document store in milliseconds.
  optional int32 native_document_store_components_persist_latency_millis = 16;

  // The latency of updating the document store checksum in milliseconds.
  optional int32 native_document_store_checksum_update_latency_millis = 17;

  // The latency of updating the document log checksum in milliseconds.
  optional int32 native_document_log_checksum_update_latency_millis = 18;

  // The latency of syncing document log data to disk in milliseconds.
  optional int32 native_document_log_data_sync_latency_millis = 19;

  // The latency of persisting the schema store in milliseconds.
  optional int32 native_schema_store_persist_latency_millis = 20;

  // The total latency of persisting all indexes in milliseconds.
  optional int32 native_index_persist_latency_millis = 21;

  // The latency of persisting the integer index in milliseconds.
  optional int32 native_integer_index_persist_latency_millis = 22;

  // The latency of persisting the qualified ID join index in milliseconds.
  optional int32 native_qualified_id_join_index_persist_latency_millis = 23;

  // The latency of persisting the embedding index in milliseconds.
  optional int32 native_embedding_index_persist_latency_millis = 24;

  // Time passed while the task is running in AppSearch without any waiting time.
  optional int32 unblocked_appsearch_latency_millis = 25;

  // The number of times that we called icing.
  optional int32 num_icing_calls = 26;
}