Loading cmds/statsd/src/StatsService.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -988,6 +988,15 @@ Status StatsService::unsetBroadcastSubscriber(int64_t configId, return Status::ok(); } Status StatsService::sendAppBreadcrumbAtom(int32_t label, int32_t state) { // Permission check not necessary as it's meant for applications to write to // statsd. android::util::stats_write(util::APP_BREADCRUMB_REPORTED, IPCThreadState::self()->getCallingUid(), label, state); return Status::ok(); } void StatsService::binderDied(const wp <IBinder>& who) { ALOGW("statscompanion service died"); StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec()); Loading cmds/statsd/src/StatsService.h +5 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,11 @@ public: /** Inform statsCompanion that statsd is ready. */ virtual void sayHiToStatsCompanion(); /** * Binder call to get AppBreadcrumbReported atom. */ virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override; /** IBinder::DeathRecipient */ virtual void binderDied(const wp<IBinder>& who) override; Loading cmds/statsd/src/metrics/MetricsManager.cpp +0 −10 Original line number Diff line number Diff line Loading @@ -247,16 +247,6 @@ void MetricsManager::onLogEvent(const LogEvent& event) { return; } // Label is 2nd from last field and must be from [0, 15]. long appHookLabel = event.GetLong(event.size()-1, &err); if (err != NO_ERROR ) { VLOG("APP_BREADCRUMB_REPORTED had error when parsing the label field"); return; } else if (appHookLabel < 0 || appHookLabel > 15) { VLOG("APP_BREADCRUMB_REPORTED does not have valid label %ld", appHookLabel); return; } // The state must be from 0,3. This part of code must be manually updated. long appHookState = event.GetLong(event.size(), &err); if (err != NO_ERROR ) { Loading core/java/android/os/IStatsManager.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -152,4 +152,10 @@ interface IStatsManager { * Requires Manifest.permission.DUMP. */ void unsetBroadcastSubscriber(long configKey, long subscriberId, in String packageName); /** * Apps can send an atom via this application breadcrumb with the specified label and state for * this label. This allows building custom metrics and predicates. */ void sendAppBreadcrumbAtom(int label, int state); } core/java/android/util/StatsLog.java +62 −20 Original line number Diff line number Diff line Loading @@ -16,59 +16,101 @@ package android.util; import android.os.Process; import android.os.IStatsManager; import android.os.RemoteException; import android.os.ServiceManager; /** * StatsLog provides an API for developers to send events to statsd. The events can be used to * define custom metrics inside statsd. */ public final class StatsLog extends StatsLogInternal { private static final String TAG = "StatsManager"; private static final String TAG = "StatsLog"; private static final boolean DEBUG = false; private static IStatsManager sService; private StatsLog() {} /** * Logs a start event. * * @param label developer-chosen label that is from [0, 16). * @param label developer-chosen label. * @return True if the log request was sent to statsd. */ public static boolean logStart(int label) { if (label >= 0 && label < 16) { StatsLog.write(APP_BREADCRUMB_REPORTED, Process.myUid(), label, APP_BREADCRUMB_REPORTED__STATE__START); return true; synchronized (StatsLog.class) { try { IStatsManager service = getIStatsManagerLocked(); if (service == null) { if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging start"); return false; } service.sendAppBreadcrumbAtom(label, StatsLog.APP_BREADCRUMB_REPORTED__STATE__START); return true; } catch (RemoteException e) { sService = null; if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging start"); return false; } } } /** * Logs a stop event. * * @param label developer-chosen label that is from [0, 16). * @param label developer-chosen label. * @return True if the log request was sent to statsd. */ public static boolean logStop(int label) { if (label >= 0 && label < 16) { StatsLog.write(APP_BREADCRUMB_REPORTED, Process.myUid(), label, APP_BREADCRUMB_REPORTED__STATE__STOP); return true; synchronized (StatsLog.class) { try { IStatsManager service = getIStatsManagerLocked(); if (service == null) { if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging stop"); return false; } service.sendAppBreadcrumbAtom(label, StatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP); return true; } catch (RemoteException e) { sService = null; if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging stop"); return false; } } } /** * Logs an event that does not represent a start or stop boundary. * * @param label developer-chosen label that is from [0, 16). * @param label developer-chosen label. * @return True if the log request was sent to statsd. */ public static boolean logEvent(int label) { if (label >= 0 && label < 16) { StatsLog.write(APP_BREADCRUMB_REPORTED, Process.myUid(), label, APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED); return true; synchronized (StatsLog.class) { try { IStatsManager service = getIStatsManagerLocked(); if (service == null) { if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging event"); return false; } service.sendAppBreadcrumbAtom( label, StatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED); return true; } catch (RemoteException e) { sService = null; if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging event"); return false; } } } private static IStatsManager getIStatsManagerLocked() throws RemoteException { if (sService != null) { return sService; } sService = IStatsManager.Stub.asInterface(ServiceManager.getService("stats")); return sService; } } Loading
cmds/statsd/src/StatsService.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -988,6 +988,15 @@ Status StatsService::unsetBroadcastSubscriber(int64_t configId, return Status::ok(); } Status StatsService::sendAppBreadcrumbAtom(int32_t label, int32_t state) { // Permission check not necessary as it's meant for applications to write to // statsd. android::util::stats_write(util::APP_BREADCRUMB_REPORTED, IPCThreadState::self()->getCallingUid(), label, state); return Status::ok(); } void StatsService::binderDied(const wp <IBinder>& who) { ALOGW("statscompanion service died"); StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec()); Loading
cmds/statsd/src/StatsService.h +5 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,11 @@ public: /** Inform statsCompanion that statsd is ready. */ virtual void sayHiToStatsCompanion(); /** * Binder call to get AppBreadcrumbReported atom. */ virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override; /** IBinder::DeathRecipient */ virtual void binderDied(const wp<IBinder>& who) override; Loading
cmds/statsd/src/metrics/MetricsManager.cpp +0 −10 Original line number Diff line number Diff line Loading @@ -247,16 +247,6 @@ void MetricsManager::onLogEvent(const LogEvent& event) { return; } // Label is 2nd from last field and must be from [0, 15]. long appHookLabel = event.GetLong(event.size()-1, &err); if (err != NO_ERROR ) { VLOG("APP_BREADCRUMB_REPORTED had error when parsing the label field"); return; } else if (appHookLabel < 0 || appHookLabel > 15) { VLOG("APP_BREADCRUMB_REPORTED does not have valid label %ld", appHookLabel); return; } // The state must be from 0,3. This part of code must be manually updated. long appHookState = event.GetLong(event.size(), &err); if (err != NO_ERROR ) { Loading
core/java/android/os/IStatsManager.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -152,4 +152,10 @@ interface IStatsManager { * Requires Manifest.permission.DUMP. */ void unsetBroadcastSubscriber(long configKey, long subscriberId, in String packageName); /** * Apps can send an atom via this application breadcrumb with the specified label and state for * this label. This allows building custom metrics and predicates. */ void sendAppBreadcrumbAtom(int label, int state); }
core/java/android/util/StatsLog.java +62 −20 Original line number Diff line number Diff line Loading @@ -16,59 +16,101 @@ package android.util; import android.os.Process; import android.os.IStatsManager; import android.os.RemoteException; import android.os.ServiceManager; /** * StatsLog provides an API for developers to send events to statsd. The events can be used to * define custom metrics inside statsd. */ public final class StatsLog extends StatsLogInternal { private static final String TAG = "StatsManager"; private static final String TAG = "StatsLog"; private static final boolean DEBUG = false; private static IStatsManager sService; private StatsLog() {} /** * Logs a start event. * * @param label developer-chosen label that is from [0, 16). * @param label developer-chosen label. * @return True if the log request was sent to statsd. */ public static boolean logStart(int label) { if (label >= 0 && label < 16) { StatsLog.write(APP_BREADCRUMB_REPORTED, Process.myUid(), label, APP_BREADCRUMB_REPORTED__STATE__START); return true; synchronized (StatsLog.class) { try { IStatsManager service = getIStatsManagerLocked(); if (service == null) { if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging start"); return false; } service.sendAppBreadcrumbAtom(label, StatsLog.APP_BREADCRUMB_REPORTED__STATE__START); return true; } catch (RemoteException e) { sService = null; if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging start"); return false; } } } /** * Logs a stop event. * * @param label developer-chosen label that is from [0, 16). * @param label developer-chosen label. * @return True if the log request was sent to statsd. */ public static boolean logStop(int label) { if (label >= 0 && label < 16) { StatsLog.write(APP_BREADCRUMB_REPORTED, Process.myUid(), label, APP_BREADCRUMB_REPORTED__STATE__STOP); return true; synchronized (StatsLog.class) { try { IStatsManager service = getIStatsManagerLocked(); if (service == null) { if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging stop"); return false; } service.sendAppBreadcrumbAtom(label, StatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP); return true; } catch (RemoteException e) { sService = null; if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging stop"); return false; } } } /** * Logs an event that does not represent a start or stop boundary. * * @param label developer-chosen label that is from [0, 16). * @param label developer-chosen label. * @return True if the log request was sent to statsd. */ public static boolean logEvent(int label) { if (label >= 0 && label < 16) { StatsLog.write(APP_BREADCRUMB_REPORTED, Process.myUid(), label, APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED); return true; synchronized (StatsLog.class) { try { IStatsManager service = getIStatsManagerLocked(); if (service == null) { if (DEBUG) Slog.d(TAG, "Failed to find statsd when logging event"); return false; } service.sendAppBreadcrumbAtom( label, StatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED); return true; } catch (RemoteException e) { sService = null; if (DEBUG) Slog.d(TAG, "Failed to connect to statsd when logging event"); return false; } } } private static IStatsManager getIStatsManagerLocked() throws RemoteException { if (sService != null) { return sService; } sService = IStatsManager.Stub.asInterface(ServiceManager.getService("stats")); return sService; } }