Merge changes Id91fabb4,I6d117032,I88fce1b2 into tm-dev
* changes: Address comment at ag/18491259 and ag/18486388 Run comparison code if the data migration finished with fallback Persisting status int on the device if fallback happened
This commit is contained in:
committed by
Android (Google) Code Review
commit
fae0ef515c
@@ -253,7 +253,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
"netstats_import_legacy_target_attempts";
|
||||
static final int DEFAULT_NETSTATS_IMPORT_LEGACY_TARGET_ATTEMPTS = 1;
|
||||
static final String NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME = "import.attempts";
|
||||
static final String NETSTATS_IMPORT_SUCCESS_COUNTER_NAME = "import.successes";
|
||||
static final String NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME = "import.successes";
|
||||
static final String NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME = "import.fallbacks";
|
||||
|
||||
private final Context mContext;
|
||||
private final NetworkStatsFactory mStatsFactory;
|
||||
@@ -273,10 +274,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
private final AlertObserver mAlertObserver = new AlertObserver();
|
||||
|
||||
// Persistent counters that backed by AtomicFile which stored in the data directory as a file,
|
||||
// to track attempts/successes count across reboot. Note that these counter values will be
|
||||
// rollback as the module rollbacks.
|
||||
// to track attempts/successes/fallbacks count across reboot. Note that these counter values
|
||||
// will be rollback as the module rollbacks.
|
||||
private PersistentInt mImportLegacyAttemptsCounter = null;
|
||||
private PersistentInt mImportLegacySuccessesCounter = null;
|
||||
private PersistentInt mImportLegacyFallbacksCounter = null;
|
||||
|
||||
@VisibleForTesting
|
||||
public static final String ACTION_NETWORK_STATS_POLL =
|
||||
@@ -619,21 +621,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the persistent counter that counts total import legacy stats attempts.
|
||||
* Create a persistent counter for given directory and name.
|
||||
*/
|
||||
public PersistentInt createImportLegacyAttemptsCounter(@NonNull Path path)
|
||||
public PersistentInt createPersistentCounter(@NonNull Path dir, @NonNull String name)
|
||||
throws IOException {
|
||||
// TODO: Modify PersistentInt to call setStartTime every time a write is made.
|
||||
// Create and pass a real logger here.
|
||||
return new PersistentInt(path.toString(), null /* logger */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the persistent counter that counts total import legacy stats successes.
|
||||
*/
|
||||
public PersistentInt createImportLegacySuccessesCounter(@NonNull Path path)
|
||||
throws IOException {
|
||||
return new PersistentInt(path.toString(), null /* logger */);
|
||||
final String path = dir.resolve(name).toString();
|
||||
return new PersistentInt(path, null /* logger */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -911,10 +906,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mImportLegacyAttemptsCounter = mDeps.createImportLegacyAttemptsCounter(
|
||||
mStatsDir.toPath().resolve(NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME));
|
||||
mImportLegacySuccessesCounter = mDeps.createImportLegacySuccessesCounter(
|
||||
mStatsDir.toPath().resolve(NETSTATS_IMPORT_SUCCESS_COUNTER_NAME));
|
||||
mImportLegacyAttemptsCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
|
||||
NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME);
|
||||
mImportLegacySuccessesCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
|
||||
NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME);
|
||||
mImportLegacyFallbacksCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
|
||||
NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME);
|
||||
} catch (IOException e) {
|
||||
Log.wtf(TAG, "Failed to create persistent counters, skip.", e);
|
||||
return;
|
||||
@@ -922,15 +919,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
|
||||
final int targetAttempts = mDeps.getImportLegacyTargetAttempts();
|
||||
final int attempts;
|
||||
final int fallbacks;
|
||||
try {
|
||||
attempts = mImportLegacyAttemptsCounter.get();
|
||||
fallbacks = mImportLegacyFallbacksCounter.get();
|
||||
} catch (IOException e) {
|
||||
Log.wtf(TAG, "Failed to read attempts counter, skip.", e);
|
||||
Log.wtf(TAG, "Failed to read counters, skip.", e);
|
||||
return;
|
||||
}
|
||||
if (attempts >= targetAttempts) return;
|
||||
// If fallbacks is not zero, proceed with reading only to give signals from dogfooders.
|
||||
// TODO(b/233752318): Remove fallbacks counter check before T formal release.
|
||||
if (attempts >= targetAttempts && fallbacks == 0) return;
|
||||
|
||||
Log.i(TAG, "Starting import : attempts " + attempts + "/" + targetAttempts);
|
||||
final boolean dryRunImportOnly = (attempts >= targetAttempts);
|
||||
if (dryRunImportOnly) {
|
||||
Log.i(TAG, "Starting import : only perform read");
|
||||
} else {
|
||||
Log.i(TAG, "Starting import : attempts " + attempts + "/" + targetAttempts);
|
||||
}
|
||||
|
||||
final MigrationInfo[] migrations = new MigrationInfo[]{
|
||||
new MigrationInfo(mDevRecorder), new MigrationInfo(mXtRecorder),
|
||||
@@ -987,6 +993,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
// For cases where the fallbacks is not zero but target attempts counts reached,
|
||||
// only perform reads above and return here.
|
||||
if (dryRunImportOnly) return;
|
||||
|
||||
// Find the latest end time.
|
||||
for (final MigrationInfo migration : migrations) {
|
||||
final long migrationEnd = migration.collection.getEndMillis();
|
||||
@@ -1009,11 +1019,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
migration.recorder.importCollectionLocked(migration.collection);
|
||||
}
|
||||
|
||||
if (endedWithFallback) {
|
||||
Log.wtf(TAG, "Imported platform collections with legacy fallback");
|
||||
} else {
|
||||
Log.i(TAG, "Successfully imported platform collections");
|
||||
}
|
||||
// Success normally or uses fallback method.
|
||||
} catch (Throwable e) {
|
||||
// The code above calls OEM code that may behave differently across devices.
|
||||
// It can throw any exception including RuntimeExceptions and
|
||||
@@ -1053,10 +1059,17 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
// Success ! No need to import again next time.
|
||||
try {
|
||||
mImportLegacyAttemptsCounter.set(targetAttempts);
|
||||
// The successes counter is only for debugging. Hence, the synchronization
|
||||
// between these two counters are not very critical.
|
||||
final int successCount = mImportLegacySuccessesCounter.get();
|
||||
mImportLegacySuccessesCounter.set(successCount + 1);
|
||||
if (endedWithFallback) {
|
||||
Log.wtf(TAG, "Imported platform collections with legacy fallback");
|
||||
final int fallbacksCount = mImportLegacyFallbacksCounter.get();
|
||||
mImportLegacyFallbacksCounter.set(fallbacksCount + 1);
|
||||
} else {
|
||||
Log.i(TAG, "Successfully imported platform collections");
|
||||
// The successes counter is only for debugging. Hence, the synchronization
|
||||
// between successes counter and attempts counter are not very critical.
|
||||
final int successCount = mImportLegacySuccessesCounter.get();
|
||||
mImportLegacySuccessesCounter.set(successCount + 1);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.wtf(TAG, "Succeed but failed to update counters.", e);
|
||||
}
|
||||
@@ -2478,6 +2491,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
pw.print("platform legacy stats import successes count",
|
||||
mImportLegacySuccessesCounter.get());
|
||||
pw.println();
|
||||
pw.print("platform legacy stats import fallbacks count",
|
||||
mImportLegacyFallbacksCounter.get());
|
||||
pw.println();
|
||||
} catch (IOException e) {
|
||||
pw.println("(failed to dump platform legacy stats import counters)");
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ import static android.text.format.DateUtils.WEEK_IN_MILLIS;
|
||||
|
||||
import static com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT;
|
||||
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
|
||||
import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME;
|
||||
import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME;
|
||||
import static com.android.server.net.NetworkStatsService.NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME;
|
||||
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -141,6 +144,7 @@ import com.android.testutils.TestBpfMap;
|
||||
import com.android.testutils.TestableNetworkStatsProviderBinder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Clock;
|
||||
@@ -239,6 +243,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
private int mImportLegacyTargetAttempts = 0;
|
||||
private @Mock PersistentInt mImportLegacyAttemptsCounter;
|
||||
private @Mock PersistentInt mImportLegacySuccessesCounter;
|
||||
private @Mock PersistentInt mImportLegacyFallbacksCounter;
|
||||
|
||||
private class MockContext extends BroadcastInterceptingContext {
|
||||
private final Context mBaseContext;
|
||||
@@ -379,15 +384,18 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentInt createImportLegacyAttemptsCounter(
|
||||
@androidx.annotation.NonNull Path path) {
|
||||
return mImportLegacyAttemptsCounter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentInt createImportLegacySuccessesCounter(
|
||||
@androidx.annotation.NonNull Path path) {
|
||||
return mImportLegacySuccessesCounter;
|
||||
public PersistentInt createPersistentCounter(@androidx.annotation.NonNull Path dir,
|
||||
@androidx.annotation.NonNull String name) throws IOException {
|
||||
switch (name) {
|
||||
case NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME:
|
||||
return mImportLegacyAttemptsCounter;
|
||||
case NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME:
|
||||
return mImportLegacySuccessesCounter;
|
||||
case NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME:
|
||||
return mImportLegacyFallbacksCounter;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown counter name: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1861,7 +1869,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
}
|
||||
|
||||
private NetworkStatsCollection getLegacyCollection(String prefix, boolean includeTags) {
|
||||
final NetworkStatsRecorder recorder = makeTestRecorder(mLegacyStatsDir, PREFIX_DEV,
|
||||
final NetworkStatsRecorder recorder = makeTestRecorder(mLegacyStatsDir, prefix,
|
||||
mSettings.getDevConfig(), includeTags);
|
||||
return recorder.getOrLoadCompleteLocked();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user