Snap for 6214566 from 8ac64bc013a7b14c9996f504eb4c50b6d71c9257 to rvc-release

Change-Id: I2dc4f607967f2e9f5baaf624e97aba7085b9b972
This commit is contained in:
android-build-team Robot
2020-02-18 03:19:15 +00:00
2 changed files with 51 additions and 22 deletions

View File

@@ -526,15 +526,17 @@ public class NetworkStatsManager {
} }
/** /**
* Registers a custom provider of {@link android.net.NetworkStats} to combine the network * Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics
* statistics that cannot be seen by the kernel to system. To unregister, invoke * to the system. To unregister, invoke {@link NetworkStatsProviderCallback#unregister()}.
* {@link NetworkStatsProviderCallback#unregister()}. * Note that no de-duplication of statistics between providers is performed, so each provider
* must only report network traffic that is not being reported by any other provider.
* *
* @param tag a human readable identifier of the custom network stats provider. * @param tag a human readable identifier of the custom network stats provider. This is only
* @param provider a custom implementation of {@link AbstractNetworkStatsProvider} that needs to * used for debugging.
* be registered to the system. * @param provider the subclass of {@link AbstractNetworkStatsProvider} that needs to be
* registered to the system.
* @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the
* system. * system or unregister the provider.
* @hide * @hide
*/ */
@SystemApi @SystemApi

View File

