diff options
| author | Tej Singh <singhtejinder@google.com> | 2019-02-12 04:11:07 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-02-12 04:11:07 +0000 |
| commit | 77f8cfb4d3a86b934dfa13a1af55587eeb4c0ab7 (patch) | |
| tree | 1100282d6a897d3d5c6bfc8c054ea7bdf1699ef2 /core/java/android | |
| parent | f6cce01894124a59a67b74b9aab7051a669b5999 (diff) | |
| parent | a0c89dd5b6d575808edd6d4d619fcd1f18954c70 (diff) | |
Merge "Statsd Puller Callback Registration"
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/StatsManager.java | 34 | ||||
| -rw-r--r-- | core/java/android/os/IStatsManager.aidl | 18 | ||||
| -rw-r--r-- | core/java/android/os/IStatsPullerCallback.aidl | 35 | ||||
| -rw-r--r-- | core/java/android/os/StatsLogEventWrapper.java | 78 |
4 files changed, 157 insertions, 8 deletions
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java index 3119b37a686e..7746148d325a 100644 --- a/core/java/android/app/StatsManager.java +++ b/core/java/android/app/StatsManager.java @@ -24,6 +24,7 @@ import android.annotation.SystemApi; import android.content.Context; import android.os.IBinder; import android.os.IStatsManager; +import android.os.IStatsPullerCallback; import android.os.RemoteException; import android.os.ServiceManager; import android.util.AndroidException; @@ -408,6 +409,39 @@ 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. Currently, this only works for atoms with tags above 100,000 that do not have a uid. + * + * @param atomTag The tag of the atom for this puller callback. Must be at least 100000. + * @param callback The callback to be invoked when the stats service pulls the atom. + * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service + * + * @hide + */ + @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS }) + public void setPullerCallback(int atomTag, IStatsPullerCallback callback) + throws StatsUnavailableException { + synchronized (this) { + try { + IStatsManager service = getIStatsManagerLocked(); + if (callback == null) { + service.unregisterPullerCallback(atomTag, mContext.getOpPackageName()); + } else { + service.registerPullerCallback(atomTag, callback, + mContext.getOpPackageName()); + } + + } catch (RemoteException e) { + Slog.e(TAG, "Failed to connect to statsd when registering data listener."); + throw new StatsUnavailableException("could not connect", e); + } catch (SecurityException e) { + throw new StatsUnavailableException(e.getMessage(), e); + } + } + } + private class StatsdDeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl index 93d6f4c12128..f1bba1ab2977 100644 --- a/core/java/android/os/IStatsManager.aidl +++ b/core/java/android/os/IStatsManager.aidl @@ -16,6 +16,8 @@ package android.os; +import android.os.IStatsPullerCallback; + /** * Binder interface to communicate with the statistics management service. * {@hide} @@ -178,4 +180,20 @@ interface IStatsManager { * this label. This allows building custom metrics and predicates. */ void sendAppBreadcrumbAtom(int label, int state); + + /** + * Registers a puller callback function that, when invoked, pulls the data + * for the specified vendor atom tag. + * + * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS + */ + oneway void registerPullerCallback(int atomTag, IStatsPullerCallback pullerCallback, + String packageName); + + /** + * Unregisters a puller callback function for the given vendor atom. + * + * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS + */ + oneway void unregisterPullerCallback(int atomTag, String packageName); } diff --git a/core/java/android/os/IStatsPullerCallback.aidl b/core/java/android/os/IStatsPullerCallback.aidl new file mode 100644 index 000000000000..1684aeb0d666 --- /dev/null +++ b/core/java/android/os/IStatsPullerCallback.aidl @@ -0,0 +1,35 @@ +/* + * 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.StatsLogEventWrapper; + +/** + * Binder interface to pull atoms for the stats service. + * {@hide} + */ +interface IStatsPullerCallback { + /** + * Pull data for the specified atom tag. Returns an array of StatsLogEventWrapper containing + * the data. + * + * Note: These pulled atoms should not have uid/attribution chain. Additionally, the event + * timestamps will be truncated to the nearest 5 minutes. + */ + StatsLogEventWrapper[] pullData(int atomTag, long elapsedNanos, long wallClocknanos); + +} diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java index acb9eac3572c..23342426693a 100644 --- a/core/java/android/os/StatsLogEventWrapper.java +++ b/core/java/android/os/StatsLogEventWrapper.java @@ -57,20 +57,18 @@ public final class StatsLogEventWrapper implements Parcelable { public static final Parcelable.Creator<StatsLogEventWrapper> CREATOR = new Parcelable.Creator<StatsLogEventWrapper>() { public StatsLogEventWrapper createFromParcel(Parcel in) { - android.util.EventLog.writeEvent(0x534e4554, "112550251", - android.os.Binder.getCallingUid(), ""); - // Purposefully leaving this method not implemented. - throw new RuntimeException("Not implemented"); + return new StatsLogEventWrapper(in); } public StatsLogEventWrapper[] newArray(int size) { - android.util.EventLog.writeEvent(0x534e4554, "112550251", - android.os.Binder.getCallingUid(), ""); - // Purposefully leaving this method not implemented. - throw new RuntimeException("Not implemented"); + return new StatsLogEventWrapper[size]; } }; + private StatsLogEventWrapper(Parcel in) { + readFromParcel(in); + } + /** * Set work source if any. */ @@ -197,6 +195,70 @@ public final class StatsLogEventWrapper implements Parcelable { } /** + * Reads from parcel and appropriately fills member fields. + */ + public void readFromParcel(Parcel in) { + mTypes = new ArrayList<>(); + mValues = new ArrayList<>(); + mWorkSource = null; + + mTag = in.readInt(); + mElapsedTimeNs = in.readLong(); + mWallClockTimeNs = in.readLong(); + + // Clear any data. + if (DEBUG) { + Slog.d(TAG, "Reading " + mTag + " " + mElapsedTimeNs + " " + mWallClockTimeNs); + } + // Set up worksource if present. + int numWorkChains = in.readInt(); + if (numWorkChains > 0) { + mWorkSource = new WorkSource(); + for (int i = 0; i < numWorkChains; i++) { + android.os.WorkSource.WorkChain workChain = mWorkSource.createWorkChain(); + int workChainSize = in.readInt(); + for (int j = 0; j < workChainSize; j++) { + int uid = in.readInt(); + String tag = in.readString(); + workChain.addNode(uid, tag); + } + } + } + + // Do the rest of the types. + int numTypes = in.readInt(); + if (DEBUG) { + Slog.d(TAG, "Reading " + numTypes + " elements"); + } + for (int i = 0; i < numTypes; i++) { + int type = in.readInt(); + mTypes.add(type); + switch (type) { + case EVENT_TYPE_INT: + mValues.add(in.readInt()); + break; + case EVENT_TYPE_LONG: + mValues.add(in.readLong()); + break; + case EVENT_TYPE_FLOAT: + mValues.add(in.readFloat()); + break; + case EVENT_TYPE_DOUBLE: + mValues.add(in.readDouble()); + break; + case EVENT_TYPE_STRING: + mValues.add(in.readString()); + break; + case EVENT_TYPE_STORAGE: + mValues.add(in.createByteArray()); + break; + default: + break; + } + } + } + + /** * Boilerplate for Parcel. */ public int describeContents() { |
