summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/StatsManager.java96
-rw-r--r--core/java/android/os/IPullAtomCallback.aidl31
-rw-r--r--core/java/android/os/IPullAtomResultReceiver.aidl32
-rw-r--r--core/java/android/os/IStatsCompanionService.aidl5
-rw-r--r--core/java/android/os/IStatsManager.aidl9
-rw-r--r--core/java/android/os/IStatsPullerCallback.aidl1
-rw-r--r--core/java/android/util/StatsEvent.aidl19
-rw-r--r--core/java/android/util/StatsEvent.java39
8 files changed, 231 insertions, 1 deletions
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index e6682d620b99..92bfee24d402 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -24,12 +24,22 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
import android.os.IBinder;
+import android.os.IPullAtomCallback;
+import android.os.IPullAtomResultReceiver;
+import android.os.IStatsCompanionService;
import android.os.IStatsManager;
import android.os.IStatsPullerCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.AndroidException;
import android.util.Slog;
+import android.util.StatsEvent;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
/**
* API for statsd clients to send configurations and retrieve data.
@@ -43,8 +53,12 @@ public final class StatsManager {
private final Context mContext;
+ @GuardedBy("this")
private IStatsManager mService;
+ @GuardedBy("this")
+ private IStatsCompanionService mStatsCompanion;
+
/**
* Long extra of uid that added the relevant stats config.
*/
@@ -449,7 +463,9 @@ public final class StatsManager {
* @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
*
* @hide
+ * @deprecated Please use registerPullAtomCallback
*/
+ @Deprecated
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public void setPullerCallback(int atomTag, IStatsPullerCallback callback)
throws StatsUnavailableException {
@@ -472,6 +488,75 @@ public final class StatsManager {
}
}
+
+ /**
+ * Registers a callback for an atom when that atom is to be pulled. The stats service will
+ * invoke pullData in the callback when the stats service determines that this atom needs to be
+ * pulled.
+ *
+ * @param atomTag The tag of the atom for this puller callback.
+ * @param coolDownNs The minimum time between successive pulls. A cache of the previous
+ * pull will be used if the time between pulls is less than coolDownNs.
+ * @param timeoutNs The maximum time a pull should take. Statsd will wait timeoutNs for
+ * the pull to complete before timing out and marking the pull as
+ * failed.
+ * @param additiveFields Fields that are added when mapping isolated uids to host uids.
+ * @param callback The callback to be invoked when the stats service pulls the atom.
+ * @throws RemoteException if unsuccessful due to failing to connect to system server.
+ *
+ * @hide
+ */
+ public void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs,
+ int[] additiveFields, @NonNull StatsPullAtomCallback callback,
+ @NonNull Executor executor) throws RemoteException, SecurityException {
+ synchronized (this) {
+ IStatsCompanionService service = getIStatsCompanionServiceLocked();
+ PullAtomCallbackInternal rec =
+ new PullAtomCallbackInternal(atomTag, callback, executor);
+ service.registerPullAtomCallback(atomTag, coolDownNs, timeoutNs, additiveFields, rec);
+ }
+ }
+
+ private static class PullAtomCallbackInternal extends IPullAtomCallback.Stub {
+ public final int mAtomId;
+ public final StatsPullAtomCallback mCallback;
+ public final Executor mExecutor;
+
+ PullAtomCallbackInternal(int atomId, StatsPullAtomCallback callback, Executor executor) {
+ mAtomId = atomId;
+ mCallback = callback;
+ mExecutor = executor;
+ }
+
+ @Override
+ public void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver) {
+ mExecutor.execute(() -> {
+ List<StatsEvent> data = new ArrayList<>();
+ boolean success = mCallback.onPullAtom(atomTag, data);
+ StatsEvent[] arr = new StatsEvent[data.size()];
+ arr = data.toArray(arr);
+ try {
+ resultReceiver.pullFinished(atomTag, success, arr);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId);
+ }
+ });
+ }
+ }
+
+ /**
+ * Callback interface for pulling atoms requested by the stats service.
+ *
+ * @hide
+ */
+ public interface StatsPullAtomCallback {
+ /**
+ * Pull data for the specified atom tag, filling in the provided list of StatsEvent data.
+ * @return if the pull was successful
+ */
+ boolean onPullAtom(int atomTag, List<StatsEvent> data);
+ }
+
private class StatsdDeathRecipient implements IBinder.DeathRecipient {
@Override
public void binderDied() {
@@ -481,6 +566,7 @@ public final class StatsManager {
}
}
+ @GuardedBy("this")
private IStatsManager getIStatsManagerLocked() throws StatsUnavailableException {
if (mService != null) {
return mService;
@@ -497,6 +583,16 @@ public final class StatsManager {
return mService;
}
+ @GuardedBy("this")
+ private IStatsCompanionService getIStatsCompanionServiceLocked() {
+ if (mStatsCompanion != null) {
+ return mStatsCompanion;
+ }
+ mStatsCompanion = IStatsCompanionService.Stub.asInterface(
+ ServiceManager.getService("statscompanion"));
+ return mStatsCompanion;
+ }
+
/**
* Exception thrown when communication with the stats service fails (eg if it is not available).
* This might be thrown early during boot before the stats service has started or if it crashed.
diff --git a/core/java/android/os/IPullAtomCallback.aidl b/core/java/android/os/IPullAtomCallback.aidl
new file mode 100644
index 000000000000..88d3c3e46ff5
--- /dev/null
+++ b/core/java/android/os/IPullAtomCallback.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 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.os;
+
+import android.os.IPullAtomResultReceiver;
+
+/**
+ * Binder interface to pull atoms for the stats service.
+ * {@hide}
+ */
+interface IPullAtomCallback {
+ /**
+ * Initiate a request for a pull for an atom.
+ */
+ void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver);
+
+}
diff --git a/core/java/android/os/IPullAtomResultReceiver.aidl b/core/java/android/os/IPullAtomResultReceiver.aidl
new file mode 100644
index 000000000000..bfb35ff0c9d1
--- /dev/null
+++ b/core/java/android/os/IPullAtomResultReceiver.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 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.os;
+
+import android.util.StatsEvent;
+
+/**
+ * Binder interface to pull atoms for the stats service.
+ * {@hide}
+ */
+interface IPullAtomResultReceiver {
+
+ /**
+ * Indicate that a pull request for an atom is complete.
+ */
+ oneway void pullFinished(int atomTag, boolean success, in StatsEvent[] output);
+
+}
diff --git a/core/java/android/os/IStatsCompanionService.aidl b/core/java/android/os/IStatsCompanionService.aidl
index 0751b964f85e..22a25374e064 100644
--- a/core/java/android/os/IStatsCompanionService.aidl
+++ b/core/java/android/os/IStatsCompanionService.aidl
@@ -16,6 +16,7 @@
package android.os;
+import android.os.IPullAtomCallback;
import android.os.StatsDimensionsValue;
import android.os.StatsLogEventWrapper;
@@ -85,4 +86,8 @@ interface IStatsCompanionService {
/** Tells StatsCompaionService to grab the uid map snapshot and send it to statsd. */
oneway void triggerUidSnapshot();
+
+ /** Tells StatsCompanionService to tell statsd to register a puller for the given atom id */
+ oneway void registerPullAtomCallback(int atomTag, long coolDownNs, long timeoutNs,
+ in int[] additiveFields, IPullAtomCallback pullerCallback);
}
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index e3f9326048d1..29871b6cf017 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -17,6 +17,7 @@
package android.os;
import android.os.IStatsPullerCallback;
+import android.os.IPullAtomCallback;
import android.os.ParcelFileDescriptor;
/**
@@ -188,11 +189,19 @@ interface IStatsManager {
* for the specified vendor atom tag.
*
* Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
+ * @deprecated please use registerPullAtomCallback.
*/
oneway void registerPullerCallback(int atomTag, IStatsPullerCallback pullerCallback,
String packageName);
/**
+ * Registers a puller callback function that, when invoked, pulls the data
+ * for the specified atom tag.
+ */
+ oneway void registerPullAtomCallback(int uid, int atomTag, long coolDownNs, long timeoutNs,
+ in int[] additiveFields, IPullAtomCallback pullerCallback);
+
+ /**
* Unregisters a puller callback function for the given vendor atom.
*
* Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
diff --git a/core/java/android/os/IStatsPullerCallback.aidl b/core/java/android/os/IStatsPullerCallback.aidl
index 1684aeb0d666..c3e1e55dde06 100644
--- a/core/java/android/os/IStatsPullerCallback.aidl
+++ b/core/java/android/os/IStatsPullerCallback.aidl
@@ -19,6 +19,7 @@ package android.os;
import android.os.StatsLogEventWrapper;
/**
+ * DEPRECATED
* Binder interface to pull atoms for the stats service.
* {@hide}
*/
diff --git a/core/java/android/util/StatsEvent.aidl b/core/java/android/util/StatsEvent.aidl
new file mode 100644
index 000000000000..deac873b0a04
--- /dev/null
+++ b/core/java/android/util/StatsEvent.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2019, 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;
+
+parcelable StatsEvent cpp_header "android/util/StatsEvent.h";
diff --git a/core/java/android/util/StatsEvent.java b/core/java/android/util/StatsEvent.java
index d6ffd38e98e8..10c9d87dfbe8 100644
--- a/core/java/android/util/StatsEvent.java
+++ b/core/java/android/util/StatsEvent.java
@@ -20,6 +20,8 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.SystemClock;
import com.android.internal.annotations.GuardedBy;
@@ -42,7 +44,7 @@ import com.android.internal.annotations.VisibleForTesting;
* </pre>
* @hide
**/
-public final class StatsEvent {
+public final class StatsEvent implements Parcelable {
private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;
// Max payload size is 4 bytes less as 4 bytes are reserved for statsEventTag.
@@ -631,4 +633,39 @@ public final class StatsEvent {
return 0;
}
}
+
+ /**
+ * Boilerplate for Parcel.
+ *
+ * @hide
+ */
+ public static final @NonNull Parcelable.Creator<StatsEvent> CREATOR =
+ new Parcelable.Creator<StatsEvent>() {
+ public StatsEvent createFromParcel(Parcel in) {
+ // Purposefully leaving this method not implemented.
+ throw new RuntimeException("Not implemented");
+ }
+
+ public StatsEvent[] newArray(int size) {
+ // Purposefully leaving this method not implemented.
+ throw new RuntimeException("Not implemented");
+ }
+ };
+
+ /**
+ * @hide
+ */
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mAtomId);
+ out.writeInt(getNumBytes());
+ out.writeByteArray(getBytes());
+ }
+
+ /**
+ * Boilerplate for Parcel.
+ */
+ public int describeContents() {
+ return 0;
+ }
+
}