1/*
2 * Copyright (C) 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 */
16
17package android.util;
18
19import android.os.IStatsManager;
20import android.os.RemoteException;
21import android.os.ServiceManager;
22
23/**
24 * StatsLog provides an API for developers to send events to statsd. The events can be used to
25 * define custom metrics inside statsd.
26 */
27public final class StatsLog extends StatsLogInternal {
28    private static final String TAG = "StatsLog";
29    private static final boolean DEBUG = false;
30
31    private static IStatsManager sService;
32
33    private StatsLog() {}
34
35    /**
36     * Logs a start event.
37     *
38     * @param label developer-chosen label.
39     * @return True if the log request was sent to statsd.
40     */
41    public static boolean logStart(int label) {
42        synchronized (StatsLog.class) {
43            try {
44                IStatsManager service = getIStatsManagerLocked();
45                if (service == null) {
46                    if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging start");
47                    return false;
48                }
49                service.sendAppBreadcrumbAtom(label,
50                        StatsLog.APP_BREADCRUMB_REPORTED__STATE__START);
51                return true;
52            } catch (RemoteException e) {
53                sService = null;
54                if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging start");
55                return false;
56            }
57        }
58    }
59
60    /**
61     * Logs a stop event.
62     *
63     * @param label developer-chosen label.
64     * @return True if the log request was sent to statsd.
65     */
66    public static boolean logStop(int label) {
67        synchronized (StatsLog.class) {
68            try {
69                IStatsManager service = getIStatsManagerLocked();
70                if (service == null) {
71                    if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging stop");
72                    return false;
73                }
74                service.sendAppBreadcrumbAtom(label, StatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP);
75                return true;
76            } catch (RemoteException e) {
77                sService = null;
78                if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging stop");
79                return false;
80            }
81        }
82    }
83
84    /**
85     * Logs an event that does not represent a start or stop boundary.
86     *
87     * @param label developer-chosen label.
88     * @return True if the log request was sent to statsd.
89     */
90    public static boolean logEvent(int label) {
91        synchronized (StatsLog.class) {
92            try {
93                IStatsManager service = getIStatsManagerLocked();
94                if (service == null) {
95                    if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging event");
96                    return false;
97                }
98                service.sendAppBreadcrumbAtom(
99                        label, StatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED);
100                return true;
101            } catch (RemoteException e) {
102                sService = null;
103                if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging event");
104                return false;
105            }
106        }
107    }
108
109    private static IStatsManager getIStatsManagerLocked() throws RemoteException {
110        if (sService != null) {
111            return sService;
112        }
113        sService = IStatsManager.Stub.asInterface(ServiceManager.getService("stats"));
114        return sService;
115    }
116}
117