1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server.stats.bootstrap; 17 18 import android.content.Context; 19 import android.os.IStatsBootstrapAtomService; 20 import android.os.StatsBootstrapAtom; 21 import android.os.StatsBootstrapAtomValue; 22 import android.util.Slog; 23 import android.util.StatsEvent; 24 import android.util.StatsLog; 25 26 import com.android.server.SystemService; 27 28 /** 29 * Proxy service for logging pushed atoms to statsd 30 * 31 * @hide 32 */ 33 public class StatsBootstrapAtomService extends IStatsBootstrapAtomService.Stub { 34 35 private static final String TAG = "StatsBootstrapAtomService"; 36 private static final boolean DEBUG = false; 37 38 @Override reportBootstrapAtom(StatsBootstrapAtom atom)39 public void reportBootstrapAtom(StatsBootstrapAtom atom) { 40 if (atom.atomId < 1 || atom.atomId >= 10000) { 41 Slog.e(TAG, "Atom ID " + atom.atomId + " is not a valid atom ID"); 42 return; 43 } 44 StatsEvent.Builder builder = StatsEvent.newBuilder().setAtomId(atom.atomId); 45 for (StatsBootstrapAtomValue atomValue : atom.values) { 46 StatsBootstrapAtomValue.Primitive value = atomValue.value; 47 switch (value.getTag()) { 48 case StatsBootstrapAtomValue.Primitive.boolValue: 49 builder.writeBoolean(value.getBoolValue()); 50 break; 51 case StatsBootstrapAtomValue.Primitive.intValue: 52 builder.writeInt(value.getIntValue()); 53 break; 54 case StatsBootstrapAtomValue.Primitive.longValue: 55 builder.writeLong(value.getLongValue()); 56 break; 57 case StatsBootstrapAtomValue.Primitive.floatValue: 58 builder.writeFloat(value.getFloatValue()); 59 break; 60 case StatsBootstrapAtomValue.Primitive.stringValue: 61 builder.writeString(value.getStringValue()); 62 break; 63 case StatsBootstrapAtomValue.Primitive.bytesValue: 64 builder.writeByteArray(value.getBytesValue()); 65 break; 66 case StatsBootstrapAtomValue.Primitive.stringArrayValue: 67 builder.writeStringArray(value.getStringArrayValue()); 68 break; 69 default: 70 Slog.e(TAG, "Unexpected value type " + value.getTag() 71 + " when logging atom " + atom.atomId); 72 return; 73 74 } 75 StatsBootstrapAtomValue.Annotation[] annotations = atomValue.annotations; 76 for (StatsBootstrapAtomValue.Annotation annotation : atomValue.annotations) { 77 if (annotation.id != StatsBootstrapAtomValue.Annotation.Id.IS_UID) { 78 Slog.e(TAG, "Unexpected annotation ID: " + annotation.id 79 + ", for atom " + atom.atomId + ": only UIDs are supported!"); 80 return; 81 } 82 83 switch (annotation.value.getTag()) { 84 case StatsBootstrapAtomValue.Annotation.Primitive.boolValue: 85 builder.addBooleanAnnotation( 86 annotation.id, annotation.value.getBoolValue()); 87 break; 88 default: 89 Slog.e(TAG, "Unexpected value type " + annotation.value.getTag() 90 + " when logging UID for atom " + atom.atomId); 91 return; 92 } 93 } 94 } 95 StatsLog.write(builder.usePooledBuffer().build()); 96 } 97 98 /** 99 * Lifecycle and related code 100 */ 101 public static final class Lifecycle extends SystemService { 102 private StatsBootstrapAtomService mStatsBootstrapAtomService; 103 Lifecycle(Context context)104 public Lifecycle(Context context) { 105 super(context); 106 } 107 108 @Override onStart()109 public void onStart() { 110 mStatsBootstrapAtomService = new StatsBootstrapAtomService(); 111 try { 112 publishBinderService(Context.STATS_BOOTSTRAP_ATOM_SERVICE, 113 mStatsBootstrapAtomService); 114 if (DEBUG) Slog.d(TAG, "Published " + Context.STATS_BOOTSTRAP_ATOM_SERVICE); 115 } catch (Exception e) { 116 Slog.e(TAG, "Failed to publishBinderService", e); 117 } 118 } 119 } 120 121 } 122