Merge changes If3dbe234,Ia1299759 into main

* changes:
  Dump current max entries and cache duration even if the flags change
  Check compat change flag for rate-limit cache
This commit is contained in:
Junyu Lai 2024-06-04 07:07:21 +00:00 • committed by Gerrit Code Review
commit 67b67908a1
3 changed files with 93 additions and 38 deletions

View file

@ -121,6 +121,20 @@ public final class ConnectivityCompatChanges {
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
public static final long NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION = 333340911L;
/**
* Enable caching for TrafficStats#get* APIs.
*
* Apps targeting Android V or later or running on Android V or later may take up to several
* seconds to see the updated results.
* Apps targeting lower android SDKs do not see cached result for backward compatibility,
* results of TrafficStats#get* APIs are reflecting network statistics immediately.
*
* @hide
*/
@ChangeId
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final long ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE = 74210811L;
private ConnectivityCompatChanges() {
}
}

View file

@ -57,6 +57,7 @@ import static android.net.TrafficStats.TYPE_TX_BYTES;
import static android.net.TrafficStats.TYPE_TX_PACKETS;
import static android.net.TrafficStats.UID_TETHERING;
import static android.net.TrafficStats.UNSUPPORTED;
import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE;
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
@ -91,6 +92,7 @@ import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.app.compat.CompatChanges;
import android.app.usage.NetworkStatsManager;
import android.content.ApexEnvironment;
import android.content.BroadcastReceiver;
@ -472,7 +474,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final TrafficStatsRateLimitCache mTrafficStatsUidCache;
static final String TRAFFICSTATS_RATE_LIMIT_CACHE_ENABLED_FLAG =
"trafficstats_rate_limit_cache_enabled_flag";
private final boolean mSupportTrafficStatsRateLimitCache;
private final boolean mAlwaysUseTrafficStatsRateLimitCache;
private final int mTrafficStatsRateLimitCacheExpiryDuration;
private final int mTrafficStatsRateLimitCacheMaxEntries;
private final Object mOpenSessionCallsLock = new Object();
@ -663,15 +667,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mEventLogger = null;
}
final long cacheExpiryDurationMs = mDeps.getTrafficStatsRateLimitCacheExpiryDuration();
final int cacheMaxEntries = mDeps.getTrafficStatsRateLimitCacheMaxEntries();
mSupportTrafficStatsRateLimitCache = mDeps.supportTrafficStatsRateLimitCache(mContext);
mAlwaysUseTrafficStatsRateLimitCache =
mDeps.alwaysUseTrafficStatsRateLimitCache(mContext);
mTrafficStatsRateLimitCacheExpiryDuration =
mDeps.getTrafficStatsRateLimitCacheExpiryDuration();
mTrafficStatsRateLimitCacheMaxEntries =
mDeps.getTrafficStatsRateLimitCacheMaxEntries();
mTrafficStatsTotalCache = new TrafficStatsRateLimitCache(mClock,
cacheExpiryDurationMs, cacheMaxEntries);
mTrafficStatsRateLimitCacheExpiryDuration, mTrafficStatsRateLimitCacheMaxEntries);
mTrafficStatsIfaceCache = new TrafficStatsRateLimitCache(mClock,
cacheExpiryDurationMs, cacheMaxEntries);
mTrafficStatsRateLimitCacheExpiryDuration, mTrafficStatsRateLimitCacheMaxEntries);
mTrafficStatsUidCache = new TrafficStatsRateLimitCache(mClock,
cacheExpiryDurationMs, cacheMaxEntries);
mTrafficStatsRateLimitCacheExpiryDuration, mTrafficStatsRateLimitCacheMaxEntries);
// TODO: Remove bpfNetMaps creation and always start SkDestroyListener
// Following code is for the experiment to verify the SkDestroyListener refactoring. Based
@ -920,12 +927,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
/**
* Get whether TrafficStats rate-limit cache is supported.
* Get whether TrafficStats rate-limit cache is always applied.
*
* This method should only be called once in the constructor,
* to ensure that the code does not need to deal with flag values changing at runtime.
*/
public boolean supportTrafficStatsRateLimitCache(@NonNull Context ctx) {
public boolean alwaysUseTrafficStatsRateLimitCache(@NonNull Context ctx) {
return SdkLevel.isAtLeastV() && DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
ctx, TRAFFICSTATS_RATE_LIMIT_CACHE_ENABLED_FLAG);
}
@ -954,6 +961,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
DEFAULT_TRAFFIC_STATS_CACHE_MAX_ENTRIES);
}
/**
* Wrapper method for {@link CompatChanges#isChangeEnabled(long, int)}
*/
public boolean isChangeEnabled(final long changeId, final int uid) {
return CompatChanges.isChangeEnabled(changeId, uid);
}
/**
* Retrieves native network total statistics.
*
@ -2085,14 +2099,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
if (!isEntryValueTypeValid(type)) return UNSUPPORTED;
if (!mSupportTrafficStatsRateLimitCache) {
return getEntryValueForType(mDeps.nativeGetUidStat(uid), type);
if (mAlwaysUseTrafficStatsRateLimitCache
|| mDeps.isChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, callingUid)) {
final NetworkStats.Entry entry = mTrafficStatsUidCache.getOrCompute(IFACE_ALL, uid,
() -> mDeps.nativeGetUidStat(uid));
return getEntryValueForType(entry, type);
}
final NetworkStats.Entry entry = mTrafficStatsUidCache.getOrCompute(IFACE_ALL, uid,
() -> mDeps.nativeGetUidStat(uid));
return getEntryValueForType(entry, type);
return getEntryValueForType(mDeps.nativeGetUidStat(uid), type);
}
@Nullable
@ -2114,14 +2128,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
Objects.requireNonNull(iface);
if (!isEntryValueTypeValid(type)) return UNSUPPORTED;
if (!mSupportTrafficStatsRateLimitCache) {
return getEntryValueForType(getIfaceStatsInternal(iface), type);
if (mAlwaysUseTrafficStatsRateLimitCache
|| mDeps.isChangeEnabled(
ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, Binder.getCallingUid())) {
final NetworkStats.Entry entry = mTrafficStatsIfaceCache.getOrCompute(iface, UID_ALL,
() -> getIfaceStatsInternal(iface));
return getEntryValueForType(entry, type);
}
final NetworkStats.Entry entry = mTrafficStatsIfaceCache.getOrCompute(iface, UID_ALL,
() -> getIfaceStatsInternal(iface));
return getEntryValueForType(entry, type);
return getEntryValueForType(getIfaceStatsInternal(iface), type);
}
private long getEntryValueForType(@Nullable NetworkStats.Entry entry, int type) {
@ -2167,14 +2182,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public long getTotalStats(int type) {
if (!isEntryValueTypeValid(type)) return UNSUPPORTED;
if (!mSupportTrafficStatsRateLimitCache) {
return getEntryValueForType(getTotalStatsInternal(), type);
if (mAlwaysUseTrafficStatsRateLimitCache
|| mDeps.isChangeEnabled(
ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, Binder.getCallingUid())) {
final NetworkStats.Entry entry = mTrafficStatsTotalCache.getOrCompute(
IFACE_ALL, UID_ALL, () -> getTotalStatsInternal());
return getEntryValueForType(entry, type);
}
final NetworkStats.Entry entry = mTrafficStatsTotalCache.getOrCompute(IFACE_ALL, UID_ALL,
() -> getTotalStatsInternal());
return getEntryValueForType(entry, type);
return getEntryValueForType(getTotalStatsInternal(), type);
}
@Override
@ -2938,13 +2954,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} catch (IOException e) {
pw.println("(failed to dump FastDataInput counters)");
}
pw.print("trafficstats.cache.supported", mSupportTrafficStatsRateLimitCache);
pw.print("trafficstats.cache.alwaysuse", mAlwaysUseTrafficStatsRateLimitCache);
pw.println();
pw.print(TRAFFIC_STATS_CACHE_EXPIRY_DURATION_NAME,
mDeps.getTrafficStatsRateLimitCacheExpiryDuration());
mTrafficStatsRateLimitCacheExpiryDuration);
pw.println();
pw.print(TRAFFIC_STATS_CACHE_MAX_ENTRIES_NAME,
mDeps.getTrafficStatsRateLimitCacheMaxEntries());
pw.print(TRAFFIC_STATS_CACHE_MAX_ENTRIES_NAME, mTrafficStatsRateLimitCacheMaxEntries);
pw.println();
pw.decreaseIndent();

View file

@ -56,6 +56,7 @@ import static android.net.NetworkTemplate.OEM_MANAGED_YES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.TrafficStats.UID_REMOVED;
import static android.net.TrafficStats.UID_TETHERING;
import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE;
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
@ -306,6 +307,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
private HandlerThread mObserverHandlerThread;
final TestDependencies mDeps = new TestDependencies();
final HashMap<String, Boolean> mFeatureFlags = new HashMap<>();
final HashMap<Long, Boolean> mCompatChanges = new HashMap<>();
// This will set feature flags from @FeatureFlag annotations
// into the map before setUp() runs.
@ -594,7 +596,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
}
@Override
public boolean supportTrafficStatsRateLimitCache(Context ctx) {
public boolean alwaysUseTrafficStatsRateLimitCache(Context ctx) {
return mFeatureFlags.getOrDefault(TRAFFICSTATS_RATE_LIMIT_CACHE_ENABLED_FLAG, false);
}
@ -608,6 +610,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
return DEFAULT_TRAFFIC_STATS_CACHE_MAX_ENTRIES;
}
@Override
public boolean isChangeEnabled(long changeId, int uid) {
return mCompatChanges.getOrDefault(changeId, true);
}
public void setChangeEnabled(long changeId, boolean enabled) {
mCompatChanges.put(changeId, enabled);
}
@Nullable
@Override
public NetworkStats.Entry nativeGetTotalStat() {
@ -2413,17 +2423,33 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
@FeatureFlag(name = TRAFFICSTATS_RATE_LIMIT_CACHE_ENABLED_FLAG, enabled = false)
@Test
public void testTrafficStatsRateLimitCache_disabled() throws Exception {
doTestTrafficStatsRateLimitCache(false /* cacheEnabled */);
public void testTrafficStatsRateLimitCache_disabledWithCompatChangeEnabled() throws Exception {
mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, true);
doTestTrafficStatsRateLimitCache(true /* expectCached */);
}
@FeatureFlag(name = TRAFFICSTATS_RATE_LIMIT_CACHE_ENABLED_FLAG)
@Test
public void testTrafficStatsRateLimitCache_enabled() throws Exception {
doTestTrafficStatsRateLimitCache(true /* cacheEnabled */);
public void testTrafficStatsRateLimitCache_enabledWithCompatChangeEnabled() throws Exception {
mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, true);
doTestTrafficStatsRateLimitCache(true /* expectCached */);
}
private void doTestTrafficStatsRateLimitCache(boolean cacheEnabled) throws Exception {
@FeatureFlag(name = TRAFFICSTATS_RATE_LIMIT_CACHE_ENABLED_FLAG, enabled = false)
@Test
public void testTrafficStatsRateLimitCache_disabledWithCompatChangeDisabled() throws Exception {
mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, false);
doTestTrafficStatsRateLimitCache(false /* expectCached */);
}
@FeatureFlag(name = TRAFFICSTATS_RATE_LIMIT_CACHE_ENABLED_FLAG)
@Test
public void testTrafficStatsRateLimitCache_enabledWithCompatChangeDisabled() throws Exception {
mDeps.setChangeEnabled(ENABLE_TRAFFICSTATS_RATE_LIMIT_CACHE, false);
doTestTrafficStatsRateLimitCache(true /* expectCached */);
}
private void doTestTrafficStatsRateLimitCache(boolean expectCached) throws Exception {
mockDefaultSettings();
// Calling uid is not injected into the service, use the real uid to pass the caller check.
final int myUid = Process.myUid();
@ -2433,7 +2459,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// Verify the values are cached.
incrementCurrentTime(DEFAULT_TRAFFIC_STATS_CACHE_EXPIRY_DURATION_MS / 2);
mockTrafficStatsValues(65L, 8L, 1055L, 9L);
if (cacheEnabled) {
if (expectCached) {
assertTrafficStatsValues(TEST_IFACE, myUid, 64L, 3L, 1024L, 8L);
} else {
assertTrafficStatsValues(TEST_IFACE, myUid, 65L, 8L, 1055L, 9L);