Merge "Get ANR delay from the MediaProvider" into sc-dev
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 4e25625..51d5139 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -223,6 +223,14 @@
field @NonNull public final java.util.List<java.lang.String> underlyingIfaces;
}
+ public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
+ ctor public VpnTransportInfo(int);
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
+ field public final int type;
+ }
+
}
package android.os {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 31ccf1e..b261d92 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -246,6 +246,7 @@
field public static final String SET_WALLPAPER_COMPONENT = "android.permission.SET_WALLPAPER_COMPONENT";
field public static final String SHOW_KEYGUARD_MESSAGE = "android.permission.SHOW_KEYGUARD_MESSAGE";
field public static final String SHUTDOWN = "android.permission.SHUTDOWN";
+ field public static final String SIGNAL_REBOOT_READINESS = "android.permission.SIGNAL_REBOOT_READINESS";
field public static final String SOUND_TRIGGER_RUN_IN_BATTERY_SAVER = "android.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER";
field public static final String START_ACTIVITIES_FROM_BACKGROUND = "android.permission.START_ACTIVITIES_FROM_BACKGROUND";
field public static final String START_FOREGROUND_SERVICES_FROM_BACKGROUND = "android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND";
@@ -11077,6 +11078,8 @@
}
public static final class CarrierConfigManager.Wifi {
+ field public static final String KEY_AVOID_5GHZ_SOFTAP_FOR_LAA_BOOL = "wifi.avoid_5ghz_softap_for_laa_bool";
+ field public static final String KEY_AVOID_5GHZ_WIFI_DIRECT_FOR_LAA_BOOL = "wifi.avoid_5ghz_wifi_direct_for_laa_bool";
field public static final String KEY_HOTSPOT_MAX_CLIENT_COUNT = "wifi.hotspot_maximum_client_count";
field public static final String KEY_PREFIX = "wifi.";
field public static final String KEY_SUGGESTION_SSID_LIST_WITH_MAC_RANDOMIZATION_DISABLED = "wifi.suggestion_ssid_list_with_mac_randomization_disabled";
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index d5e9570..c047fc2 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -128,11 +128,13 @@
import android.net.IEthernetManager;
import android.net.IIpSecService;
import android.net.INetworkPolicyManager;
+import android.net.IVpnManager;
import android.net.IpSecManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkScoreManager;
import android.net.NetworkWatchlistManager;
import android.net.TetheringManager;
+import android.net.VpnManager;
import android.net.lowpan.ILowpanManager;
import android.net.lowpan.LowpanManager;
import android.net.nsd.INsdManager;
@@ -384,6 +386,15 @@
ctx, () -> ServiceManager.getService(Context.TETHERING_SERVICE));
}});
+ registerService(Context.VPN_MANAGEMENT_SERVICE, VpnManager.class,
+ new CachedServiceFetcher<VpnManager>() {
+ @Override
+ public VpnManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getService(Context.VPN_MANAGEMENT_SERVICE);
+ IVpnManager service = IVpnManager.Stub.asInterface(b);
+ return new VpnManager(ctx, service);
+ }});
+
registerService(Context.VCN_MANAGEMENT_SERVICE, VcnManager.class,
new CachedServiceFetcher<VcnManager>() {
@Override
diff --git a/core/java/android/net/IVpnManager.aidl b/core/java/android/net/IVpnManager.aidl
new file mode 100644
index 0000000..271efe4
--- /dev/null
+++ b/core/java/android/net/IVpnManager.aidl
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.Network;
+
+import com.android.internal.net.LegacyVpnInfo;
+import com.android.internal.net.VpnConfig;
+import com.android.internal.net.VpnProfile;
+
+/**
+ * Interface that manages VPNs.
+ */
+/** {@hide} */
+interface IVpnManager {
+ /** VpnService APIs */
+ boolean prepareVpn(String oldPackage, String newPackage, int userId);
+ void setVpnPackageAuthorization(String packageName, int userId, int vpnType);
+ ParcelFileDescriptor establishVpn(in VpnConfig config);
+ boolean addVpnAddress(String address, int prefixLength);
+ boolean removeVpnAddress(String address, int prefixLength);
+ boolean setUnderlyingNetworksForVpn(in Network[] networks);
+
+ /** VpnManager APIs */
+ boolean provisionVpnProfile(in VpnProfile profile, String packageName);
+ void deleteVpnProfile(String packageName);
+ void startVpnProfile(String packageName);
+ void stopVpnProfile(String packageName);
+
+ /** Always-on VPN APIs */
+ boolean isAlwaysOnVpnPackageSupported(int userId, String packageName);
+ boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown,
+ in List<String> lockdownAllowlist);
+ String getAlwaysOnVpnPackage(int userId);
+ boolean isVpnLockdownEnabled(int userId);
+ List<String> getVpnLockdownAllowlist(int userId);
+ boolean isCallerCurrentAlwaysOnVpnApp();
+ boolean isCallerCurrentAlwaysOnVpnLockdownApp();
+
+ /** Legacy VPN APIs */
+ void startLegacyVpn(in VpnProfile profile);
+ LegacyVpnInfo getLegacyVpnInfo(int userId);
+ boolean updateLockdownVpn();
+
+ /** General system APIs */
+ VpnConfig getVpnConfig(int userId);
+ void factoryReset();
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 201c529..ba43ee7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5471,6 +5471,13 @@
<permission android:name="android.permission.MANAGE_GAME_MODE"
android:protectionLevel="signature" />
+ <!-- @SystemApi Allows the holder to register callbacks to inform the RebootReadinessManager
+ when they are performing reboot-blocking work.
+ @hide -->
+ <permission android:name="android.permission.SIGNAL_REBOOT_READINESS"
+ android:protectionLevel="signature|privileged" />
+
+
<!-- Attribution for Geofencing service. -->
<attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
<!-- Attribution for Country Detector. -->
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 0484a9a..403dc65 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -474,6 +474,8 @@
<!-- Permission required for GTS test - GtsAssistIntentTestCases -->
<permission name="android.permission.MANAGE_SOUND_TRIGGER" />
<permission name="android.permission.CAPTURE_AUDIO_HOTWORD" />
+ <!-- Permission required for CTS test - CtsRebootReadinessTestCases -->
+ <permission name="android.permission.SIGNAL_REBOOT_READINESS" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
index 9afa5d1..92a792b 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
@@ -49,17 +49,6 @@
}
);
- // TODO: move outside of the connectivity JAR
- SystemServiceRegistry.registerContextAwareService(
- Context.VPN_MANAGEMENT_SERVICE,
- VpnManager.class,
- (context) -> {
- final ConnectivityManager cm = context.getSystemService(
- ConnectivityManager.class);
- return cm.createVpnManager();
- }
- );
-
SystemServiceRegistry.registerContextAwareService(
Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
ConnectivityDiagnosticsManager.class,
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index 0a02e3a..92d7bf0 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -824,6 +824,7 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
private final IConnectivityManager mService;
+
/**
* A kludge to facilitate static access where a Context pointer isn't available, like in the
* case of the static set/getProcessDefaultNetwork methods and from the Network class.
@@ -1069,106 +1070,55 @@
}
/**
- * Checks if a VPN app supports always-on mode.
- *
- * In order to support the always-on feature, an app has to
- * <ul>
- * <li>target {@link VERSION_CODES#N API 24} or above, and
- * <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
- * meta-data field.
- * </ul>
- *
- * @param userId The identifier of the user for whom the VPN app is installed.
- * @param vpnPackage The canonical package name of the VPN app.
- * @return {@code true} if and only if the VPN app exists and supports always-on mode.
+ * Calls VpnManager#isAlwaysOnVpnPackageSupportedForUser.
+ * @deprecated TODO: remove when callers have migrated to VpnManager.
* @hide
*/
+ @Deprecated
public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
- try {
- return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getVpnManager().isAlwaysOnVpnPackageSupportedForUser(userId, vpnPackage);
}
/**
- * Configures an always-on VPN connection through a specific application.
- * This connection is automatically granted and persisted after a reboot.
- *
- * <p>The designated package should declare a {@link VpnService} in its
- * manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
- * otherwise the call will fail.
- *
- * @param userId The identifier of the user to set an always-on VPN for.
- * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
- * to remove an existing always-on VPN configuration.
- * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
- * {@code false} otherwise.
- * @param lockdownAllowlist The list of packages that are allowed to access network directly
- * when VPN is in lockdown mode but is not running. Non-existent packages are ignored so
- * this method must be called when a package that should be allowed is installed or
- * uninstalled.
- * @return {@code true} if the package is set as always-on VPN controller;
- * {@code false} otherwise.
+ * Calls VpnManager#setAlwaysOnVpnPackageForUser.
+ * @deprecated TODO: remove when callers have migrated to VpnManager.
* @hide
*/
- @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
+ @Deprecated
public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
- try {
- return mService.setAlwaysOnVpnPackage(
- userId, vpnPackage, lockdownEnabled, lockdownAllowlist);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getVpnManager().setAlwaysOnVpnPackageForUser(userId, vpnPackage, lockdownEnabled,
+ lockdownAllowlist);
}
- /**
- * Returns the package name of the currently set always-on VPN application.
- * If there is no always-on VPN set, or the VPN is provided by the system instead
- * of by an app, {@code null} will be returned.
- *
- * @return Package name of VPN controller responsible for always-on VPN,
- * or {@code null} if none is set.
+ /**
+ * Calls VpnManager#getAlwaysOnVpnPackageForUser.
+ * @deprecated TODO: remove when callers have migrated to VpnManager.
* @hide
*/
- @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
+ @Deprecated
public String getAlwaysOnVpnPackageForUser(int userId) {
- try {
- return mService.getAlwaysOnVpnPackage(userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getVpnManager().getAlwaysOnVpnPackageForUser(userId);
}
/**
- * @return whether always-on VPN is in lockdown mode.
- *
+ * Calls VpnManager#isVpnLockdownEnabled.
+ * @deprecated TODO: remove when callers have migrated to VpnManager.
* @hide
- **/
- @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
+ */
+ @Deprecated
public boolean isVpnLockdownEnabled(int userId) {
- try {
- return mService.isVpnLockdownEnabled(userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
+ return getVpnManager().isVpnLockdownEnabled(userId);
}
/**
- * @return the list of packages that are allowed to access network when always-on VPN is in
- * lockdown mode but not connected. Returns {@code null} when VPN lockdown is not active.
- *
+ * Calls VpnManager#getVpnLockdownAllowlist.
+ * @deprecated TODO: remove when callers have migrated to VpnManager.
* @hide
- **/
- @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
- public List<String> getVpnLockdownWhitelist(int userId) {
- try {
- return mService.getVpnLockdownWhitelist(userId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ */
+ @Deprecated
+ public List<String> getVpnLockdownAllowlist(int userId) {
+ return getVpnManager().getVpnLockdownAllowlist(userId);
}
/**
@@ -1221,6 +1171,45 @@
}
/**
+ * Informs ConnectivityService of whether the legacy lockdown VPN, as implemented by
+ * LockdownVpnTracker, is in use. This is deprecated for new devices starting from Android 12
+ * but is still supported for backwards compatibility.
+ * <p>
+ * This type of VPN is assumed always to use the system default network, and must always declare
+ * exactly one underlying network, which is the network that was the default when the VPN
+ * connected.
+ * <p>
+ * Calling this method with {@code true} enables legacy behaviour, specifically:
+ * <ul>
+ * <li>Any VPN that applies to userId 0 behaves specially with respect to deprecated
+ * {@link #CONNECTIVITY_ACTION} broadcasts. Any such broadcasts will have the state in the
+ * {@link #EXTRA_NETWORK_INFO} replaced by state of the VPN network. Also, any time the VPN
+ * connects, a {@link #CONNECTIVITY_ACTION} broadcast will be sent for the network
+ * underlying the VPN.</li>
+ * <li>Deprecated APIs that return {@link NetworkInfo} objects will have their state
+ * similarly replaced by the VPN network state.</li>
+ * <li>Information on current network interfaces passed to NetworkStatsService will not
+ * include any VPN interfaces.</li>
+ * </ul>
+ *
+ * @param enabled whether legacy lockdown VPN is enabled or disabled
+ *
+ * TODO: @SystemApi(client = MODULE_LIBRARIES)
+ *
+ * @hide
+ */
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_SETTINGS})
+ public void setLegacyLockdownVpnEnabled(boolean enabled) {
+ try {
+ mService.setLegacyLockdownVpnEnabled(enabled);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Returns details about the currently active default data network
* for a given uid. This is for internal use only to avoid spying
* other apps.
@@ -3180,20 +3169,13 @@
}
/**
- * If the LockdownVpn mechanism is enabled, updates the vpn
- * with a reload of its profile.
- *
- * @return a boolean with {@code} indicating success
- *
- * <p>This method can only be called by the system UID
- * {@hide}
+ * Calls VpnManager#updateLockdownVpn.
+ * @deprecated TODO: remove when callers have migrated to VpnManager.
+ * @hide
*/
+ @Deprecated
public boolean updateLockdownVpn() {
- try {
- return mService.updateLockdownVpn();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getVpnManager().updateLockdownVpn();
}
/**
@@ -4557,6 +4539,8 @@
try {
mService.factoryReset();
mTetheringManager.stopAllTethering();
+ // TODO: Migrate callers to VpnManager#factoryReset.
+ getVpnManager().factoryReset();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4850,9 +4834,13 @@
return new TestNetworkManager(ITestNetworkManager.Stub.asInterface(tnBinder));
}
- /** @hide */
- public VpnManager createVpnManager() {
- return new VpnManager(mContext, mService);
+ /**
+ * Temporary hack to shim calls from ConnectivityManager to VpnManager. We cannot store a
+ * private final mVpnManager because ConnectivityManager is initialized before VpnManager.
+ * @hide TODO: remove.
+ */
+ public VpnManager getVpnManager() {
+ return mContext.getSystemService(VpnManager.class);
}
/** @hide */
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index befd4fb..6391802 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -43,9 +43,6 @@
import android.os.ResultReceiver;
import com.android.connectivity.aidl.INetworkAgent;
-import com.android.internal.net.LegacyVpnInfo;
-import com.android.internal.net.VpnConfig;
-import com.android.internal.net.VpnProfile;
/**
* Interface that answers queries about, and allows changing, the
@@ -123,35 +120,8 @@
ProxyInfo getProxyForNetwork(in Network nework);
- boolean prepareVpn(String oldPackage, String newPackage, int userId);
-
- void setVpnPackageAuthorization(String packageName, int userId, int vpnType);
-
- ParcelFileDescriptor establishVpn(in VpnConfig config);
-
- boolean provisionVpnProfile(in VpnProfile profile, String packageName);
-
- void deleteVpnProfile(String packageName);
-
- void startVpnProfile(String packageName);
-
- void stopVpnProfile(String packageName);
-
- VpnConfig getVpnConfig(int userId);
-
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- void startLegacyVpn(in VpnProfile profile);
-
- LegacyVpnInfo getLegacyVpnInfo(int userId);
-
- boolean updateLockdownVpn();
- boolean isAlwaysOnVpnPackageSupported(int userId, String packageName);
- boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown,
- in List<String> lockdownWhitelist);
- String getAlwaysOnVpnPackage(int userId);
- boolean isVpnLockdownEnabled(int userId);
- List<String> getVpnLockdownWhitelist(int userId);
void setRequireVpnForUids(boolean requireVpn, in UidRange[] ranges);
+ void setLegacyLockdownVpnEnabled(boolean enabled);
void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);
@@ -200,10 +170,6 @@
int getRestoreDefaultNetworkDelay(int networkType);
- boolean addVpnAddress(String address, int prefixLength);
- boolean removeVpnAddress(String address, int prefixLength);
- boolean setUnderlyingNetworksForVpn(in Network[] networks);
-
void factoryReset();
void startNattKeepalive(in Network network, int intervalSeconds,
@@ -223,8 +189,6 @@
byte[] getNetworkWatchlistConfigHash();
int getConnectionOwnerUid(in ConnectionInfo connectionInfo);
- boolean isCallerCurrentAlwaysOnVpnApp();
- boolean isCallerCurrentAlwaysOnVpnLockdownApp();
void registerConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback,
in NetworkRequest request, String callingPackageName);
diff --git a/packages/Connectivity/framework/src/android/net/VpnManager.java b/packages/Connectivity/framework/src/android/net/VpnManager.java
index 1e30283..f472ed4 100644
--- a/packages/Connectivity/framework/src/android/net/VpnManager.java
+++ b/packages/Connectivity/framework/src/android/net/VpnManager.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.content.ComponentName;
@@ -37,6 +38,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.security.GeneralSecurityException;
+import java.util.List;
/**
* This class provides an interface for apps to manage platform VPN profiles
@@ -76,13 +78,19 @@
@Deprecated
public static final int TYPE_VPN_LEGACY = 3;
+ /**
+ * Channel for VPN notifications.
+ * @hide
+ */
+ public static final String NOTIFICATION_CHANNEL_VPN = "VPN";
+
/** @hide */
@IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM, TYPE_VPN_LEGACY})
@Retention(RetentionPolicy.SOURCE)
public @interface VpnType {}
@NonNull private final Context mContext;
- @NonNull private final IConnectivityManager mService;
+ @NonNull private final IVpnManager mService;
private static Intent getIntentForConfirmation() {
final Intent intent = new Intent();
@@ -101,9 +109,9 @@
*
* @hide
*/
- public VpnManager(@NonNull Context ctx, @NonNull IConnectivityManager service) {
+ public VpnManager(@NonNull Context ctx, @NonNull IVpnManager service) {
mContext = checkNotNull(ctx, "missing Context");
- mService = checkNotNull(service, "missing IConnectivityManager");
+ mService = checkNotNull(service, "missing IVpnManager");
}
/**
@@ -195,6 +203,19 @@
}
/**
+ * Resets all VPN settings back to factory defaults.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ public void factoryReset() {
+ try {
+ mService.factoryReset();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Prepare for a VPN application.
* VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
* {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
@@ -240,6 +261,108 @@
}
/**
+ * Checks if a VPN app supports always-on mode.
+ *
+ * In order to support the always-on feature, an app has to
+ * <ul>
+ * <li>target {@link VERSION_CODES#N API 24} or above, and
+ * <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
+ * meta-data field.
+ * </ul>
+ *
+ * @param userId The identifier of the user for whom the VPN app is installed.
+ * @param vpnPackage The canonical package name of the VPN app.
+ * @return {@code true} if and only if the VPN app exists and supports always-on mode.
+ * @hide
+ */
+ public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
+ try {
+ return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Configures an always-on VPN connection through a specific application.
+ * This connection is automatically granted and persisted after a reboot.
+ *
+ * <p>The designated package should declare a {@link VpnService} in its
+ * manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
+ * otherwise the call will fail.
+ *
+ * @param userId The identifier of the user to set an always-on VPN for.
+ * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
+ * to remove an existing always-on VPN configuration.
+ * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
+ * {@code false} otherwise.
+ * @param lockdownAllowlist The list of packages that are allowed to access network directly
+ * when VPN is in lockdown mode but is not running. Non-existent packages are ignored so
+ * this method must be called when a package that should be allowed is installed or
+ * uninstalled.
+ * @return {@code true} if the package is set as always-on VPN controller;
+ * {@code false} otherwise.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
+ public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
+ boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
+ try {
+ return mService.setAlwaysOnVpnPackage(
+ userId, vpnPackage, lockdownEnabled, lockdownAllowlist);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns the package name of the currently set always-on VPN application.
+ * If there is no always-on VPN set, or the VPN is provided by the system instead
+ * of by an app, {@code null} will be returned.
+ *
+ * @return Package name of VPN controller responsible for always-on VPN,
+ * or {@code null} if none is set.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
+ public String getAlwaysOnVpnPackageForUser(int userId) {
+ try {
+ return mService.getAlwaysOnVpnPackage(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @return whether always-on VPN is in lockdown mode.
+ *
+ * @hide
+ **/
+ @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
+ public boolean isVpnLockdownEnabled(int userId) {
+ try {
+ return mService.isVpnLockdownEnabled(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @return the list of packages that are allowed to access network when always-on VPN is in
+ * lockdown mode but not connected. Returns {@code null} when VPN lockdown is not active.
+ *
+ * @hide
+ **/
+ @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
+ public List<String> getVpnLockdownAllowlist(int userId) {
+ try {
+ return mService.getVpnLockdownAllowlist(userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Return the legacy VPN information for the specified user ID.
* @hide
*/
diff --git a/packages/Connectivity/framework/src/android/net/VpnService.java b/packages/Connectivity/framework/src/android/net/VpnService.java
index 8e90a119..e43b0b6 100644
--- a/packages/Connectivity/framework/src/android/net/VpnService.java
+++ b/packages/Connectivity/framework/src/android/net/VpnService.java
@@ -170,12 +170,11 @@
"android.net.VpnService.SUPPORTS_ALWAYS_ON";
/**
- * Use IConnectivityManager since those methods are hidden and not
- * available in ConnectivityManager.
+ * Use IVpnManager since those methods are hidden and not available in VpnManager.
*/
- private static IConnectivityManager getService() {
- return IConnectivityManager.Stub.asInterface(
- ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+ private static IVpnManager getService() {
+ return IVpnManager.Stub.asInterface(
+ ServiceManager.getService(Context.VPN_MANAGEMENT_SERVICE));
}
/**
@@ -226,15 +225,15 @@
@SystemApi
@RequiresPermission(android.Manifest.permission.CONTROL_VPN)
public static void prepareAndAuthorize(Context context) {
- IConnectivityManager cm = getService();
+ IVpnManager vm = getService();
String packageName = context.getPackageName();
try {
// Only prepare if we're not already prepared.
int userId = context.getUserId();
- if (!cm.prepareVpn(packageName, null, userId)) {
- cm.prepareVpn(null, packageName, userId);
+ if (!vm.prepareVpn(packageName, null, userId)) {
+ vm.prepareVpn(null, packageName, userId);
}
- cm.setVpnPackageAuthorization(packageName, userId, VpnManager.TYPE_VPN_SERVICE);
+ vm.setVpnPackageAuthorization(packageName, userId, VpnManager.TYPE_VPN_SERVICE);
} catch (RemoteException e) {
// ignore
}
diff --git a/core/java/android/net/VpnTransportInfo.java b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
similarity index 88%
rename from core/java/android/net/VpnTransportInfo.java
rename to packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
index 082fa58..0242ba0 100644
--- a/core/java/android/net/VpnTransportInfo.java
+++ b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
@@ -16,8 +16,10 @@
package android.net;
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
import android.annotation.NonNull;
-import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -26,7 +28,15 @@
import java.util.Objects;
-/** @hide */
+/**
+ * Container for VPN-specific transport information.
+ *
+ * @see android.net.TransportInfo
+ * @see NetworkCapabilities#getTransportInfo()
+ *
+ * @hide
+ */
+@SystemApi(client = MODULE_LIBRARIES)
public final class VpnTransportInfo implements TransportInfo, Parcelable {
private static final SparseArray<String> sTypeToString =
MessageUtils.findMessageNames(new Class[]{VpnManager.class}, new String[]{"TYPE_VPN_"});
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 34e1152..577fb66 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Skep tans nuwe gebruiker …"</string>
<string name="user_nickname" msgid="262624187455825083">"Bynaam"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Voeg gas by"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Beëindig gastesessie"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Verwyder gas"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gas"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data, drie stawe."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Datasein vol."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet is ontkoppel."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 6c7f877..c554e2e 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"አዲስ ተጠቃሚ በመፍጠር ላይ…"</string>
<string name="user_nickname" msgid="262624187455825083">"ቅጽል ስም"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"እንግዳን አክል"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"የእንግዳ ክፍለ-ጊዜ ጨርስ"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"እንግዳን አስወግድ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"እንግዳ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ፎቶ አንሳ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ምስል ይምረጡ"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"የውሂብ ሦስት አሞሌዎች።"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"የውሂብ አመልካች ሙሉ ነው።"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ኤተርኔት ተነቅሏል።"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ኢተርኔት።"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index e87939d..b23cebd 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -558,7 +558,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"جارٍ إنشاء مستخدم جديد…"</string>
<string name="user_nickname" msgid="262624187455825083">"اللقب"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"إضافة ضيف"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"إنهاء جلسة الضيف"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"إزالة جلسة الضيف"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ضيف"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"التقاط صورة"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"اختيار صورة"</string>
@@ -595,6 +595,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"إشارة البيانات تتكون من ثلاثة أشرطة."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"إشارة البيانات كاملة."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"تم قطع اتصال Ethernet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"إيثرنت"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 6575f1a..2380b2f 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰি থকা হৈছে…"</string>
<string name="user_nickname" msgid="262624187455825083">"উপনাম"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ কৰক"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"অতিথিৰ ছেশ্বন সমাপ্ত কৰক"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string>
<string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"এখন ফট’ তোলক"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"ডেটা ছিংগনেলত তিনিডাল দণ্ড আছে।"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"ডেটা ছিগনেল পূৰা আছে।"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ইথাৰনেট সংযোগ বিচ্ছিন্ন হৈছে।"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ইথাৰনেট।"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index da4d512..f70bb84 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Yeni istifadəçi yaradılır…"</string>
<string name="user_nickname" msgid="262624187455825083">"Ləqəb"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Qonaq əlavə edin"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Qonaq sessiyasını bitirin"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Qonağı silin"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Qonaq"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Foto çəkin"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Şəkil seçin"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data üç xətdir."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Data siqnalı tamdır."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet bağlantısı kəsilib."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4c79265..749f864 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -555,7 +555,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Pravi se novi korisnik…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Završi sesiju gosta"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
@@ -592,6 +592,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Signal za podatke od tri crte."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Signal za podatke je najjači."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Veza sa eternetom je prekinuta."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Eternet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 3a9141ff..6b2740d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Ствараецца новы карыстальнік…"</string>
<string name="user_nickname" msgid="262624187455825083">"Псеўданім"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Дадаць госця"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Завяршыць гасцявы сеанс"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Выдаліць госця"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Госць"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Зрабіць фота"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Выбраць відарыс"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"3 планкі дадзеных."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Поўны сігнал перадачы дадзеных."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet адлучаны."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 8f1a43c..1a24b9e 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Създава се нов потребител…"</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавяне на гост"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Прекратяване на сесията като гост"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Премахване на госта"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гост"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Правене на снимка"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Избиране на изображение"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Сигналът за данни е пълен."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Връзката с Ethernet е прекратена."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index afa6521..1c9f84f 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"নতুন ব্যবহারকারী তৈরি করা হচ্ছে…"</string>
<string name="user_nickname" msgid="262624187455825083">"বিশেষ নাম"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ করুন"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"গেস্ট সেশন শেষ করুন"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি সরান"</string>
<string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ফটো তুলুন"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"একটি ইমেজ বেছে নিন"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"পূর্ণ ডেটার সংকেত রয়েছে৷"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ইথারনেটের সংযোগ বিচ্ছিন্ন হয়েছে৷"</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ইথারনেট।"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index ae4a157..f701421 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -555,7 +555,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Kreiranje novog korisnika…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Završi sesiju gosta"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string>
@@ -592,6 +592,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Prijenos podataka na tri crtice."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Signal za prijenos podataka pun."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Veza sa Ethernetom je prekinuta."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index fd81f99..78ef109 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"S\'està creant l\'usuari…"</string>
<string name="user_nickname" msgid="262624187455825083">"Àlies"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Afegeix un convidat"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Finalitza la sessió de convidat"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Suprimeix el convidat"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidat"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Senyal de dades: tres barres."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Senyal de dades: complet."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"S\'ha desconnectat l\'Ethernet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index e35bd00..8ca9800 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Vytváření nového uživatele…"</string>
<string name="user_nickname" msgid="262624187455825083">"Přezdívka"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Přidat hosta"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Ukončení relace hosta"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Odstranit hosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Host"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Pořídit fotku"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrat obrázek"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Tři čárky signálu datové sítě."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Plný signál datové sítě."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Síť ethernet je odpojena."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 0cba4ff..5d55a12 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Opretter ny bruger…"</string>
<string name="user_nickname" msgid="262624187455825083">"Kaldenavn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tilføj gæsten"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Afslut gæstesessionen"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gæsten"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gæst"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tag et billede"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Vælg et billede"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data tre bjælker."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Datasignal fuldt."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet er ikke tilsluttet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index c476e68..1fbb391 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Neuer Nutzer wird erstellt…"</string>
<string name="user_nickname" msgid="262624187455825083">"Alias"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gast hinzufügen"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Gastsitzung beenden"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Gast entfernen"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gast"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Foto machen"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Bild auswählen"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Datensignal - drei Balken"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Volle Datensignalstärke"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet nicht verbunden"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 49cd2e6..32bcf87 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Δημιουργία νέου χρήστη…"</string>
<string name="user_nickname" msgid="262624187455825083">"Ψευδώνυμο"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Προσθήκη επισκέπτη"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Λήξη περιόδου σύνδεσης επισκέπτη"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Κατάργηση επισκέπτη"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Επισκέπτης"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Τρεις γραμμές δεδομένων."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Πλήρες σήμα δεδομένων."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Το Ethernet αποσυνδέθηκε."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index cad79a5..6241953 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"End Guest session"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Guest"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -591,6 +591,6 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data three bars."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Data signal full."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
- <skip />
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index b8083a0..198fee4 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"End Guest session"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Guest"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -591,6 +591,6 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data three bars."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Data signal full."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
- <skip />
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index cad79a5..6241953 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"End Guest session"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Guest"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -591,6 +591,6 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data three bars."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Data signal full."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
- <skip />
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index cad79a5..6241953 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"End Guest session"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Guest"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -591,6 +591,6 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data three bars."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Data signal full."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
- <skip />
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index d4dcf66..27cd8b3 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creating new user…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"End guest session"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Guest"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
@@ -592,4 +592,5 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Data signal full."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index d7bdec1..0f76576 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creando usuario nuevo…"</string>
<string name="user_nickname" msgid="262624187455825083">"Sobrenombre"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Agregar invitado"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Finalizar sesión de invitado"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Invitado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tomar una foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Elegir una imagen"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Tres barras de datos"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Señal de datos completa"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet desconectada"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 87f5dee..abd209c 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creando usuario…"</string>
<string name="user_nickname" msgid="262624187455825083">"Apodo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Añadir invitado"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Finalizar sesión de invitado"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Invitado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Tres barras de datos"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Señal de datos al máximo"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Conexión Ethernet desconectada."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 1b8f35d..2e9f3b8 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Uue kasutaja loomine …"</string>
<string name="user_nickname" msgid="262624187455825083">"Hüüdnimi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisa külaline"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Lõpeta külastajaseanss"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Külaline"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Andmeside: kolm pulka."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Andmesignaal on tugev."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Etherneti-ühendus on katkestatud."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index d2603a5..ecb4f75 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Beste erabiltzaile bat sortzen…"</string>
<string name="user_nickname" msgid="262624187455825083">"Goitizena"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gehitu gonbidatua"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Amaitu gonbidatuentzako saioa"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Kendu gonbidatua"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gonbidatua"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Datu-seinaleak hiru barra ditu."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Datu-seinale osoa."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet bidezko konexioa eten da."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 118ef23..56ade54 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"درحال ایجاد کاربر جدید…"</string>
<string name="user_nickname" msgid="262624187455825083">"نام مستعار"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"افزودن مهمان"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"پایان دادن به جلسه مهمان"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"حذف مهمان"</string>
<string name="guest_nickname" msgid="6332276931583337261">"مهمان"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"عکس گرفتن"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"انتخاب تصویر"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"سه نوار برای داده."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"قدرت سیگنال داده کامل است."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"اترنت قطع شد."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"اترنت."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index c9587c7..e26ecb7 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Luodaan uutta käyttäjää…"</string>
<string name="user_nickname" msgid="262624187455825083">"Lempinimi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Lopeta Vierailija-käyttökerta"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Vieras"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Datasignaali - kolme palkkia"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Vahva kuuluvuus."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet on irrotettu."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index fc45388..d61ebc0 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Créer un utilisateur…"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Mettre fin à la session d\'invité"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Invité"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Sélectionner une image"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Signal bon"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Signal excellent"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet déconnecté."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 99d0294..64c06fa 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Création d\'un nouvel utilisateur…"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Fermer la session Invité"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Invité"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Choisir une image"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Signal bon"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Signal excellent"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet déconnecté"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 0ecb3a1..cf63dd7 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creando usuario novo…"</string>
<string name="user_nickname" msgid="262624187455825083">"Alcume"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engadir convidado"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Finalizar sesión de invitado"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar convidado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escoller imaxe"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Tres barras de sinal de datos"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Sinal de datos: completo"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Desconectouse a Ethernet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index d753be9..427ce56 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"નવા વપરાશકર્તા બનાવી રહ્યાં છીએ…"</string>
<string name="user_nickname" msgid="262624187455825083">"ઉપનામ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"અતિથિ ઉમેરો"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"અતિથિ સત્ર સમાપ્ત કરો"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"અતિથિને કાઢી નાખો"</string>
<string name="guest_nickname" msgid="6332276931583337261">"અતિથિ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ફોટો લો"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"છબી પસંદ કરો"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"ડેટા ત્રણ બાર."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"ડેટા સિગ્નલ પૂર્ણ."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ઇથરનેટ ડિસ્કનેક્ટ થયું."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ઇથરનેટ."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 1a6f192..159d2db 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"नया उपयोगकर्ता बनाया जा रहा है…"</string>
<string name="user_nickname" msgid="262624187455825083">"प्रचलित नाम"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"मेहमान जोड़ें"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"मेहमान के तौर पर ब्राउज़ करने का सेशन खत्म करें"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"मेहमान हटाएं"</string>
<string name="guest_nickname" msgid="6332276931583337261">"मेहमान"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"फ़ोटो खींचें"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"कोई इमेज चुनें"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"डेटा सिग्नल पूरा."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ईथरनेट डिस्कनेक्ट किया गया."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ईथरनेट."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 7846212..5e33ef3 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -555,7 +555,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Izrada novog korisnika…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodavanje gosta"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Završi gostujuću sesiju"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Uklanjanje gosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
@@ -592,6 +592,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Podatkovni signal tri stupca."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Podatkovni signal pun."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Prekinuta je veza s ethernetom."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 99c8527..28975be 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Új felhasználó létrehozása…"</string>
<string name="user_nickname" msgid="262624187455825083">"Becenév"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Vendég hozzáadása"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"A vendég munkamenet befejezése"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Vendég munkamenet eltávolítása"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Vendég"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Adat három sáv."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Adatjel teljes."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet leválasztva."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 6e4ece8..a207526 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Ստեղծվում է օգտատիրոջ նոր պրոֆիլ…"</string>
<string name="user_nickname" msgid="262624187455825083">"Կեղծանուն"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ավելացնել հյուր"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Ավարտել հյուրի աշխատաշրջանը"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Հեռացնել հյուրին"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Հյուր"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Լուսանկարել"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Ընտրել պատկեր"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Տվյալների երեք գիծ:"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Տվյալների ազդանշանը լրիվ է:"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet-ը անջատված է:"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet։"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index e71ccb5..c4d752d 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Membuat pengguna baru …"</string>
<string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tambahkan tamu"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Akhiri sesi tamu"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Hapus tamu"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Tamu"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih gambar"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data tiga batang."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Sinyal data penuh."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet terputus."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 3605c09..56b0a81 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Stofnar nýjan notanda…"</string>
<string name="user_nickname" msgid="262624187455825083">"Gælunafn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Bæta gesti við"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Ljúka gestalotu"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Fjarlægja gest"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gestur"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Sendistyrkur gagnatengingar er þrjú strik."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Fullur sendistyrkur gagnatengingar."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet aftengt."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 941fa89..f045d27 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creazione nuovo utente…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Aggiungi ospite"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Termina sessione Ospite"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Rimuovi ospite"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Ospite"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Dati: tre barre."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Massimo segnale dati."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Connessione Ethernet annullata."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 835e98a..ba3a467 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"בתהליך יצירה של משתמש חדש…"</string>
<string name="user_nickname" msgid="262624187455825083">"כינוי"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"הוספת אורח"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"הפסקת הגלישה כאורח"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"הסרת אורח"</string>
<string name="guest_nickname" msgid="6332276931583337261">"אורח"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"צילום תמונה"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"לבחירת תמונה"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"שלושה פסים של נתונים."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"אות הנתונים מלא."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"אתרנט מנותק."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"אתרנט."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index b2e49d7..6f398b6 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"新しいユーザーを作成しています…"</string>
<string name="user_nickname" msgid="262624187455825083">"ニックネーム"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ゲストを追加"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"ゲスト セッションを終了する"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"ゲストを削除"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ゲスト"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"写真を撮る"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"画像を選択"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"データ信号:レベル3"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"データ信号:フル"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"イーサネット接続を解除しました。"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"イーサネット。"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index bc53ac6..5bf1dd0 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"მიმდინარეობს ახალი მომხმარებლის შექმნა…"</string>
<string name="user_nickname" msgid="262624187455825083">"მეტსახელი"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"სტუმრის დამატება"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"სტუმრის სესიის დასრულება"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"სტუმრის ამოშლა"</string>
<string name="guest_nickname" msgid="6332276931583337261">"სტუმარი"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ფოტოს გადაღება"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"აირჩიეთ სურათი"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"მონაცემების გადაცემა: სამი ზოლი"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"მონაცემთა გადაცემის საიმედო სიგნალი."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet კავშირი შეწყვეტილია."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 0a08e39..c7c3837 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Жаңа пайдаланушы профилі жасалуда…"</string>
<string name="user_nickname" msgid="262624187455825083">"Лақап ат"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Қонақты енгізу"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Қонақ сеансын аяқтау"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты өшіру"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Қонақ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Дерекқор үш баған."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Дерекқор сигналы толы."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet ажыратылған."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 64ae7d7..99a73e1 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"កំពុងបង្កើតអ្នកប្រើប្រាស់ថ្មី…"</string>
<string name="user_nickname" msgid="262624187455825083">"ឈ្មោះហៅក្រៅ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"បញ្ចូលភ្ញៀវ"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"បញ្ចប់វគ្គភ្ញៀវ"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"លុបភ្ញៀវ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ភ្ញៀវ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ថតរូប"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ជ្រើសរើសរូបភាព"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"ទិន្នន័យបីកាំ។"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"សញ្ញាទិន្នន័យពេញ។"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"បានផ្តាច់អ៊ីសឺរណិត។"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"អ៊ីសឺរណិត។"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 9d00ba4..54a42a8 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="user_nickname" msgid="262624187455825083">"ಅಡ್ಡ ಹೆಸರು"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ಅತಿಥಿಯನ್ನು ಸೇರಿಸಿ"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"ಅತಿಥಿ ಸೆಷನ್ ಅಂತ್ಯಗೊಳಿಸಿ"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ಅತಿಥಿ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ಚಿತ್ರವನ್ನು ಆರಿಸಿ"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"ಡೇಟಾ ಸಂಕೇತ ತುಂಬಿದೆ."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ಇಥರ್ನೆಟ್ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ಇಥರ್ನೆಟ್."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 9bc7a59..9e9fea9 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"새로운 사용자를 만드는 중…"</string>
<string name="user_nickname" msgid="262624187455825083">"닉네임"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"게스트 추가"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"게스트 세션 종료"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"게스트 삭제"</string>
<string name="guest_nickname" msgid="6332276931583337261">"게스트"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"사진 찍기"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"이미지 선택"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"데이터 신호 막대가 세 개입니다."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"데이터 신호가 강합니다."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"이더넷에서 연결 해제되었습니다."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"이더넷에 연결되었습니다."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index e5418fe..2aec5cb 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Жаңы колдонуучу түзүлүүдө…"</string>
<string name="user_nickname" msgid="262624187455825083">"Ылакап аты"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Конок кошуу"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Конок сеансын бүтүрүү"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Конокту өчүрүү"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Конок"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Сүрөткө тартуу"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Сүрөт тандаңыз"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Мобилдик интернеттин сигналы үч таякча."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Мобилдик интернеттин сигналы толук."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet ажырады."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 2ed5131..e199e1f 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ກຳລັງສ້າງຜູ້ໃຊ້ໃໝ່…"</string>
<string name="user_nickname" msgid="262624187455825083">"ຊື່ຫຼິ້ນ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ເພີ່ມແຂກ"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"ສິ້ນສຸດເຊດຊັນແຂກ"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"ລຶບແຂກອອກ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ແຂກ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ຖ່າຍຮູບ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ເລືອກຮູບ"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"ຂໍ້ມູນສາມຂີດ."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"ສັນຍານຂໍ້ມູນເຕັມ."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ອີເທີເນັດຕັດເຊື່ອມຕໍ່ແລ້ວ."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ອີເທີເນັດ."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 084df08..a25c59f5 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Kuriamas naujas naudotojas…"</string>
<string name="user_nickname" msgid="262624187455825083">"Slapyvardis"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridėti svečią"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Baigti svečio sesiją"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Pašalinti svečią"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Svečias"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografuoti"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pasirinkti vaizdą"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Trys duomenų juostos."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Stiprus duomenų signalas."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Atsijungta nuo eterneto."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Eternetas."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 8633366..f360c90 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -555,7 +555,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Notiek jauna lietotāja izveide…"</string>
<string name="user_nickname" msgid="262624187455825083">"Segvārds"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pievienot viesi"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Beigt viesa sesiju"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Noņemt viesi"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Viesis"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Uzņemt fotoattēlu"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Izvēlēties attēlu"</string>
@@ -592,6 +592,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Dati: trīs joslas."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Pilna piekļuve datu signālam."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Pārtraukts savienojums ar tīklu Ethernet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Tīkls Ethernet"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index ef595a7..a32d00b 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Се создава нов корисник…"</string>
<string name="user_nickname" msgid="262624187455825083">"Прекар"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додај гостин"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Заврши ја гостинската сесија"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Отстрани гостин"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гостин"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Фотографирајте"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Одберете слика"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Сигналот за податоци е исполнет."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Етернетот е исклучен."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Етернет."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 3d0a274..902507d 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"പുതിയ ഉപയോക്താവിനെ സൃഷ്ടിക്കുന്നു…"</string>
<string name="user_nickname" msgid="262624187455825083">"വിളിപ്പേര്"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"അതിഥിയെ ചേർക്കുക"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"അതിഥി സെഷൻ അവസാനിപ്പിക്കുക"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string>
<string name="guest_nickname" msgid="6332276931583337261">"അതിഥി"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"ഡാറ്റ സിഗ്നൽ പൂർണ്ണമാണ്."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ഇതർനെറ്റ് വിച്ഛേദിച്ചു."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ഇതർനെറ്റ്."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 0722e3f..83009b7 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Шинэ хэрэглэгч үүсгэж байна…"</string>
<string name="user_nickname" msgid="262624187455825083">"Хоч"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Зочин нэмэх"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Зочны сургалтыг дуусгах"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Зочин хасах"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Зочин"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Зураг авах"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Зураг сонгох"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Дата гурван баганатай."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Дата дохио дүүрэн."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet саллаа."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Этернэт."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 166a282..359f525 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"नवीन वापरकर्ता तयार करत आहे…"</string>
<string name="user_nickname" msgid="262624187455825083">"टोपणनाव"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"अतिथी सत्र संपवा"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string>
<string name="guest_nickname" msgid="6332276931583337261">"अतिथी"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"फोटो काढा"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"इमेज निवडा"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"डेटा सिग्नल पूर्ण."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"इथरनेट डिस्कनेक्ट केले."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"इथरनेट."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index a5913dd..eba89da 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Mencipta pengguna baharu…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tambah tetamu"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Tamatkan sesi tetamu"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Alih keluar tetamu"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Tetamu"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih imej"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data tiga bar."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Isyarat data penuh."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet diputuskan sambungan."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 37aaa09..e982aa9 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"အသုံးပြုသူအသစ် ပြုလုပ်နေသည်…"</string>
<string name="user_nickname" msgid="262624187455825083">"နာမည်ပြောင်"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ဧည့်သည့် ထည့်ရန်"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"ဧည့်သည်ဆက်ရှင်ကို အဆုံးသတ်ရန်"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"ဧည့်သည်ကို ဖယ်ထုတ်ရန်"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ဧည့်သည်"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"ဒေတာထုတ်လွှင့်မှုအပြည့်ဖမ်းမိခြင်း"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet နှင့်ချိတ်ဆက်မှုပြတ်တောက်"</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"အီသာနက်။"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 4cf365b..abbb5e7 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Oppretter en ny bruker …"</string>
<string name="user_nickname" msgid="262624187455825083">"Kallenavn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Legg til en gjest"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Avslutt gjesteøkten"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gjest"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ta et bilde"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Velg et bilde"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data – tre stolper."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Datasignal er fullt."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet er frakoblet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index d022aa7..d7a32bf 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"नयाँ प्रयोगकर्ता बनाउँदै…"</string>
<string name="user_nickname" msgid="262624187455825083">"उपनाम"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथि थप्नुहोस्"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"अतिथिको सत्र अन्त्य गर्नुहोस्"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"अतिथि हटाउनुहोस्"</string>
<string name="guest_nickname" msgid="6332276931583337261">"अतिथि"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"फोटो खिच्नुहोस्"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"कुनै फोटो छनौट गर्नुहोस्"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"डेटा तिन बाधाहरू।"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"डेटा संकेत पूर्ण।"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"इथरनेट विच्छेद भयो।"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"इथरनेट।"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 7773322..7e739bc 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Nieuwe gebruiker maken…"</string>
<string name="user_nickname" msgid="262624187455825083">"Bijnaam"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gast toevoegen"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Gastsessie beëindigen"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Gast verwijderen"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gast"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Foto maken"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Afbeelding kiezen"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Gegevens: drie streepjes."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Gegevenssignaal is op volle sterkte."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernetverbinding verbroken."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 72190c9..1e842b7 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରାଯାଉଛି…"</string>
<string name="user_nickname" msgid="262624187455825083">"ଡାକନାମ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ଅତିଥି ଯୋଗ କରନ୍ତୁ"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"ଅତିଥି ସେସନ୍ ଶେଷ କରନ୍ତୁ"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"ଅତିଥିଙ୍କୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ଅତିଥି"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ଏକ ଛବି ବାଛନ୍ତୁ"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"ଡାଟାର ତିନୋଟି ବାର୍ ଅଛି।"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"ଡାଟା ସିଗ୍ନାଲ୍ ପୂର୍ଣ୍ଣ ଅଛି।"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ଇଥରନେଟ୍ ବିଚ୍ଛିନ୍ନ ହୋଇଛି।"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ଇଥରନେଟ୍।"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index e5f95e7..d035fc0 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਇਆ ਜਾ ਰਿਹਾ ਹੈ…"</string>
<string name="user_nickname" msgid="262624187455825083">"ਉਪਨਾਮ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ਮਹਿਮਾਨ ਸ਼ਾਮਲ ਕਰੋ"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਸਮਾਪਤ ਕਰੋ"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"ਮਹਿਮਾਨ ਹਟਾਓ"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ਮਹਿਮਾਨ"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ਇੱਕ ਫ਼ੋਟੋ ਖਿੱਚੋ"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ਕੋਈ ਚਿੱਤਰ ਚੁਣੋ"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">" ਡਾਟਾ ਸਿਗਨਲ ਪੂਰਾ।"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ਈਥਰਨੈੱਟ ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ।"</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ਈਥਰਨੈੱਟ।"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 794e41f..8a732cb 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Tworzę nowego użytkownika…"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gościa"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Kończenie sesji gościa"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Usuń gościa"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gość"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Dane: trzy paski."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Dane: pełna moc sygnału."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Rozłączono z siecią Ethernet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 765dbf5..a63b9b5 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Criando novo usuário…"</string>
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Encerrar sessão de visitante"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Sinal de dados cheio."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet desconectada."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 8dcc21a..ab23059 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"A criar novo utilizador…"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudónimo"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Terminar a sessão de convidado"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Três barras de dados."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Sinal de dados completo."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet desligada."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 765dbf5..a63b9b5 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Criando novo usuário…"</string>
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Encerrar sessão de visitante"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Sinal de dados cheio."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet desconectada."</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 0c33d12..98edb32 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -555,7 +555,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Se creează un utilizator nou…"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adăugați un invitat"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Încheiați sesiunea pentru invitați"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Ștergeți invitatul"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Invitat"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Faceți o fotografie"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Alegeți o imagine"</string>
@@ -592,6 +592,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Semnal pentru date: trei bare."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Semnal pentru date: complet."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet deconectat."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 039a64c..972dc20 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Создаем нового пользователя…"</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавить аккаунт гостя"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Завершить гостевой сеанс"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Удалить аккаунт гостя"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гость"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Сигнал передачи данных: три деления."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Надежный сигнал передачи данных."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Устройство отключено от Ethernet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index ed8cb4c..0dee8e1 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"නව පරිශීලක තනමින්…"</string>
<string name="user_nickname" msgid="262624187455825083">"අපනාමය"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"අමුත්තා එක් කරන්න"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"ආරාධිත සැසිය අවසන් කරන්න"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"අමුත්තා ඉවත් කරන්න"</string>
<string name="guest_nickname" msgid="6332276931583337261">"අමුත්තා"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ඡායාරූපයක් ගන්න"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"රූපයක් තෝරන්න"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"දත්ත තීරු 3."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"දත්ත සංඥාව පිරී ඇත."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ඊතර්නෙට් විසන්ධි කරන ලදී."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ඊතර්නෙට්."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 209749f..7d49ca3 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Vytvára sa nový používateľ…"</string>
<string name="user_nickname" msgid="262624187455825083">"Prezývka"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridať hosťa"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Ukončiť reláciu hosťa"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Hosť"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Tri čiarky signálu dátovej siete."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Plný signál dátovej siete."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Sieť ethernet je odpojená"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 88d06a1..48e5dcc 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Ustvarjanje novega uporabnika …"</string>
<string name="user_nickname" msgid="262624187455825083">"Vzdevek"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodajanje gosta"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Končaj sejo gosta"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Odstranitev gosta"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gost"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Podatki s tremi črticami."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Podatkovni signal poln."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernetna povezava je prekinjena."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 2ce2753..0bc905e 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Po krijohet një përdorues i ri…"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudonimi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Shto të ftuar"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Jepi fund sesionit të vizitorit"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Hiq të ftuarin"</string>
<string name="guest_nickname" msgid="6332276931583337261">"I ftuar"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Bëj një fotografi"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Zgjidh një imazh"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Sinjali është me tre vija."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Sinjali i të dhënave është i plotë."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Lidhja e eternetit u shkëput."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Eternet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 735d861..6d19af8 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -555,7 +555,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Прави се нови корисник…"</string>
<string name="user_nickname" msgid="262624187455825083">"Надимак"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додај госта"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Заврши сесију госта"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гост"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
@@ -592,6 +592,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Сигнал за податке од три црте."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Сигнал за податке је најјачи."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Веза са етернетом је прекинута."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Етернет."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index d4a7d1b..944c423 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Skapar ny användare …"</string>
<string name="user_nickname" msgid="262624187455825083">"Smeknamn"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lägg till gäst"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Avsluta gästsession"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Ta bort gäst"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Gäst"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data: tre staplar."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Datasignalen är full."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet har kopplats från."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index b1142d3..442f54b 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Inaweka mtumiaji mpya…"</string>
<string name="user_nickname" msgid="262624187455825083">"Jina wakilishi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Weka mgeni"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Maliza kipindi cha mgeni"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Ondoa mgeni"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Mgeni"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Piga picha"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Chagua picha"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Fito tatu za habari."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Ishara ya data imejaa."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethaneti imeondolewa."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethaneti."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index fd17d13..561a122 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"புதிய பயனரை உருவாக்குகிறது…"</string>
<string name="user_nickname" msgid="262624187455825083">"புனைப்பெயர்"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"கெஸ்ட்டைச் சேர்"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"விருந்தினர் அமர்வை நிறைவுசெய்"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"கெஸ்ட்டை அகற்று"</string>
<string name="guest_nickname" msgid="6332276931583337261">"கெஸ்ட்"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"படமெடுங்கள்"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"படத்தைத் தேர்வுசெய்யுங்கள்"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"தரவு சிக்னல் மூன்று கோட்டில் உள்ளது."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"தரவு சிக்னல் முழுமையாக உள்ளது."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ஈத்தர்நெட் துண்டிக்கப்பட்டது."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ஈதர்நெட்."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 2373b09..18d7f28 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"కొత్త యూజర్ను క్రియేట్ చేస్తోంది…"</string>
<string name="user_nickname" msgid="262624187455825083">"మారుపేరు"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"అతిథిని జోడించండి"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"గెస్ట్ సెషన్ను ముగించు"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"అతిథిని తీసివేయండి"</string>
<string name="guest_nickname" msgid="6332276931583337261">"అతిథి"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ఒక ఫోటో తీయండి"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ఇమేజ్ను ఎంచుకోండి"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"డేటా మూడు బార్లు."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"డేటా సిగ్నల్ సంపూర్ణంగా ఉంది."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ఈథర్నెట్ డిస్కనెక్ట్ చేయబడింది."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ఈథర్నెట్."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index b284358..ceab26c 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"กำลังสร้างผู้ใช้ใหม่…"</string>
<string name="user_nickname" msgid="262624187455825083">"ชื่อเล่น"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"เพิ่มผู้เข้าร่วม"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"จบเซสชันผู้เยี่ยมชม"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"นำผู้เข้าร่วมออก"</string>
<string name="guest_nickname" msgid="6332276931583337261">"ผู้ใช้ชั่วคราว"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"สัญญาณข้อมูลสามขีด"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"สัญญาณข้อมูลเต็ม"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ยกเลิกการเชื่อมต่ออีเทอร์เน็ตแล้ว"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"อีเทอร์เน็ต"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 855d2f5..671fa14 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Gumagawa ng bagong user…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Magdagdag ng bisita"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Tapusin ang session ng bisita"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Alisin ang bisita"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Bisita"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Kumuha ng larawan"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Pumili ng larawan"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Data na tatlong bar."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Puno ang signal ng data."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Nadiskonekta ang Ethernet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index a1556a1..98d89f3 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Yeni kullanıcı oluşturuluyor…"</string>
<string name="user_nickname" msgid="262624187455825083">"Takma ad"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Misafir ekle"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Misafir oturumunu sonlandır"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Misafir oturumunu kaldır"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Misafir"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Fotoğraf çek"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Resim seç"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Veri sinyali üç çubuk."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Veri sinyali tam."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet bağlantısı kesildi."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 8ee2b8e0..4e739ac 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -556,7 +556,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Створення нового користувача…"</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдонім"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додати гостя"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Завершити сеанс у режимі \"Гість\""</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Видалити гостя"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Гість"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string>
@@ -593,6 +593,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Три смужки сигналу даних."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Максимальний сигнал даних."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet відключено."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 827c80a..c7dee95 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"نیا صارف تخلیق کرنا…"</string>
<string name="user_nickname" msgid="262624187455825083">"عرفی نام"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"مہمان سیشن ختم کریں"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string>
<string name="guest_nickname" msgid="6332276931583337261">"مہمان"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"ایک تصویر لیں"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"ایک تصویر منتخب کریں"</string>
@@ -592,4 +592,6 @@
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"ڈیٹا سگنل بھرا ہوا ہے۔"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ایتھرنیٹ منقطع ہے۔"</string>
<string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ایتھرنیٹ۔"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
+ <skip />
</resources>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index e4d0c33..433096b 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Yangi foydalanuvchi yaratilmoqda…"</string>
<string name="user_nickname" msgid="262624187455825083">"Nik"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Mehmon seansini yakunlash"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Mehmon rejimini olib tashlash"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Mehmon"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Suratga olish"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Rasm tanlash"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Ma’lumotlar uchta panelda."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Internet signali butun."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Qurilma Ethernet tarmog‘idan uzildi."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index eb86a80..a14462b 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Đang tạo người dùng mới…"</string>
<string name="user_nickname" msgid="262624187455825083">"Biệt hiệu"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Thêm khách"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Kết thúc phiên khách"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Xóa phiên khách"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Khách"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Chụp ảnh"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Chọn một hình ảnh"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Tín hiệu dữ liệu ba vạch."</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Tín hiệu dữ liệu đầy đủ."</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Đã ngắt kết nối Ethernet."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index ab34683..f6bea91 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"正在创建新用户…"</string>
<string name="user_nickname" msgid="262624187455825083">"昵称"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"添加访客"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"结束访客会话"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"移除访客"</string>
<string name="guest_nickname" msgid="6332276931583337261">"访客"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"拍摄照片"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"选择图片"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"数据信号强度为三格。"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"数据信号满格。"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"以太网已断开连接。"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"以太网。"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index db5a5240..3cf15a9 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"正在建立新使用者…"</string>
<string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"結束訪客工作階段"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
<string name="guest_nickname" msgid="6332276931583337261">"訪客"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"數據網絡訊號強度為三格。"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"數據網絡訊號滿格。"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"以太網連接中斷。"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"以太網絡。"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 7e73705..7cf0297 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"正在建立新使用者…"</string>
<string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"結束訪客工作階段"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
<string name="guest_nickname" msgid="6332276931583337261">"訪客"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"數據網路訊號強度三格。"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"數據網路訊號滿格。"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"未連上乙太網路。"</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"乙太網路。"</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index f487db1..d950d58 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -554,7 +554,7 @@
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Idala umsebenzisi omusha…"</string>
<string name="user_nickname" msgid="262624187455825083">"Isiteketiso"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engeza isivakashi"</string>
- <string name="guest_exit_guest" msgid="4754204715192830850">"Misa isikhathi sesihambeli"</string>
+ <string name="guest_exit_guest" msgid="5908239569510734136">"Susa isihambeli"</string>
<string name="guest_nickname" msgid="6332276931583337261">"Isihambeli"</string>
<string name="user_image_take_photo" msgid="467512954561638530">"Thatha isithombe"</string>
<string name="user_image_choose_photo" msgid="1363820919146782908">"Khetha isithombe"</string>
@@ -591,6 +591,7 @@
<string name="accessibility_data_three_bars" msgid="2813876214466722413">"Amabha amathathu edatha"</string>
<string name="accessibility_data_signal_full" msgid="1808301899314382337">"Igcwele i-signal yedatha"</string>
<string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"I-Ethernet inqanyuliwe."</string>
- <!-- no translation found for accessibility_ethernet_connected (6175942685957461563) -->
+ <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"I-Ethernet."</string>
+ <!-- no translation found for accessibility_no_calling (3540827068323895748) -->
<skip />
</resources>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 1566b76..35a4e81 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -402,6 +402,9 @@
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.BIND_RESUME_ON_REBOOT_SERVICE" />
+ <!-- Permission required for CTS test - CtsRebootReadinessTestCases -->
+ <uses-permission android:name="android.permission.SIGNAL_REBOOT_READINESS" />
+
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
diff --git a/services/core/Android.bp b/services/core/Android.bp
index afa0840..542a260 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -228,8 +228,5 @@
"java/com/android/server/connectivity/QosCallbackAgentConnection.java",
"java/com/android/server/connectivity/QosCallbackTracker.java",
"java/com/android/server/connectivity/TcpKeepaliveController.java",
- "java/com/android/server/connectivity/Vpn.java",
- "java/com/android/server/connectivity/VpnIkev2Utils.java",
- "java/com/android/server/net/LockdownVpnTracker.java",
],
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1012875..65b670b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -16,7 +16,6 @@
package com.android.server;
-import static android.Manifest.permission.NETWORK_STACK;
import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
@@ -141,7 +140,6 @@
import android.net.UnderlyingNetworkInfo;
import android.net.Uri;
import android.net.VpnManager;
-import android.net.VpnService;
import android.net.VpnTransportInfo;
import android.net.metrics.INetdEventListener;
import android.net.metrics.IpConnectivityLog;
@@ -173,8 +171,6 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import android.security.Credentials;
-import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -190,9 +186,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.net.LegacyVpnInfo;
-import com.android.internal.net.VpnConfig;
-import com.android.internal.net.VpnProfile;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.IndentingPrintWriter;
@@ -217,9 +210,7 @@
import com.android.server.connectivity.PermissionMonitor;
import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.QosCallbackTracker;
-import com.android.server.connectivity.Vpn;
import com.android.server.net.BaseNetworkObserver;
-import com.android.server.net.LockdownVpnTracker;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.utils.PriorityDump;
@@ -312,18 +303,7 @@
private final PerUidCounter mNetworkRequestCounter;
- private KeyStore mKeyStore;
-
- @VisibleForTesting
- @GuardedBy("mVpns")
- protected final SparseArray<Vpn> mVpns = new SparseArray<>();
-
- // TODO: investigate if mLockdownEnabled can be removed and replaced everywhere by
- // a direct call to LockdownVpnTracker.isEnabled().
- @GuardedBy("mVpns")
- private boolean mLockdownEnabled;
- @GuardedBy("mVpns")
- private LockdownVpnTracker mLockdownTracker;
+ private volatile boolean mLockdownEnabled;
/**
* Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal
@@ -764,6 +744,27 @@
}
}
+ // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying
+ // network type, to preserve previous behaviour.
+ private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) {
+ if (vpnNai != mService.getLegacyLockdownNai()) return;
+
+ if (vpnNai.declaredUnderlyingNetworks == null
+ || vpnNai.declaredUnderlyingNetworks.length != 1) {
+ Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: "
+ + Arrays.toString(vpnNai.declaredUnderlyingNetworks));
+ return;
+ }
+ final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork(
+ vpnNai.declaredUnderlyingNetworks[0]);
+ if (underlyingNai == null) return;
+
+ final int type = underlyingNai.networkInfo.getType();
+ final DetailedState state = DetailedState.CONNECTED;
+ maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */);
+ mService.sendLegacyNetworkBroadcast(underlyingNai, state, type);
+ }
+
/** Adds the given network to the specified legacy type list. */
public void add(int type, NetworkAgentInfo nai) {
if (!isTypeSupported(type)) {
@@ -781,9 +782,17 @@
// Send a broadcast if this is the first network of its type or if it's the default.
final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
+
+ // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts
+ // to preserve previous behaviour.
+ final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED);
if ((list.size() == 1) || isDefaultNetwork) {
- maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
- mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
+ maybeLogBroadcast(nai, state, type, isDefaultNetwork);
+ mService.sendLegacyNetworkBroadcast(nai, state, type);
+ }
+
+ if (type == TYPE_VPN && state == DetailedState.CONNECTED) {
+ maybeSendLegacyLockdownBroadcast(nai);
}
}
@@ -978,13 +987,6 @@
}
/**
- * Get a reference to the system keystore.
- */
- public KeyStore getKeyStore() {
- return KeyStore.getInstance();
- }
-
- /**
* @see ProxyTracker
*/
public ProxyTracker makeProxyTracker(@NonNull Context context,
@@ -1093,7 +1095,6 @@
mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
mNetd = netd;
- mKeyStore = mDeps.getKeyStore();
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mLocationPermissionChecker = new LocationPermissionChecker(mContext);
@@ -1182,43 +1183,15 @@
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
- // Set up the listener for user state for creating user VPNs.
+ // Listen for user add/removes to inform PermissionMonitor.
// Should run on mHandler to avoid any races.
IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_USER_STARTED);
- intentFilter.addAction(Intent.ACTION_USER_STOPPED);
intentFilter.addAction(Intent.ACTION_USER_ADDED);
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
- intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
- mUserAllContext.registerReceiver(
- mIntentReceiver,
- intentFilter,
- null /* broadcastPermission */,
- mHandler);
- mContext.createContextAsUser(UserHandle.SYSTEM, 0 /* flags */).registerReceiver(
- mUserPresentReceiver,
- new IntentFilter(Intent.ACTION_USER_PRESENT),
- null /* broadcastPermission */,
- null /* scheduler */);
-
- // Listen to package add and removal events for all users.
- intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
- intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- intentFilter.addDataScheme("package");
- mUserAllContext.registerReceiver(
- mIntentReceiver,
- intentFilter,
- null /* broadcastPermission */,
- mHandler);
-
- // Listen to lockdown VPN reset.
- intentFilter = new IntentFilter();
- intentFilter.addAction(LockdownVpnTracker.ACTION_LOCKDOWN_RESET);
- mUserAllContext.registerReceiver(
- mIntentReceiver, intentFilter, NETWORK_STACK, mHandler);
+ mUserAllContext.registerReceiver(mIntentReceiver, intentFilter,
+ null /* broadcastPermission */, mHandler);
mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mNMS);
@@ -1407,9 +1380,7 @@
}
private Network[] getVpnUnderlyingNetworks(int uid) {
- synchronized (mVpns) {
- if (mLockdownEnabled) return null;
- }
+ if (mLockdownEnabled) return null;
final NetworkAgentInfo nai = getVpnForUid(uid);
if (nai != null) return nai.declaredUnderlyingNetworks;
return null;
@@ -1494,11 +1465,9 @@
if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
}
- synchronized (mVpns) {
- if (mLockdownTracker != null) {
- mLockdownTracker.augmentNetworkInfo(networkInfo);
- }
- }
+ networkInfo.setDetailedState(
+ getLegacyLockdownState(networkInfo.getDetailedState()),
+ "" /* reason */, null /* extraInfo */);
}
/**
@@ -1557,14 +1526,6 @@
return nai.network;
}
- // Public because it's used by mLockdownTracker.
- public NetworkInfo getActiveNetworkInfoUnfiltered() {
- enforceAccessPermission();
- final int uid = mDeps.getCallingUid();
- NetworkState state = getUnfilteredActiveNetworkState(uid);
- return state.networkInfo;
- }
-
@Override
public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
NetworkStack.checkNetworkStackPermission(mContext);
@@ -2186,22 +2147,6 @@
isBackgroundRestricted);
}
- /**
- * Require that the caller is either in the same user or has appropriate permission to interact
- * across users.
- *
- * @param userId Target user for whatever operation the current IPC is supposed to perform.
- */
- private void enforceCrossUserPermission(int userId) {
- if (userId == UserHandle.getCallingUserId()) {
- // Not a cross-user call.
- return;
- }
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- "ConnectivityService");
- }
-
private boolean checkAnyPermissionOf(String... permissions) {
for (String permission : permissions) {
if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
@@ -2282,12 +2227,6 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
}
- private void enforceControlAlwaysOnVpnPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CONTROL_ALWAYS_ON_VPN,
- "ConnectivityService");
- }
-
private void enforceNetworkStackOrSettingsPermission() {
enforceAnyPermissionOf(
android.Manifest.permission.NETWORK_SETTINGS,
@@ -2366,13 +2305,6 @@
}
private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
- synchronized (mVpns) {
- if (mLockdownTracker != null) {
- info = new NetworkInfo(info);
- mLockdownTracker.augmentNetworkInfo(info);
- }
- }
-
Intent intent = new Intent(bcastType);
intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
@@ -2466,10 +2398,6 @@
}
}
- // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait
- // for user to unlock device too.
- updateLockdownVpn();
-
// Create network requests for always-on networks.
mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
}
@@ -2953,7 +2881,15 @@
Log.wtf(TAG, "Non-virtual networks cannot have underlying networks");
break;
}
+
final List<Network> underlying = (List<Network>) arg.second;
+
+ if (isLegacyLockdownNai(nai)
+ && (underlying == null || underlying.size() != 1)) {
+ Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString()
+ + " must have exactly one underlying network: " + underlying);
+ }
+
final Network[] oldUnderlying = nai.declaredUnderlyingNetworks;
nai.declaredUnderlyingNetworks = (underlying != null)
? underlying.toArray(new Network[0]) : null;
@@ -3562,7 +3498,6 @@
// incorrect) behavior.
mNetworkActivityTracker.updateDataActivityTracking(
null /* newNetwork */, nai);
- notifyLockdownVpn(nai);
ensureNetworkTransitionWakelock(nai.toShortString());
}
}
@@ -4807,183 +4742,6 @@
}
/**
- * Prepare for a VPN application.
- * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
- * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
- *
- * @param oldPackage Package name of the application which currently controls VPN, which will
- * be replaced. If there is no such application, this should should either be
- * {@code null} or {@link VpnConfig.LEGACY_VPN}.
- * @param newPackage Package name of the application which should gain control of VPN, or
- * {@code null} to disable.
- * @param userId User for whom to prepare the new VPN.
- *
- * @hide
- */
- @Override
- public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage,
- int userId) {
- enforceCrossUserPermission(userId);
-
- synchronized (mVpns) {
- throwIfLockdownEnabled();
- Vpn vpn = mVpns.get(userId);
- if (vpn != null) {
- return vpn.prepare(oldPackage, newPackage, VpnManager.TYPE_VPN_SERVICE);
- } else {
- return false;
- }
- }
- }
-
- /**
- * Set whether the VPN package has the ability to launch VPNs without user intervention. This
- * method is used by system-privileged apps. VPN permissions are checked in the {@link Vpn}
- * class. If the caller is not {@code userId}, {@link
- * android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
- *
- * @param packageName The package for which authorization state should change.
- * @param userId User for whom {@code packageName} is installed.
- * @param authorized {@code true} if this app should be able to start a VPN connection without
- * explicit user approval, {@code false} if not.
- * @param vpnType The {@link VpnManager.VpnType} constant representing what class of VPN
- * permissions should be granted. When unauthorizing an app, {@link
- * VpnManager.TYPE_VPN_NONE} should be used.
- * @hide
- */
- @Override
- public void setVpnPackageAuthorization(
- String packageName, int userId, @VpnManager.VpnType int vpnType) {
- enforceCrossUserPermission(userId);
-
- synchronized (mVpns) {
- Vpn vpn = mVpns.get(userId);
- if (vpn != null) {
- vpn.setPackageAuthorization(packageName, vpnType);
- }
- }
- }
-
- /**
- * Configure a TUN interface and return its file descriptor. Parameters
- * are encoded and opaque to this class. This method is used by VpnBuilder
- * and not available in ConnectivityManager. Permissions are checked in
- * Vpn class.
- * @hide
- */
- @Override
- public ParcelFileDescriptor establishVpn(VpnConfig config) {
- int user = UserHandle.getUserId(mDeps.getCallingUid());
- synchronized (mVpns) {
- throwIfLockdownEnabled();
- return mVpns.get(user).establish(config);
- }
- }
-
- /**
- * Stores the given VPN profile based on the provisioning package name.
- *
- * <p>If there is already a VPN profile stored for the provisioning package, this call will
- * overwrite the profile.
- *
- * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
- * exclusively by the Settings app, and passed into the platform at startup time.
- *
- * @return {@code true} if user consent has already been granted, {@code false} otherwise.
- * @hide
- */
- @Override
- public boolean provisionVpnProfile(@NonNull VpnProfile profile, @NonNull String packageName) {
- final int user = UserHandle.getUserId(mDeps.getCallingUid());
- synchronized (mVpns) {
- return mVpns.get(user).provisionVpnProfile(packageName, profile, mKeyStore);
- }
- }
-
- /**
- * Deletes the stored VPN profile for the provisioning package
- *
- * <p>If there are no profiles for the given package, this method will silently succeed.
- *
- * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
- * exclusively by the Settings app, and passed into the platform at startup time.
- *
- * @hide
- */
- @Override
- public void deleteVpnProfile(@NonNull String packageName) {
- final int user = UserHandle.getUserId(mDeps.getCallingUid());
- synchronized (mVpns) {
- mVpns.get(user).deleteVpnProfile(packageName, mKeyStore);
- }
- }
-
- /**
- * Starts the VPN based on the stored profile for the given package
- *
- * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
- * exclusively by the Settings app, and passed into the platform at startup time.
- *
- * @throws IllegalArgumentException if no profile was found for the given package name.
- * @hide
- */
- @Override
- public void startVpnProfile(@NonNull String packageName) {
- final int user = UserHandle.getUserId(mDeps.getCallingUid());
- synchronized (mVpns) {
- throwIfLockdownEnabled();
- mVpns.get(user).startVpnProfile(packageName, mKeyStore);
- }
- }
-
- /**
- * Stops the Platform VPN if the provided package is running one.
- *
- * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
- * exclusively by the Settings app, and passed into the platform at startup time.
- *
- * @hide
- */
- @Override
- public void stopVpnProfile(@NonNull String packageName) {
- final int user = UserHandle.getUserId(mDeps.getCallingUid());
- synchronized (mVpns) {
- mVpns.get(user).stopVpnProfile(packageName);
- }
- }
-
- /**
- * Start legacy VPN, controlling native daemons as needed. Creates a
- * secondary thread to perform connection work, returning quickly.
- */
- @Override
- public void startLegacyVpn(VpnProfile profile) {
- int user = UserHandle.getUserId(mDeps.getCallingUid());
- final LinkProperties egress = getActiveLinkProperties();
- if (egress == null) {
- throw new IllegalStateException("Missing active network connection");
- }
- synchronized (mVpns) {
- throwIfLockdownEnabled();
- mVpns.get(user).startLegacyVpn(profile, mKeyStore, null /* underlying */, egress);
- }
- }
-
- /**
- * Return the information of the ongoing legacy VPN. This method is used
- * by VpnSettings and not available in ConnectivityManager. Permissions
- * are checked in Vpn class.
- */
- @Override
- public LegacyVpnInfo getLegacyVpnInfo(int userId) {
- enforceCrossUserPermission(userId);
-
- synchronized (mVpns) {
- return mVpns.get(userId).getLegacyVpnInfo();
- }
- }
-
- /**
* Return the information of all ongoing VPNs.
*
* <p>This method is used to update NetworkStatsService.
@@ -4992,10 +4750,8 @@
*/
private UnderlyingNetworkInfo[] getAllVpnInfo() {
ensureRunningOnConnectivityServiceThread();
- synchronized (mVpns) {
- if (mLockdownEnabled) {
- return new UnderlyingNetworkInfo[0];
- }
+ if (mLockdownEnabled) {
+ return new UnderlyingNetworkInfo[0];
}
List<UnderlyingNetworkInfo> infoList = new ArrayList<>();
for (NetworkAgentInfo nai : mNetworkAgentInfos) {
@@ -5051,25 +4807,6 @@
nai.linkProperties.getInterfaceName(), interfaces);
}
- /**
- * Returns the information of the ongoing VPN for {@code userId}. This method is used by
- * VpnDialogs and not available in ConnectivityManager.
- * Permissions are checked in Vpn class.
- * @hide
- */
- @Override
- public VpnConfig getVpnConfig(int userId) {
- enforceCrossUserPermission(userId);
- synchronized (mVpns) {
- Vpn vpn = mVpns.get(userId);
- if (vpn != null) {
- return vpn.getVpnConfig();
- } else {
- return null;
- }
- }
- }
-
// TODO This needs to be the default network that applies to the NAI.
private Network[] underlyingNetworksOrDefault(final int ownerUid,
Network[] underlyingNetworks) {
@@ -5157,195 +4894,54 @@
mVpnBlockedUidRanges = newVpnBlockedUidRanges;
}
- private boolean isLockdownVpnEnabled() {
- return mKeyStore.contains(Credentials.LOCKDOWN_VPN);
- }
-
@Override
- public boolean updateLockdownVpn() {
- // Allow the system UID for the system server and for Settings.
- // Also, for unit tests, allow the process that ConnectivityService is running in.
- if (mDeps.getCallingUid() != Process.SYSTEM_UID
- && Binder.getCallingPid() != Process.myPid()) {
- logw("Lockdown VPN only available to system process or AID_SYSTEM");
- return false;
- }
-
- synchronized (mVpns) {
- // Tear down existing lockdown if profile was removed
- mLockdownEnabled = isLockdownVpnEnabled();
- if (mLockdownEnabled) {
- byte[] profileTag = mKeyStore.get(Credentials.LOCKDOWN_VPN);
- if (profileTag == null) {
- loge("Lockdown VPN configured but cannot be read from keystore");
- return false;
- }
- String profileName = new String(profileTag);
- final VpnProfile profile = VpnProfile.decode(
- profileName, mKeyStore.get(Credentials.VPN + profileName));
- if (profile == null) {
- loge("Lockdown VPN configured invalid profile " + profileName);
- setLockdownTracker(null);
- return true;
- }
- int user = UserHandle.getUserId(mDeps.getCallingUid());
- Vpn vpn = mVpns.get(user);
- if (vpn == null) {
- logw("VPN for user " + user + " not ready yet. Skipping lockdown");
- return false;
- }
- setLockdownTracker(
- new LockdownVpnTracker(mContext, this, mHandler, mKeyStore, vpn, profile));
- } else {
- setLockdownTracker(null);
- }
- }
-
- return true;
- }
-
- /**
- * Internally set new {@link LockdownVpnTracker}, shutting down any existing
- * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown.
- */
- @GuardedBy("mVpns")
- private void setLockdownTracker(LockdownVpnTracker tracker) {
- // Shutdown any existing tracker
- final LockdownVpnTracker existing = mLockdownTracker;
- // TODO: Add a trigger when the always-on VPN enable/disable to reevaluate and send the
- // necessary onBlockedStatusChanged callbacks.
- mLockdownTracker = null;
- if (existing != null) {
- existing.shutdown();
- }
-
- if (tracker != null) {
- mLockdownTracker = tracker;
- mLockdownTracker.init();
- }
- }
-
- /**
- * Throws if there is any currently running, always-on Legacy VPN.
- *
- * <p>The LockdownVpnTracker and mLockdownEnabled both track whether an always-on Legacy VPN is
- * running across the entire system. Tracking for app-based VPNs is done on a per-user,
- * per-package basis in Vpn.java
- */
- @GuardedBy("mVpns")
- private void throwIfLockdownEnabled() {
- if (mLockdownEnabled) {
- throw new IllegalStateException("Unavailable in lockdown mode");
- }
- }
-
- /**
- * Starts the always-on VPN {@link VpnService} for user {@param userId}, which should perform
- * some setup and then call {@code establish()} to connect.
- *
- * @return {@code true} if the service was started, the service was already connected, or there
- * was no always-on VPN to start. {@code false} otherwise.
- */
- private boolean startAlwaysOnVpn(int userId) {
- synchronized (mVpns) {
- Vpn vpn = mVpns.get(userId);
- if (vpn == null) {
- // Shouldn't happen as all code paths that point here should have checked the Vpn
- // exists already.
- Log.wtf(TAG, "User " + userId + " has no Vpn configuration");
- return false;
- }
-
- return vpn.startAlwaysOnVpn(mKeyStore);
- }
- }
-
- @Override
- public boolean isAlwaysOnVpnPackageSupported(int userId, String packageName) {
+ public void setLegacyLockdownVpnEnabled(boolean enabled) {
enforceSettingsPermission();
- enforceCrossUserPermission(userId);
-
- synchronized (mVpns) {
- Vpn vpn = mVpns.get(userId);
- if (vpn == null) {
- logw("User " + userId + " has no Vpn configuration");
- return false;
- }
- return vpn.isAlwaysOnPackageSupported(packageName, mKeyStore);
- }
+ mHandler.post(() -> mLockdownEnabled = enabled);
}
- @Override
- public boolean setAlwaysOnVpnPackage(
- int userId, String packageName, boolean lockdown, List<String> lockdownWhitelist) {
- enforceControlAlwaysOnVpnPermission();
- enforceCrossUserPermission(userId);
-
- synchronized (mVpns) {
- // Can't set always-on VPN if legacy VPN is already in lockdown mode.
- if (isLockdownVpnEnabled()) {
- return false;
- }
-
- Vpn vpn = mVpns.get(userId);
- if (vpn == null) {
- logw("User " + userId + " has no Vpn configuration");
- return false;
- }
- if (!vpn.setAlwaysOnPackage(packageName, lockdown, lockdownWhitelist, mKeyStore)) {
- return false;
- }
- if (!startAlwaysOnVpn(userId)) {
- vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
- return false;
- }
- }
- return true;
+ private boolean isLegacyLockdownNai(NetworkAgentInfo nai) {
+ return mLockdownEnabled
+ && getVpnType(nai) == VpnManager.TYPE_VPN_LEGACY
+ && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID);
}
- @Override
- public String getAlwaysOnVpnPackage(int userId) {
- enforceControlAlwaysOnVpnPermission();
- enforceCrossUserPermission(userId);
-
- synchronized (mVpns) {
- Vpn vpn = mVpns.get(userId);
- if (vpn == null) {
- logw("User " + userId + " has no Vpn configuration");
- return null;
- }
- return vpn.getAlwaysOnPackage();
+ private NetworkAgentInfo getLegacyLockdownNai() {
+ if (!mLockdownEnabled) {
+ return null;
}
- }
+ // The legacy lockdown VPN always only applies to userId 0.
+ final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID);
+ if (nai == null || !isLegacyLockdownNai(nai)) return null;
- @Override
- public boolean isVpnLockdownEnabled(int userId) {
- enforceControlAlwaysOnVpnPermission();
- enforceCrossUserPermission(userId);
-
- synchronized (mVpns) {
- Vpn vpn = mVpns.get(userId);
- if (vpn == null) {
- logw("User " + userId + " has no Vpn configuration");
- return false;
- }
- return vpn.getLockdown();
+ // The legacy lockdown VPN must always have exactly one underlying network.
+ // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in
+ // a local variable. There is no need to make a copy because its contents cannot change.
+ final Network[] underlying = nai.declaredUnderlyingNetworks;
+ if (underlying == null || underlying.length != 1) {
+ return null;
}
- }
- @Override
- public List<String> getVpnLockdownWhitelist(int userId) {
- enforceControlAlwaysOnVpnPermission();
- enforceCrossUserPermission(userId);
-
- synchronized (mVpns) {
- Vpn vpn = mVpns.get(userId);
- if (vpn == null) {
- logw("User " + userId + " has no Vpn configuration");
- return null;
- }
- return vpn.getLockdownAllowlist();
+ // The legacy lockdown VPN always uses the default network.
+ // If the VPN's underlying network is no longer the current default network, it means that
+ // the default network has just switched, and the VPN is about to disconnect.
+ // Report that the VPN is not connected, so when the state of NetworkInfo objects
+ // overwritten by getLegacyLockdownState will be set to CONNECTING and not CONNECTED.
+ final NetworkAgentInfo defaultNetwork = getDefaultNetwork();
+ if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) {
+ return null;
}
+
+ return nai;
+ };
+
+ private DetailedState getLegacyLockdownState(DetailedState origState) {
+ if (origState != DetailedState.CONNECTED) {
+ return origState;
+ }
+ return (mLockdownEnabled && getLegacyLockdownNai() == null)
+ ? DetailedState.CONNECTING
+ : DetailedState.CONNECTED;
}
@Override
@@ -5380,165 +4976,36 @@
}
}
- private void onUserStarted(int userId) {
- synchronized (mVpns) {
- Vpn userVpn = mVpns.get(userId);
- if (userVpn != null) {
- loge("Starting user already has a VPN");
- return;
- }
- userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, mNetd, userId, mKeyStore);
- mVpns.put(userId, userVpn);
- if (mUserManager.getUserInfo(userId).isPrimary() && isLockdownVpnEnabled()) {
- updateLockdownVpn();
- }
- }
- }
-
- private void onUserStopped(int userId) {
- synchronized (mVpns) {
- Vpn userVpn = mVpns.get(userId);
- if (userVpn == null) {
- loge("Stopped user has no VPN");
- return;
- }
- userVpn.onUserStopped();
- mVpns.delete(userId);
- }
- }
-
private void onUserAdded(int userId) {
mPermissionMonitor.onUserAdded(userId);
- synchronized (mVpns) {
- final int vpnsSize = mVpns.size();
- for (int i = 0; i < vpnsSize; i++) {
- Vpn vpn = mVpns.valueAt(i);
- vpn.onUserAdded(userId);
- }
- }
}
private void onUserRemoved(int userId) {
mPermissionMonitor.onUserRemoved(userId);
- synchronized (mVpns) {
- final int vpnsSize = mVpns.size();
- for (int i = 0; i < vpnsSize; i++) {
- Vpn vpn = mVpns.valueAt(i);
- vpn.onUserRemoved(userId);
- }
- }
- }
-
- private void onPackageReplaced(String packageName, int uid) {
- if (TextUtils.isEmpty(packageName) || uid < 0) {
- Log.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid);
- return;
- }
- final int userId = UserHandle.getUserId(uid);
- synchronized (mVpns) {
- final Vpn vpn = mVpns.get(userId);
- if (vpn == null) {
- return;
- }
- // Legacy always-on VPN won't be affected since the package name is not set.
- if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) {
- log("Restarting always-on VPN package " + packageName + " for user "
- + userId);
- vpn.startAlwaysOnVpn(mKeyStore);
- }
- }
- }
-
- private void onPackageRemoved(String packageName, int uid, boolean isReplacing) {
- if (TextUtils.isEmpty(packageName) || uid < 0) {
- Log.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid);
- return;
- }
-
- final int userId = UserHandle.getUserId(uid);
- synchronized (mVpns) {
- final Vpn vpn = mVpns.get(userId);
- if (vpn == null) {
- return;
- }
- // Legacy always-on VPN won't be affected since the package name is not set.
- if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) {
- log("Removing always-on VPN package " + packageName + " for user "
- + userId);
- vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
- }
- }
- }
-
- private void onUserUnlocked(int userId) {
- synchronized (mVpns) {
- // User present may be sent because of an unlock, which might mean an unlocked keystore.
- if (mUserManager.getUserInfo(userId).isPrimary() && isLockdownVpnEnabled()) {
- updateLockdownVpn();
- } else {
- startAlwaysOnVpn(userId);
- }
- }
- }
-
- private void onVpnLockdownReset() {
- synchronized (mVpns) {
- if (mLockdownTracker != null) mLockdownTracker.reset();
- }
}
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- ensureRunningOnConnectivityServiceThread();
+ // TODO: make BroadcastInterceptingContext use the Handler passed in to registerReceiver
+ // and put this back.
+ // ensureRunningOnConnectivityServiceThread();
final String action = intent.getAction();
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
- final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
- final Uri packageData = intent.getData();
- final String packageName =
- packageData != null ? packageData.getSchemeSpecificPart() : null;
-
- if (LockdownVpnTracker.ACTION_LOCKDOWN_RESET.equals(action)) {
- onVpnLockdownReset();
- }
// UserId should be filled for below intents, check the existence.
if (userId == UserHandle.USER_NULL) return;
- if (Intent.ACTION_USER_STARTED.equals(action)) {
- onUserStarted(userId);
- } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
- onUserStopped(userId);
- } else if (Intent.ACTION_USER_ADDED.equals(action)) {
+ if (Intent.ACTION_USER_ADDED.equals(action)) {
onUserAdded(userId);
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
onUserRemoved(userId);
- } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
- onUserUnlocked(userId);
- } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
- onPackageReplaced(packageName, uid);
- } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
- final boolean isReplacing = intent.getBooleanExtra(
- Intent.EXTRA_REPLACING, false);
- onPackageRemoved(packageName, uid, isReplacing);
- } else {
+ } else {
Log.wtf(TAG, "received unexpected intent: " + action);
}
}
};
- private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // Try creating lockdown tracker, since user present usually means
- // unlocked keystore.
- updateLockdownVpn();
- // Use the same context that registered receiver before to unregister it. Because use
- // different context to unregister receiver will cause exception.
- context.unregisterReceiver(this);
- }
- };
-
private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>();
private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
@@ -5916,7 +5383,8 @@
// changes don't alter request matching.
if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT &&
(!networkCapabilities.equalRequestableCapabilities(defaultNc))) {
- Log.wtf(TAG, "TRACK_SYSTEM_DEFAULT capabilities don't match default request: "
+ throw new IllegalStateException(
+ "TRACK_SYSTEM_DEFAULT capabilities don't match default request: "
+ networkCapabilities + " vs. " + defaultNc);
}
@@ -7449,7 +6917,6 @@
mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork);
}
mNetworkActivityTracker.updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork);
- notifyLockdownVpn(newDefaultNetwork);
handleApplyDefaultProxy(null != newDefaultNetwork
? newDefaultNetwork.linkProperties.getHttpProxy() : null);
updateTcpBufferSizes(null != newDefaultNetwork
@@ -7907,12 +7374,6 @@
mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0;
mLegacyTypeTracker.add(
newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
- // If the legacy VPN is connected, notifyLockdownVpn may end up sending a broadcast
- // to reflect the NetworkInfo of this new network. This broadcast has to be sent
- // after the disconnect broadcasts above, but before the broadcasts sent by the
- // legacy type tracker below.
- // TODO : refactor this, it's too complex
- notifyLockdownVpn(newDefaultNetwork);
}
}
@@ -7970,18 +7431,6 @@
sendInetConditionBroadcast(nai.networkInfo);
}
- private void notifyLockdownVpn(NetworkAgentInfo nai) {
- synchronized (mVpns) {
- if (mLockdownTracker != null) {
- if (nai != null && nai.isVPN()) {
- mLockdownTracker.onVpnStateChanged(nai.networkInfo);
- } else {
- mLockdownTracker.onNetworkInfoChanged();
- }
- }
- }
- }
-
@NonNull
private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) {
final NetworkInfo newInfo = new NetworkInfo(info);
@@ -8020,7 +7469,6 @@
oldInfo = networkAgent.networkInfo;
networkAgent.networkInfo = newInfo;
}
- notifyLockdownVpn(networkAgent);
if (DBG) {
log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from "
@@ -8321,34 +7769,6 @@
}
@Override
- public boolean addVpnAddress(String address, int prefixLength) {
- int user = UserHandle.getUserId(mDeps.getCallingUid());
- synchronized (mVpns) {
- throwIfLockdownEnabled();
- return mVpns.get(user).addAddress(address, prefixLength);
- }
- }
-
- @Override
- public boolean removeVpnAddress(String address, int prefixLength) {
- int user = UserHandle.getUserId(mDeps.getCallingUid());
- synchronized (mVpns) {
- throwIfLockdownEnabled();
- return mVpns.get(user).removeAddress(address, prefixLength);
- }
- }
-
- @Override
- public boolean setUnderlyingNetworksForVpn(Network[] networks) {
- int user = UserHandle.getUserId(mDeps.getCallingUid());
- final boolean success;
- synchronized (mVpns) {
- success = mVpns.get(user).setUnderlyingNetworks(networks);
- }
- return success;
- }
-
- @Override
public String getCaptivePortalServerUrl() {
enforceNetworkStackOrSettingsPermission();
String settingUrl = mContext.getResources().getString(
@@ -8427,8 +7847,6 @@
return;
}
- final int userId = UserHandle.getCallingUserId();
-
final long token = Binder.clearCallingIdentity();
try {
final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
@@ -8440,44 +7858,6 @@
// Turn airplane mode off
setAirplaneMode(false);
- if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
- // Remove always-on package
- synchronized (mVpns) {
- final String alwaysOnPackage = getAlwaysOnVpnPackage(userId);
- if (alwaysOnPackage != null) {
- setAlwaysOnVpnPackage(userId, null, false, null);
- setVpnPackageAuthorization(alwaysOnPackage, userId, VpnManager.TYPE_VPN_NONE);
- }
-
- // Turn Always-on VPN off
- if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) {
- final long ident = Binder.clearCallingIdentity();
- try {
- mKeyStore.delete(Credentials.LOCKDOWN_VPN);
- mLockdownEnabled = false;
- setLockdownTracker(null);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- // Turn VPN off
- VpnConfig vpnConfig = getVpnConfig(userId);
- if (vpnConfig != null) {
- if (vpnConfig.legacy) {
- prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
- } else {
- // Prevent this app (packagename = vpnConfig.user) from initiating
- // VPN connections in the future without user intervention.
- setVpnPackageAuthorization(
- vpnConfig.user, userId, VpnManager.TYPE_VPN_NONE);
-
- prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
- }
- }
- }
- }
-
// restore private DNS settings to default mode (opportunistic)
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) {
Settings.Global.putString(mContext.getContentResolver(),
@@ -8569,25 +7949,6 @@
}
}
- @GuardedBy("mVpns")
- private Vpn getVpnIfOwner() {
- return getVpnIfOwner(mDeps.getCallingUid());
- }
-
- // TODO: stop calling into Vpn.java and get this information from data in this class.
- @GuardedBy("mVpns")
- private Vpn getVpnIfOwner(int uid) {
- final int user = UserHandle.getUserId(uid);
-
- final Vpn vpn = mVpns.get(user);
- if (vpn == null) {
- return null;
- } else {
- final UnderlyingNetworkInfo info = vpn.getUnderlyingNetworkInfo();
- return (info == null || info.ownerUid != uid) ? null : vpn;
- }
- }
-
private @VpnManager.VpnType int getVpnType(@Nullable NetworkAgentInfo vpn) {
if (vpn == null) return VpnManager.TYPE_VPN_NONE;
final TransportInfo ti = vpn.networkCapabilities.getTransportInfo();
@@ -8624,22 +7985,6 @@
return uid;
}
- @Override
- public boolean isCallerCurrentAlwaysOnVpnApp() {
- synchronized (mVpns) {
- Vpn vpn = getVpnIfOwner();
- return vpn != null && vpn.getAlwaysOn();
- }
- }
-
- @Override
- public boolean isCallerCurrentAlwaysOnVpnLockdownApp() {
- synchronized (mVpns) {
- Vpn vpn = getVpnIfOwner();
- return vpn != null && vpn.getLockdown();
- }
- }
-
/**
* Returns a IBinder to a TestNetworkService. Will be lazily created as needed.
*
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
new file mode 100644
index 0000000..5d89bf1
--- /dev/null
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -0,0 +1,918 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.Manifest.permission.NETWORK_STACK;
+
+import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.INetd;
+import android.net.IVpnManager;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkStack;
+import android.net.UnderlyingNetworkInfo;
+import android.net.Uri;
+import android.net.VpnManager;
+import android.net.VpnService;
+import android.net.util.NetdService;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.INetworkManagementService;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.security.Credentials;
+import android.security.KeyStore;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.net.LegacyVpnInfo;
+import com.android.internal.net.VpnConfig;
+import com.android.internal.net.VpnProfile;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.connectivity.Vpn;
+import com.android.server.net.LockdownVpnTracker;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Service that tracks and manages VPNs, and backs the VpnService and VpnManager APIs.
+ * @hide
+ */
+public class VpnManagerService extends IVpnManager.Stub {
+ private static final String TAG = VpnManagerService.class.getSimpleName();
+
+ @VisibleForTesting
+ protected final HandlerThread mHandlerThread;
+ private final Handler mHandler;
+
+ private final Context mContext;
+ private final Context mUserAllContext;
+
+ private final Dependencies mDeps;
+
+ private final ConnectivityManager mCm;
+ private final KeyStore mKeyStore;
+ private final INetworkManagementService mNMS;
+ private final INetd mNetd;
+ private final UserManager mUserManager;
+
+ @VisibleForTesting
+ @GuardedBy("mVpns")
+ protected final SparseArray<Vpn> mVpns = new SparseArray<>();
+
+ // TODO: investigate if mLockdownEnabled can be removed and replaced everywhere by
+ // a direct call to LockdownVpnTracker.isEnabled().
+ @GuardedBy("mVpns")
+ private boolean mLockdownEnabled;
+ @GuardedBy("mVpns")
+ private LockdownVpnTracker mLockdownTracker;
+
+ /**
+ * Dependencies of VpnManager, for injection in tests.
+ */
+ @VisibleForTesting
+ public static class Dependencies {
+ /** Returns the calling UID of an IPC. */
+ public int getCallingUid() {
+ return Binder.getCallingUid();
+ }
+
+ /** Creates a HandlerThread to be used by this class. */
+ public HandlerThread makeHandlerThread() {
+ return new HandlerThread("VpnManagerService");
+ }
+
+ /** Returns the KeyStore instance to be used by this class. */
+ public KeyStore getKeyStore() {
+ return KeyStore.getInstance();
+ }
+
+ public INetd getNetd() {
+ return NetdService.getInstance();
+ }
+
+ public INetworkManagementService getINetworkManagementService() {
+ return INetworkManagementService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
+ }
+ }
+
+ public VpnManagerService(Context context, Dependencies deps) {
+ mContext = context;
+ mDeps = deps;
+ mHandlerThread = mDeps.makeHandlerThread();
+ mHandlerThread.start();
+ mHandler = mHandlerThread.getThreadHandler();
+ mKeyStore = mDeps.getKeyStore();
+ mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
+ mCm = mContext.getSystemService(ConnectivityManager.class);
+ mNMS = mDeps.getINetworkManagementService();
+ mNetd = mDeps.getNetd();
+ mUserManager = mContext.getSystemService(UserManager.class);
+ registerReceivers();
+ log("VpnManagerService starting up");
+ }
+
+ /** Creates a new VpnManagerService */
+ public static VpnManagerService create(Context context) {
+ return new VpnManagerService(context, new Dependencies());
+ }
+
+ /** Informs the service that the system is ready. */
+ public void systemReady() {
+ // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait
+ // for user to unlock device too.
+ updateLockdownVpn();
+ }
+
+ @Override
+ /** Dumps service state. */
+ protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
+ @Nullable String[] args) {
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
+ IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
+ pw.println("VPNs:");
+ pw.increaseIndent();
+ synchronized (mVpns) {
+ for (int i = 0; i < mVpns.size(); i++) {
+ pw.println(mVpns.keyAt(i) + ": " + mVpns.valueAt(i).getPackage());
+ }
+ pw.decreaseIndent();
+ }
+ }
+
+ /**
+ * Prepare for a VPN application.
+ * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
+ * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
+ *
+ * @param oldPackage Package name of the application which currently controls VPN, which will
+ * be replaced. If there is no such application, this should should either be
+ * {@code null} or {@link VpnConfig.LEGACY_VPN}.
+ * @param newPackage Package name of the application which should gain control of VPN, or
+ * {@code null} to disable.
+ * @param userId User for whom to prepare the new VPN.
+ *
+ * @hide
+ */
+ @Override
+ public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage,
+ int userId) {
+ enforceCrossUserPermission(userId);
+
+ synchronized (mVpns) {
+ throwIfLockdownEnabled();
+ Vpn vpn = mVpns.get(userId);
+ if (vpn != null) {
+ return vpn.prepare(oldPackage, newPackage, VpnManager.TYPE_VPN_SERVICE);
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Set whether the VPN package has the ability to launch VPNs without user intervention. This
+ * method is used by system-privileged apps. VPN permissions are checked in the {@link Vpn}
+ * class. If the caller is not {@code userId}, {@link
+ * android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
+ *
+ * @param packageName The package for which authorization state should change.
+ * @param userId User for whom {@code packageName} is installed.
+ * @param vpnType The {@link VpnManager.VpnType} constant representing what class of VPN
+ * permissions should be granted. When unauthorizing an app, {@link
+ * VpnManager.TYPE_VPN_NONE} should be used.
+ * @hide
+ */
+ @Override
+ public void setVpnPackageAuthorization(
+ String packageName, int userId, @VpnManager.VpnType int vpnType) {
+ enforceCrossUserPermission(userId);
+
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(userId);
+ if (vpn != null) {
+ vpn.setPackageAuthorization(packageName, vpnType);
+ }
+ }
+ }
+
+ /**
+ * Configure a TUN interface and return its file descriptor. Parameters
+ * are encoded and opaque to this class. This method is used by VpnBuilder
+ * and not available in VpnManager. Permissions are checked in
+ * Vpn class.
+ * @hide
+ */
+ @Override
+ public ParcelFileDescriptor establishVpn(VpnConfig config) {
+ int user = UserHandle.getUserId(mDeps.getCallingUid());
+ synchronized (mVpns) {
+ throwIfLockdownEnabled();
+ return mVpns.get(user).establish(config);
+ }
+ }
+
+ @Override
+ public boolean addVpnAddress(String address, int prefixLength) {
+ int user = UserHandle.getUserId(mDeps.getCallingUid());
+ synchronized (mVpns) {
+ throwIfLockdownEnabled();
+ return mVpns.get(user).addAddress(address, prefixLength);
+ }
+ }
+
+ @Override
+ public boolean removeVpnAddress(String address, int prefixLength) {
+ int user = UserHandle.getUserId(mDeps.getCallingUid());
+ synchronized (mVpns) {
+ throwIfLockdownEnabled();
+ return mVpns.get(user).removeAddress(address, prefixLength);
+ }
+ }
+
+ @Override
+ public boolean setUnderlyingNetworksForVpn(Network[] networks) {
+ int user = UserHandle.getUserId(mDeps.getCallingUid());
+ final boolean success;
+ synchronized (mVpns) {
+ success = mVpns.get(user).setUnderlyingNetworks(networks);
+ }
+ return success;
+ }
+
+ /**
+ * Stores the given VPN profile based on the provisioning package name.
+ *
+ * <p>If there is already a VPN profile stored for the provisioning package, this call will
+ * overwrite the profile.
+ *
+ * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
+ * exclusively by the Settings app, and passed into the platform at startup time.
+ *
+ * @return {@code true} if user consent has already been granted, {@code false} otherwise.
+ * @hide
+ */
+ @Override
+ public boolean provisionVpnProfile(@NonNull VpnProfile profile, @NonNull String packageName) {
+ final int user = UserHandle.getUserId(mDeps.getCallingUid());
+ synchronized (mVpns) {
+ return mVpns.get(user).provisionVpnProfile(packageName, profile, mKeyStore);
+ }
+ }
+
+ /**
+ * Deletes the stored VPN profile for the provisioning package
+ *
+ * <p>If there are no profiles for the given package, this method will silently succeed.
+ *
+ * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
+ * exclusively by the Settings app, and passed into the platform at startup time.
+ *
+ * @hide
+ */
+ @Override
+ public void deleteVpnProfile(@NonNull String packageName) {
+ final int user = UserHandle.getUserId(mDeps.getCallingUid());
+ synchronized (mVpns) {
+ mVpns.get(user).deleteVpnProfile(packageName, mKeyStore);
+ }
+ }
+
+ /**
+ * Starts the VPN based on the stored profile for the given package
+ *
+ * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
+ * exclusively by the Settings app, and passed into the platform at startup time.
+ *
+ * @throws IllegalArgumentException if no profile was found for the given package name.
+ * @hide
+ */
+ @Override
+ public void startVpnProfile(@NonNull String packageName) {
+ final int user = UserHandle.getUserId(mDeps.getCallingUid());
+ synchronized (mVpns) {
+ throwIfLockdownEnabled();
+ mVpns.get(user).startVpnProfile(packageName, mKeyStore);
+ }
+ }
+
+ /**
+ * Stops the Platform VPN if the provided package is running one.
+ *
+ * <p>This is designed to serve the VpnManager only; settings-based VPN profiles are managed
+ * exclusively by the Settings app, and passed into the platform at startup time.
+ *
+ * @hide
+ */
+ @Override
+ public void stopVpnProfile(@NonNull String packageName) {
+ final int user = UserHandle.getUserId(mDeps.getCallingUid());
+ synchronized (mVpns) {
+ mVpns.get(user).stopVpnProfile(packageName);
+ }
+ }
+
+ /**
+ * Start legacy VPN, controlling native daemons as needed. Creates a
+ * secondary thread to perform connection work, returning quickly.
+ */
+ @Override
+ public void startLegacyVpn(VpnProfile profile) {
+ int user = UserHandle.getUserId(mDeps.getCallingUid());
+ final LinkProperties egress = mCm.getActiveLinkProperties();
+ if (egress == null) {
+ throw new IllegalStateException("Missing active network connection");
+ }
+ synchronized (mVpns) {
+ throwIfLockdownEnabled();
+ mVpns.get(user).startLegacyVpn(profile, mKeyStore, null /* underlying */, egress);
+ }
+ }
+
+ /**
+ * Return the information of the ongoing legacy VPN. This method is used
+ * by VpnSettings and not available in ConnectivityManager. Permissions
+ * are checked in Vpn class.
+ */
+ @Override
+ public LegacyVpnInfo getLegacyVpnInfo(int userId) {
+ enforceCrossUserPermission(userId);
+
+ synchronized (mVpns) {
+ return mVpns.get(userId).getLegacyVpnInfo();
+ }
+ }
+
+ /**
+ * Returns the information of the ongoing VPN for {@code userId}. This method is used by
+ * VpnDialogs and not available in ConnectivityManager.
+ * Permissions are checked in Vpn class.
+ * @hide
+ */
+ @Override
+ public VpnConfig getVpnConfig(int userId) {
+ enforceCrossUserPermission(userId);
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(userId);
+ if (vpn != null) {
+ return vpn.getVpnConfig();
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private boolean isLockdownVpnEnabled() {
+ return mKeyStore.contains(Credentials.LOCKDOWN_VPN);
+ }
+
+ @Override
+ public boolean updateLockdownVpn() {
+ // Allow the system UID for the system server and for Settings.
+ // Also, for unit tests, allow the process that ConnectivityService is running in.
+ if (mDeps.getCallingUid() != Process.SYSTEM_UID
+ && Binder.getCallingPid() != Process.myPid()) {
+ logw("Lockdown VPN only available to system process or AID_SYSTEM");
+ return false;
+ }
+
+ synchronized (mVpns) {
+ // Tear down existing lockdown if profile was removed
+ mLockdownEnabled = isLockdownVpnEnabled();
+ if (!mLockdownEnabled) {
+ setLockdownTracker(null);
+ return true;
+ }
+
+ byte[] profileTag = mKeyStore.get(Credentials.LOCKDOWN_VPN);
+ if (profileTag == null) {
+ loge("Lockdown VPN configured but cannot be read from keystore");
+ return false;
+ }
+ String profileName = new String(profileTag);
+ final VpnProfile profile = VpnProfile.decode(
+ profileName, mKeyStore.get(Credentials.VPN + profileName));
+ if (profile == null) {
+ loge("Lockdown VPN configured invalid profile " + profileName);
+ setLockdownTracker(null);
+ return true;
+ }
+ int user = UserHandle.getUserId(mDeps.getCallingUid());
+ Vpn vpn = mVpns.get(user);
+ if (vpn == null) {
+ logw("VPN for user " + user + " not ready yet. Skipping lockdown");
+ return false;
+ }
+ setLockdownTracker(
+ new LockdownVpnTracker(mContext, mHandler, mKeyStore, vpn, profile));
+ }
+
+ return true;
+ }
+
+ /**
+ * Internally set new {@link LockdownVpnTracker}, shutting down any existing
+ * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown.
+ */
+ @GuardedBy("mVpns")
+ private void setLockdownTracker(LockdownVpnTracker tracker) {
+ // Shutdown any existing tracker
+ final LockdownVpnTracker existing = mLockdownTracker;
+ // TODO: Add a trigger when the always-on VPN enable/disable to reevaluate and send the
+ // necessary onBlockedStatusChanged callbacks.
+ mLockdownTracker = null;
+ if (existing != null) {
+ existing.shutdown();
+ }
+
+ if (tracker != null) {
+ mLockdownTracker = tracker;
+ mLockdownTracker.init();
+ }
+ }
+
+ /**
+ * Throws if there is any currently running, always-on Legacy VPN.
+ *
+ * <p>The LockdownVpnTracker and mLockdownEnabled both track whether an always-on Legacy VPN is
+ * running across the entire system. Tracking for app-based VPNs is done on a per-user,
+ * per-package basis in Vpn.java
+ */
+ @GuardedBy("mVpns")
+ private void throwIfLockdownEnabled() {
+ if (mLockdownEnabled) {
+ throw new IllegalStateException("Unavailable in lockdown mode");
+ }
+ }
+
+ /**
+ * Starts the always-on VPN {@link VpnService} for user {@param userId}, which should perform
+ * some setup and then call {@code establish()} to connect.
+ *
+ * @return {@code true} if the service was started, the service was already connected, or there
+ * was no always-on VPN to start. {@code false} otherwise.
+ */
+ private boolean startAlwaysOnVpn(int userId) {
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(userId);
+ if (vpn == null) {
+ // Shouldn't happen as all code paths that point here should have checked the Vpn
+ // exists already.
+ Log.wtf(TAG, "User " + userId + " has no Vpn configuration");
+ return false;
+ }
+
+ return vpn.startAlwaysOnVpn(mKeyStore);
+ }
+ }
+
+ @Override
+ public boolean isAlwaysOnVpnPackageSupported(int userId, String packageName) {
+ enforceSettingsPermission();
+ enforceCrossUserPermission(userId);
+
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(userId);
+ if (vpn == null) {
+ logw("User " + userId + " has no Vpn configuration");
+ return false;
+ }
+ return vpn.isAlwaysOnPackageSupported(packageName, mKeyStore);
+ }
+ }
+
+ @Override
+ public boolean setAlwaysOnVpnPackage(
+ int userId, String packageName, boolean lockdown, List<String> lockdownAllowlist) {
+ enforceControlAlwaysOnVpnPermission();
+ enforceCrossUserPermission(userId);
+
+ synchronized (mVpns) {
+ // Can't set always-on VPN if legacy VPN is already in lockdown mode.
+ if (isLockdownVpnEnabled()) {
+ return false;
+ }
+
+ Vpn vpn = mVpns.get(userId);
+ if (vpn == null) {
+ logw("User " + userId + " has no Vpn configuration");
+ return false;
+ }
+ if (!vpn.setAlwaysOnPackage(packageName, lockdown, lockdownAllowlist, mKeyStore)) {
+ return false;
+ }
+ if (!startAlwaysOnVpn(userId)) {
+ vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String getAlwaysOnVpnPackage(int userId) {
+ enforceControlAlwaysOnVpnPermission();
+ enforceCrossUserPermission(userId);
+
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(userId);
+ if (vpn == null) {
+ logw("User " + userId + " has no Vpn configuration");
+ return null;
+ }
+ return vpn.getAlwaysOnPackage();
+ }
+ }
+
+ @Override
+ public boolean isVpnLockdownEnabled(int userId) {
+ enforceControlAlwaysOnVpnPermission();
+ enforceCrossUserPermission(userId);
+
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(userId);
+ if (vpn == null) {
+ logw("User " + userId + " has no Vpn configuration");
+ return false;
+ }
+ return vpn.getLockdown();
+ }
+ }
+
+ @Override
+ public List<String> getVpnLockdownAllowlist(int userId) {
+ enforceControlAlwaysOnVpnPermission();
+ enforceCrossUserPermission(userId);
+
+ synchronized (mVpns) {
+ Vpn vpn = mVpns.get(userId);
+ if (vpn == null) {
+ logw("User " + userId + " has no Vpn configuration");
+ return null;
+ }
+ return vpn.getLockdownAllowlist();
+ }
+ }
+
+ @GuardedBy("mVpns")
+ private Vpn getVpnIfOwner() {
+ return getVpnIfOwner(mDeps.getCallingUid());
+ }
+
+ // TODO: stop calling into Vpn.java and get this information from data in this class.
+ @GuardedBy("mVpns")
+ private Vpn getVpnIfOwner(int uid) {
+ final int user = UserHandle.getUserId(uid);
+
+ final Vpn vpn = mVpns.get(user);
+ if (vpn == null) {
+ return null;
+ } else {
+ final UnderlyingNetworkInfo info = vpn.getUnderlyingNetworkInfo();
+ return (info == null || info.ownerUid != uid) ? null : vpn;
+ }
+ }
+
+ private void registerReceivers() {
+ // Set up the listener for user state for creating user VPNs.
+ // Should run on mHandler to avoid any races.
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_USER_STARTED);
+ intentFilter.addAction(Intent.ACTION_USER_STOPPED);
+ intentFilter.addAction(Intent.ACTION_USER_ADDED);
+ intentFilter.addAction(Intent.ACTION_USER_REMOVED);
+ intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+
+ mUserAllContext.registerReceiver(
+ mIntentReceiver,
+ intentFilter,
+ null /* broadcastPermission */,
+ mHandler);
+ mContext.createContextAsUser(UserHandle.SYSTEM, 0 /* flags */).registerReceiver(
+ mUserPresentReceiver,
+ new IntentFilter(Intent.ACTION_USER_PRESENT),
+ null /* broadcastPermission */,
+ mHandler /* scheduler */);
+
+ // Listen to package add and removal events for all users.
+ intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+ intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ intentFilter.addDataScheme("package");
+ mUserAllContext.registerReceiver(
+ mIntentReceiver,
+ intentFilter,
+ null /* broadcastPermission */,
+ mHandler);
+
+ // Listen to lockdown VPN reset.
+ intentFilter = new IntentFilter();
+ intentFilter.addAction(LockdownVpnTracker.ACTION_LOCKDOWN_RESET);
+ mUserAllContext.registerReceiver(
+ mIntentReceiver, intentFilter, NETWORK_STACK, mHandler);
+ }
+
+ private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ ensureRunningOnHandlerThread();
+ final String action = intent.getAction();
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ final Uri packageData = intent.getData();
+ final String packageName =
+ packageData != null ? packageData.getSchemeSpecificPart() : null;
+
+ if (LockdownVpnTracker.ACTION_LOCKDOWN_RESET.equals(action)) {
+ onVpnLockdownReset();
+ }
+
+ // UserId should be filled for below intents, check the existence.
+ if (userId == UserHandle.USER_NULL) return;
+
+ if (Intent.ACTION_USER_STARTED.equals(action)) {
+ onUserStarted(userId);
+ } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
+ onUserStopped(userId);
+ } else if (Intent.ACTION_USER_ADDED.equals(action)) {
+ onUserAdded(userId);
+ } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ onUserRemoved(userId);
+ } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
+ onUserUnlocked(userId);
+ } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
+ onPackageReplaced(packageName, uid);
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ final boolean isReplacing = intent.getBooleanExtra(
+ Intent.EXTRA_REPLACING, false);
+ onPackageRemoved(packageName, uid, isReplacing);
+ } else {
+ Log.wtf(TAG, "received unexpected intent: " + action);
+ }
+ }
+ };
+
+ private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ ensureRunningOnHandlerThread();
+ // Try creating lockdown tracker, since user present usually means
+ // unlocked keystore.
+ updateLockdownVpn();
+ // Use the same context that registered receiver before to unregister it. Because use
+ // different context to unregister receiver will cause exception.
+ context.unregisterReceiver(this);
+ }
+ };
+
+ private void onUserStarted(int userId) {
+ synchronized (mVpns) {
+ Vpn userVpn = mVpns.get(userId);
+ if (userVpn != null) {
+ loge("Starting user already has a VPN");
+ return;
+ }
+ userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, mNetd, userId, mKeyStore);
+ mVpns.put(userId, userVpn);
+ if (mUserManager.getUserInfo(userId).isPrimary() && isLockdownVpnEnabled()) {
+ updateLockdownVpn();
+ }
+ }
+ }
+
+ private void onUserStopped(int userId) {
+ synchronized (mVpns) {
+ Vpn userVpn = mVpns.get(userId);
+ if (userVpn == null) {
+ loge("Stopped user has no VPN");
+ return;
+ }
+ userVpn.onUserStopped();
+ mVpns.delete(userId);
+ }
+ }
+
+ @Override
+ public boolean isCallerCurrentAlwaysOnVpnApp() {
+ synchronized (mVpns) {
+ Vpn vpn = getVpnIfOwner();
+ return vpn != null && vpn.getAlwaysOn();
+ }
+ }
+
+ @Override
+ public boolean isCallerCurrentAlwaysOnVpnLockdownApp() {
+ synchronized (mVpns) {
+ Vpn vpn = getVpnIfOwner();
+ return vpn != null && vpn.getLockdown();
+ }
+ }
+
+
+ private void onUserAdded(int userId) {
+ synchronized (mVpns) {
+ final int vpnsSize = mVpns.size();
+ for (int i = 0; i < vpnsSize; i++) {
+ Vpn vpn = mVpns.valueAt(i);
+ vpn.onUserAdded(userId);
+ }
+ }
+ }
+
+ private void onUserRemoved(int userId) {
+ synchronized (mVpns) {
+ final int vpnsSize = mVpns.size();
+ for (int i = 0; i < vpnsSize; i++) {
+ Vpn vpn = mVpns.valueAt(i);
+ vpn.onUserRemoved(userId);
+ }
+ }
+ }
+
+ private void onPackageReplaced(String packageName, int uid) {
+ if (TextUtils.isEmpty(packageName) || uid < 0) {
+ Log.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid);
+ return;
+ }
+ final int userId = UserHandle.getUserId(uid);
+ synchronized (mVpns) {
+ final Vpn vpn = mVpns.get(userId);
+ if (vpn == null) {
+ return;
+ }
+ // Legacy always-on VPN won't be affected since the package name is not set.
+ if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) {
+ log("Restarting always-on VPN package " + packageName + " for user "
+ + userId);
+ vpn.startAlwaysOnVpn(mKeyStore);
+ }
+ }
+ }
+
+ private void onPackageRemoved(String packageName, int uid, boolean isReplacing) {
+ if (TextUtils.isEmpty(packageName) || uid < 0) {
+ Log.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid);
+ return;
+ }
+
+ final int userId = UserHandle.getUserId(uid);
+ synchronized (mVpns) {
+ final Vpn vpn = mVpns.get(userId);
+ if (vpn == null) {
+ return;
+ }
+ // Legacy always-on VPN won't be affected since the package name is not set.
+ if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) {
+ log("Removing always-on VPN package " + packageName + " for user "
+ + userId);
+ vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
+ }
+ }
+ }
+
+ private void onUserUnlocked(int userId) {
+ synchronized (mVpns) {
+ // User present may be sent because of an unlock, which might mean an unlocked keystore.
+ if (mUserManager.getUserInfo(userId).isPrimary() && isLockdownVpnEnabled()) {
+ updateLockdownVpn();
+ } else {
+ startAlwaysOnVpn(userId);
+ }
+ }
+ }
+
+ private void onVpnLockdownReset() {
+ synchronized (mVpns) {
+ if (mLockdownTracker != null) mLockdownTracker.reset();
+ }
+ }
+
+
+ @Override
+ public void factoryReset() {
+ enforceSettingsPermission();
+
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)
+ || mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
+ return;
+ }
+
+ // Remove always-on package
+ final int userId = UserHandle.getCallingUserId();
+ synchronized (mVpns) {
+ final String alwaysOnPackage = getAlwaysOnVpnPackage(userId);
+ if (alwaysOnPackage != null) {
+ setAlwaysOnVpnPackage(userId, null, false, null);
+ setVpnPackageAuthorization(alwaysOnPackage, userId, VpnManager.TYPE_VPN_NONE);
+ }
+
+ // Turn Always-on VPN off
+ if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mKeyStore.delete(Credentials.LOCKDOWN_VPN);
+ mLockdownEnabled = false;
+ setLockdownTracker(null);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ // Turn VPN off
+ VpnConfig vpnConfig = getVpnConfig(userId);
+ if (vpnConfig != null) {
+ if (vpnConfig.legacy) {
+ prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
+ } else {
+ // Prevent this app (packagename = vpnConfig.user) from initiating
+ // VPN connections in the future without user intervention.
+ setVpnPackageAuthorization(
+ vpnConfig.user, userId, VpnManager.TYPE_VPN_NONE);
+
+ prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
+ }
+ }
+ }
+ }
+
+ private void ensureRunningOnHandlerThread() {
+ if (mHandler.getLooper().getThread() != Thread.currentThread()) {
+ throw new IllegalStateException(
+ "Not running on VpnManagerService thread: "
+ + Thread.currentThread().getName());
+ }
+ }
+
+ private void enforceControlAlwaysOnVpnPermission() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CONTROL_ALWAYS_ON_VPN,
+ "VpnManagerService");
+ }
+
+ /**
+ * Require that the caller is either in the same user or has appropriate permission to interact
+ * across users.
+ *
+ * @param userId Target user for whatever operation the current IPC is supposed to perform.
+ */
+ private void enforceCrossUserPermission(int userId) {
+ if (userId == UserHandle.getCallingUserId()) {
+ // Not a cross-user call.
+ return;
+ }
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "VpnManagerService");
+ }
+
+ private void enforceSettingsPermission() {
+ enforceAnyPermissionOf(mContext,
+ android.Manifest.permission.NETWORK_SETTINGS,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+ }
+
+ private static void log(String s) {
+ Log.d(TAG, s);
+ }
+
+ private static void logw(String s) {
+ Log.w(TAG, s);
+ }
+
+ private static void loge(String s) {
+ Log.e(TAG, s);
+ }
+}
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 6f112d7..508739f 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -79,7 +79,6 @@
// server.
public static final String NOTIFICATION_CHANNEL_NETWORK_STATUS = "NETWORK_STATUS";
public static final String NOTIFICATION_CHANNEL_NETWORK_ALERTS = "NETWORK_ALERTS";
- public static final String NOTIFICATION_CHANNEL_VPN = "VPN";
// The context is for the current user (system server)
private final Context mContext;
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 33c19b1..a769e88 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -21,10 +21,10 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE;
+import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
-import static com.android.server.connectivity.NetworkNotificationManager.NOTIFICATION_CHANNEL_VPN;
import android.Manifest;
import android.annotation.NonNull;
@@ -172,6 +172,12 @@
*/
@VisibleForTesting static final int MAX_VPN_PROFILE_SIZE_BYTES = 1 << 17; // 128kB
+ /**
+ * Network score that VPNs will announce to ConnectivityService.
+ * TODO: remove when the network scoring refactor lands.
+ */
+ private static final int VPN_DEFAULT_SCORE = 101;
+
// TODO: create separate trackers for each unique VPN to support
// automated reconnection
@@ -496,6 +502,11 @@
updateAlwaysOnNotification(detailedState);
}
+ private void resetNetworkCapabilities() {
+ mNetworkCapabilities.setUids(null);
+ mNetworkCapabilities.setTransportInfo(new VpnTransportInfo(VpnManager.TYPE_VPN_NONE));
+ }
+
/**
* Chooses whether to force all connections to go though VPN.
*
@@ -520,6 +531,11 @@
}
}
+ /** Returns the package name that is currently prepared. */
+ public String getPackage() {
+ return mPackage;
+ }
+
/**
* Check whether to prevent all traffic outside of a VPN even when the VPN is not connected.
*
@@ -930,8 +946,7 @@
agentDisconnect();
jniReset(mInterface);
mInterface = null;
- mNetworkCapabilities.setUids(null);
- mNetworkCapabilities.setTransportInfo(null);
+ resetNetworkCapabilities();
}
// Revoke the connection or stop the VpnRunner.
@@ -1229,8 +1244,7 @@
}
mNetworkAgent = new NetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
- mNetworkCapabilities, lp,
- ConnectivityConstants.VPN_DEFAULT_SCORE, networkAgentConfig, mNetworkProvider) {
+ mNetworkCapabilities, lp, VPN_DEFAULT_SCORE, networkAgentConfig, mNetworkProvider) {
@Override
public void unwanted() {
// We are user controlled, not driven by NetworkRequest.
@@ -1744,8 +1758,7 @@
private void cleanupVpnStateLocked() {
mStatusIntent = null;
- mNetworkCapabilities.setUids(null);
- mNetworkCapabilities.setTransportInfo(null);
+ resetNetworkCapabilities();
mConfig = null;
mInterface = null;
diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java
index 6d1c680..3cc32be 100644
--- a/services/core/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java
@@ -16,10 +16,10 @@
package com.android.server.net;
-import static android.net.ConnectivityManager.TYPE_NONE;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
import static android.provider.Settings.ACTION_VPN_SETTINGS;
-import static com.android.server.connectivity.NetworkNotificationManager.NOTIFICATION_CHANNEL_VPN;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -28,43 +28,37 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
+import android.net.Network;
import android.net.NetworkInfo;
-import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkInfo.State;
+import android.net.NetworkRequest;
import android.os.Handler;
import android.security.KeyStore;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile;
-import com.android.server.ConnectivityService;
-import com.android.server.EventLogTags;
import com.android.server.connectivity.Vpn;
import java.util.List;
import java.util.Objects;
/**
- * State tracker for lockdown mode. Watches for normal {@link NetworkInfo} to be
- * connected and kicks off VPN connection, managing any required {@code netd}
- * firewall rules.
+ * State tracker for legacy lockdown VPN. Watches for physical networks to be
+ * connected and kicks off VPN connection.
*/
public class LockdownVpnTracker {
private static final String TAG = "LockdownVpnTracker";
- /** Number of VPN attempts before waiting for user intervention. */
- private static final int MAX_ERROR_COUNT = 4;
-
public static final String ACTION_LOCKDOWN_RESET = "com.android.server.action.LOCKDOWN_RESET";
@NonNull private final Context mContext;
- @NonNull private final ConnectivityService mConnService;
+ @NonNull private final ConnectivityManager mCm;
@NonNull private final NotificationManager mNotificationManager;
@NonNull private final Handler mHandler;
@NonNull private final Vpn mVpn;
@@ -76,19 +70,73 @@
@NonNull private final PendingIntent mConfigIntent;
@NonNull private final PendingIntent mResetIntent;
+ @NonNull private final NetworkCallback mDefaultNetworkCallback = new NetworkCallback();
+ @NonNull private final VpnNetworkCallback mVpnNetworkCallback = new VpnNetworkCallback();
+
+ private class NetworkCallback extends ConnectivityManager.NetworkCallback {
+ private Network mNetwork = null;
+ private LinkProperties mLinkProperties = null;
+
+ @Override
+ public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
+ boolean networkChanged = false;
+ if (!network.equals(mNetwork)) {
+ // The default network just changed.
+ mNetwork = network;
+ networkChanged = true;
+ }
+ mLinkProperties = lp;
+ // Backwards compatibility: previously, LockdownVpnTracker only responded to connects
+ // and disconnects, not LinkProperties changes on existing networks.
+ if (networkChanged) {
+ synchronized (mStateLock) {
+ handleStateChangedLocked();
+ }
+ }
+ }
+
+ @Override
+ public void onLost(Network network) {
+ // The default network has gone down.
+ mNetwork = null;
+ mLinkProperties = null;
+ synchronized (mStateLock) {
+ handleStateChangedLocked();
+ }
+ }
+
+ public Network getNetwork() {
+ return mNetwork;
+ }
+
+ public LinkProperties getLinkProperties() {
+ return mLinkProperties;
+ }
+ }
+
+ private class VpnNetworkCallback extends NetworkCallback {
+ @Override
+ public void onAvailable(Network network) {
+ synchronized (mStateLock) {
+ handleStateChangedLocked();
+ }
+ }
+ @Override
+ public void onLost(Network network) {
+ onAvailable(network);
+ }
+ }
+
@Nullable
private String mAcceptedEgressIface;
- private int mErrorCount;
-
public LockdownVpnTracker(@NonNull Context context,
- @NonNull ConnectivityService connService,
@NonNull Handler handler,
@NonNull KeyStore keyStore,
@NonNull Vpn vpn,
@NonNull VpnProfile profile) {
mContext = Objects.requireNonNull(context);
- mConnService = Objects.requireNonNull(connService);
+ mCm = mContext.getSystemService(ConnectivityManager.class);
mHandler = Objects.requireNonNull(handler);
mVpn = Objects.requireNonNull(vpn);
mProfile = Objects.requireNonNull(profile);
@@ -110,24 +158,20 @@
* connection when ready, or setting firewall rules once VPN is connected.
*/
private void handleStateChangedLocked() {
-
- final NetworkInfo egressInfo = mConnService.getActiveNetworkInfoUnfiltered();
- final LinkProperties egressProp = mConnService.getActiveLinkProperties();
+ final Network network = mDefaultNetworkCallback.getNetwork();
+ final LinkProperties egressProp = mDefaultNetworkCallback.getLinkProperties();
final NetworkInfo vpnInfo = mVpn.getNetworkInfo();
final VpnConfig vpnConfig = mVpn.getLegacyVpnConfig();
// Restart VPN when egress network disconnected or changed
- final boolean egressDisconnected = egressInfo == null
- || State.DISCONNECTED.equals(egressInfo.getState());
+ final boolean egressDisconnected = (network == null);
final boolean egressChanged = egressProp == null
|| !TextUtils.equals(mAcceptedEgressIface, egressProp.getInterfaceName());
- final int egressType = (egressInfo == null) ? TYPE_NONE : egressInfo.getType();
final String egressIface = (egressProp == null) ?
null : egressProp.getInterfaceName();
- Log.d(TAG, "handleStateChanged: egress=" + egressType
- + " " + mAcceptedEgressIface + "->" + egressIface);
+ Log.d(TAG, "handleStateChanged: egress=" + mAcceptedEgressIface + "->" + egressIface);
if (egressDisconnected || egressChanged) {
mAcceptedEgressIface = null;
@@ -138,46 +182,49 @@
return;
}
- if (vpnInfo.getDetailedState() == DetailedState.FAILED) {
- EventLogTags.writeLockdownVpnError(egressType);
- }
-
- if (mErrorCount > MAX_ERROR_COUNT) {
- showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
-
- } else if (egressInfo.isConnected() && !vpnInfo.isConnectedOrConnecting()) {
- if (mProfile.isValidLockdownProfile()) {
- Log.d(TAG, "Active network connected; starting VPN");
- EventLogTags.writeLockdownVpnConnecting(egressType);
- showNotification(R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected);
-
- mAcceptedEgressIface = egressProp.getInterfaceName();
- try {
- // Use the privileged method because Lockdown VPN is initiated by the system, so
- // no additional permission checks are necessary.
- mVpn.startLegacyVpnPrivileged(mProfile, mKeyStore, null, egressProp);
- } catch (IllegalStateException e) {
- mAcceptedEgressIface = null;
- Log.e(TAG, "Failed to start VPN", e);
- showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
- }
- } else {
+ // At this point, |network| is known to be non-null.
+ if (!vpnInfo.isConnectedOrConnecting()) {
+ if (!mProfile.isValidLockdownProfile()) {
Log.e(TAG, "Invalid VPN profile; requires IP-based server and DNS");
showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
+ return;
}
+ Log.d(TAG, "Active network connected; starting VPN");
+ showNotification(R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected);
+
+ mAcceptedEgressIface = egressIface;
+ try {
+ // Use the privileged method because Lockdown VPN is initiated by the system, so
+ // no additional permission checks are necessary.
+ //
+ // Pass in the underlying network here because the legacy VPN is, in fact, tightly
+ // coupled to a given underlying network and cannot provide mobility. This makes
+ // things marginally more correct in two ways:
+ //
+ // 1. When the legacy lockdown VPN connects, LegacyTypeTracker broadcasts an extra
+ // CONNECTED broadcast for the underlying network type. The underlying type comes
+ // from here. LTT *could* assume that the underlying network is the default
+ // network, but that might introduce a race condition if, say, the VPN starts
+ // connecting on cell, but when the connection succeeds and the agent is
+ // registered, the default network is now wifi.
+ // 2. If no underlying network is passed in, then CS will assume the underlying
+ // network is the system default. So, if the VPN is up and underlying network
+ // (e.g., wifi) disconnects, CS will inform apps that the VPN's capabilities have
+ // changed to match the new default network (e.g., cell).
+ mVpn.startLegacyVpnPrivileged(mProfile, mKeyStore, network, egressProp);
+ } catch (IllegalStateException e) {
+ mAcceptedEgressIface = null;
+ Log.e(TAG, "Failed to start VPN", e);
+ showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
+ }
} else if (vpnInfo.isConnected() && vpnConfig != null) {
final String iface = vpnConfig.interfaze;
final List<LinkAddress> sourceAddrs = vpnConfig.addresses;
Log.d(TAG, "VPN connected using iface=" + iface
+ ", sourceAddr=" + sourceAddrs.toString());
- EventLogTags.writeLockdownVpnConnected(egressType);
showNotification(R.string.vpn_lockdown_connected, R.drawable.vpn_connected);
-
- final NetworkInfo clone = new NetworkInfo(egressInfo);
- augmentNetworkInfo(clone);
- mConnService.sendConnectedBroadcast(clone);
}
}
@@ -192,7 +239,15 @@
mVpn.setEnableTeardown(false);
mVpn.setLockdown(true);
+ mCm.setLegacyLockdownVpnEnabled(true);
handleStateChangedLocked();
+
+ mCm.registerSystemDefaultNetworkCallback(mDefaultNetworkCallback, mHandler);
+ final NetworkRequest vpnRequest = new NetworkRequest.Builder()
+ .clearCapabilities()
+ .addTransportType(TRANSPORT_VPN)
+ .build();
+ mCm.registerNetworkCallback(vpnRequest, mVpnNetworkCallback, mHandler);
}
public void shutdown() {
@@ -205,20 +260,21 @@
Log.d(TAG, "shutdownLocked()");
mAcceptedEgressIface = null;
- mErrorCount = 0;
mVpn.stopVpnRunnerPrivileged();
mVpn.setLockdown(false);
+ mCm.setLegacyLockdownVpnEnabled(false);
hideNotification();
mVpn.setEnableTeardown(true);
+ mCm.unregisterNetworkCallback(mDefaultNetworkCallback);
+ mCm.unregisterNetworkCallback(mVpnNetworkCallback);
}
/**
* Reset VPN lockdown tracker. Called by ConnectivityService when receiving
* {@link #ACTION_LOCKDOWN_RESET} pending intent.
*/
- @GuardedBy("mConnService.mVpns")
public void reset() {
Log.d(TAG, "reset()");
synchronized (mStateLock) {
@@ -229,28 +285,6 @@
}
}
- public void onNetworkInfoChanged() {
- synchronized (mStateLock) {
- handleStateChangedLocked();
- }
- }
-
- public void onVpnStateChanged(NetworkInfo info) {
- if (info.getDetailedState() == DetailedState.FAILED) {
- mErrorCount++;
- }
- synchronized (mStateLock) {
- handleStateChangedLocked();
- }
- }
-
- public void augmentNetworkInfo(NetworkInfo info) {
- if (info.isConnected()) {
- final NetworkInfo vpnInfo = mVpn.getNetworkInfo();
- info.setDetailedState(vpnInfo.getDetailedState(), vpnInfo.getReason(), null);
- }
- }
-
private void showNotification(int titleRes, int iconRes) {
final Notification.Builder builder =
new Notification.Builder(mContext, NOTIFICATION_CHANNEL_VPN)
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b063e67..9a692be7 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -6372,7 +6372,7 @@
Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
return mInjector.binderWithCleanCallingIdentity(
- () -> mInjector.getConnectivityManager().getVpnLockdownWhitelist(
+ () -> mInjector.getConnectivityManager().getVpnLockdownAllowlist(
caller.getUserId()));
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a0e5c5d..3f47227 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1295,6 +1295,7 @@
IStorageManager storageManager = null;
NetworkManagementService networkManagement = null;
IpSecService ipSecService = null;
+ VpnManagerService vpnManager = null;
VcnManagementService vcnManagement = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
@@ -1883,6 +1884,15 @@
networkPolicy.bindConnectivityManager(connectivity);
t.traceEnd();
+ t.traceBegin("StartVpnManagerService");
+ try {
+ vpnManager = VpnManagerService.create(context);
+ ServiceManager.addService(Context.VPN_MANAGEMENT_SERVICE, vpnManager);
+ } catch (Throwable e) {
+ reportWtf("starting VPN Manager Service", e);
+ }
+ t.traceEnd();
+
t.traceBegin("StartVcnManagementService");
try {
vcnManagement = VcnManagementService.create(context);
@@ -2611,6 +2621,7 @@
final MediaRouterService mediaRouterF = mediaRouter;
final MmsServiceBroker mmsServiceF = mmsService;
final IpSecService ipSecServiceF = ipSecService;
+ final VpnManagerService vpnManagerF = vpnManager;
final VcnManagementService vcnManagementF = vcnManagement;
final WindowManagerService windowManagerF = wm;
final ConnectivityManager connectivityF = (ConnectivityManager)
@@ -2725,6 +2736,15 @@
reportWtf("making Connectivity Service ready", e);
}
t.traceEnd();
+ t.traceBegin("MakeVpnManagerServiceReady");
+ try {
+ if (vpnManagerF != null) {
+ vpnManagerF.systemReady();
+ }
+ } catch (Throwable e) {
+ reportWtf("making VpnManagerService ready", e);
+ }
+ t.traceEnd();
t.traceBegin("MakeVcnManagementServiceReady");
try {
if (vcnManagementF != null) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 21cf3e5..3f6162d 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -5351,11 +5351,28 @@
public static final String KEY_SUGGESTION_SSID_LIST_WITH_MAC_RANDOMIZATION_DISABLED =
KEY_PREFIX + "suggestion_ssid_list_with_mac_randomization_disabled";
+ /**
+ * Avoid SoftAp in 5GHz if cellular is on unlicensed 5Ghz using License Assisted Access
+ * (LAA).
+ */
+ public static final String KEY_AVOID_5GHZ_SOFTAP_FOR_LAA_BOOL =
+ KEY_PREFIX + "avoid_5ghz_softap_for_laa_bool";
+
+ /**
+ * Avoid Wifi Direct in 5GHz if cellular is on unlicensed 5Ghz using License Assisted
+ * Access (LAA).
+ */
+ public static final String KEY_AVOID_5GHZ_WIFI_DIRECT_FOR_LAA_BOOL =
+ KEY_PREFIX + "avoid_5ghz_wifi_direct_for_laa_bool";
+
+
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putInt(KEY_HOTSPOT_MAX_CLIENT_COUNT, 0);
defaults.putStringArray(KEY_SUGGESTION_SSID_LIST_WITH_MAC_RANDOMIZATION_DISABLED,
new String[0]);
+ defaults.putBoolean(KEY_AVOID_5GHZ_SOFTAP_FOR_LAA_BOOL, false);
+ defaults.putBoolean(KEY_AVOID_5GHZ_WIFI_DIRECT_FOR_LAA_BOOL, false);
return defaults;
}
diff --git a/tests/net/java/android/net/VpnManagerTest.java b/tests/net/java/android/net/VpnManagerTest.java
index 95a7942..c548e30 100644
--- a/tests/net/java/android/net/VpnManagerTest.java
+++ b/tests/net/java/android/net/VpnManagerTest.java
@@ -49,7 +49,7 @@
private static final String IDENTITY_STRING = "Identity";
private static final byte[] PSK_BYTES = "preSharedKey".getBytes();
- private IConnectivityManager mMockCs;
+ private IVpnManager mMockService;
private VpnManager mVpnManager;
private final MockContext mMockContext =
new MockContext() {
@@ -61,24 +61,26 @@
@Before
public void setUp() throws Exception {
- mMockCs = mock(IConnectivityManager.class);
- mVpnManager = new VpnManager(mMockContext, mMockCs);
+ mMockService = mock(IVpnManager.class);
+ mVpnManager = new VpnManager(mMockContext, mMockService);
}
@Test
public void testProvisionVpnProfilePreconsented() throws Exception {
final PlatformVpnProfile profile = getPlatformVpnProfile();
- when(mMockCs.provisionVpnProfile(any(VpnProfile.class), eq(PKG_NAME))).thenReturn(true);
+ when(mMockService.provisionVpnProfile(any(VpnProfile.class), eq(PKG_NAME)))
+ .thenReturn(true);
// Expect there to be no intent returned, as consent has already been granted.
assertNull(mVpnManager.provisionVpnProfile(profile));
- verify(mMockCs).provisionVpnProfile(eq(profile.toVpnProfile()), eq(PKG_NAME));
+ verify(mMockService).provisionVpnProfile(eq(profile.toVpnProfile()), eq(PKG_NAME));
}
@Test
public void testProvisionVpnProfileNeedsConsent() throws Exception {
final PlatformVpnProfile profile = getPlatformVpnProfile();
- when(mMockCs.provisionVpnProfile(any(VpnProfile.class), eq(PKG_NAME))).thenReturn(false);
+ when(mMockService.provisionVpnProfile(any(VpnProfile.class), eq(PKG_NAME)))
+ .thenReturn(false);
// Expect intent to be returned, as consent has not already been granted.
final Intent intent = mVpnManager.provisionVpnProfile(profile);
@@ -88,25 +90,25 @@
ComponentName.unflattenFromString(
"com.android.vpndialogs/com.android.vpndialogs.PlatformVpnConfirmDialog");
assertEquals(expectedComponentName, intent.getComponent());
- verify(mMockCs).provisionVpnProfile(eq(profile.toVpnProfile()), eq(PKG_NAME));
+ verify(mMockService).provisionVpnProfile(eq(profile.toVpnProfile()), eq(PKG_NAME));
}
@Test
public void testDeleteProvisionedVpnProfile() throws Exception {
mVpnManager.deleteProvisionedVpnProfile();
- verify(mMockCs).deleteVpnProfile(eq(PKG_NAME));
+ verify(mMockService).deleteVpnProfile(eq(PKG_NAME));
}
@Test
public void testStartProvisionedVpnProfile() throws Exception {
mVpnManager.startProvisionedVpnProfile();
- verify(mMockCs).startVpnProfile(eq(PKG_NAME));
+ verify(mMockService).startVpnProfile(eq(PKG_NAME));
}
@Test
public void testStopProvisionedVpnProfile() throws Exception {
mVpnManager.stopProvisionedVpnProfile();
- verify(mMockCs).stopVpnProfile(eq(PKG_NAME));
+ verify(mMockService).stopVpnProfile(eq(PKG_NAME));
}
private Ikev2VpnProfile getPlatformVpnProfile() throws Exception {
diff --git a/tests/net/java/android/net/VpnTransportInfoTest.java b/tests/net/java/android/net/VpnTransportInfoTest.java
index 2fd5e38..866f38c 100644
--- a/tests/net/java/android/net/VpnTransportInfoTest.java
+++ b/tests/net/java/android/net/VpnTransportInfoTest.java
@@ -17,7 +17,6 @@
package android.net;
import static com.android.testutils.ParcelUtils.assertParcelSane;
-import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -36,7 +35,6 @@
public void testParceling() {
VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM);
assertParcelSane(v, 1 /* fieldCount */);
- assertParcelingIsLossless(v);
}
@Test
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e639a36..ee04973 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -200,6 +200,7 @@
import android.net.RouteInfo;
import android.net.RouteInfoParcel;
import android.net.SocketKeepalive;
+import android.net.TransportInfo;
import android.net.UidRange;
import android.net.UidRangeParcel;
import android.net.UnderlyingNetworkInfo;
@@ -376,6 +377,7 @@
private MockContext mServiceContext;
private HandlerThread mCsHandlerThread;
+ private HandlerThread mVMSHandlerThread;
private ConnectivityService.Dependencies mDeps;
private ConnectivityService mService;
private WrappedConnectivityManager mCm;
@@ -390,6 +392,7 @@
private TestNetIdManager mNetIdManager;
private QosCallbackMockHelper mQosCallbackMockHelper;
private QosCallbackTracker mQosCallbackTracker;
+ private VpnManagerService mVpnManagerService;
// State variables required to emulate NetworkPolicyManagerService behaviour.
private int mUidRules = RULE_NONE;
@@ -1262,24 +1265,57 @@
r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new);
}
- private void mockVpn(int uid) {
- synchronized (mService.mVpns) {
- int userId = UserHandle.getUserId(uid);
- mMockVpn = new MockVpn(userId);
- // This has no effect unless the VPN is actually connected, because things like
- // getActiveNetworkForUidInternal call getNetworkAgentInfoForNetId on the VPN
- // netId, and check if that network is actually connected.
- mService.mVpns.put(userId, mMockVpn);
- }
+ private VpnManagerService makeVpnManagerService() {
+ final VpnManagerService.Dependencies deps = new VpnManagerService.Dependencies() {
+ public int getCallingUid() {
+ return mDeps.getCallingUid();
+ }
+
+ public HandlerThread makeHandlerThread() {
+ return mVMSHandlerThread;
+ }
+
+ public KeyStore getKeyStore() {
+ return mKeyStore;
+ }
+
+ public INetd getNetd() {
+ return mMockNetd;
+ }
+
+ public INetworkManagementService getINetworkManagementService() {
+ return mNetworkManagementService;
+ }
+ };
+ return new VpnManagerService(mServiceContext, deps);
+ }
+
+ private void assertVpnTransportInfo(NetworkCapabilities nc, int type) {
+ assertNotNull(nc);
+ final TransportInfo ti = nc.getTransportInfo();
+ assertTrue("VPN TransportInfo is not a VpnTransportInfo: " + ti,
+ ti instanceof VpnTransportInfo);
+ assertEquals(type, ((VpnTransportInfo) ti).type);
+
}
private void processBroadcastForVpn(Intent intent) {
// The BroadcastReceiver for this broadcast checks it is being run on the handler thread.
- final Handler handler = new Handler(mCsHandlerThread.getLooper());
+ final Handler handler = new Handler(mVMSHandlerThread.getLooper());
handler.post(() -> mServiceContext.sendBroadcast(intent));
+ HandlerUtils.waitForIdle(handler, TIMEOUT_MS);
waitForIdle();
}
+ private void mockVpn(int uid) {
+ synchronized (mVpnManagerService.mVpns) {
+ int userId = UserHandle.getUserId(uid);
+ mMockVpn = new MockVpn(userId);
+ // Every running user always has a Vpn in the mVpns array, even if no VPN is running.
+ mVpnManagerService.mVpns.put(userId, mMockVpn);
+ }
+ }
+
private void mockUidNetworkingBlocked() {
doAnswer(i -> mContext.getSystemService(NetworkPolicyManager.class)
.checkUidNetworkingBlocked(i.getArgument(0) /* uid */, mUidRules,
@@ -1403,6 +1439,7 @@
initAlarmManager(mAlarmManager, mAlarmManagerThread.getThreadHandler());
mCsHandlerThread = new HandlerThread("TestConnectivityService");
+ mVMSHandlerThread = new HandlerThread("TestVpnManagerService");
mDeps = makeDependencies();
returnRealCallingUid();
mService = new ConnectivityService(mServiceContext,
@@ -1425,6 +1462,8 @@
// getSystemService() correctly.
mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
mService.systemReadyInternal();
+ mVpnManagerService = makeVpnManagerService();
+ mVpnManagerService.systemReady();
mockVpn(Process.myUid());
mCm.bindProcessToNetwork(null);
mQosCallbackTracker = mock(QosCallbackTracker.class);
@@ -1452,7 +1491,6 @@
doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
doReturn(mBatteryStatsService).when(deps).getBatteryStatsService();
- doReturn(mKeyStore).when(deps).getKeyStore();
doAnswer(inv -> {
mPolicyTracker = new WrappedMultinetworkPolicyTracker(
inv.getArgument(0), inv.getArgument(1), inv.getArgument(2));
@@ -3873,6 +3911,24 @@
mCm.unregisterNetworkCallback(cellNetworkCallback);
}
+ @Test
+ public void testRegisterSystemDefaultCallbackRequiresNetworkSettings() throws Exception {
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.connect(false /* validated */);
+
+ final Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ assertThrows(SecurityException.class,
+ () -> mCm.registerSystemDefaultNetworkCallback(callback, handler));
+ callback.assertNoCallback();
+
+ mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS,
+ PERMISSION_GRANTED);
+ mCm.registerSystemDefaultNetworkCallback(callback, handler);
+ callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
+ mCm.unregisterNetworkCallback(callback);
+ }
+
private void setCaptivePortalMode(int mode) {
ContentResolver cr = mServiceContext.getContentResolver();
Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode);
@@ -6484,6 +6540,8 @@
assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED));
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED));
assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+
+ assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE);
}
private void assertDefaultNetworkCapabilities(int userId, NetworkAgentWrapper... networks) {
@@ -6523,6 +6581,7 @@
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED));
// A VPN without underlying networks is not suspended.
assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
+ assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE);
final int userId = UserHandle.getUserId(Process.myUid());
assertDefaultNetworkCapabilities(userId /* no networks */);
@@ -6686,6 +6745,7 @@
// By default, VPN is set to track default network (i.e. its underlying networks is null).
// In case of no default network, VPN is considered metered.
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED));
+ assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE);
// Connect to Cell; Cell is the default network.
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
@@ -6743,6 +6803,7 @@
NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
assertNotNull("nc=" + nc, nc.getUids());
assertEquals(nc.getUids(), uidRangesForUid(uid));
+ assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE);
// Set an underlying network and expect to see the VPN transports change.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -6825,8 +6886,8 @@
// Enable always-on VPN lockdown. The main user loses network access because no VPN is up.
final ArrayList<String> allowList = new ArrayList<>();
- mService.setAlwaysOnVpnPackage(PRIMARY_USER, ALWAYS_ON_PACKAGE, true /* lockdown */,
- allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, ALWAYS_ON_PACKAGE,
+ true /* lockdown */, allowList);
waitForIdle();
assertNull(mCm.getActiveNetworkForUid(uid));
// This is arguably overspecified: a UID that is not running doesn't have an active network.
@@ -6856,7 +6917,8 @@
assertNull(mCm.getActiveNetworkForUid(uid));
assertNotNull(mCm.getActiveNetworkForUid(restrictedUid));
- mService.setAlwaysOnVpnPackage(PRIMARY_USER, null, false /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(PRIMARY_USER, null, false /* lockdown */,
+ allowList);
waitForIdle();
}
@@ -7232,7 +7294,8 @@
final int uid = Process.myUid();
final int userId = UserHandle.getUserId(uid);
final ArrayList<String> allowList = new ArrayList<>();
- mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */,
+ allowList);
waitForIdle();
UidRangeParcel firstHalf = new UidRangeParcel(1, VPN_UID - 1);
@@ -7254,7 +7317,7 @@
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
// Disable lockdown, expect to see the network unblocked.
- mService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
callback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
vpnUidCallback.assertNoCallback();
@@ -7267,7 +7330,8 @@
// Add our UID to the allowlist and re-enable lockdown, expect network is not blocked.
allowList.add(TEST_PACKAGE_NAME);
- mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */,
+ allowList);
callback.assertNoCallback();
defaultCallback.assertNoCallback();
vpnUidCallback.assertNoCallback();
@@ -7300,11 +7364,12 @@
// Disable lockdown, remove our UID from the allowlist, and re-enable lockdown.
// Everything should now be blocked.
- mService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
waitForIdle();
expectNetworkRejectNonSecureVpn(inOrder, false, piece1, piece2, piece3);
allowList.clear();
- mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */,
+ allowList);
waitForIdle();
expectNetworkRejectNonSecureVpn(inOrder, true, firstHalf, secondHalf);
defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent);
@@ -7317,7 +7382,7 @@
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
// Disable lockdown. Everything is unblocked.
- mService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
assertBlockedCallbackInAnyOrder(callback, false, mWiFiNetworkAgent, mCellNetworkAgent);
vpnUidCallback.assertNoCallback();
@@ -7329,7 +7394,8 @@
// Enable and disable an always-on VPN package without lockdown. Expect no changes.
reset(mMockNetd);
- mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, false /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, false /* lockdown */,
+ allowList);
inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any());
callback.assertNoCallback();
defaultCallback.assertNoCallback();
@@ -7340,7 +7406,7 @@
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
- mService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, null, false /* lockdown */, allowList);
inOrder.verify(mMockNetd, never()).networkRejectNonSecureVpn(anyBoolean(), any());
callback.assertNoCallback();
defaultCallback.assertNoCallback();
@@ -7352,7 +7418,8 @@
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
// Enable lockdown and connect a VPN. The VPN is not blocked.
- mService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */, allowList);
+ mVpnManagerService.setAlwaysOnVpnPackage(userId, ALWAYS_ON_PACKAGE, true /* lockdown */,
+ allowList);
defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent);
assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent);
vpnUidCallback.assertNoCallback();
@@ -7398,11 +7465,14 @@
when(mKeyStore.get(Credentials.VPN + profileName)).thenReturn(encodedProfile);
}
- private void establishLegacyLockdownVpn() throws Exception {
+ private void establishLegacyLockdownVpn(Network underlying) throws Exception {
+ // The legacy lockdown VPN only supports userId 0, and must have an underlying network.
+ assertNotNull(underlying);
mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY);
// The legacy lockdown VPN only supports userId 0.
final Set<UidRange> ranges = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
mMockVpn.registerAgent(ranges);
+ mMockVpn.setUnderlyingNetworks(new Network[]{underlying});
mMockVpn.connect(true);
}
@@ -7410,6 +7480,9 @@
public void testLegacyLockdownVpn() throws Exception {
mServiceContext.setPermission(
Manifest.permission.CONTROL_VPN, PERMISSION_GRANTED);
+ // For LockdownVpnTracker to call registerSystemDefaultNetworkCallback.
+ mServiceContext.setPermission(
+ Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
final TestNetworkCallback callback = new TestNetworkCallback();
@@ -7418,6 +7491,10 @@
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(defaultCallback);
+ final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback();
+ mCm.registerSystemDefaultNetworkCallback(systemDefaultCallback,
+ new Handler(ConnectivityThread.getInstanceLooper()));
+
// Pretend lockdown VPN was configured.
setupLegacyLockdownVpn();
@@ -7447,6 +7524,7 @@
mCellNetworkAgent.connect(false /* validated */);
callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
+ systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
waitForIdle();
assertNull(mMockVpn.getAgent());
@@ -7458,6 +7536,8 @@
mCellNetworkAgent.sendLinkProperties(cellLp);
callback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
defaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ systemDefaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ mCellNetworkAgent);
waitForIdle();
assertNull(mMockVpn.getAgent());
@@ -7467,6 +7547,7 @@
mCellNetworkAgent.disconnect();
callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
b1.expectBroadcast();
// When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten
@@ -7476,6 +7557,7 @@
mCellNetworkAgent.connect(false /* validated */);
callback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
+ systemDefaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
b1.expectBroadcast();
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7498,9 +7580,10 @@
mMockVpn.expectStartLegacyVpnRunner();
b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
ExpectedBroadcast b2 = expectConnectivityAction(TYPE_MOBILE, DetailedState.CONNECTED);
- establishLegacyLockdownVpn();
+ establishLegacyLockdownVpn(mCellNetworkAgent.getNetwork());
callback.expectAvailableThenValidatedCallbacks(mMockVpn);
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
+ systemDefaultCallback.assertNoCallback();
NetworkCapabilities vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
b1.expectBroadcast();
b2.expectBroadcast();
@@ -7512,9 +7595,7 @@
assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR));
assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI));
assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED));
- VpnTransportInfo ti = (VpnTransportInfo) vpnNc.getTransportInfo();
- assertNotNull(ti);
- assertEquals(VpnManager.TYPE_VPN_LEGACY, ti.type);
+ assertVpnTransportInfo(vpnNc, VpnManager.TYPE_VPN_LEGACY);
// Switch default network from cell to wifi. Expect VPN to disconnect and reconnect.
final LinkProperties wifiLp = new LinkProperties();
@@ -7542,11 +7623,10 @@
// fact that a VPN is connected should only result in the VPN itself being unblocked, not
// any other network. Bug in isUidBlockedByVpn?
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCapabilitiesThat(mMockVpn, nc -> nc.hasTransport(TRANSPORT_WIFI));
callback.expectCallback(CallbackEntry.LOST, mMockVpn);
- defaultCallback.expectCapabilitiesThat(mMockVpn, nc -> nc.hasTransport(TRANSPORT_WIFI));
defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
+ systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
// While the VPN is reconnecting on the new network, everything is blocked.
assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
@@ -7557,9 +7637,10 @@
// The VPN comes up again on wifi.
b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
b2 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED);
- establishLegacyLockdownVpn();
+ establishLegacyLockdownVpn(mWiFiNetworkAgent.getNetwork());
callback.expectAvailableThenValidatedCallbacks(mMockVpn);
defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
+ systemDefaultCallback.assertNoCallback();
b1.expectBroadcast();
b2.expectBroadcast();
assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7573,14 +7654,10 @@
assertTrue(vpnNc.hasCapability(NET_CAPABILITY_NOT_METERED));
// Disconnect cell. Nothing much happens since it's not the default network.
- // Whenever LockdownVpnTracker is connected, it will send a connected broadcast any time any
- // NetworkInfo is updated. This is probably a bug.
- // TODO: consider fixing this.
- b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.CONNECTED);
mCellNetworkAgent.disconnect();
- b1.expectBroadcast();
callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
defaultCallback.assertNoCallback();
+ systemDefaultCallback.assertNoCallback();
assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
@@ -7590,6 +7667,7 @@
b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
mWiFiNetworkAgent.disconnect();
callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
b1.expectBroadcast();
callback.expectCapabilitiesThat(mMockVpn, nc -> !nc.hasTransport(TRANSPORT_WIFI));
b2 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED);