/*
 * 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.wear.connectivity;

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

option java_package = "com.android.os.wear.connectivity";
option java_multiple_files = true;

extend Atom {
  optional MediatorUpdated mediator_updated = 721 [(module) = "wearconnectivity"];
  // Deprecated, use proxy_bytes_transfer_by_fg_bg (10200) instead.
  optional SysproxyBluetoothBytesTransfer sysproxy_bluetooth_bytes_transfer = 10196
      [(module) = "wearconnectivity", deprecated = true];
  optional SysproxyConnectionUpdated sysproxy_connection_updated = 786
      [(module) = "wearconnectivity"];
  optional WearCompanionConnectionState wear_companion_connection_state = 921
      [(module) = "wearconnectivity"];
  optional SysproxyServiceStateUpdated sysproxy_service_state_updated = 949
      [(module) = "wearconnectivity"];
  optional WearBleMigrationStateChanged wear_ble_migration_state_changed = 1081
      [(module) = 'wearconnectivity'];
  optional WearNetworkStateChanged wear_network_state_changed = 1139
      [(module) = 'wearconnectivity'];
}

/**
 * Logged whenever WearXMediator changes status, for example ON -> OFF.
 *
 * Logged from package:
 * frameworks/opt/wear/src/com/android/clockwork/connectivity
 */
message MediatorUpdated {
  // e.g. Bluetooth, Wifi, Wifi Scan, Cellular Radio, Cellular Data
  optional com.google.android.wearable.connectivity.MediatorType mediatorType = 1;

  // The mediator action taken. e.g. ON/OFF
  optional com.google.android.wearable.connectivity.MediatorAction action = 2;

  // The reason of mediator state change
  optional com.google.android.wearable.connectivity.Reason reason = 3;

  // The event that triggers mediator state change
  optional com.google.android.wearable.connectivity.TriggerEvent triggerEvent = 4;

  // Timestamp of the event log time in ElapsedRealtime
  optional int64 timestamp_millis = 5;

  // Timestamp(ElapsedRealtime) of when the last linger(the one that actually fired) before the mediator starts the action.
  // A "Linger" is a delay that sometimes the mediator applies before actually turning off the radio after the mediator
  // decides to turn off the radio due to certain signals(e.g. proxy reconnected), for various purposes, such as
  // avoid proxy connection thrashing causing the mediator to frequently toggle the radio.
  optional int64 last_linger_start_timestamp_millis = 6;

  // Count of times the linger canceled before the action was actually performed.
  optional int32 linger_canceled_count = 7;

  // Bluetooth Transport used for Sysproxy on this device. This does NOT imply whether Sysproxy is
  // connected or not.
  optional com.google.android.wearable.connectivity.SysproxyTransportType sysproxy_transport_type = 8;
}

/**
 * Pulls bytes transferred via Sysproxy. Each pull produces atoms that record stats of all processes
 * that used sysproxy since device boot. Sysproxy is a process that runs on Wear OS and that enables
 * internet access via Bluetooth when the companion phone is connected to the watch.
 */
message SysproxyBluetoothBytesTransfer {
  // UID of a process that had some bytes received or transmitted via sysproxy.
  // UID is set to -1 if it impossible to identify which process the bytes should be attributed to.
  optional int32 uid = 1 [(is_uid) = true];

  // Number of bytes received since device boot.
  optional int64 rx_bytes = 2;

  // Number of bytes transmitted since device boot.
  optional int64 tx_bytes = 3;
}

/**
 * Captures Sysproxy connection updates, such as CONNECT and DISCONNECT. Also captures
 * additional information to understand why the connection update happened.
 */
message SysproxyConnectionUpdated {
  // The sysproxy connection action taken. e.g. CONNECTED/DISCONNECTED
  optional com.google.android.wearable.connectivity.SysproxyConnectionAction action = 1;

  // Reason for change. e.g. ACL CONNECT/DISCONNECT, BLUETOOTH_RADIO_OFF, etc.
  optional com.google.android.wearable.connectivity.SysproxyConnectionChangeReason reason = 2;

  // Timestamp of the event log time in ElapsedRealtime
  optional int64 timestamp_millis = 3;

  // bluetooth connection states. eg. ACL_CONNECT, ACL_DISCONNECT. Max size is 3.
  repeated com.google.android.wearable.connectivity.BluetoothConnectionChange bluetooth_connection_change = 4;

  // timestamp of bluetooth connection change in ElapsedRealtime. Order matches order of
  // bluetooth_connection_change. Max size is 3. This is to keep track of when
  // WearConnectivityService receives the Bluetooth connection change broadcast.
  repeated int64 bluetooth_connection_change_timestamp_millis = 5;

  // timestamp when reason was determined
  optional int64 reason_timestamp_millis = 6;

  // Bluetooth Transport used for the current Sysproxy connection
  optional com.google.android.wearable.connectivity.SysproxyTransportType transport_type = 7;
}

