11481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen/* 21481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Copyright (C) 2017 The Android Open Source Project 31481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * 41481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Licensed under the Apache License, Version 2.0 (the "License"); 51481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * you may not use this file except in compliance with the License. 61481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * You may obtain a copy of the License at 71481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * 81481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * http://www.apache.org/licenses/LICENSE-2.0 91481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * 101481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Unless required by applicable law or agreed to in writing, software 111481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * distributed under the License is distributed on an "AS IS" BASIS, 121481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * See the License for the specific language governing permissions and 141481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * limitations under the License. 151481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 161481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chenpackage android.os; 171481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 181481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chenimport java.io.ByteArrayOutputStream; 191481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chenimport java.nio.charset.StandardCharsets; 201481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 211481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen/** 221481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Wrapper class for sending data from Android OS to StatsD. 231481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * 241481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * @hide 251481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 261481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chenpublic final class StatsLogEventWrapper implements Parcelable { 271481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private ByteArrayOutputStream mStorage = new ByteArrayOutputStream(); 281481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 291481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen // Below are constants copied from log/log.h 301481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private static final int EVENT_TYPE_INT = 0; /* int32_t */ 311481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private static final int EVENT_TYPE_LONG = 1; /* int64_t */ 321481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private static final int EVENT_TYPE_STRING = 2; 331481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private static final int EVENT_TYPE_LIST = 3; 341481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private static final int EVENT_TYPE_FLOAT = 4; 351481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 366842a8c66f4458d2da92c75da056287fa3931637Chenjie Yu // Keep this in sync with system/core/logcat/event.logtags 376842a8c66f4458d2da92c75da056287fa3931637Chenjie Yu private static final int STATS_BUFFER_TAG_ID = 1937006964; 381481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 391481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Creates a log_event that is binary-encoded as implemented in 401481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * system/core/liblog/log_event_list.c; this allows us to use the same parsing logic in statsd 411481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * for pushed and pulled data. The write* methods must be called in the same order as their 421481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * field number. There is no checking that the correct number of write* methods is called. 431481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * We also write an END_LIST character before beginning to write to parcel, but this END_LIST 441481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * may be unnecessary. 451481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * 461481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * @param tag The integer representing the tag for this event. 471481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * @param fields The number of fields specified in this event. 481481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 49c552b35316937827531a2b7efdfb8f4fc8dba3b0Yangster-mac public StatsLogEventWrapper(long elapsedNanos, int tag, int fields) { 501481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen // Write four bytes from tag, starting with least-significant bit. 516842a8c66f4458d2da92c75da056287fa3931637Chenjie Yu // For pulled data, this tag number is not really used. We use the same tag number as 526842a8c66f4458d2da92c75da056287fa3931637Chenjie Yu // pushed ones to be consistent. 536842a8c66f4458d2da92c75da056287fa3931637Chenjie Yu write4Bytes(STATS_BUFFER_TAG_ID); 541481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_LIST); // This is required to start the log entry. 55c552b35316937827531a2b7efdfb8f4fc8dba3b0Yangster-mac mStorage.write(fields + 2); // Indicate number of elements in this list. +1 for the tag 56c552b35316937827531a2b7efdfb8f4fc8dba3b0Yangster-mac // The first element is the elapsed realtime. 57c552b35316937827531a2b7efdfb8f4fc8dba3b0Yangster-mac writeLong(elapsedNanos); 58c552b35316937827531a2b7efdfb8f4fc8dba3b0Yangster-mac // The second element is the real atom tag number 59c552b35316937827531a2b7efdfb8f4fc8dba3b0Yangster-mac writeInt(tag); 601481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 611481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 621481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 631481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Boilerplate for Parcel. 641481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 651481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public static final Parcelable.Creator<StatsLogEventWrapper> CREATOR = new 661481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen Parcelable.Creator<StatsLogEventWrapper>() { 671481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public StatsLogEventWrapper createFromParcel(Parcel in) { 681481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen return new StatsLogEventWrapper(in); 691481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 701481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 711481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public StatsLogEventWrapper[] newArray(int size) { 721481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen return new StatsLogEventWrapper[size]; 731481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 741481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen }; 751481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 761481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private void write4Bytes(int val) { 771481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(val); 781481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(val >>> 8); 791481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(val >>> 16); 801481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(val >>> 24); 811481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 821481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 831481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private void write8Bytes(long val) { 841481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes((int) (val & 0xFFFFFFFF)); // keep the lowe 32-bits 851481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes((int) (val >>> 32)); // Write the high 32-bits. 861481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 871481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 881481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 891481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Adds 32-bit integer to output. 901481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 911481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeInt(int val) { 921481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_INT); 931481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes(val); 941481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 951481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 961481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 971481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Adds 64-bit long to output. 981481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 991481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeLong(long val) { 1001481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_LONG); 1011481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write8Bytes(val); 1021481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1031481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1041481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1051481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Adds a 4-byte floating point value to output. 1061481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1071481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeFloat(float val) { 1081481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen int v = Float.floatToIntBits(val); 1091481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_FLOAT); 1101481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes(v); 1111481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1121481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1131481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1141481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Adds a string to the output. 1151481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1161481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeString(String val) { 1171481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_STRING); 1181481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes(val.length()); 1191481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen byte[] bytes = val.getBytes(StandardCharsets.UTF_8); 1201481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(bytes, 0, bytes.length); 1211481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1221481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1231481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private StatsLogEventWrapper(Parcel in) { 1241481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen readFromParcel(in); 1251481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1261481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1271481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1281481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Writes the stored fields to a byte array. Will first write a new-line character to denote 1291481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * END_LIST before writing contents to byte array. 1301481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1311481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeToParcel(Parcel out, int flags) { 1321481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(10); // new-line character is same as END_LIST 1331481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen out.writeByteArray(mStorage.toByteArray()); 1341481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1351481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1361481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1371481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Not implemented. 1381481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1391481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void readFromParcel(Parcel in) { 1401481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen // Not needed since this java class is for sending to statsd only. 1411481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1421481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1431481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1441481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Boilerplate for Parcel. 1451481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1461481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public int describeContents() { 1471481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen return 0; 1481481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1491481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen} 150