Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7604aeaf authored by Yangster-mac's avatar Yangster-mac
Browse files

Stats log api for attribution chain.

Test: all unit test passed.
Change-Id: I628d409e517f4f95c8da1d0c7fd4d514c1d9196d
parent 8cf5b695
Loading
Loading
Loading
Loading
+23 −8
Original line number Diff line number Diff line
@@ -97,19 +97,29 @@ message Atom {
        CpuTimePerUidFreqPulled cpu_time_per_uid_freq_pulled = 1010;
        WifiActivityEnergyInfoPulled wifi_activity_energy_info_pulled = 1011;
        ModemActivityInfoPulled modem_activity_info_pulled = 1012;
        AttributionChainDummyAtom attribution_chain_dummy_atom = 10000;
    }
}

/**
 * A WorkSource represents the chained attribution of applications that
 * An attribution represents an application or module that is part of process where a particular bit
 * of work is done.
 */
message Attribution {
    // The uid for an application or module.
    optional int32 uid = 1;
    // The string tag for the attribution node.
    optional string tag = 2;
}

/**
 * An attribution chain represents the chained attributions of applications or modules that
 * resulted in a particular bit of work being done.
 * The ordering of the attributions is that of calls, that is uid = [A, B, C] if A calls B that
 * calls C.
 */
