diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2017-11-14 20:25:09 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-11-14 20:25:09 +0000 |
| commit | 341775bfefdbe24821dd80a4d5ea4b976f1bf051 (patch) | |
| tree | 921c14a5e5e3608b2122c44a921e45a87556f766 /core/java/android | |
| parent | fa361abde85b2bf6225f89d16e0cd9c2ca7a8a18 (diff) | |
| parent | adaf8b344e312853530e276ceff05783133ecf17 (diff) | |
Merge "Adds client API for interacting with statsd."
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/SystemServiceRegistry.java | 8 | ||||
| -rw-r--r-- | core/java/android/content/Context.java | 7 | ||||
| -rw-r--r-- | core/java/android/os/IStatsCompanionService.aidl | 3 | ||||
| -rw-r--r-- | core/java/android/os/IStatsManager.aidl | 23 | ||||
| -rw-r--r-- | core/java/android/util/StatsManager.java | 134 |
5 files changed, 170 insertions, 5 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index d813d666746b..e48946f2c3e4 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -137,6 +137,7 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.euicc.EuiccManager; import android.util.Log; +import android.util.StatsManager; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.WindowManager; @@ -452,6 +453,13 @@ final class SystemServiceRegistry { ctx.mMainThread.getHandler().getLooper()); }}); + registerService(Context.STATS_MANAGER, StatsManager.class, + new StaticServiceFetcher<StatsManager>() { + @Override + public StatsManager createService() throws ServiceNotFoundException { + return new StatsManager(); + }}); + registerService(Context.STATUS_BAR_SERVICE, StatusBarManager.class, new CachedServiceFetcher<StatusBarManager>() { @Override diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 72f75112c560..19e24ad58ab4 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4044,6 +4044,13 @@ public abstract class Context { public static final String STATS_COMPANION_SERVICE = "statscompanion"; /** + * Use with {@link #getSystemService} to retrieve an {@link android.stats.StatsManager}. + * @hide + */ + @SystemApi + public static final String STATS_MANAGER = "stats"; + + /** * Use with {@link #getSystemService} to retrieve a {@link * android.content.om.OverlayManager} for managing overlay packages. * diff --git a/core/java/android/os/IStatsCompanionService.aidl b/core/java/android/os/IStatsCompanionService.aidl index c0a95cc08dec..3314f604f940 100644 --- a/core/java/android/os/IStatsCompanionService.aidl +++ b/core/java/android/os/IStatsCompanionService.aidl @@ -53,4 +53,7 @@ interface IStatsCompanionService { /** Pull the specified data. Results will be sent to statsd when complete. */ StatsLogEventWrapper[] pullData(int pullCode); + + /** Send a broadcast to the specified pkg and class that it should getData now. */ + oneway void sendBroadcast(String pkg, String cls); } diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl index 480296c12e50..a6c3009acba2 100644 --- a/core/java/android/os/IStatsManager.aidl +++ b/core/java/android/os/IStatsManager.aidl @@ -65,13 +65,26 @@ interface IStatsManager { oneway void informOnePackageRemoved(in String app, in int uid); /** - * Trigger pushLog to force push stats log entries from statsd on client side. + * Fetches data for the specified configuration key. Returns a byte array representing proto + * wire-encoded of ConfigMetricsReport. */ - void requestPush(); + byte[] getData(in String key); /** - * Listen to statsd to send stats log entries. - * TODO: Limit callbacks with specific configurations. + * Sets a configuration with the specified config key and subscribes to updates for this + * configuration key. Broadcasts will be sent if this configuration needs to be collected. + * The configuration must be a wire-encoded StatsDConfig. The caller specifies the name of the + * package and class that should receive these broadcasts. + * + * Returns if this configuration was correctly registered. */ - void subscribeStatsLog(IStatsCallbacks callbacks); + boolean addConfiguration(in String configKey, in byte[] config, in String pkg, in String cls); + + /** + * Removes the configuration with the matching config key. No-op if this config key does not + * exist. + * + * Returns if this configuration key was removed. + */ + boolean removeConfiguration(in String configKey); } diff --git a/core/java/android/util/StatsManager.java b/core/java/android/util/StatsManager.java new file mode 100644 index 000000000000..55b33a617a60 --- /dev/null +++ b/core/java/android/util/StatsManager.java @@ -0,0 +1,134 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.util; + +import android.Manifest; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.os.IBinder; +import android.os.IStatsManager; +import android.os.RemoteException; +import android.os.ServiceManager; + +/** + * API for StatsD clients to send configurations and retrieve data. + * + * @hide + */ +@SystemApi +public final class StatsManager { + IStatsManager mService; + private static final String TAG = "StatsManager"; + + /** + * Constructor for StatsManagerClient. + * + * @hide + */ + public StatsManager() { + } + + /** + * Clients can send a configuration and simultaneously registers the name of a broadcast + * receiver that listens for when it should request data. + * + * @param configKey An arbitrary string that allows clients to track the configuration. + * @param config Wire-encoded StatsDConfig proto that specifies metrics (and all + * dependencies eg, conditions and matchers). + * @param pkg The package name to receive the broadcast. + * @param cls The name of the class that receives the broadcast. + * @return true if successful + */ + @RequiresPermission(Manifest.permission.DUMP) + public boolean addConfiguration(String configKey, byte[] config, String pkg, String cls) { + synchronized (this) { + try { + IStatsManager service = getIStatsManagerLocked(); + if (service == null) { + throw new RuntimeException("StatsD service connection lost"); + } + return service.addConfiguration(configKey, config, pkg, cls); + } catch (RemoteException e) { + Slog.d(TAG, "Failed to connect to statsd when getting data"); + return false; + } + } + } + + /** + * Remove a configuration from logging. + * + * @param configKey Configuration key to remove. + * @return true if successful + */ + @RequiresPermission(Manifest.permission.DUMP) + public boolean removeConfiguration(String configKey) { + synchronized (this) { + try { + IStatsManager service = getIStatsManagerLocked(); + if (service == null) { + throw new RuntimeException("StatsD service connection lost"); + } + return service.removeConfiguration(configKey); + } catch (RemoteException e) { + Slog.d(TAG, "Failed to connect to statsd when getting data"); + return false; + } + } + } + + /** + * Clients can request data with a binder call. + * + * @param configKey Configuration key to retrieve data from. + * @return Serialized ConfigMetricsReport proto. Returns null on failure. + */ + @RequiresPermission(Manifest.permission.DUMP) + public byte[] getData(String configKey) { + synchronized (this) { + try { + IStatsManager service = getIStatsManagerLocked(); + if (service == null) { + throw new RuntimeException("StatsD service connection lost"); + } + return service.getData(configKey); + } catch (RemoteException e) { + Slog.d(TAG, "Failed to connecto statsd when getting data"); + return null; + } + } + } + + private class StatsdDeathRecipient implements IBinder.DeathRecipient { + @Override + public void binderDied() { + synchronized (this) { + mService = null; + } + } + } + + private IStatsManager getIStatsManagerLocked() throws RemoteException { + if (mService != null) { + return mService; + } + mService = IStatsManager.Stub.asInterface(ServiceManager.getService("stats")); + if (mService != null) { + mService.asBinder().linkToDeath(new StatsdDeathRecipient(), 0); + } + return mService; + } +} |
