StatsLogEventWrapper.java revision 6842a8c66f4458d2da92c75da056287fa3931637
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 */ 491481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public StatsLogEventWrapper(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. 551481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(fields); // Indicate number of elements in this list. 566842a8c66f4458d2da92c75da056287fa3931637Chenjie Yu mStorage.write(EVENT_TYPE_INT); 576842a8c66f4458d2da92c75da056287fa3931637Chenjie Yu // The first element is the real atom tag number 586842a8c66f4458d2da92c75da056287fa3931637Chenjie Yu write4Bytes(tag); 591481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 601481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 611481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 621481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Boilerplate for Parcel. 631481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 641481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public static final Parcelable.Creator<StatsLogEventWrapper> CREATOR = new 651481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen Parcelable.Creator<StatsLogEventWrapper>() { 661481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public StatsLogEventWrapper createFromParcel(Parcel in) { 671481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen return new StatsLogEventWrapper(in); 681481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 691481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 701481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public StatsLogEventWrapper[] newArray(int size) { 711481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen return new StatsLogEventWrapper[size]; 721481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 731481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen }; 741481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 751481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private void write4Bytes(int val) { 761481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(val); 771481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(val >>> 8); 781481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(val >>> 16); 791481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(val >>> 24); 801481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 811481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 821481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private void write8Bytes(long val) { 831481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes((int) (val & 0xFFFFFFFF)); // keep the lowe 32-bits 841481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes((int) (val >>> 32)); // Write the high 32-bits. 851481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 861481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 871481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 881481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Adds 32-bit integer to output. 891481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 901481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeInt(int val) { 911481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_INT); 921481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes(val); 931481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 941481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 951481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 961481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Adds 64-bit long to output. 971481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 981481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeLong(long val) { 991481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_LONG); 1001481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write8Bytes(val); 1011481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1021481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1031481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1041481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Adds a 4-byte floating point value to output. 1051481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1061481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeFloat(float val) { 1071481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen int v = Float.floatToIntBits(val); 1081481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_FLOAT); 1091481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes(v); 1101481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1111481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1121481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1131481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Adds a string to the output. 1141481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1151481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeString(String val) { 1161481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(EVENT_TYPE_STRING); 1171481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen write4Bytes(val.length()); 1181481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen byte[] bytes = val.getBytes(StandardCharsets.UTF_8); 1191481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(bytes, 0, bytes.length); 1201481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1211481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1221481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen private StatsLogEventWrapper(Parcel in) { 1231481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen readFromParcel(in); 1241481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1251481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1261481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1271481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Writes the stored fields to a byte array. Will first write a new-line character to denote 1281481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * END_LIST before writing contents to byte array. 1291481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1301481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void writeToParcel(Parcel out, int flags) { 1311481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen mStorage.write(10); // new-line character is same as END_LIST 1321481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen out.writeByteArray(mStorage.toByteArray()); 1331481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1341481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1351481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1361481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Not implemented. 1371481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1381481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public void readFromParcel(Parcel in) { 1391481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen // Not needed since this java class is for sending to statsd only. 1401481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1411481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen 1421481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen /** 1431481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen * Boilerplate for Parcel. 1441481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen */ 1451481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen public int describeContents() { 1461481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen return 0; 1471481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen } 1481481fe142d36d5f0b36eeebc358d5a8aef7bf28aDavid Chen} 149