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

import "frameworks/proto_logging/stats/atoms.proto";
import "frameworks/proto_logging/stats/atom_field_options.proto";
import "frameworks/proto_logging/stats/enums/hardware/biometrics/enums.proto";
import "frameworks/proto_logging/stats/enums/app_shared/app_enums.proto";
import "frameworks/proto_logging/stats/enums/app_shared/app_op_enums.proto";
import "frameworks/proto_logging/stats/enums/framework/compat/enums.proto";
import "frameworks/proto_logging/stats/enums/os/enums.proto";
import "frameworks/proto_logging/stats/enums/security/advancedprotection/enums.proto";

option java_package = "com.android.os.framework";

extend Atom {
    optional FullScreenIntentLaunched full_screen_intent_launched = 631 [(module) = "framework"];
    optional BalAllowed bal_allowed = 632 [(module) = "framework"];
    optional InTaskActivityStarted in_task_activity_started = 685 [(module) = "framework"];
    optional DeviceOrientationChanged device_orientation_changed = 906 [(module) = "framework"];
    optional CachedAppsHighWaterMark cached_apps_high_watermark = 10189 [(module) = "framework"];
    optional StylusPredictionMetricsReported stylus_prediction_metrics_reported = 718 [(module) = "libinput"];
    optional UserRiskEventReported user_risk_event_reported = 725 [(module) = "framework"];
    optional MediaProjectionStateChanged media_projection_state_changed = 729 [(module) = "framework"];
    optional MediaProjectionTargetChanged media_projection_target_changed = 730 [(module) = "framework"];
    optional ExcessiveBinderProxyCountReported excessive_binder_proxy_count_reported = 853
            [(module) = "framework"];
    optional ProxyBytesTransferByFgBg proxy_bytes_transfer_by_fg_bg = 10200 [(module) = "framework"];
    optional MobileBytesTransferByProcState mobile_bytes_transfer_by_proc_state = 10204
            [(module) = "framework", (truncate_timestamp) = true];
    optional BiometricFRRNotification biometric_frr_notification = 817 [(module) = "framework"];
    optional SensitiveContentMediaProjectionSession sensitive_content_media_projection_session = 830 [(module) = "framework"];
    optional SensitiveNotificationAppProtectionSession sensitive_notification_app_protection_session = 831 [(module) = "framework"];
    optional SensitiveNotificationAppProtectionApplied sensitive_notification_app_protection_applied = 832 [(module) = "framework"];
    optional SensitiveNotificationRedaction sensitive_notification_redaction = 833
            [(module) = "framework"];
    optional SensitiveContentAppProtection sensitive_content_app_protection = 835 [(module) = "framework"];
    optional AppRestrictionStateChanged app_restriction_state_changed = 866 [(module) = "framework"];
    optional BatteryUsageStatsPerUid battery_usage_stats_per_uid = 10209 [(module) = "framework"];
    optional PostGCMemorySnapshot postgc_memory_snapshot = 924 [(module) = "framework"];
    optional PowerSaveTempAllowlistChanged power_save_temp_allowlist_changed = 926 [(module) = "framework"];
    optional AppOpAccessTracked app_op_access_tracked = 931 [(module) = "framework"];
    optional ContentOrFileUriEventReported content_or_file_uri_event_reported = 933 [(module) = "framework"];
    optional DeviceIdleTempAllowlistUpdated device_idle_temp_allowlist_updated = 940 [(module) = "framework"];
    optional AppOpNoteOpOrCheckOpBinderApiCalled app_op_note_op_or_check_op_binder_api_called = 943 [(module) = "framework"];
    optional FrameworkWakelockInfo framework_wakelock_info = 10230 [(module) = "framework"];
    optional JankFrameCountByWidgetReported jank_frame_count_by_widget_reported = 950 [(module)="framework"];
    optional IntentCreatorTokenAdded intent_creator_token_added = 978 [(module)="framework"];
    optional NotificationChannelClassification notification_channel_classification = 983 [(module) = "framework"];
    optional CameraStatusForCompatibilityChanged camera_status_for_compatibility_changed = 999 [(module) = "framework"];
    optional NotificationBundleInteracted notification_bundle_interacted = 1000 [(module) = "framework"];
    optional SqliteDiscreteOpEventReported sqlite_discrete_op_event_reported = 1009 [(module) = "framework"];
    optional DeviceStateAutoRotateSettingIssueReported device_state_auto_rotate_setting_issue_reported = 1011 [(module) = "framework"];
    optional ProcessTextActionLaunchedReported process_text_action_launched_reported = 1016 [(module) = "framework"];
    optional IntentRedirectBlocked intent_redirect_blocked = 1037 [(module) = "framework"];
    optional WidgetMemoryStats widget_memory_stats = 10234 [(module) = "framework"];
    optional AdvancedProtectionStateChanged advanced_protection_state_changed = 1040 [(module) = "framework"];
    optional AdvancedProtectionSupportDialogDisplayed advanced_protection_support_dialog_displayed = 1041 [(module) = "framework"];
    optional ExtraIntentKeysCollectedOnServer extra_intent_keys_collected_on_server = 1042 [(module) = "framework"];
    optional ClipboardGetEventReported clipboard_get_event_reported = 1048 [(module) = "framework"];
    optional AdvancedProtectionStateInfo advanced_protection_state_info = 10236 [(module) = "framework"];
    optional AdvancedProtectionUsbStateChangeErrorReported advanced_protection_usb_state_change_error_reported = 1054 [(module) = "framework"];
    optional BinderSpamReported binder_spam_reported = 1064 [(module) = "framework"];
    optional DevicePresenceChanged device_presence_changed = 1080 [(module) = "framework"];
    optional ImplicitUriGrantEventReported implicit_uri_grant_event_reported = 1088 [(module) = "framework"];
    optional AppRestartOccurred app_restart_occurred = 1089 [(module) = "framework"];
    optional BinderCallsReported binder_calls_reported = 1090 [(module) = "framework"];
    optional SqliteAppOpEventReported sqlite_app_op_event_reported = 1098 [(module) = "framework"];
    optional PermissionOneTimeSessionEventReported permission_one_time_session_event_reported = 1100 [(module) = "framework"];
    optional AggregatedAppOpAccessEventReported aggregated_app_op_access_event_reported = 1103 [(module) = "framework"];
    optional DisplayCompatRestartMenuEventReported display_compat_restart_menu_event_reported = 1134 [(module) = "framework"];
    optional AdvancedProtectionUsbNotificationDisplayed advanced_protection_usb_notification_displayed = 1141 [(module) = "framework"];
    optional WidgetInteractionEvent widget_interaction_event = 1175 [(module) = "framework"];
    optional EthernetBytesTransfer ethernet_bytes_transfer = 10249 [(module) = "framework"];
    optional SatelliteBytesTransfer satellite_bytes_transfer = 10250 [(module) = "framework"];
    optional CustomVibrationPatternReported custom_vibration_pattern_reported = 1173 [(module) = "framework"];
}

/**
 * Logs when a full screen intent is launched.
 *
 * Logged from:
 *   frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
 */
message FullScreenIntentLaunched {
    optional int32 creator_uid = 1 [(is_uid) = true];
    optional string activity = 2;
}

