/*
 * Copyright (C) 2018 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;
option java_package = "com.android.os";
option java_multiple_files = true;
option java_outer_classname = "AtomFieldOptions";

import "google/protobuf/descriptor.proto";

// Used to annotate an atom that represents a state change. A state change atom must have exactly
// ONE exclusive state field, and any number of primary key fields. For example, message
// UidProcessStateChanged {
//    optional int32 uid = 1 [(state_field_option).primary_field = true];
//    optional android.app.ProcessStateEnum state =
//            2 [(state_field_option).exclusive_state = true];
//  }
// Each UidProcessStateChanged atom event represents a state change for a specific uid.
// A new state automatically overrides the previous state.
//
// If the atom has 2 or more primary fields, it means the combination of the
// primary fields are the primary key.
// For example:
// message ThreadStateChanged {
//    optional int32 pid = 1  [(state_field_option).primary_field = true];
//    optional int32 tid = 2  [(state_field_option).primary_field = true];
//    optional int32 state = 3 [(state_field_option).exclusive_state = true];
// }
//
// Sometimes, there is no primary key field, when the state is GLOBAL.
// For example,
// message ScreenStateChanged {
//    optional android.view.DisplayStateEnum state =
//          1 [(state_field_option).exclusive_state = true];
// }
//
// For state atoms with attribution chain, sometimes the primary key is the first uid in the chain.
// For example:
// message AudioStateChanged {
//   repeated AttributionNode attribution_node = 1
//       [(stateFieldOption).primary_field_first_uid = true];
//
//    enum State {
//      OFF = 0;
//      ON = 1;
//      // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes).
//      RESET = 2;
//    }
//    optional State state = 2 [(stateFieldOption).exclusive_state = true];
// }
message StateAtomFieldOption {
    // Fields that represent the key that the state belongs to.
    // Used on simple proto fields. Do not use on attribution chains.
    optional bool primary_field = 1 [default = false];

    // The field that represents the state. It's an exclusive state.
    optional bool exclusive_state = 2 [default = false];

    // Used on an attribution chain field to indicate that the first uid is the
    // primary field.
    optional bool primary_field_first_uid = 3 [default = false];

    // Note: We cannot annotate directly on the enums because many enums are imported from other
    // proto files in the platform. proto-lite cc library does not support annotations unfortunately

    // Knowing the default state value allows state trackers to remove entries that become the
    // default state. If there is no default value specified, the default value is unknown, and all
    // states will be tracked in memory.
    optional int32 default_state_value = 4;

    // A reset state signals all states go to default value. For example, BLE reset means all active
    // BLE scans are to be turned off.
    optional int32 trigger_state_reset_value = 5;

    // If the state change needs to count nesting. For example, given an exclusive_state field with
    // possible states of OFF and ON, a sequence of N OFF events will require N ON events for the
    // tracked state to change back to ON.
    // Note: only valid for fields marked with exclusive_state where there are only 2 possible
    // states.
    optional bool nested = 6 [default = false];
}

// Used to generate StatsLog.write APIs.
enum LogMode {
    MODE_UNSET = 0;
    // Log fields as their actual types e.g., all primary data types.
    // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode
    MODE_AUTOMATIC = 1;
    // Log fields in their proto binary format. These fields will not be parsed in statsd
    MODE_BYTES = 2;
}

// Used to annotate an atom as belonging to a retriction category.
enum RestrictionCategory {
    RESTRICTION_UNSET = 0;
    RESTRICTION_DIAGNOSTIC = 1;
    RESTRICTION_SYSTEM_INTELLIGENCE = 2;
    RESTRICTION_AUTHENTICATION = 3;
    RESTRICTION_FRAUD_AND_ABUSE = 4;
}

// Options for restricting fields of atoms
message FieldRestrictionOption {
    optional bool peripheral_device_info = 1;
    optional bool app_usage = 2;
    optional bool app_activity = 3;
    optional bool health_connect = 4;
    optional bool accessibility = 5;
    optional bool system_search = 6;
    optional bool user_engagement = 7;
    optional bool ambient_sensing = 8;
    optional bool demographic_classification = 9;
}

extend google.protobuf.FieldOptions {
    // Flags to decorate an atom that presents a state change.
    optional StateAtomFieldOption state_field_option = 50000;

    // Flags to decorate the uid fields in an atom.
    optional bool is_uid = 50001 [default = false];

    optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];

    repeated string module = 50004;

    optional bool truncate_timestamp = 50005 [default = false];

    optional RestrictionCategory restriction_category = 50006;

    optional FieldRestrictionOption field_restriction_option = 50007;
}