blob: 51fb18a95c4cbbeede243b2b6d54a6bf77e7153f [file] [log] [blame]
David Chenadaf8b32017-11-03 15:42:08 -07001/*
2 * Copyright 2017 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 */
16package android.util;
17
18import android.Manifest;
19import android.annotation.RequiresPermission;
David Chenadaf8b32017-11-03 15:42:08 -070020import android.os.IBinder;
21import android.os.IStatsManager;
22import android.os.RemoteException;
23import android.os.ServiceManager;
24
Bookatzc6977972018-01-16 16:55:05 -080025
26/*
27 *
28 *
29 *
30 *
31 * THIS ENTIRE FILE IS ONLY TEMPORARY TO PREVENT BREAKAGES OF DEPENDENCIES ON OLD APIS.
32 * The new StatsManager is to be found in android.app.StatsManager.
33 * TODO: Delete this file!
34 *
35 *
36 *
37 *
38 */
39
40
David Chenadaf8b32017-11-03 15:42:08 -070041/**
42 * API for StatsD clients to send configurations and retrieve data.
43 *
44 * @hide
45 */
Bookatzc6977972018-01-16 16:55:05 -080046public class StatsManager {
David Chenadaf8b32017-11-03 15:42:08 -070047 IStatsManager mService;
48 private static final String TAG = "StatsManager";
49
50 /**
51 * Constructor for StatsManagerClient.
52 *
53 * @hide
54 */
55 public StatsManager() {
56 }
57
58 /**
David Chen5914fa02018-01-16 16:38:42 -080059 * Temporary to prevent build failures. Will be deleted.
60 */
61 @RequiresPermission(Manifest.permission.DUMP)
62 public boolean addConfiguration(String configKey, byte[] config, String pkg, String cls) {
David Chen76ce2d62018-01-31 16:38:13 -080063 synchronized (this) {
64 try {
65 IStatsManager service = getIStatsManagerLocked();
66 if (service == null) {
67 Slog.d(TAG, "Failed to find statsd when adding configuration");
68 return false;
69 }
70 return service.addConfiguration(Long.parseLong(configKey), config, pkg, cls);
71 } catch (RemoteException e) {
72 Slog.d(TAG, "Failed to connect to statsd when adding configuration");
73 return false;
74 }
75 }
David Chen5914fa02018-01-16 16:38:42 -080076 }
77
78 /**
David Chenadaf8b32017-11-03 15:42:08 -070079 * Clients can send a configuration and simultaneously registers the name of a broadcast
80 * receiver that listens for when it should request data.
81 *
Bookatzc6977972018-01-16 16:55:05 -080082 * @param configKey An arbitrary integer that allows clients to track the configuration.
David Chenadaf8b32017-11-03 15:42:08 -070083 * @param config Wire-encoded StatsDConfig proto that specifies metrics (and all
84 * dependencies eg, conditions and matchers).
85 * @param pkg The package name to receive the broadcast.
86 * @param cls The name of the class that receives the broadcast.
87 * @return true if successful
88 */
89 @RequiresPermission(Manifest.permission.DUMP)
Yangster-mac94e197c2018-01-02 16:03:03 -080090 public boolean addConfiguration(long configKey, byte[] config, String pkg, String cls) {
David Chenadaf8b32017-11-03 15:42:08 -070091 synchronized (this) {
92 try {
93 IStatsManager service = getIStatsManagerLocked();
94 if (service == null) {
David Chenc562bfb2017-11-17 17:44:33 -080095 Slog.d(TAG, "Failed to find statsd when adding configuration");
96 return false;
David Chenadaf8b32017-11-03 15:42:08 -070097 }
98 return service.addConfiguration(configKey, config, pkg, cls);
99 } catch (RemoteException e) {
David Chenc562bfb2017-11-17 17:44:33 -0800100 Slog.d(TAG, "Failed to connect to statsd when adding configuration");
David Chenadaf8b32017-11-03 15:42:08 -0700101 return false;
102 }
103 }
104 }
105
106 /**
David Chen5914fa02018-01-16 16:38:42 -0800107 * Temporary to prevent build failures. Will be deleted.
108 */
109 @RequiresPermission(Manifest.permission.DUMP)
110 public boolean removeConfiguration(String configKey) {
111 // To prevent breakages of old dependencies.
David Chen76ce2d62018-01-31 16:38:13 -0800112 synchronized (this) {
113 try {
114 IStatsManager service = getIStatsManagerLocked();
115 if (service == null) {
116 Slog.d(TAG, "Failed to find statsd when removing configuration");
117 return false;
118 }
119 return service.removeConfiguration(Long.parseLong(configKey));
120 } catch (RemoteException e) {
121 Slog.d(TAG, "Failed to connect to statsd when removing configuration");
122 return false;
123 }
124 }
David Chen5914fa02018-01-16 16:38:42 -0800125 }
126
127 /**
David Chenadaf8b32017-11-03 15:42:08 -0700128 * Remove a configuration from logging.
129 *
130 * @param configKey Configuration key to remove.
131 * @return true if successful
132 */
133 @RequiresPermission(Manifest.permission.DUMP)
Yangster-mac94e197c2018-01-02 16:03:03 -0800134 public boolean removeConfiguration(long configKey) {
David Chenadaf8b32017-11-03 15:42:08 -0700135 synchronized (this) {
136 try {
137 IStatsManager service = getIStatsManagerLocked();
138 if (service == null) {
David Chenc562bfb2017-11-17 17:44:33 -0800139 Slog.d(TAG, "Failed to find statsd when removing configuration");
140 return false;
David Chenadaf8b32017-11-03 15:42:08 -0700141 }
142 return service.removeConfiguration(configKey);
143 } catch (RemoteException e) {
David Chenc562bfb2017-11-17 17:44:33 -0800144 Slog.d(TAG, "Failed to connect to statsd when removing configuration");
David Chenadaf8b32017-11-03 15:42:08 -0700145 return false;
146 }
147 }
148 }
149
150 /**
David Chen5914fa02018-01-16 16:38:42 -0800151 * Temporary to prevent build failures. Will be deleted.
152 */
153 @RequiresPermission(Manifest.permission.DUMP)
154 public byte[] getData(String configKey) {
155 // TODO: remove this and all other methods with String-based config keys.
156 // To prevent build breakages of dependencies.
David Chen76ce2d62018-01-31 16:38:13 -0800157 synchronized (this) {
158 try {
159 IStatsManager service = getIStatsManagerLocked();
160 if (service == null) {
161 Slog.d(TAG, "Failed to find statsd when getting data");
162 return null;
163 }
164 return service.getData(Long.parseLong(configKey));
165 } catch (RemoteException e) {
166 Slog.d(TAG, "Failed to connecto statsd when getting data");
167 return null;
168 }
169 }
David Chen5914fa02018-01-16 16:38:42 -0800170 }
171
172 /**
David Chen2e8f3802017-11-22 10:56:48 -0800173 * Clients can request data with a binder call. This getter is destructive and also clears
174 * the retrieved metrics from statsd memory.
David Chenadaf8b32017-11-03 15:42:08 -0700175 *
176 * @param configKey Configuration key to retrieve data from.
David Chen2e8f3802017-11-22 10:56:48 -0800177 * @return Serialized ConfigMetricsReportList proto. Returns null on failure.
David Chenadaf8b32017-11-03 15:42:08 -0700178 */
179 @RequiresPermission(Manifest.permission.DUMP)
Yangster-mac94e197c2018-01-02 16:03:03 -0800180 public byte[] getData(long configKey) {
David Chenadaf8b32017-11-03 15:42:08 -0700181 synchronized (this) {
182 try {
183 IStatsManager service = getIStatsManagerLocked();
184 if (service == null) {
David Chenc562bfb2017-11-17 17:44:33 -0800185 Slog.d(TAG, "Failed to find statsd when getting data");
186 return null;
David Chenadaf8b32017-11-03 15:42:08 -0700187 }
188 return service.getData(configKey);
189 } catch (RemoteException e) {
190 Slog.d(TAG, "Failed to connecto statsd when getting data");
191 return null;
192 }
193 }
194 }
195
David Chen2e8f3802017-11-22 10:56:48 -0800196 /**
197 * Clients can request metadata for statsd. Will contain stats across all configurations but not
198 * the actual metrics themselves (metrics must be collected via {@link #getData(String)}.
199 * This getter is not destructive and will not reset any metrics/counters.
200 *
201 * @return Serialized StatsdStatsReport proto. Returns null on failure.
202 */
203 @RequiresPermission(Manifest.permission.DUMP)
204 public byte[] getMetadata() {
205 synchronized (this) {
206 try {
207 IStatsManager service = getIStatsManagerLocked();
208 if (service == null) {
209 Slog.d(TAG, "Failed to find statsd when getting metadata");
210 return null;
211 }
212 return service.getMetadata();
213 } catch (RemoteException e) {
214 Slog.d(TAG, "Failed to connecto statsd when getting metadata");
215 return null;
216 }
217 }
218 }
219
David Chenadaf8b32017-11-03 15:42:08 -0700220 private class StatsdDeathRecipient implements IBinder.DeathRecipient {
221 @Override
222 public void binderDied() {
223 synchronized (this) {
224 mService = null;
225 }
226 }
227 }
228
229 private IStatsManager getIStatsManagerLocked() throws RemoteException {
230 if (mService != null) {
231 return mService;
232 }
233 mService = IStatsManager.Stub.asInterface(ServiceManager.getService("stats"));
234 if (mService != null) {
235 mService.asBinder().linkToDeath(new StatsdDeathRecipient(), 0);
236 }
237 return mService;
238 }
239}