message BalAllowed {
    optional string target_activity = 1;
    optional Status allowed_reason = 2;

    optional int32 calling_uid = 3 [(is_uid) = true];
    optional int32 real_calling_uid = 4 [(is_uid) = true];

    // caller and real caller details are only provided if available.
    optional Status caller_allowed_reason = 5;
    optional bool caller_opt_in = 6;
    optional bool caller_opt_in_explicit = 7;

    optional Status real_caller_allowed_reason = 8;
    optional bool real_caller_opt_in = 9;
    optional bool real_caller_opt_in_explicit = 10;

    optional int32 caller_target_sdk = 11;
    optional int32 real_caller_target_sdk = 12;

    enum Status {
        BAL_STATUS_UNKNOWN = 0;
        BAL_ALLOW_DEFAULT = 1; // never serialized
        BAL_ALLOW_ALLOWLISTED_UID = 2;
        BAL_ALLOW_ALLOWLISTED_COMPONENT = 3;
        BAL_ALLOW_VISIBLE_WINDOW = 4;
        BAL_ALLOW_PENDING_INTENT = 5; // obsolete
        BAL_ALLOW_BAL_PERMISSION = 6;
        BAL_ALLOW_SAW_PERMISSION = 7;
        BAL_ALLOW_GRACE_PERIOD = 8;
        BAL_ALLOW_FOREGROUND = 9;
        BAL_ALLOW_SDK_SANDBOX = 10;
        BAL_ALLOW_NON_APP_VISIBLE_WINDOW = 11;
        BAL_ALLOW_TOKEN = 12;
        BAL_ALLOW_BOUND_BY_FOREGROUND = 13;
        BAL_ALLOW_NOTIFICATION_TOKEN = 14;
        BAL_ALLOW_WALLPAPER = 15;
        BAL_BLOCKED = 127; // largest int32 serializable as 1 byte
    }

}

/**
 * Logs when an activity is started in a task with existing visible activities.
 *
 * Logged from: com.android.server.wm.ActivityMetricsLogger
 */
message InTaskActivityStarted {
    // The uid of the started activity.
    optional int32 uid = 1 [(is_uid) = true];

    enum TransitionType {
        UNKNOWN = 0;
        WARM = 1;
        HOT = 2;
        COLD = 3;
        RELAUNCH = 4;
    }
    optional TransitionType type = 2;

    // Whether the activity is opaque or translucent.
    optional bool is_opaque = 3;

    // The delay to start transition.
    optional int32 transition_delay_millis = 4;

    // How long the activity took to be drawn.
    optional int32 windows_drawn_delay_millis = 5;

    // The timestamp(SystemClock#elapsedRealtime()) when starting activity.
    optional int64 activity_start_timestamp_millis = 6;
}

/**
 * Logs when the device (i.e. default display) orientation is changed.
 * Logged from: com.android.server.wm.ActivityTaskManagerService
 * Estimated Logging Rate:
 *   Peak: 6 times in 1 min | Avg: 8 times per device per day
 */
message DeviceOrientationChanged {
    enum Orientation {
        UNDEFINED = 0;
        PORTRAIT = 1;
        LANDSCAPE = 2;
    }
    optional Orientation orientation = 1 [
        (state_field_option).exclusive_state = true,
        (state_field_option).nested = false
    ];
}

/**
 * Logs the cached apps high water mark.
 */
message CachedAppsHighWaterMark {
  // The high water mark of the number of cached apps.
  optional int32 cached_app_high_watermark = 1;

  // The uptime (in seconds) at the high watermark.
  // Note this is going to be pull metrics, so we'll need the timestamp here.
  optional int32 uptime_in_seconds = 2;

  // The number of binder proxy at that high water mark.
  optional int32 binder_proxy_snapshot = 3;

  // Free physical memory (in kb) on device.
  optional int32 free_in_kb = 4;

  // Cched physical memory (in kb) on device.
  optional int32 cached_in_kb = 5;

  // zram (in kb) on device.
  optional int32 zram_in_kb = 6;

  // Kernel memory (in kb) on device.
  optional int32 kernel_in_kb = 7;

  // The number of apps in frozen state.
  optional int32 num_frozen_apps = 8;

  // The longest frozen time (now - last_frozen) in current frozen apps.
  optional int32 longest_frozen_time_in_seconds = 9;

  // The shortest frozen time (now - last_frozen) in current frozen apps.
  optional int32 shortest_frozen_time_in_seconds = 10;

  // The mean frozen time (now - last_frozen) in current frozen apps.
  optional int32 mean_frozen_time_in_seconds = 11;

  // The average frozen time (now - last_frozen) in current frozen apps.
  optional int32 average_frozen_time_in_seconds = 12;
}

/**
 * [Pushed] Log stylus prediction error metrics (go/stylus-prediction-metrics).
 * Logged once for each time bucket per touch event.
 *
 * Logged from: frameworks/native/libs/input/MotionPredictorMetricsManager.cpp.
 */
message StylusPredictionMetricsReported {
    // Allow data to be sliced by stylus hardware information.
    optional int32 stylus_vendor_id = 1;
    optional int32 stylus_product_id = 2;

    // Allow data to be sliced by time bucket.
    optional int32 delta_time_bucket_milliseconds = 3;

    // General errors.
    optional int32 along_trajectory_error_mean_millipixels = 4;

    // Standard deviation of the along-trajectory error.
    optional int32 along_trajectory_error_std_millipixels = 5;

    optional int32 off_trajectory_rmse_millipixels = 6;

    optional int32 pressure_rmse_milliunits = 7;

    // High-velocity errors.
    optional int32 high_velocity_along_trajectory_rmse_millipixels = 8;

    optional int32 high_velocity_off_trajectory_rmse_millipixels = 9;

    // Scale-invariant errors.
    optional int32 scale_invariant_along_trajectory_rmse_millipixels = 10;

    optional int32 scale_invariant_off_trajectory_rmse_millipixels = 11;
}

/**
 * Logs user risk events sent to UserRiskManager
 */
message UserRiskEventReported {
  optional EventType event_type = 1;

  // Call Details

  // time that an active call was connected (picked up), -1 if a call is not active
  optional int64 call_connected_timestamp_millis = 2;
  optional CallDirection call_direction = 3;
  optional NumberVerificationStatus call_number_verification_status = 4;
  // time of the last update to the contact associated with the call, -1 if there is no contact
  optional int64 call_contact_last_updated_timestamp_millis = 5;
  optional int32 call_log_previous_incoming_count = 6;
  optional int32 call_log_previous_outgoing_count = 7;

  // Media Projection Details

  // time of MP start, -1 if MP is not active
  optional int64 mp_start_timestamp_millis = 8;
  optional int32 mp_app_uid = 9 [(is_uid) = true];
  optional int32 mp_installing_app_uid = 10 [(is_uid) = true];
  // time that the MP app was installed
  optional int64 mp_app_first_install_timestamp_millis = 11;

  // A11y details

  // time of A11y grant, -1 if not granted
  optional int64 a11y_capability_granted_timestamp_millis = 12;
  optional int32 a11y_app_uid = 13 [(is_uid) = true];
  optional int32 a11y_installing_app_uid = 14 [(is_uid) = true];
  // time that the A11y app was installed
  optional int64 a11y_app_first_install_timestamp_mills = 15;

  enum EventType {
    UNKNOWN = 0;
    A11Y_CONSENT_DIALOG_SHOWN = 1;
    A11Y_GRANTED = 2;
    A11Y_DENIED = 3;
    A11Y_APP_UNINSTALLED = 4;
    MEDIA_PROJECTION_CONSENT_DIALOG_SHOWN = 5;
    MEDIA_PROJECTION_GRANTED = 6;
    MEDIA_PROJECTION_DENIED = 7;
    MEDIA_PROJECTION_STARTED = 8;
    ACTIVE_CALL_STARTED = 9;
    ACTIVE_CALL_CHANGED = 10;
    ACTIVE_CALL_ENDED = 11;
  }

  enum CallDirection {
    UNKNOWN_DIRECTION = 0;
    INCOMING = 1;
    OUTGOING = 2;
  }

  enum NumberVerificationStatus {
    UNKNOWN_STATUS = 0;
    NOT_VERIFIED = 1;
    PASSED = 2;
    FAILED = 3;
  }
}

/**
 * Logs when MediaProjection goes through state changes.
 *
 * MediaProjection API allows apps to capture the contents of a display
 * or a single app.
 *
 * Logged from:
 * frameworks/base/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
 */