@@ -155,6 +155,8 @@ import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/** /**
* Collect and persist detailed network statistics, and provide this data to * Collect and persist detailed network statistics, and provide this data to
@@ -255,7 +257,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
private final Object mStatsLock = new Object(); private final Object mStatsLock = new Object();
private final Object mStatsProviderLock = new Object();
/** Set of currently active ifaces. */ /** Set of currently active ifaces. */
@GuardedBy("mStatsLock") @GuardedBy("mStatsLock")
@@ -280,8 +281,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final DropBoxNonMonotonicObserver mNonMonotonicObserver = private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
new DropBoxNonMonotonicObserver(); new DropBoxNonMonotonicObserver();
private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
private final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList = private final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
new RemoteCallbackList<>(); new RemoteCallbackList<>();
/** Semaphore used to wait for stats provider to respond to request stats update. */
private final Semaphore mStatsProviderSem = new Semaphore(0, true);
@GuardedBy("mStatsLock") @GuardedBy("mStatsLock")
private NetworkStatsRecorder mDevRecorder; private NetworkStatsRecorder mDevRecorder;
@@ -1337,6 +1341,25 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0; final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0; final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
// Request asynchronous stats update from all providers for next poll. And wait a bit of
// time to allow providers report-in given that normally binder call should be fast.
// TODO: request with a valid token.
Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount();
mStatsProviderSem.drainPermits();
invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */));
try {
mStatsProviderSem.tryAcquire(registeredCallbackCount,
MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// Strictly speaking it's possible a provider happened to deliver between the timeout
// and the log, and that doesn't matter too much as this is just a debug log.
Log.d(TAG, "requestStatsUpdate - providers responded "
+ mStatsProviderSem.availablePermits()
+ "/" + registeredCallbackCount + " : " + e);
}
Trace.traceEnd(TRACE_TAG_NETWORK);
// TODO: consider marking "untrusted" times in historical stats // TODO: consider marking "untrusted" times in historical stats
final long currentTime = mClock.millis(); final long currentTime = mClock.millis();
@@ -1374,10 +1397,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
performSampleLocked(); performSampleLocked();
} }
// request asynchronous stats update from all providers for next poll.
// TODO: request with a valid token.
invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */));
// finally, dispatch updated event to any listeners // finally, dispatch updated event to any listeners
final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED); final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -1501,8 +1520,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
@Override @Override
public void setStatsProviderLimit(@NonNull String iface, long quota) { public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
Slog.v(TAG, "setStatsProviderLimit(" + iface + "," + quota + ")"); Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota)); invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota));
} }
} }
@@ -1783,9 +1802,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* {@code unregister()} of the returned callback. * {@code unregister()} of the returned callback.
* *
* @param tag a human readable identifier of the custom network stats provider. * @param tag a human readable identifier of the custom network stats provider.
* @param provider the binder interface of * @param provider the {@link INetworkStatsProvider} binder corresponding to the
* {@link android.net.netstats.provider.AbstractNetworkStatsProvider} that * {@link android.net.netstats.provider.AbstractNetworkStatsProvider} to be
* needs to be registered to the system. * registered.
* *
* @return a binder interface of * @return a binder interface of
* {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be * {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be
@@ -1798,7 +1817,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
Objects.requireNonNull(tag, "tag is null"); Objects.requireNonNull(tag, "tag is null");
try { try {
NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl( NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
tag, provider, mAlertObserver, mStatsProviderCbList); tag, provider, mStatsProviderSem, mAlertObserver,
mStatsProviderCbList);
mStatsProviderCbList.register(callback); mStatsProviderCbList.register(callback);
Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid=" Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
+ getCallingUid() + "/" + getCallingPid()); + getCallingUid() + "/" + getCallingPid());
@@ -1823,7 +1843,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private void invokeForAllStatsProviderCallbacks( private void invokeForAllStatsProviderCallbacks(
@NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) { @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
synchronized (mStatsProviderCbList) { synchronized (mStatsLock) {
final int length = mStatsProviderCbList.beginBroadcast(); final int length = mStatsProviderCbList.beginBroadcast();
try { try {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@@ -1844,25 +1864,30 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub
implements IBinder.DeathRecipient { implements IBinder.DeathRecipient {
@NonNull final String mTag; @NonNull final String mTag;
@NonNull private final Object mProviderStatsLock = new Object();
@NonNull final INetworkStatsProvider mProvider; @NonNull final INetworkStatsProvider mProvider;
@NonNull private final Semaphore mSemaphore;
@NonNull final INetworkManagementEventObserver mAlertObserver; @NonNull final INetworkManagementEventObserver mAlertObserver;
@NonNull final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList; @NonNull final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
@NonNull private final Object mProviderStatsLock = new Object();
@GuardedBy("mProviderStatsLock") @GuardedBy("mProviderStatsLock")
// STATS_PER_IFACE and STATS_PER_UID // Track STATS_PER_IFACE and STATS_PER_UID separately.
private final NetworkStats mIfaceStats = new NetworkStats(0L, 0); private final NetworkStats mIfaceStats = new NetworkStats(0L, 0);
@GuardedBy("mProviderStatsLock") @GuardedBy("mProviderStatsLock")
private final NetworkStats mUidStats = new NetworkStats(0L, 0); private final NetworkStats mUidStats = new NetworkStats(0L, 0);
NetworkStatsProviderCallbackImpl( NetworkStatsProviderCallbackImpl(
@NonNull String tag, @NonNull INetworkStatsProvider provider, @NonNull String tag, @NonNull INetworkStatsProvider provider,
@NonNull Semaphore semaphore,
@NonNull INetworkManagementEventObserver alertObserver, @NonNull INetworkManagementEventObserver alertObserver,
@NonNull RemoteCallbackList<NetworkStatsProviderCallbackImpl> cbList) @NonNull RemoteCallbackList<NetworkStatsProviderCallbackImpl> cbList)
throws RemoteException { throws RemoteException {
mTag = tag; mTag = tag;
mProvider = provider; mProvider = provider;
mProvider.asBinder().linkToDeath(this, 0); mProvider.asBinder().linkToDeath(this, 0);
mSemaphore = semaphore;
mAlertObserver = alertObserver; mAlertObserver = alertObserver;
mStatsProviderCbList = cbList; mStatsProviderCbList = cbList;
} }
@@ -1881,7 +1906,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
default: default:
throw new IllegalArgumentException("Invalid type: " + how); throw new IllegalArgumentException("Invalid type: " + how);
} }
// Return a defensive copy instead of local reference. // Callers might be able to mutate the returned object. Return a defensive copy
// instead of local reference.
return stats.clone(); return stats.clone();
} }
} }
@@ -1895,6 +1921,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats); if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats);
if (uidStats != null) mUidStats.combineAllValues(uidStats); if (uidStats != null) mUidStats.combineAllValues(uidStats);
} }
mSemaphore.release();
} }
@Override @Override