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";
|
"netstats_import_legacy_target_attempts";
|
||||||
static final int DEFAULT_NETSTATS_IMPORT_LEGACY_TARGET_ATTEMPTS = 1;
|
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_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 Context mContext;
|
||||||
private final NetworkStatsFactory mStatsFactory;
|
private final NetworkStatsFactory mStatsFactory;
|
||||||
@@ -273,10 +274,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
private final AlertObserver mAlertObserver = new AlertObserver();
|
private final AlertObserver mAlertObserver = new AlertObserver();
|
||||||
|
|
||||||
// Persistent counters that backed by AtomicFile which stored in the data directory as a file,
|
// 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
|
// to track attempts/successes/fallbacks count across reboot. Note that these counter values
|
||||||
// rollback as the module rollbacks.
|
// will be rollback as the module rollbacks.
|
||||||
private PersistentInt mImportLegacyAttemptsCounter = null;
|
private PersistentInt mImportLegacyAttemptsCounter = null;
|
||||||
private PersistentInt mImportLegacySuccessesCounter = null;
|
private PersistentInt mImportLegacySuccessesCounter = null;
|
||||||
|
private PersistentInt mImportLegacyFallbacksCounter = null;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public static final String ACTION_NETWORK_STATS_POLL =
|
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 {
|
throws IOException {
|
||||||
// TODO: Modify PersistentInt to call setStartTime every time a write is made.
|
// TODO: Modify PersistentInt to call setStartTime every time a write is made.
|
||||||
// Create and pass a real logger here.
|
// Create and pass a real logger here.
|
||||||
return new PersistentInt(path.toString(), null /* logger */);
|
final String path = dir.resolve(name).toString();
|
||||||
}
|
return new PersistentInt(path, 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 */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -911,10 +906,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mImportLegacyAttemptsCounter = mDeps.createImportLegacyAttemptsCounter(
|
mImportLegacyAttemptsCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
|
||||||
mStatsDir.toPath().resolve(NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME));
|
NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME);
|
||||||
mImportLegacySuccessesCounter = mDeps.createImportLegacySuccessesCounter(
|
mImportLegacySuccessesCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
|
||||||
mStatsDir.toPath().resolve(NETSTATS_IMPORT_SUCCESS_COUNTER_NAME));
|
NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME);
|
||||||
|
mImportLegacyFallbacksCounter = mDeps.createPersistentCounter(mStatsDir.toPath(),
|
||||||
|
NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.wtf(TAG, "Failed to create persistent counters, skip.", e);
|
Log.wtf(TAG, "Failed to create persistent counters, skip.", e);
|
||||||
return;
|
return;
|
||||||
@@ -922,15 +919,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
final int targetAttempts = mDeps.getImportLegacyTargetAttempts();
|
final int targetAttempts = mDeps.getImportLegacyTargetAttempts();
|
||||||
final int attempts;
|
final int attempts;
|
||||||
|
final int fallbacks;
|
||||||
try {
|
try {
|
||||||
attempts = mImportLegacyAttemptsCounter.get();
|
attempts = mImportLegacyAttemptsCounter.get();
|
||||||
|
fallbacks = mImportLegacyFallbacksCounter.get();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.wtf(TAG, "Failed to read attempts counter, skip.", e);
|
Log.wtf(TAG, "Failed to read counters, skip.", e);
|
||||||
return;
|
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[]{
|
final MigrationInfo[] migrations = new MigrationInfo[]{
|
||||||
new MigrationInfo(mDevRecorder), new MigrationInfo(mXtRecorder),
|
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.
|
// Find the latest end time.
|
||||||
for (final MigrationInfo migration : migrations) {
|
for (final MigrationInfo migration : migrations) {
|
||||||
final long migrationEnd = migration.collection.getEndMillis();
|
final long migrationEnd = migration.collection.getEndMillis();
|
||||||
@@ -1009,11 +1019,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
migration.recorder.importCollectionLocked(migration.collection);
|
migration.recorder.importCollectionLocked(migration.collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endedWithFallback) {
|
// Success normally or uses fallback method.
|
||||||
Log.wtf(TAG, "Imported platform collections with legacy fallback");
|
|
||||||
} else {
|
|
||||||
Log.i(TAG, "Successfully imported platform collections");
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// The code above calls OEM code that may behave differently across devices.
|
// The code above calls OEM code that may behave differently across devices.
|
||||||
// It can throw any exception including RuntimeExceptions and
|
// 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.
|
// Success ! No need to import again next time.
|
||||||
try {
|
try {
|
||||||
mImportLegacyAttemptsCounter.set(targetAttempts);
|
mImportLegacyAttemptsCounter.set(targetAttempts);
|
||||||
// The successes counter is only for debugging. Hence, the synchronization
|
if (endedWithFallback) {
|
||||||
// between these two counters are not very critical.
|
Log.wtf(TAG, "Imported platform collections with legacy fallback");
|
||||||
final int successCount = mImportLegacySuccessesCounter.get();
|
final int fallbacksCount = mImportLegacyFallbacksCounter.get();
|
||||||
mImportLegacySuccessesCounter.set(successCount + 1);
|
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) {
|
} catch (IOException e) {
|
||||||
Log.wtf(TAG, "Succeed but failed to update counters.", 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",
|
pw.print("platform legacy stats import successes count",
|
||||||
mImportLegacySuccessesCounter.get());
|
mImportLegacySuccessesCounter.get());
|
||||||
pw.println();
|
pw.println();
|
||||||
|
pw.print("platform legacy stats import fallbacks count",
|
||||||
|
mImportLegacyFallbacksCounter.get());
|
||||||
|
pw.println();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
pw.println("(failed to dump platform legacy stats import counters)");
|
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.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.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 com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -141,6 +144,7 @@ import com.android.testutils.TestBpfMap;
|
|||||||
import com.android.testutils.TestableNetworkStatsProviderBinder;
|
import com.android.testutils.TestableNetworkStatsProviderBinder;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
@@ -239,6 +243,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
private int mImportLegacyTargetAttempts = 0;
|
private int mImportLegacyTargetAttempts = 0;
|
||||||
private @Mock PersistentInt mImportLegacyAttemptsCounter;
|
private @Mock PersistentInt mImportLegacyAttemptsCounter;
|
||||||
private @Mock PersistentInt mImportLegacySuccessesCounter;
|
private @Mock PersistentInt mImportLegacySuccessesCounter;
|
||||||
|
private @Mock PersistentInt mImportLegacyFallbacksCounter;
|
||||||
|
|
||||||
private class MockContext extends BroadcastInterceptingContext {
|
private class MockContext extends BroadcastInterceptingContext {
|
||||||
private final Context mBaseContext;
|
private final Context mBaseContext;
|
||||||
@@ -379,15 +384,18 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PersistentInt createImportLegacyAttemptsCounter(
|
public PersistentInt createPersistentCounter(@androidx.annotation.NonNull Path dir,
|
||||||
@androidx.annotation.NonNull Path path) {
|
@androidx.annotation.NonNull String name) throws IOException {
|
||||||
return mImportLegacyAttemptsCounter;
|
switch (name) {
|
||||||
}
|
case NETSTATS_IMPORT_ATTEMPTS_COUNTER_NAME:
|
||||||
|
return mImportLegacyAttemptsCounter;
|
||||||
@Override
|
case NETSTATS_IMPORT_SUCCESSES_COUNTER_NAME:
|
||||||
public PersistentInt createImportLegacySuccessesCounter(
|
return mImportLegacySuccessesCounter;
|
||||||
@androidx.annotation.NonNull Path path) {
|
case NETSTATS_IMPORT_FALLBACKS_COUNTER_NAME:
|
||||||
return mImportLegacySuccessesCounter;
|
return mImportLegacyFallbacksCounter;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown counter name: " + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1861,7 +1869,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private NetworkStatsCollection getLegacyCollection(String prefix, boolean includeTags) {
|
private NetworkStatsCollection getLegacyCollection(String prefix, boolean includeTags) {
|
||||||
final NetworkStatsRecorder recorder = makeTestRecorder(mLegacyStatsDir, PREFIX_DEV,
|
final NetworkStatsRecorder recorder = makeTestRecorder(mLegacyStatsDir, prefix,
|
||||||
mSettings.getDevConfig(), includeTags);
|
mSettings.getDevConfig(), includeTags);
|
||||||
return recorder.getOrLoadCompleteLocked();
|
return recorder.getOrLoadCompleteLocked();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user