message MediaProjectionStateChanged {
  // Unique session identifier, to identify which events belong to which session.
  // An incrementing integer that persists across device reboots.
  optional int32 session_id = 1 [(state_field_option).primary_field = true];

  // The current state that is entered.
  optional MediaProjectionState state = 2 [
    (state_field_option).exclusive_state = true,
    (state_field_option).nested = false
  ];

  // Previous state.
  optional MediaProjectionState previous_state = 3;

  // UID of the package that initiates MediaProjection.
  // -2 - if can't report (e.g. side loaded app)
  optional int32 host_uid = 4 [(is_uid) = true];

  // UID of the package that is captured if selected.
  // -1 - full screen sharing (app is not selected)
  // -2 - can't report (e.g. side loaded app)
  optional int32 target_uid = 5 [(is_uid) = true];

  // Time since last active session ended in seconds. May not be set if there
  // was no known last session. Only set when in state MEDIA_PROJECTION_STATE_INITIATED.
  optional int32 time_since_last_active_session_seconds = 6;

  // Where this session started.
  // Only present when in state MEDIA_PROJECTION_STATE_INITIATED.
  optional SessionCreationSource creation_source = 7;

  // Where this session stopped.
  // Only present when in state MEDIA_PROJECTION_STATE_STOPPED.
  optional SessionStopSource stop_source = 8;

  // Possible states for a MediaProjection session.
  enum MediaProjectionState {
    MEDIA_PROJECTION_STATE_UNKNOWN = 0;
    // Media projection session first initiated by the app requesting the
    // user's consent to capture.
    // Should be sent even if the permission dialog is not shown.
    MEDIA_PROJECTION_STATE_INITIATED = 1;
    // The user entered the setup flow and permission dialog is displayed.
    // This state is not sent when the permission is already granted and
    // we skipped showing the permission dialog.
    MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED = 2;
    // The app selector dialog is shown for the user.
    MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED = 3;
    // The VirtualDisplay is created and capturing the selected region begins.
    MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS = 4;
    // The capturing is paused.
    MEDIA_PROJECTION_STATE_CAPTURING_PAUSED = 5;
    // The capturing has resumed after being in paused state.
    MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS_RESUMED = 6;
    // Capturing stopped, either normally or because of error.
    MEDIA_PROJECTION_STATE_STOPPED = 7;
    // Media projection setup cancelled, user dismissed the dialog
    MEDIA_PROJECTION_STATE_CANCELLED = 8;
  }

  // The possible entry points for the session.
  enum SessionCreationSource {
    CREATION_SOURCE_UNKNOWN = 0;
    // Created through public MediaProjection API, used by 1P/3P apps.
    CREATION_SOURCE_APP = 1;
    // Created using a SystemUI screen recorder, accessible from screen
    // recorder quick settings tile.
    CREATION_SOURCE_SYSTEM_UI_SCREEN_RECORDER = 2;
    // Created through Cast SDK, e.g. screencast quick settings tile.
    CREATION_SOURCE_CAST = 3;
  }

  // The possible exit points for the session.
  enum SessionStopSource {
    STOP_SOURCE_UNKNOWN = 0;
    // Stopped through calling MediaProjection#stop()
    STOP_SOURCE_HOST_APP_STOP = 1;
    // Stopped by the capture target calling onRemoved() after being exited
    STOP_SOURCE_TASK_APP_CLOSE = 2;
    // Stopped by the device keyguard being locked
    STOP_SOURCE_DEVICE_LOCK = 3;
    // Stopped via the MediaProjection status bar privacy chip
    STOP_SOURCE_STATUS_BAR_CHIP_STOP = 4;
    // Stopped via the Quick Settings cast tile
    STOP_SOURCE_QS_TILE = 5;
    // Stopped due to the device switching users
    STOP_SOURCE_USER_SWITCH = 6;
    // Stopped due to a change in the MediaProjection foreground service
    STOP_SOURCE_FOREGROUND_SERVICE_CHANGE = 7;
    // Stopped due to a new MediaProjection coming to replace the currently active projection
    STOP_SOURCE_NEW_PROJECTION = 8;
    // Stopped due to a new MediaRoute being chosen while casting
    STOP_SOURCE_NEW_MEDIA_ROUTE = 9;
    // Stopped due to some error affecting the MediaProjection capture process
    STOP_SOURCE_ERROR = 10;
  }
}

/**
 * Logs when the region captured in the MediaProjection session changes.
 *
 * This may be due to a the user changing the region, or the captured app changing
 * windowing mode.
 *
 * It should be reported only after a MediaProjection session enters
 * MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS state.
 *
 * Logged from:
 * frameworks/base/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
 */
message MediaProjectionTargetChanged {
  // Unique session identifier, to identify which events belong to which session.
  // An incrementing integer that persists across device reboots.
  optional int32 session_id = 1 [(state_field_option).primary_field = true];

  // The classification for the type of change applied to the capture target
  optional TargetChangeType target_change_type = 10;

  // The area that is being captured.
  optional TargetType target_type = 2;

  // UID of the package that initiates MediaProjection.
  // -2 - can't report (e.g. side loaded app)
  optional int32 host_uid = 3 [(is_uid) = true];

  // UID of the package that is captured by MediaProjection.
  // Not filled if not known, for example if the user chose
  // display capture.
  // -2 - can't report (e.g. side loaded app)
  optional int32 target_uid = 4 [(is_uid) = true];

  // The current windowing mode of the target app.
  optional WindowingMode target_windowing_mode = 5 [
    (state_field_option).exclusive_state = true,
    (state_field_option).nested = false
  ];

  optional int32 width = 6;
  optional int32 height = 7;
  optional int32 center_x = 8;
  optional int32 center_y = 9;

  // Enum that represents the type of change happening to the capture target
  enum TargetChangeType {
    TARGET_CHANGE_TYPE_UNKNOWN = 0;
    // The target has updated its windowing mode (full screen, split screen, freeform, etc.)
    TARGET_CHANGE_WINDOWING_MODE = 1;
    // The target has changed the position it is centered at (size remains unchanged)
    TARGET_CHANGE_POSITION = 2;
    // The target has changed its bounds (changed size and centered position)
    TARGET_CHANGE_BOUNDS = 3;
  }

  // Enum that represents the type of area that is being captured.
  enum TargetType {
    TARGET_TYPE_UNKNOWN = 0;
    // Capturing a single display.
    TARGET_TYPE_DISPLAY = 1;
    // Capturing one task of an app.
    TARGET_TYPE_APP_TASK = 2;
    // Capturing via an overlay.
    TARGET_TYPE_OVERLAY = 3;
  }

  // Windowing mode of the captured task, if the user chose to capture
  // a single app instance.
  enum WindowingMode {
    WINDOWING_MODE_UNKNOWN = 0;
    // The app is not visible (e.g. another app is in full-screen foreground)
    WINDOWING_MODE_HIDDEN = 1;
    // The app is in fullscreen mode.
    WINDOWING_MODE_FULLSCREEN = 2;
    // The app is in a split screen.
    WINDOWING_MODE_SPLIT_SCREEN = 3;
    // The app is in freeform mode
    WINDOWING_MODE_FREEFORM = 4;
  }
}

/**
 * Pulls bytes transferred via network with TYPE_PROXY from NetworkStats. Each pull produces atoms
 * that record stats of all processes that used sysproxy since device boot.
 * Network with TYPE_PROXY is used on Wear OS to enable internet access via Bluetooth when the
 * companion phone is connected to the watch.
 */
message ProxyBytesTransferByFgBg {
  optional int32 uid = 1 [(is_uid) = true];

  optional bool is_foreground = 2;

  optional int64 rx_bytes = 3;

  optional int64 rx_packets = 4;

  optional int64 tx_bytes = 5;

  optional int64 tx_packets = 6;
}

/**
 * Pulls bytes transferred via mobile networks (separated by proc state).
 *
 * Pulled from:
 *   StatsCompanionService (using BatteryStats to get which interfaces are mobile data)
 */
 message MobileBytesTransferByProcState {
    optional int32 uid = 1 [(is_uid) = true];

    optional android.app.ProcessStateEnum proc_state = 2;

    optional int64 rx_bytes = 3;

    optional int64 rx_packets = 4;

    optional int64 tx_bytes = 5;

    optional int64 tx_packets = 6;
}

/**
 * Logs when an FRR notification action has been presented to the user.
 *
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/biometrics
 */