/**
 * Captures Sysproxy service state updates, such as service bringup/teardown. Also captures
 * additional details on the sysproxy service state, such as iptables rules states.
 */
message SysproxyServiceStateUpdated {
  // The Sysproxy service state. e.g. SERVICE_STARTUP_FINISHED, SERVICE_SHUTDOWN_FINISHED.
  optional com.google.android.wearable.connectivity.SysproxyServiceState service_state = 1;

  // The iptables config state for sysproxy. e.g. RULES_SETUP_SUCCESS, RULES_SETUP_FAILURE.
  optional com.google.android.wearable.connectivity.SysproxyIptablesState iptables_state = 2;

  // The error code for the iptables operation(setup, teardown, etc.).
  // If the operation didn't fail, 0 is logged.
  // If there are multiple cmds failed in the operation, the first failed cmd error code is logged.
  optional int64 iptables_failure_error_code = 3;

  // The index of the failed iptables cmd in the setup/teardown cmd list.
  // If all cmds succeeded, -1 is logged.
  optional int32 iptables_first_failed_cmd_index = 4;

  // Total count of cmds failed(even after retry) in the iptables operation(iptables setup/teardown).
  optional int32 iptables_failed_cmd_count = 5;

  // Total count of cmds retried in the iptables operation.
  // Compare with iptables_failed_cmd_count to understand how many cmds succeeded with retry.
  optional int32 iptables_retried_cmd_count = 6;

  // Total count of iptables recovery attempted in the background since the service is started.
  optional int32 iptables_recovery_attempt_count = 7;
}

/**
 * Captures updates of the connections to the companion phone.
 * Only the one used for important data connectivity (Sysproxy, Comms, Assistant, etc.) is logged
 * even when both are connected. Specifically, before the BLE migration is activated on the
 * device(go/wear-ble), BTC_ACL is logged, after that, BLE_ACL is logged.
 * Note that this atom does NOT aim to comprehensively log all the ongoing BT connection between
 * the watch and the companion phone, but only limited to the logs described above. Connections(for
 * example, BTC ACL after BLE migration) not being logged in this atom does NOT mean it's
 * not connected(or not disconnected).
 */
message WearCompanionConnectionState {
  optional com.google.android.wearable.connectivity.CompanionConnectionType connection_type = 1;

  optional com.google.android.wearable.connectivity.CompanionConnectionChange connection_change = 2;
}

/**
 * Captures updates of the Platform side Wear BLE migrations state.
 * The sequence of the steps are: STEP_SYSPROXY_PSM_RECEIVED -> STEP_SYSPROXY_TRANSPORT_MIGRATED.
 */
message WearBleMigrationStateChanged {
  optional com.google.android.wearable.connectivity.BleMigrationStep ble_migration_step = 1;
}

/**
 * Logs when certain Wear Network states are updated, such as capabilities, availabilities.
 * Logged from:
 *   frameworks/opt/wear/src/com/android/clockwork/connectivity/logging/WearNetworkStateLogger.java
 * Estimated Logging Rate:
 *   Peak: 1 time in 1 sec | Avg: 5 times per device per day
 */
message WearNetworkStateChanged {
  // The current status of the network.
  optional com.google.android.wearable.connectivity.NetworkStatus network_status = 1;

  // The transport type of the network.
  optional com.google.android.wearable.connectivity.NetworkTransportType transport_type = 2;

  // A bitmask of the network capabilities that the network now has.
  // The integer will have n-th bit set if it has a capability type of value n.
  // See packages/modules/Connectivity/framework/src/android/net/NetworkCapabilities.java
  optional int64 network_capabilities = 3;

  // Whether the network is reported in SUSPENDED state.
  optional bool is_suspended = 4;
}
