diff options
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/app/StatsManager.java | 96 | ||||
| -rw-r--r-- | core/java/android/os/IPullAtomCallback.aidl | 31 | ||||
| -rw-r--r-- | core/java/android/os/IPullAtomResultReceiver.aidl | 32 | ||||
| -rw-r--r-- | core/java/android/os/IStatsCompanionService.aidl | 5 | ||||
| -rw-r--r-- | core/java/android/os/IStatsManager.aidl | 9 | ||||
| -rw-r--r-- | core/java/android/os/IStatsPullerCallback.aidl | 1 | ||||
| -rw-r--r-- | core/java/android/util/StatsEvent.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/util/StatsEvent.java | 39 |
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; + } + } |