message BiometricFRRNotification {
    optional android.hardware.biometrics.FRRNotificationAction action = 1;
    optional android.hardware.biometrics.ModalityEnum modality = 2;
}

/*
 * Logs that indicate a sensitive protection session has started
 *
 * Logs from :
 * packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
 * frameworks/base/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
 */
message SensitiveContentMediaProjectionSession {
    optional int64 session_id = 1;
    optional int32 projection_app_uid = 2 [(is_uid) = true];
    optional bool exempted = 3;
    optional State state = 4;
    enum State {
       UNDEFINED_STATE = 0;
       START = 1;
       STOP = 2;
    }
    optional LoggingSource source = 5;
    enum LoggingSource {
       UNDEFINED_SOURCE = 0;
       SYS_UI = 1;
       FRAMEWORKS = 2;
    }
}

/*
 * Logs that a sensitive content session has started
 *
 * Logs from : frameworks/base/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
 *
 */
message SensitiveNotificationAppProtectionSession {
    // id which identifies single screen share session
    optional int64 session_id = 1;
    optional int32 num_notifications = 2;
    optional int32 num_otp_notifications = 3;
}

/*
 * Logs that an app has been opened from a sensitive context
 *
 * Logs from :  com.android.server.wm
 *
 */
message SensitiveNotificationAppProtectionApplied {
    // id which identifies single screen share session
    optional int64 session_id = 1;
    // uid of app to be protected
    optional int32 uid = 2 [(is_uid) = true];
}

/**
 * Reports a notification got an Adjustment with the KEY_SENSITIVE_CONTENT value set, and whether
 * the system redacted the notification
 *
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/notification/
 */
message SensitiveNotificationRedaction {
     optional bool receive_adjustment_before_post = 1;
     optional bool redact = 2;
     optional int32 latency_ms = 3;
}


/**
* Logged when a user has started screen sharing and then opens an app activity
* which renders sensitive content (i.e. username, password) on the screen.
*
* Logs from: frameworks/base/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
*/

message SensitiveContentAppProtection {
  // unique for each media projection session.
  optional int64 session_id = 1;
  // uid which got flag_secure applied.
  optional int32 protected_uid = 2 [(is_uid) = true];
  // uid starting media projection.
  optional int32 projection_uid = 3 [(is_uid) = true];
  enum State {
    UNKNOWN = 0;
    BLOCKED = 1;
    UNBLOCKED = 2;
  }
  // whether an app window got blocked or unblocked as sensitive view
  // become visible/invisible in the window.
  optional State state = 4;
}

/**
 * Logs when there are too many binder proxies sent from certain UID to the system.
 *
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
 *
 */
message ExcessiveBinderProxyCountReported {
    optional int32 offending_uid = 1 [(is_uid) = true];
}

/**
 * Logs when an app's restriction state changes.
 *
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/am/AppRestrictionController.java
 */
message AppRestrictionStateChanged {
  optional int32 uid = 1 [(is_uid) = true];

  enum RestrictionType {
    TYPE_UNKNOWN = 0;
    TYPE_UNRESTRICTED = 1;
    TYPE_EXEMPTED = 2;
    TYPE_ADAPTIVE = 3;
    TYPE_RESTRICTED_BUCKET = 4;
    TYPE_BACKGROUND_RESTRICTED = 5;
    TYPE_FORCE_STOPPED = 6;
    TYPE_USER_LAUNCH_ONLY = 7;
    TYPE_CUSTOM = 8;
  }
  // The type of restriction/unrestriction
  optional RestrictionType restriction_type = 2;

  // Whether the restriction type is being enabled or disabled
  optional bool enabled = 3;

  enum RestrictionChangeReason {
    REASON_UNKNOWN = 0;
    REASON_DEFAULT = 1;
    REASON_DORMANT = 2;
    REASON_USAGE = 3; // For unrestriction
    REASON_USER = 4;
    reserved 5;
    REASON_SYSTEM_HEALTH = 6;
    REASON_POLICY = 7;
    REASON_OTHER = 8;
  }
  // The main reason for restriction state change
  optional RestrictionChangeReason main_reason = 4;

  // An optional sub reason that provides more detail specific to the restriction type
  optional string sub_reason = 5; // At most 16 chars

  // The threshold that was applied to make the decision
  optional int64 threshold_exceeded = 6;

  enum RestrictionChangeSource {
    SOURCE_UNKNOWN = 0;
    SOURCE_USER = 1;
    SOURCE_USER_NUDGED = 2;
    SOURCE_SYSTEM = 3;
    SOURCE_COMMAND_LINE = 4;
    SOURCE_REMOTE_TRIGGER = 5;
  }
  // The source of the change - initiated by the user, the system automatically, etc.
  optional RestrictionChangeSource source = 7;
}

/**
 * Pulls detailed battery attribution slices.
 *
 * Pulled from:
 *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
 *
 * The charging_state and screen_state (and other states potentially) can be used as a dimensions
 * for corresponding metrics to pull this atom and rely on statsd tracking of states instead
 */
message BatteryUsageStatsPerUid {

  enum ProcessState {
    UNSPECIFIED = 0;
    FOREGROUND = 1;
    BACKGROUND = 2;
    FOREGROUND_SERVICE = 3;
    CACHED = 4;
  }

  // Overall SessionStats data

  // The session start timestamp in UTC milliseconds since January 1, 1970, per Date#getTime().
  // All data is no older than this time.
  optional int64 session_start_millis = 1;

  // The session end timestamp in UTC milliseconds since January 1, 1970, per Date#getTime().
  // All data is no more recent than this time.
  optional int64 session_end_millis = 2;

  // Length that the reported data covered. This usually will be equal to the entire session,
  // session_end_millis - session_start_millis, but may not be if some data during this time frame
  // is missing.
  optional int64 session_duration_millis = 3;

  // Sum of all discharge percentage point drops during the reported session.
  // Reported by Health HAL - as an integer ranging from 0 to 100
  optional int32 session_discharge_percentage = 4;

  // Total amount of time battery was discharging during the reported session
  optional int64 session_discharge_duration_millis = 5;

  // Per Uid BatteryConsumer data

  optional int32 uid = 6 [(is_uid) = true];    // for device-wide atom Process.INVALID_UID (-1)
  optional ProcessState proc_state = 7;        // for device-wide atom ProcessState.UNSPECIFIED
  optional int64 time_in_state_millis = 8;

  optional string power_component_name = 9;
  optional float total_consumed_power_mah = 10;
  optional float consumed_power_mah = 11;
  optional int64 duration_millis = 12;
}

/**
 * Logs the post-GC memory state for a process
 */
message PostGCMemorySnapshot {
    // The process uid
    optional int32 uid = 1 [(is_uid) = true];

    // The process name.
    optional string process_name = 2;

    // The pid of the process.
    // Allows to disambiguate instances of the process.
    optional int32 pid = 3;

    // The current OOM score adjustment value.
    // Placeholder -1001 (OOM_SCORE_ADJ_MIN - 1, outside of allowed range) for native ones.
    optional int32 oom_score_adj = 4;

    // The current RSS of the process.
    // VmRSS from /proc/pid/status.
    optional int32 rss_in_kb = 5;

    // The current anon RSS of the process.
    // RssAnon from /proc/pid/status.
    optional int32 anon_rss_in_kb = 6;

    // The current swap size of the process.
    // VmSwap from /proc/pid/status.
    optional int32 swap_in_kb = 7;

    // The sum of rss_in_kilobytes and swap_in_kilobytes.
    optional int32 anon_rss_and_swap_in_kb = 8;

    // Names of the classes with native allocations registered
    repeated string native_allocation_class = 9;

    // Numbers of malloced native allocations registered
    repeated int64  native_allocation_malloced_count = 10;

    // Memory sizes in bytes of malloced native allocations registered
    repeated int64  native_allocation_malloced_bytes = 11;

    // Numbers of nonmalloced native allocations registered
    repeated int64  native_allocation_nonmalloced_count = 12;

    // Memory sizes in bytes of nonmalloced native allocations registered
    repeated int64  native_allocation_nonmalloced_bytes = 13;

    // java.lang.Runtime.freeMemory() bytes.
    optional int64 java_free_memory_bytes = 14;

    // java.lang.Runtime.totalMemory() bytes.
    optional int64 java_total_memory_bytes = 15;

    // java.lang.Runtime.maxMemory() bytes.
    optional int64 java_max_memory_bytes = 16;
}

