• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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