Merge tag 'android-14.0.0_r17' into staging/lineage-21.0_merge-android-14.0.0_r17
Android 14.0.0 Release 17 (UQ1A.231205.015)
# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZXDPNAAKCRDorT+BmrEO
# eFM+AJ9m+Z/E/kowJ3tfdRRqadgPM+RjBACeMQkAHimCveNIXVGr3+QbJo/xivk=
# =2L8P
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed Dec 6 21:44:52 2023 EET
# gpg: using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [marginal]
# gpg: initial-contribution@android.com: Verified 2188 signatures in the past
# 2 years. Encrypted 4 messages in the past 23 months.
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg: It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 4340 D135 70EF 945E 8381 0964 E8AD 3F81 9AB1 0E78
# By Bill Yi (23) and others
# Via Automerger Merge Worker (915) and others
* tag 'android-14.0.0_r17': (32 commits)
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Remove unnecessary override of Parcelable.getStability()
Update tests for VPN data stall recovery
Skip writing the metrics before T.
Evaluation delay = 8 secs for explicitly selected networks
Allow firing the LOST_INTERNET intent immediately in config
[DO NOT MERGE] Disable tests that depend on the prebuilt version in U
Never create native network immediately.
Revert "Always disconnect agents immediately."
...
Change-Id: I120c41f8c98c681f7c19ec7d7758ea649e2affb4
diff --git a/Tethering/res/values-ky/strings.xml b/Tethering/res/values-ky/strings.xml
index 35e6453..4696a72 100644
--- a/Tethering/res/values-ky/strings.xml
+++ b/Tethering/res/values-ky/strings.xml
@@ -20,7 +20,7 @@
<string name="tethered_notification_message" msgid="2338023450330652098">"Тууралоо үчүн басыңыз."</string>
<string name="disable_tether_notification_title" msgid="3183576627492925522">"Модем режими өчүк"</string>
<string name="disable_tether_notification_message" msgid="6655882039707534929">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
- <string name="notification_channel_tethering_status" msgid="7030733422705019001">"Хотспот жана байланыш түйүнүүн статусу"</string>
+ <string name="notification_channel_tethering_status" msgid="7030733422705019001">"Байланыш түйүнү жана байланыш түйүнүүн статусу"</string>
<string name="no_upstream_notification_title" msgid="2052743091868702475"></string>
<string name="no_upstream_notification_message" msgid="6932020551635470134"></string>
<string name="no_upstream_notification_disable_button" msgid="8836277213343697023"></string>
diff --git a/nearby/halfsheet/res/values-zh-rCN/strings.xml b/nearby/halfsheet/res/values-zh-rCN/strings.xml
index 8117bac..55dd8b0 100644
--- a/nearby/halfsheet/res/values-zh-rCN/strings.xml
+++ b/nearby/halfsheet/res/values-zh-rCN/strings.xml
@@ -26,7 +26,7 @@
<string name="fast_pair_unable_to_connect_description" msgid="3926830740860653891">"请尝试手动与该设备配对"</string>
<string name="fast_pair_turn_on_bt_device_pairing_mode" msgid="3197372738187738030">"请尝试让设备进入配对模式"</string>
<string name="devices_within_reach_channel_name" msgid="876280551450910440">"附近的设备"</string>
- <string name="devices_with_your_account_channel_name" msgid="8120067812798598102">"与您的帐号相关联的设备"</string>
+ <string name="devices_with_your_account_channel_name" msgid="8120067812798598102">"与您的账号相关联的设备"</string>
<string name="fast_pair_your_device" msgid="3662423897069320840">"您保存的设备已可供使用"</string>
<string name="common_nearby_title" msgid="5480324514713607015">"附近"</string>
<string name="common_devices" msgid="2635603125608104442">"设备"</string>
diff --git a/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java b/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
index 7ab0523..d69d42d 100644
--- a/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
+++ b/nearby/service/java/com/android/server/nearby/provider/ChreDiscoveryProvider.java
@@ -132,7 +132,6 @@
protected void onSetScanFilters(List<ScanFilter> filters) {
synchronized (mLock) {
mScanFilters = filters == null ? null : List.copyOf(filters);
- updateFiltersLocked();
}
}
diff --git a/service/ServiceConnectivityResources/res/values-as/strings.xml b/service/ServiceConnectivityResources/res/values-as/strings.xml
index e753cb3..7e4dd42 100644
--- a/service/ServiceConnectivityResources/res/values-as/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-as/strings.xml
@@ -18,7 +18,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="connectivityResourcesAppLabel" msgid="2476261877900882974">"ছিষ্টেম সংযোগৰ উৎস"</string>
- <string name="wifi_available_sign_in" msgid="8041178343789805553">"ৱাই-ফাই নেটৱৰ্কত ছাইন ইন কৰক"</string>
+ <string name="wifi_available_sign_in" msgid="8041178343789805553">"Wi-Fi নেটৱৰ্কত ছাইন ইন কৰক"</string>
<string name="network_available_sign_in" msgid="2622520134876355561">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
<!-- no translation found for network_available_sign_in_detailed (8439369644697866359) -->
<skip />
diff --git a/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java b/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java
index d59d526..414aca3 100644
--- a/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java
+++ b/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java
@@ -45,6 +45,7 @@
import com.android.metrics.KeepaliveLifetimeForCarrier;
import com.android.metrics.KeepaliveLifetimePerCarrier;
import com.android.modules.utils.BackgroundThread;
+import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.CollectionUtils;
import com.android.server.ConnectivityStatsLog;
@@ -251,6 +252,22 @@
public long getElapsedRealtime() {
return SystemClock.elapsedRealtime();
}
+
+ /**
+ * Writes a DAILY_KEEPALIVE_INFO_REPORTED to ConnectivityStatsLog.
+ *
+ * @param dailyKeepaliveInfoReported the proto to write to statsD.
+ */
+ public void writeStats(DailykeepaliveInfoReported dailyKeepaliveInfoReported) {
+ ConnectivityStatsLog.write(
+ ConnectivityStatsLog.DAILY_KEEPALIVE_INFO_REPORTED,
+ dailyKeepaliveInfoReported.getDurationPerNumOfKeepalive().toByteArray(),
+ dailyKeepaliveInfoReported.getKeepaliveLifetimePerCarrier().toByteArray(),
+ dailyKeepaliveInfoReported.getKeepaliveRequests(),
+ dailyKeepaliveInfoReported.getAutomaticKeepaliveRequests(),
+ dailyKeepaliveInfoReported.getDistinctUserCount(),
+ CollectionUtils.toIntArray(dailyKeepaliveInfoReported.getUidList()));
+ }
}
public KeepaliveStatsTracker(@NonNull Context context, @NonNull Handler handler) {
@@ -637,15 +654,15 @@
/** Writes the stored metrics to ConnectivityStatsLog and resets. */
public void writeAndResetMetrics() {
ensureRunningOnHandlerThread();
+ // Keepalive stats use repeated atoms, which are only supported on T+. If written to statsd
+ // on S- they will bootloop the system, so they must not be sent on S-. See b/289471411.
+ if (!SdkLevel.isAtLeastT()) {
+ Log.d(TAG, "KeepaliveStatsTracker is disabled before T, skipping write");
+ return;
+ }
+
final DailykeepaliveInfoReported dailyKeepaliveInfoReported = buildAndResetMetrics();
- ConnectivityStatsLog.write(
- ConnectivityStatsLog.DAILY_KEEPALIVE_INFO_REPORTED,
- dailyKeepaliveInfoReported.getDurationPerNumOfKeepalive().toByteArray(),
- dailyKeepaliveInfoReported.getKeepaliveLifetimePerCarrier().toByteArray(),
- dailyKeepaliveInfoReported.getKeepaliveRequests(),
- dailyKeepaliveInfoReported.getAutomaticKeepaliveRequests(),
- dailyKeepaliveInfoReported.getDistinctUserCount(),
- CollectionUtils.toIntArray(dailyKeepaliveInfoReported.getUidList()));
+ mDependencies.writeStats(dailyKeepaliveInfoReported);
}
private void ensureRunningOnHandlerThread() {
diff --git a/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java b/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
index 0d2e540..0d1b548 100644
--- a/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
@@ -19,6 +19,8 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
+import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import static com.android.testutils.HandlerUtils.visibleOnHandlerThread;
import static org.junit.Assert.assertArrayEquals;
@@ -31,6 +33,7 @@
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.content.BroadcastReceiver;
@@ -62,6 +65,7 @@
import com.android.testutils.HandlerUtils;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -103,6 +107,8 @@
.build();
}
+ @Rule public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
private HandlerThread mHandlerThread;
private Handler mTestHandler;
@@ -1192,4 +1198,43 @@
expectKeepaliveCarrierStats1, expectKeepaliveCarrierStats2
});
}
+
+ @Test
+ @IgnoreAfter(Build.VERSION_CODES.S_V2)
+ public void testWriteMetrics_doNothingBeforeT() {
+ // Keepalive stats use repeated atoms, which are only supported on T+. If written to statsd
+ // on S- they will bootloop the system, so they must not be sent on S-. See b/289471411.
+ final int writeTime = 1000;
+ setElapsedRealtime(writeTime);
+ visibleOnHandlerThread(mTestHandler, () -> mKeepaliveStatsTracker.writeAndResetMetrics());
+ verify(mDependencies, never()).writeStats(any());
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testWriteMetrics() {
+ final int writeTime = 1000;
+
+ final ArgumentCaptor<DailykeepaliveInfoReported> dailyKeepaliveInfoReportedCaptor =
+ ArgumentCaptor.forClass(DailykeepaliveInfoReported.class);
+
+ setElapsedRealtime(writeTime);
+ visibleOnHandlerThread(mTestHandler, () -> mKeepaliveStatsTracker.writeAndResetMetrics());
+ // Ensure writeStats is called with the correct DailykeepaliveInfoReported metrics.
+ verify(mDependencies).writeStats(dailyKeepaliveInfoReportedCaptor.capture());
+ final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
+ dailyKeepaliveInfoReportedCaptor.getValue();
+
+ // Same as the no keepalive case
+ final int[] expectRegisteredDurations = new int[] {writeTime};
+ final int[] expectActiveDurations = new int[] {writeTime};
+ assertDailyKeepaliveInfoReported(
+ dailyKeepaliveInfoReported,
+ /* expectRequestsCount= */ 0,
+ /* expectAutoRequestsCount= */ 0,
+ /* expectAppUids= */ new int[0],
+ expectRegisteredDurations,
+ expectActiveDurations,
+ new KeepaliveCarrierStats[0]);
+ }
}
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index f7b9fcf..ff98853 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -2745,23 +2745,31 @@
new PersistableBundle());
}
- private void verifyMobikeTriggered(List<Network> expected) {
+ private void verifyMobikeTriggered(List<Network> expected, int retryIndex) {
+ // Verify retry is scheduled
+ final long expectedDelaySec = mTestDeps.getValidationFailRecoverySeconds(retryIndex);
+ final ArgumentCaptor<Long> delayCaptor = ArgumentCaptor.forClass(Long.class);
+ verify(mExecutor, times(retryIndex + 1)).schedule(
+ any(Runnable.class), delayCaptor.capture(), eq(TimeUnit.SECONDS));
+ final List<Long> delays = delayCaptor.getAllValues();
+ assertEquals(expectedDelaySec, (long) delays.get(delays.size() - 1));
+
final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class);
- verify(mIkeSessionWrapper).setNetwork(networkCaptor.capture(),
- anyInt() /* ipVersion */, anyInt() /* encapType */, anyInt() /* keepaliveDelay */);
+ // TODO: Make the timeout shorter if real timeout will be used
+ verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS + expectedDelaySec * 1000))
+ .setNetwork(networkCaptor.capture(), anyInt() /* ipVersion */,
+ anyInt() /* encapType */, anyInt() /* keepaliveDelay */);
assertEquals(expected, Collections.singletonList(networkCaptor.getValue()));
}
@Test
public void testDataStallInIkev2VpnMobikeDisabled() throws Exception {
- verifySetupPlatformVpn(
+ final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */));
doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork();
- final ConnectivityDiagnosticsCallback connectivityDiagCallback =
- getConnectivityDiagCallback();
- final DataStallReport report = createDataStallReport();
- connectivityDiagCallback.onDataStallSuspected(report);
+ ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
+ NetworkAgent.VALIDATION_STATUS_NOT_VALID);
// Should not trigger MOBIKE if MOBIKE is not enabled
verify(mIkeSessionWrapper, never()).setNetwork(any() /* network */,
@@ -2774,19 +2782,11 @@
createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */));
doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork();
- final ConnectivityDiagnosticsCallback connectivityDiagCallback =
- getConnectivityDiagCallback();
- final DataStallReport report = createDataStallReport();
- connectivityDiagCallback.onDataStallSuspected(report);
-
+ ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
+ NetworkAgent.VALIDATION_STATUS_NOT_VALID);
// Verify MOBIKE is triggered
- verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks());
-
- // Expect to skip other data stall event if MOBIKE was started.
- reset(mIkeSessionWrapper);
- connectivityDiagCallback.onDataStallSuspected(report);
- verify(mIkeSessionWrapper, never()).setNetwork(any() /* network */,
- anyInt() /* ipVersion */, anyInt() /* encapType */, anyInt() /* keepaliveDelay */);
+ verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(),
+ 0 /* retryIndex */);
reset(mIkev2SessionCreator);
@@ -2796,14 +2796,6 @@
NetworkAgent.VALIDATION_STATUS_VALID);
verify(mIkev2SessionCreator, never()).createIkeSession(
any(), any(), any(), any(), any(), any());
-
- // Send invalid result to verify no ike session reset since the data stall suspected
- // variables(timer counter and boolean) was reset.
- ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
- NetworkAgent.VALIDATION_STATUS_NOT_VALID);
- verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any());
- verify(mIkev2SessionCreator, never()).createIkeSession(
- any(), any(), any(), any(), any(), any());
}
@Test
@@ -2811,31 +2803,46 @@
final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */));
- final ConnectivityDiagnosticsCallback connectivityDiagCallback =
- getConnectivityDiagCallback();
-
+ int retry = 0;
doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork();
- final DataStallReport report = createDataStallReport();
- connectivityDiagCallback.onDataStallSuspected(report);
-
- verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks());
+ ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
+ NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(),
+ retry++);
reset(mIkev2SessionCreator);
+ // Second validation status update.
+ ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
+ NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(),
+ retry++);
+
+ // Use real delay to verify reset session will not be performed if there is an existing
+ // recovery for resetting the session.
+ mExecutor.delayMs = TestExecutor.REAL_DELAY;
+ mExecutor.executeDirect = true;
// Send validation status update should result in ike session reset.
((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
NetworkAgent.VALIDATION_STATUS_NOT_VALID);
- // Verify reset is scheduled and run.
- verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any());
+ // Verify session reset is scheduled
+ long expectedDelay = mTestDeps.getValidationFailRecoverySeconds(retry++);
+ final ArgumentCaptor<Long> delayCaptor = ArgumentCaptor.forClass(Long.class);
+ verify(mExecutor, times(retry)).schedule(any(Runnable.class), delayCaptor.capture(),
+ eq(TimeUnit.SECONDS));
+ final List<Long> delays = delayCaptor.getAllValues();
+ assertEquals(expectedDelay, (long) delays.get(delays.size() - 1));
// Another invalid status reported should not trigger other scheduled recovery.
- reset(mExecutor);
+ expectedDelay = mTestDeps.getValidationFailRecoverySeconds(retry++);
((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
NetworkAgent.VALIDATION_STATUS_NOT_VALID);
- verify(mExecutor, never()).schedule(any(Runnable.class), anyLong(), any());
+ verify(mExecutor, never()).schedule(
+ any(Runnable.class), eq(expectedDelay), eq(TimeUnit.SECONDS));
- verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS))
+ // Verify that session being reset
+ verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS + expectedDelay * 1000))
.createIkeSession(any(), any(), any(), any(), any(), any());
}
@@ -3114,6 +3121,12 @@
}
@Override
+ public long getValidationFailRecoverySeconds(int retryCount) {
+ // Simply return retryCount as the delay seconds for retrying.
+ return retryCount;
+ }
+
+ @Override
public ScheduledThreadPoolExecutor newScheduledThreadPoolExecutor() {
return mExecutor;
}