/**
 * A PowerSaveTempAllowlistChanged atom indicates that an app is added to or removed from
 * the temp allowlist, which contains a list of apps that are allowed to bypass
 * certain power or process management restrictions.
 *
 * Logged from: OomAdjuster.setUidTempAllowlistStateLSP via Hummingbird
 */
message PowerSaveTempAllowlistChanged {
    optional int32 uid = 1 [(is_uid) = true];
    optional bool add_to_allowlist = 2;
}

/**
 * Records invocations of ActivityManagerService$LocalService.updateDeviceIdleTempAllowlist
 *
 * Logged via Hummingbird
 */
message DeviceIdleTempAllowlistUpdated {
    optional int32 changing_uid = 1 [(is_uid) = true];
    optional bool adding = 2;
    optional int64 duration_ms = 3;
    optional int32 type = 4;
    optional int32 reason_code = 5;
    optional string reason = 6;
    optional int32 calling_uid = 7 [(is_uid) = true];
}

/**
 * [Pushed Atom] Logs when an AppOp is accessed through noteOp, startOp, finishOp and that access
 * history can be stored in the AppOp discrete access data store.
 *
 * Logged from: frameworks/base/services/core/java/com/android/server/appop/DiscreteRegistry.java
 */
message AppOpAccessTracked {
    enum AccessType {
        UNKNOWN = 0;
        NOTE_OP = 1;
        START_OP = 2;
        FINISH_OP = 3;
        PAUSE_OP = 4;
        RESUME_OP = 5;
    }

    // Uid of the package requesting the op
    optional int32 uid = 1 [(is_uid) = true];

    // operation id
    optional android.app.AppOpEnum op_id = 2 [default = APP_OP_NONE];

    // One of the access types
    optional AccessType access_type = 3 ;

    // The uid state of the package performing the op
    optional int32 uid_state = 4;

    // The flags of the op
    optional int32 op_flag = 5;

    // The flags of the attribution chain
    optional int32 attribution_flag = 6;

    // attribution_tag; provided by developer when accessing related API, limited at 50 chars by
    // API. Attributions must be provided through manifest using <attribution> tag available in R
    // and above.
    optional string attribution_tag = 7;

    // Chain Id that is used to link a finish_op to a start_op
    optional int32 attribution_chain_id = 8;
}

/**
 * [Pushed Atom] Logs when AppOp checkOperation and noteOperation binder APIs are called in
 * AppOpsService
 *
 * Logged from: frameworks/base/services/core/java/com/android/server/appop/AppOpsService.java
 */
message AppOpNoteOpOrCheckOpBinderApiCalled {
    enum BinderApi {
        UNKNOWN = 0;
        CHECK_OPERATION = 1;
        NOTE_OPERATION = 2;
        NOTE_PROXY_OPERATION = 3;
    }

    // Uid of the package requesting the op
    optional int32 uid = 1 [(is_uid) = true];

    // AppOp code
    optional android.app.AppOpEnum op_id = 2 [default = APP_OP_NONE];

    // One of the BinderApi
    optional BinderApi binder_api = 3;

    // Whether the binder call has attribution tag in the arguments
    optional bool has_attribution_tag = 4;
}

/**
 * Pushed atom. Logs the duration between device state change and device state
 * based auto rotate setting change if the duration is less than certain
 * threshold.
 *
 * Logged from:
 *  frameworks/base/services/core/java/com/android/server/wm/DeviceStateAutoRotateSettingIssueLogger.java
 *
 * Estimated Logging Rate:
 *   Avg: < 1 per device per day
*/
message DeviceStateAutoRotateSettingIssueReported {
  // Duration between device state change and device state based auto rotate
  // setting change.
  optional int32 duration_ms = 1;
  // Boolean is true if the device state change is the first one to happen
  // followed by device state based auto rotate setting change.
  // False if the device state based auto rotate setting change is the first one
  // to happen followed by device state change.
  optional bool is_device_state_change_first = 2;
}

/**
 * [Pushed Atom] Log discrete ops performance results for sqlite implementation.
 *
 * Logged from: frameworks/base/services/core/java/com/android/server/appop/DiscreteOpsSqlRegistry.java
 */
message SqliteDiscreteOpEventReported {
  optional int64 read_time_millis = 1 ;
  optional int64 write_time_millis = 2 ;
  optional int64 storage_bytes = 3 ;
}

/**
 * [Pushed Atom] Log AppOps performance results for (unified schema) sqlite implementation.
 *
 * Logged from: frameworks/base/services/core/java/com/android/server/appop/AppOpHistoryDbHelper.java
 */
message SqliteAppOpEventReported {
  optional int64 read_time_millis = 1 ;
  optional int64 write_time_millis = 2 ;
  optional int64 storage_bytes = 3 ;
  // Appop are stored in 2 databases, and the data is aggregated based on time interval.
  enum DatabaseType {
    DB_UNKNOWN = 0;
    DB_SHORT_INTERVAL = 1;
    DB_LONG_INTERVAL = 2;
  }
  optional DatabaseType database_type = 4;
  // What triggered the database write.
  enum WriteType {
    WRITE_UNKNOWN = 0;
    WRITE_CACHE_FULL = 1;
    WRITE_PERIODIC = 2;
    WRITE_SHUTDOWN = 3;
    // During read we flush the cache into database to simplify read queries.
    WRITE_READ = 4;
    WRITE_MIGRATION = 5;
  }
  optional WriteType write_type = 5;
}

/**
 * Logs when specific content and file URIs are encountered in several locations. See EventType for
 * more details.
 */
message ContentOrFileUriEventReported {
  enum EventType {
    UNKNOWN = 0;
    // When the caller tries to launch an activity with a Content URI it doesn't have read access to
    // and the callee has requireContentUriPermissionFromCaller as "none"
    CONTENT_URI_WITHOUT_CALLER_READ_PERMISSION = 1;
    // When the ContentResolver receives a File URI
    FILE_URI_IN_CONTENT_RESOLVER = 2;
    // When the Icon receives a non Content URI
    NON_CONTENT_URI_IN_ICON = 3;
    // When the NotificationRecord receives a non Content URI
    NON_CONTENT_URI_IN_NOTIFICATION_RECORD = 4;
    // When the MediaDataManager receives a non Content URI
    NON_CONTENT_URI_IN_MEDIA_DATA_MANAGER = 5;
  }
  optional EventType event_type = 1;
  optional string action_type = 2;
  optional int32 caller_uid = 3 [(is_uid) = true];
  optional string caller_activity_class_name = 4;
  optional int32 callee_uid = 5 [(is_uid) = true];
  optional string callee_activity_class_name = 6;
  optional bool is_start_activity_for_result = 7;
  optional string uri_authority = 8;
  optional string uri_type = 9;
  optional string uri_mime_type = 10;
}

/**
 * Logs aggregate time and count of framework wakelocks.
 */
message FrameworkWakelockInfo {
  // The primary (index 0) uid for this WakeLock in the attribution chain.
  optional int32 attribution_uid = 1 [(is_uid) = true];
  optional string attribution_tag = 2;

  // The type (level) of the wakelock; e.g. a partial wakelock or a full wakelock.
  // From frameworks/proto_logging/stats/enums/os/enums.proto.
  optional android.os.WakeLockLevelEnum type = 3;

  // Accumulated uptime attributed to this WakeLock since boot, where overlap
  // between WakeLocks with the same UID and tag is ignored. Specifically, if two
  // WakeLocks with the same UID and tag were acquired at exactly the same time and
  // held for 100 ms, the total contribution of the two WakeLocks to uptime_millis
  // is 100 ms.
  optional int64 uptime_millis = 4;

  // Count of WakeLocks that have been acquired and then released.
  optional int64 completed_count = 5;
}
/**
 * [Pushed atom] Logged after a set number of JankData batches have been processed or when an Activity is
 * paused.
 *
 * Pushed from:
 *   frameworks/base/core/java/android/app/jank/JankDataProcessor.java
 *
 * Estimated Logging Rate:
 *  Peak: 25 times every 20 sec while frames are being rendered.
 *  Avg: 500 times per device per day.
 */