message WorkSource {
    // The uid for a given element in the attribution chain.
    repeated int32 uid = 1;
    // The (optional) string tag for an element in the attribution chain. If the
    // element has no tag, it is encoded as an empty string.
    repeated string tag = 2;
message AttributionChain {
    repeated Attribution attribution = 1;
}

/*
@@ -127,7 +137,7 @@ message WorkSource {
 *   - The CamelCase name of the message type should match the
 *     underscore_separated name as defined in Atom.
 *   - If an atom represents work that can be attributed to an app, there can
 *     be exactly one WorkSource field. It must be field number 1.
 *     be exactly one AttributionChain field. It must be field number 1.
 *   - A field that is a uid should be a string field, tagged with the [xxx]
 *     annotation. The generated code on android will be represented by UIDs,
 *     and those UIDs will be translated in xxx to those strings.
@@ -138,6 +148,11 @@ message WorkSource {
 * *****************************************************************************
 */

message AttributionChainDummyAtom {
    optional AttributionChain attribution_chain = 1;
    optional int32 value = 2;
}

/**
 * Logs when the screen state changes.
 *
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ cc_library_shared {
    cflags: [
        "-Wall",
        "-Werror",
        "-fexceptions",
    ],
    export_generated_headers: ["statslog.h"],
    shared_libs: [
+143 −127
Original line number Diff line number Diff line
@@ -111,8 +111,9 @@ java_type(const FieldDescriptor* field)
            return JAVA_TYPE_UNKNOWN;
        case FieldDescriptor::TYPE_MESSAGE:
            // TODO: not the final package name
            if (field->message_type()->full_name() == "android.os.statsd.WorkSource") {
                return JAVA_TYPE_WORK_SOURCE;
            if (field->message_type()->full_name() ==
                "android.os.statsd.AttributionChain") {
              return JAVA_TYPE_ATTRIBUTION_CHAIN;
            } else {
                return JAVA_TYPE_OBJECT;
            }
@@ -136,33 +137,14 @@ java_type(const FieldDescriptor* field)
}

/**
 * Gather the info about the atoms.
 * Gather the info about an atom proto.
 */
int
collate_atoms(const Descriptor* descriptor, Atoms* atoms)
{
    int errorCount = 0;
    const bool dbg = false;

    for (int i=0; i<descriptor->field_count(); i++) {
        const FieldDescriptor* atomField = descriptor->field(i);
int collate_atom(const Descriptor *atom, AtomDecl *atomDecl,
                 vector<java_type_t> *signature) {

        if (dbg) {
            printf("   %s (%d)\n", atomField->name().c_str(), atomField->number());
        }

        // StatsEvent only has one oneof, which contains only messages. Don't allow other types.
        if (atomField->type() != FieldDescriptor::TYPE_MESSAGE) {
            print_error(atomField,
                    "Bad type for atom. StatsEvent can only have message type fields: %s\n",
                    atomField->name().c_str());
            errorCount++;
            continue;
        }

        const Descriptor* atom = atomField->message_type();

        // Build a sorted list of the fields. Descriptor has them in source file order.
  int errorCount = 0;
  // Build a sorted list of the fields. Descriptor has them in source file
  // order.
  map<int, const FieldDescriptor *> fields;
  for (int j = 0; j < atom->field_count(); j++) {
    const FieldDescriptor *field = atom->field(j);
@@ -176,7 +158,8 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms)
    const int number = it->first;
    const FieldDescriptor *field = it->second;
    if (number != expectedNumber) {
                print_error(field, "Fields must be numbered consecutively starting at 1:"
      print_error(field,
                  "Fields must be numbered consecutively starting at 1:"
                  " '%s' is %d but should be %d\n",
                  field->name().c_str(), number, expectedNumber);
      errorCount++;
@@ -198,7 +181,7 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms)
      errorCount++;
      continue;
    } else if (javaType == JAVA_TYPE_OBJECT) {
                // Allow WorkSources, but only at position 1.
      // Allow attribution chain, but only at position 1.
      print_error(field, "Message type not allowed for field: %s\n",
                  field->name().c_str());
      errorCount++;
@@ -211,25 +194,24 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms)
    }
  }

        // Check that if there's a WorkSource, it's at position 1.
  // Check that if there's an attribution chain, it's at position 1.
  for (map<int, const FieldDescriptor *>::const_iterator it = fields.begin();
       it != fields.end(); it++) {
    int number = it->first;
    if (number != 1) {
      const FieldDescriptor *field = it->second;
      java_type_t javaType = java_type(field);
                if (javaType == JAVA_TYPE_WORK_SOURCE) {
                    print_error(field, "WorkSource fields must have field id 1, in message: '%s'\n",
      if (javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
        print_error(
            field,
            "AttributionChain fields must have field id 1, in message: '%s'\n",
            atom->name().c_str());
        errorCount++;
      }
    }
  }

        AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());

  // Build the type signature and the atom data.
        vector<java_type_t> signature;
  for (map<int, const FieldDescriptor *>::const_iterator it = fields.begin();
       it != fields.end(); it++) {
    const FieldDescriptor *field = it->second;
@@ -238,28 +220,62 @@ collate_atoms(const Descriptor* descriptor, Atoms* atoms)
    AtomField atField(field->name(), javaType);
    if (javaType == JAVA_TYPE_ENUM) {
      // All enums are treated as ints when it comes to function signatures.
                signature.push_back(JAVA_TYPE_INT);
      signature->push_back(JAVA_TYPE_INT);
      const EnumDescriptor *enumDescriptor = field->enum_type();
      for (int i = 0; i < enumDescriptor->value_count(); i++) {
        atField.enumValues[enumDescriptor->value(i)->number()] =
            enumDescriptor->value(i)->name().c_str();
      }
    } else {
                signature.push_back(javaType);
      signature->push_back(javaType);
    }
    atomDecl->fields.push_back(atField);
  }
            atomDecl.fields.push_back(atField);

  return errorCount;
}

/**
 * Gather the info about the atoms.
 */
int collate_atoms(const Descriptor *descriptor, Atoms *atoms) {
  int errorCount = 0;
  const bool dbg = false;

  for (int i = 0; i < descriptor->field_count(); i++) {
    const FieldDescriptor *atomField = descriptor->field(i);

    if (dbg) {
      printf("   %s (%d)\n", atomField->name().c_str(), atomField->number());
    }

    // StatsEvent only has one oneof, which contains only messages. Don't allow
    // other types.
    if (atomField->type() != FieldDescriptor::TYPE_MESSAGE) {
      print_error(atomField,
                  "Bad type for atom. StatsEvent can only have message type "
                  "fields: %s\n",
                  atomField->name().c_str());
      errorCount++;
      continue;
    }

    const Descriptor *atom = atomField->message_type();
    AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());
    vector<java_type_t> signature;
    errorCount += collate_atom(atom, &atomDecl, &signature);
    atoms->signatures.insert(signature);
    atoms->decls.insert(atomDecl);
  }

  if (dbg) {
    printf("signatures = [\n");
        for (set<vector<java_type_t>>::const_iterator it = atoms->signatures.begin();
    for (set<vector<java_type_t>>::const_iterator it =
             atoms->signatures.begin();
         it != atoms->signatures.end(); it++) {
      printf("   ");
            for (vector<java_type_t>::const_iterator jt = it->begin(); jt != it->end(); jt++) {
      for (vector<java_type_t>::const_iterator jt = it->begin();
           jt != it->end(); jt++) {
        printf(" %d", (int)*jt);
      }
      printf("\n");
+16 −15
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ using google::protobuf::Descriptor;
typedef enum {
  JAVA_TYPE_UNKNOWN = 0,

    JAVA_TYPE_WORK_SOURCE = 1,
  JAVA_TYPE_ATTRIBUTION_CHAIN = 1,
  JAVA_TYPE_BOOLEAN = 2,
  JAVA_TYPE_INT = 3,
  JAVA_TYPE_LONG = 4,
@@ -52,7 +52,6 @@ typedef enum {
  JAVA_TYPE_BYTE_ARRAY = -2,
} java_type_t;


/**
 * The name and type for an atom field.
 */
@@ -100,6 +99,8 @@ struct Atoms {
 * Gather the information about the atoms.  Returns the number of errors.
 */
int collate_atoms(const Descriptor* descriptor, Atoms* atoms);
int collate_atom(const Descriptor *atom, AtomDecl *atomDecl,
                 vector<java_type_t> *signature);

}  // namespace stats_log_api_gen
}  // namespace android
+246 −61

File changed.

Preview size limit exceeded, changes collapsed.

Loading