message JankFrameCountByWidgetReported {
  // UID of the app
  optional int32 uid = 1 [(is_uid) = true];

  // The name of the activity that is currently collecting frame metrics.
  optional string activity_name = 2;

  // The id that has been set for the widget.
  optional string widget_id = 3;

  // The refresh rate of the display when logged.
  optional int32 refresh_rate = 4;

  // High level categories to group functionally similar UI elements.
  enum WidgetCategory {
    // Category not set.
    WIDGET_CATEGORY_UNSPECIFIED = 0;
    // UI elements that facilitate scrolling.
    SCROLL = 1;
    // UI elements that facilitate playing animations.
    ANIMATION = 2;
    // UI elements that facilitate media playback or streaming.
    MEDIA = 3;
    // UI elements that facilitate in app navigation.
    NAVIGATION = 4;
    // UI elements that facilitate displaying, hiding or interacting with keyboard.
    KEYBOARD = 5;
    // UI elements that don't fall in on of the other categories.
    OTHER = 6;
  }
  optional WidgetCategory widget_type = 5;

  // The states that the UI elements can report
  enum WidgetState {
    // State not set.
    WIDGET_STATE_UNSPECIFIED = 0;
    // Element that is idle or not in any active state.
    NONE = 1;
    // Element that is currently scrolling.
    SCROLLING = 2;
    // Element that is currently being flung.
    FLINGING = 3;
    // Element that is currently being swiped.
    SWIPING = 4;
    // Element that is currently being dragged.
    DRAGGING = 5;
    // Element that is currently zooming.
    ZOOMING = 6;
    // Element that is currently animating.
    ANIMATING = 7;
    // Element that is currently engaging in media playback.
    PLAYBACK = 8;
    // Element that is currently being tapped on.
    TAPPING = 9;
    // Element that is currently performing a back navigation gesture.
    PREDICTIVE_BACK = 10;
  }
  optional WidgetState widget_state = 6;

  // The number of frames reported during this state.
  optional int64 total_frames = 7;

  // Total number of frames determined to be janky during the reported state.
  optional int64 janky_frames = 8;

  // Histogram of frame duration overruns.
  repeated int32 frame_overrun_histogram = 9;
}

/**
 * [Pushed atom] Logged when an IntentCreatorToken is added to an Intent.
 *
 * Pushed from:
 *   frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
 *      #addCreatorToken
 *
 * Estimated Logging Rate:
 *  Peak: 100 times per device per day.
 *  Avg: 20 times per device per day.
 */
message IntentCreatorTokenAdded {
  // creator uid
  optional int32 creator_uid = 1 [(is_uid) = true];
  // true if the creator and top level intent target share the same package
  optional bool is_optimized = 2;
}

/**
 * [Pushed atom] Logged when an intent redirect attack is blocked.
 *
 * Pushed from:
 *   frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
 *      #Request.resolveActivity
 *      #executeRequest
 *   frameworks/base/services/core/java/com/android/server/am/ActivityStartController.java
 *      #startActivities
 *
 * Estimated Logging Rate:
 *  Peak: 10 times per device per day.
 *  Avg: 0 times per device per day.
 */
message IntentRedirectBlocked {
  // creator uid
  optional int32 creator_uid = 1 [(is_uid) = true];
  // calling uid
  optional int32 calling_uid = 2 [(is_uid) = true];
  // reason code
  optional Reason reason = 3;
  enum Reason {
    INTENT_REDIRECT_BLOCKED_UNSPECIFIED = 0;
    INTENT_REDIRECT_EXCEPTION_MISSING_OR_INVALID_TOKEN = 1;
    INTENT_REDIRECT_EXCEPTION_GRANT_URI_PERMISSION = 2;
    INTENT_REDIRECT_EXCEPTION_START_ANY_ACTIVITY_PERMISSION = 3;
    INTENT_REDIRECT_ABORT_START_ANY_ACTIVITY_PERMISSION = 4;
    INTENT_REDIRECT_ABORT_INTENT_FIREWALL_START_ACTIVITY = 5;
    INTENT_REDIRECT_ABORT_PERMISSION_POLICY_START_ACTIVITY = 6;
  }
}

/**
 * [Pushed atom] Logged when extra intent keys have to be collected on the system server.
 *
 * Pushed from:
 *   frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
 *      #addCreatorToken
 *
 * Estimated Logging Rate:
 *  Peak: 10 times per device per day.
 *  Avg: 0 times per device per day.
 */
message ExtraIntentKeysCollectedOnServer {
  // creator uid
  optional int32 creator_uid = 1 [(is_uid) = true];
}

/**
 * Reports a notification got an Adjustment with the KEY_TYPE value set. These adjustments generally
 * mean a notification has been classified as belonging to a particular type (e.g., news).
 * (go/sysui-notification-bundle-metrics)
 *
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/notification/
 * Estimated Logging Rate:
 *   Peak: 300 times per device per day. | Avg: 40 times per device per day.
 */
message NotificationChannelClassification {
    // Was the notification reclassified to a new channel after it was already posted.
    optional bool receive_adjustment_after_post = 1;

    // Was the notification high enough priority to be "alerting" before it got reclassified.
    optional bool was_alerting = 2;

    // The new channel type the notification has been reclassified as (e.g., Adjustment.TYPE_NEWS).
    optional int32 type = 3;

    // The length of the lifetime of the notification up to when it got reclassified.
    optional int32 latency_ms = 4;

    // As for UiEventReported; used to indicate the event which caused the reclassification.
    optional int32 event_id = 5;

    // The instance ID of the notification whose channel has been classified.
    optional int32 instance_id = 6;

    // The uid of the activity which posted the notification.
    optional int32 uid = 7 [(is_uid) = true];
}

/**
 * Reports that an instance of a notification bundle was interacted with.
 * (go/sysui-notification-bundle-metrics)
 *
 * A notification bundle is a grouping of a number of notifications, based on their type, rather
 * than based on the app that posted them. For example, a number of notifications from different
 * apps that are all news related may be categorized as such, and grouped together in a UI element
 * that groups, or "bundles" them.
 *
 * This proto indicates that a particular bundle was interacted with in some way; for example, a
 * user may choose to dismiss an entire bundle, which would log a NotificationBundleInteracted
 * with an event_id that represents bundle dismissal.
 *
 * Logged from:
 *   frameworks/base/packages/SystemUI/src/com/android/systemui/
 * Estimated Logging Rate:
 *   Peak: 300 times per device per day. | Avg: <40 times per device per day.
 */
message NotificationBundleInteracted {
    // As for UiEventReported; used to indicate the modification made.
    optional int32 event_id = 1;

    // The channel type of the bundle (e.g., TYPE_NEWS).
    optional int32 type = 2;

    // Whether the full contents of this bundle have ever been shown to the user.
    optional bool contents_shown = 3;
}

/**
 * Reports that a camera compatibility status has changed.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/wm/CameraStateMonitor.java
 * Estimated Logging Rate:
 *   Peak: 10 times per device per day. | Avg: 1 time per device per day.
 *
 */
message CameraStatusForCompatibilityChanged {
    // The freeform camera compatibility mode the activity is in at the time the
    // camera opened or closed signal is received.
    optional android.framework.compat.FreeformCameraCompatMode freeform_camera_compat_mode_state = 1;

    // Whether this state is logged on camera opened or closed.
    optional android.framework.compat.CameraState camera_state = 2;

    // The latency of the camera compat mode setup - from the time the camera
    // opened signal was received for the first time, to the time the camera
    // compat mode was set up, camera restarted, and the camera opened signal
    // was received again.
    optional int32 latency_ms = 3;
}

/**
 * Reports that an activity has been launched from the PROCESS_TEXT activity
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
 * Estimated Logging Rate:
 *   Peak: 25 times per device per day | Avg: Between 0 and 1 times per device per day
 */
message ProcessTextActionLaunchedReported {
    // The uid of the app that is calling the PROCESS_TEXT action.
    optional int32 calling_uid = 1 [(is_uid) = true];

    // The uid of the app that is launched.
    optional int32 launched_uid = 2 [(is_uid) = true];
}

/**
 * Logs the bitmap memory usage in system_server of a bound widget.
 *
 * Logged from:
 *   frameworks/base/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
 */
message WidgetMemoryStats {
    // The uid of the app that provides this widget.
    optional int32 uid = 1 [(is_uid) = true];

    // The app widget ID. Used to disambiguate multiple widgets from the same provider.
    optional int32 app_widget_id = 2;

    // The bitmap memory usage in bytes.
    optional int64 bitmap_memory_bytes = 3;
}


/**
 * Reports that the Advanced Protection setting has changed.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
 * Estimated Logging Rate:
 *   Peak: 2 times per device per day. | Avg: 1 time per device (total)
 */
message AdvancedProtectionStateChanged {
    // The new state of Advanced Protection
    optional bool enabled = 1;
    // The number of hours since the last time this atom was logged
    optional int32 hours_since_last_change = 2;
    // The last dialog shown.
    // AdvancedProtectionSupportDialogDisplayed.FeatureId
    optional android.security.advancedprotection.FeatureId last_dialog_feature_id = 3;
    // Why the last dialog was shown
    optional android.security.advancedprotection.DialogueType last_dialogue_type = 4;
    // Whether the learn more button was clicked in the last dialog shown
    optional bool last_dialog_learn_more_clicked = 5;
    optional int32 last_dialog_hours_since_enabled = 6;
}

/**
 * Reports that the Advanced Protection support dialog has been displayed.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
 * Estimated Logging Rate:
 *   Peak: 10 times per device per day. | Avg: <1 time per device per day.
 */
message AdvancedProtectionSupportDialogDisplayed {
    // The feature id of the dialog shown
    optional android.security.advancedprotection.FeatureId feature_id = 1;
    // Why the dialog was shown
    optional android.security.advancedprotection.DialogueType dialogue_type = 2;
    // Whether the learn more button was clicked in the dialog
    optional bool learn_more_clicked = 3;
    optional int32 hours_since_enabled = 4;
}

/** Pull atom for the current state of Advanced Protection.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
 * Estimated Logging Rate:
 *   Peak: 1 times per device per day. | Avg: <1 time per device per day.
*/
message AdvancedProtectionStateInfo {
    optional bool enabled = 1;
    optional int32 hours_since_last_change = 2;
}

/** Reports failures of enableUsbData signal API calls for the USB data protection feature and unexpected USB events.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/security/advancedprotection/features/UsbDataAdvancedProtectionHook.java
 * Estimated Logging Rate:
 *   Peak: <1 times per device per day. | Avg: <1 time per device per day.
 */
message AdvancedProtectionUsbStateChangeErrorReported {
    // The desired signal state of the API call. If false, then the API call failed to disable
    // USB data. If true, then the API call failed to enable USB data.
    optional bool desired_signal_state = 1;
    optional int32 retries_occurred = 2;
    optional android.security.advancedprotection.UsbErrorType error_type = 3;
}

/** Reports the type of notification displayed for USB data protection.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/security/advancedprotection/features/UsbDataAdvancedProtectionHook.java
 * Estimated Logging Rate:
 *   Peak: 25 times per device per day. | Avg: 1-3 times per device per day.
 */
message AdvancedProtectionUsbNotificationDisplayed {
    optional android.security.advancedprotection.UsbNotificationType notification_type = 1;
}

/**
 * Logged by clipboard service when the user pastes clips from the system clipboard.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/clipboard/ClipboardService.java
 * Estimated Logging Rate:
 *   Peak: 100 times per device per day. | Avg: 10 time per device per day.
 */
message ClipboardGetEventReported {
    /**
     * The types of clip data.
     *
     * Keep it in sync with frameworks/base/core/java/android/content/ClipDescription.java
     */
    enum ClipDataType {
        MIMETYPE_UNKNOWN = 0;
        MIMETYPE_TEXT_PLAIN = 1;
        MIMETYPE_TEXT_HTML = 2;
        MIMETYPE_TEXT_URILIST = 3;
        MIMETYPE_TEXT_INTENT = 4;
        MIMETYPE_APPLICATION_ACTIVITY = 5;
        MIMETYPE_APPLICATION_SHORTCUT = 6;
        MIMETYPE_APPLICATION_TASK = 7;
    }

    /**
     * The source app where this clip data comes from.
     */
    optional int32 source_uid = 1 [(is_uid) = true];

    /**
     * The target app where this clip data is pasting into.
     */
    optional int32 target_uid = 2 [(is_uid) = true];

    /**
     * The target app's process state.
     */
    optional android.app.ProcessStateEnum target_process_state = 3;

    /**
     * The types of the clip data types, it should be the combination of enum ClipDataType.
     */
    repeated ClipDataType clip_data_type = 4;

    /**
     * Time between the clip data is set and the clip data is retrieved,
     * measured in seconds, including the device asleep time.
     */
    optional int32 time_since_set_in_secs = 5;
}

/**
 * Reports that binder spam was detected.
 * Logged from:
 *   frameworks/native/libs/binder/IPCThreadState.cpp
 * Estimated Logging Rate:
 *   Peak: Every second. | Avg: 2 times per device per day.
 */
message BinderSpamReported {
    // The worksource UID if known, otherwise the calling process UID
    optional int32 client_uid = 1 [(is_uid) = true];
    optional int32 server_uid = 2 [(is_uid) = true];
    optional string aidl_interface = 3;
    optional string aidl_method = 4; // (or "#<transaction code>" if unknown)

    // New seconds of spam since last report. Intended for SUM aggregation.
    optional int32 seconds_with_at_least_125_calls = 5;
    optional int32 seconds_with_at_least_250_calls = 6;
}

/**
 * Logged the change in CDM device presence status
 * Logged from: frameworks/base/services/companion/java/com/android/server/companion/devicepresence
 */
message DevicePresenceChanged {
    enum DeviceProfile {
        DEVICE_PROFILE_UNKNOWN = 0;
        DEVICE_PROFILE_UUID = 1;
        DEVICE_PROFILE_NULL = 2;
        DEVICE_PROFILE_WATCH = 3;
        DEVICE_PROFILE_APP_STREAMING = 4;
        DEVICE_PROFILE_AUTO_PROJECTION = 5;
        DEVICE_PROFILE_COMPUTER = 6;
        DEVICE_PROFILE_GLASSES = 7;
        DEVICE_PROFILE_NEARBY_DEVICE_STREAMING = 8;
        DEVICE_PROFILE_VIRTUAL_DEVICE = 9;
        DEVICE_PROFILE_WEARABLE_SENSING = 10;
        DEVICE_PROFILE_FITNESS_TRACKER = 11;
    }

    enum DevicePresenceStatus {
        NOTIFY_UNKNOWN = 0;
        NOTIFY_BLE_APPEARED = 1;
        NOTIFY_BLE_DISAPPEARED = 2;
        NOTIFY_BT_CONNECTED = 3;
        NOTIFY_BT_DISCONNECTED = 4;
        NOTIFY_SELF_MANAGED_APPEARED = 5;
        NOTIFY_SELF_MANAGED_DISAPPEARED = 6;
    }

    // The companion app's UID.
    optional int32 uid = 1 [(is_uid) = true];
    // Name of the Companion Device Manager Association profile.
    optional DeviceProfile device_profile = 2;
    optional DevicePresenceStatus device_presence_status = 3;
}

/**
 * Logged (once per process) when the first activity is started in the process AND the last exit
 * info is available.
 *
 * Logged from: frameworks/base/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
 *
 * Estimated Logging Rate:
 *   Avg: 50 per device per day
 *   P95: 150 per device per day
 */
message AppRestartOccurred {
    // The app's uid.
    optional int32 uid = 1 [(is_uid) = true];

    enum StartType {
        UNKNOWN = 0;

        // The process was created specifically for the activity.
        COLD = 1;

        // The process was created for other reason (e.g. to handle a broadcast),
        // but this activity is the first one to be started in the process.
        WARM = 2;
    }
    optional StartType type = 2;

    optional int64 millis_since_last_exit = 3;

    // Select fields from the ApplicationExitInfo.
    optional android.app.AppExitReasonCode last_exit_reason = 4;
    optional android.app.AppExitSubReasonCode last_exit_sub_reason = 5;
    optional android.app.Importance last_exit_importance = 6;
}

/**
 * [Pushed Atom] Logs implicit URI permission grant events.
 *
 * Logged from: frameworks/base/core/java/android/content/Intent.java
 */
message ImplicitUriGrantEventReported {
    enum GrantType {
        GRANT_TYPE_UNKNOWN = 0;
        GRANTED = 1;
        RESTRICTED = 2;
    }

    enum AccessType {
        ACCESS_TYPE_UNKNOWN = 0;
        READ = 1;
        WRITE = 2;
    }

    enum ActionType {
        ACTION_TYPE_UNKNOWN = 0;
        SEND = 1;
        SEND_MULTIPLE = 2;
        IMAGE_CAPTURE = 3;
    }

    // Uid of the package requesting the op
    optional int32 uid = 1 [(is_uid) = true];
    optional GrantType grant_type = 2;
    optional AccessType access_type = 3;
    optional ActionType action_type = 4;
}

/**
 * Reports that binder calls were received.
 * Logged from:
 *   frameworks/native/libs/binder/IPCThreadState.cpp
 * Estimated Logging Rate:
 *   Peak: 100 times per second. | Avg: every second.
 */
message BinderCallsReported {
    // The worksource UID if known, otherwise the calling process UID
    optional int32 client_uid = 1 [(is_uid) = true];
    optional int32 server_uid = 2 [(is_uid) = true];
    optional string aidl_interface = 3;
    optional string aidl_method = 4; // (or "#<transaction code>" if unknown)

    // The number of calls received since last report.
    optional int64 call_count = 5;

    // The total duration for executing the calls since last report.
    optional int64 call_duration_sum_micros = 6;

    // Duration stats for low-rate spam. These are not necessarily excessive,
    // so they are part of the general stats rather than spam.
    // Unlike the fields in BinderSpamReported, these field are only reported
    // for the AIDL targets for which we collect call stats.
    optional int32 seconds_with_at_least_10_calls = 7;
    optional int32 seconds_with_at_least_50_calls = 8;
}

/**
 * Reports that one time permission session has completed.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
 */
message PermissionOneTimeSessionEventReported {
    optional int32 uid = 1 [(is_uid) = true];
    // The permission names that were granted as "only this time" in this session.
    repeated string permission_names = 2;
    // The duration of the session in milliseconds.
    optional int64 duration_millis= 3;
}


/**
 * Aggregated app ops data per package and attribution tag.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/appop/AppOpHistoryHelper.java
 */
message AggregatedAppOpAccessEventReported {
    optional string package_name = 1;
    // The attribution tag from the app, defined in the app's manifest.
    optional string attribution_tag = 2;
    optional android.app.AppOpEnum op = 3 [default = APP_OP_NONE];
    optional int64 foreground_accessed_count = 4;
    optional int64 background_accessed_count = 5;
    optional int64 foreground_rejected_count = 6;
    optional int64 background_rejected_count = 7;
    optional int64 foreground_duration_millis = 8;
    optional int64 background_duration_millis = 9;
}

/**
 * Logs events reported for the Display Compat restart menu of an app.
 *
 * Logged from:
 *   frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
 *   frameworks/base/services/core/java/com/android/server/wm/AppCompatDisplayCompatModePolicy.java
 */
message DisplayCompatRestartMenuEventReported {
  // UID of the package that has the button.
  optional int32 uid = 1 [(is_uid) = true];

  // The event that was reported.
  optional android.framework.compat.RestartMenuEvent event = 2;
}

/**
 * Reports bytes transferred via ethernet by UID. Each pull produces atoms that record stats of
 * all processes that used ethernet data since device boot.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
 */
message EthernetBytesTransfer {
    // The UID of the app using network bytes. Isolated UIDs are dropped in StatsPullAtomService,
    // and we do not record data usage for them. Isolated UIDs are frequently recycled, and we can't
    // accurately attribute the data usage to a source.
    optional int32 uid = 1 [(is_uid) = true];

    // Network tag for the data transmitted - see TrafficStats#getAndSetThreadStatsTag for more
    // details regarding network tags.
    optional int32 tag = 2;

    // Was the data usage logged here transmitted via a metered network?
    optional bool is_metered = 3;

    // Was the data used from a process running in foreground of background?
    optional bool is_foreground = 4;

    optional int64 rx_bytes = 5;

    optional int64 rx_packets = 6;

    optional int64 tx_bytes = 7;

    optional int64 tx_packets = 8;
}

/**
 * Reports bytes transferred via satellite by UID. Each pull produces atoms that record stats of
 * all processes that used satellite data since device boot.
 * Logged from:
 *   frameworks/base/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
 */
message SatelliteBytesTransfer {
    // The UID of the app using network bytes. Isolated UIDs are dropped in StatsPullAtomService,
    // and we do not record data usage for them. Isolated UIDs are frequently recycled, and we can't
    // accurately attribute the data usage to a source.
    optional int32 uid = 1 [(is_uid) = true];

    // Network tag for the data transmitted - see TrafficStats#getAndSetThreadStatsTag for more
    // details regarding network tags.
    optional int32 tag = 2;

    // Was the data usage logged here transmitted via a metered network?
    optional bool is_metered = 3;

    // Was the data used from a process running in foreground of background?
    optional bool is_foreground = 4;

    optional int64 rx_bytes = 5;

    optional int64 rx_packets = 6;

    optional int64 tx_bytes = 7;

    optional int64 tx_packets = 8;
}

/**
 * Atom for a custom vibration pattern has saved or played by a ringtone or a notification.
 * Estimated logging rate:
 *   The event collected when the user saved a new selected custom vibration pattern from system
 *   settings, or when a user receives calls/texts, or other notifications play the selected
 *   custom vibration pattern. Roughly it could be up to ~200 atoms / day.
 */
message CustomVibrationPatternReported {
  optional EventType event_type = 1;
  /** The ringtone type defined in RingtoneManager#TYPE_*/
  optional int32 ringtone_type = 2;
  /** The ID of the vibration pattern */
  optional int32 pattern_id = 3;
  /** The current ringer mode from AudioManager */
  optional int32 current_ringer_mode = 4;
  /**
   * Whether the vibration pattern is from the ringtone contains audio-coupled haptics channels.
   * See RingtoneManager#hasHapticChannels, if true means the rhythm of the pattern is synchronized
   * with the audio channel.
   */
  optional bool is_audio_coupled_haptics = 5;

  enum EventType {
    UNKNOWN = 0;
    VIBRATION_PATTERN_SAVED = 1;
    VIBRATION_PATTERN_PLAYED = 2;
  }
}

/*
 * Logs the interaction with widgets managed by AppWidgetService.
 * Estimated Logging Rate: 24 per device per day
 * Logged from:
 *   frameworks/base/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
 */
message WidgetInteractionEvent {
    // The uid of the app that hosts this widget.
    optional int32 host_uid = 1 [(is_uid) = true];

    // The ComponentName of the AppWidgetProvider. Allows us to identify what type of widget this
    // interaction came from.
    optional string provider = 2;

    // The start of the time range that this event represents in epoch milliseconds.
    optional int64 start_millis = 3;

    // The end of the time range that this event represents in epoch milliseconds.
    optional int64 end_millis = 4;

    // The duration that the widget was visible within the range of time that this event represents.
    optional int64 visible_duration_millis = 5;

    // The global coordinates of the widget at the end of the event time range.
    optional int32 rect_left = 6;
    optional int32 rect_top = 7;
    optional int32 rect_right = 8;
    optional int32 rect_bottom = 9;
}
