diff --git a/framework/Android.bp b/framework/Android.bp index 86433e1c38..017ff51f36 100644 --- a/framework/Android.bp +++ b/framework/Android.bp @@ -23,6 +23,25 @@ package { default_applicable_licenses: ["frameworks_base_license"], } +java_library { + name: "framework-connectivity-protos", + proto: { + type: "nano", + }, + srcs: [ + // TODO: consider moving relevant .proto files directly to the module directory + ":framework-javastream-protos", + ], + apex_available: [ + "//apex_available:platform", + "com.android.tethering", + ], + jarjar_rules: "jarjar-rules-proto.txt", + visibility: [ + "//visibility:private", + ], +} + filegroup { name: "framework-connectivity-internal-sources", srcs: [ @@ -111,6 +130,7 @@ java_library { "ServiceConnectivityResources", ], static_libs: [ + "framework-connectivity-protos", "net-utils-device-common", ], jarjar_rules: "jarjar-rules.txt", diff --git a/framework/jarjar-rules-proto.txt b/framework/jarjar-rules-proto.txt new file mode 100644 index 0000000000..37b4dec1c3 --- /dev/null +++ b/framework/jarjar-rules-proto.txt @@ -0,0 +1,3 @@ +keep android.net.NetworkCapabilitiesProto +keep android.net.NetworkProto +keep android.net.NetworkRequestProto diff --git a/framework/jarjar-rules.txt b/framework/jarjar-rules.txt index 381a4ac875..0959840f2d 100644 --- a/framework/jarjar-rules.txt +++ b/framework/jarjar-rules.txt @@ -5,3 +5,6 @@ zap android.annotation.** zap com.android.net.module.annotation.** zap com.android.internal.annotations.** +rule android.net.NetworkCapabilitiesProto* android.net.connectivity.proto.NetworkCapabilitiesProto@1 +rule android.net.NetworkProto* android.net.connectivity.proto.NetworkProto@1 +rule android.net.NetworkRequestProto* android.net.connectivity.proto.NetworkRequestProto@1 diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index e32622391c..a5e9f31a5b 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -62,7 +62,6 @@ import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; -import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.UserHandle; import android.provider.Settings; @@ -74,7 +73,6 @@ import android.util.Log; import android.util.Range; import android.util.SparseIntArray; -import com.android.connectivity.aidl.INetworkAgent; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; @@ -842,7 +840,6 @@ public class ConnectivityManager { private final Context mContext; - private INetworkPolicyManager mNPManager; private final TetheringManager mTetheringManager; /** @@ -4794,17 +4791,6 @@ public class ConnectivityManager { public @interface RestrictBackgroundStatus { } - private INetworkPolicyManager getNetworkPolicyManager() { - synchronized (this) { - if (mNPManager != null) { - return mNPManager; - } - mNPManager = INetworkPolicyManager.Stub.asInterface(ServiceManager - .getService(Context.NETWORK_POLICY_SERVICE)); - return mNPManager; - } - } - /** * Determines if the calling application is subject to metered network restrictions while * running on background. @@ -4815,7 +4801,7 @@ public class ConnectivityManager { */ public @RestrictBackgroundStatus int getRestrictBackgroundStatus() { try { - return getNetworkPolicyManager().getRestrictBackgroundByCaller(); + return mService.getRestrictBackgroundStatusByCaller(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/services/core/java/com/android/server/connectivity/ConnectivityResources.java b/framework/src/android/net/ConnectivityResources.java similarity index 69% rename from services/core/java/com/android/server/connectivity/ConnectivityResources.java rename to framework/src/android/net/ConnectivityResources.java index 45cf21e035..18f0de0cc9 100644 --- a/services/core/java/com/android/server/connectivity/ConnectivityResources.java +++ b/framework/src/android/net/ConnectivityResources.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity; +package android.net; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; @@ -27,13 +27,14 @@ import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.util.Log; -import com.android.server.ConnectivityService; +import com.android.internal.annotations.VisibleForTesting; import java.util.List; /** - * Utility to obtain the {@link ConnectivityService} {@link Resources}, in the + * Utility to obtain the {@link com.android.server.ConnectivityService} {@link Resources}, in the * ServiceConnectivityResources APK. + * @hide */ public class ConnectivityResources { private static final String RESOURCES_APK_INTENT = @@ -44,18 +45,35 @@ public class ConnectivityResources { private final Context mContext; @Nullable - private Resources mResources = null; + private Context mResourcesContext = null; + + @Nullable + private static Context sTestResourcesContext = null; public ConnectivityResources(Context context) { mContext = context; } /** - * Get the {@link Resources} of the ServiceConnectivityResources APK. + * Convenience method to mock all resources for the duration of a test. + * + * Call with a null context to reset after the test. */ - public synchronized Resources get() { - if (mResources != null) { - return mResources; + @VisibleForTesting + public static void setResourcesContextForTest(@Nullable Context testContext) { + sTestResourcesContext = testContext; + } + + /** + * Get the {@link Context} of the resources package. + */ + public synchronized Context getResourcesContext() { + if (sTestResourcesContext != null) { + return sTestResourcesContext; + } + + if (mResourcesContext != null) { + return mResourcesContext; } final List pkgs = mContext.getPackageManager() @@ -77,7 +95,14 @@ public class ConnectivityResources { throw new IllegalStateException("Resolved package not found", e); } - mResources = pkgContext.getResources(); - return mResources; + mResourcesContext = pkgContext; + return pkgContext; + } + + /** + * Get the {@link Resources} of the ServiceConnectivityResources APK. + */ + public Resources get() { + return getResourcesContext().getResources(); } } diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl index d83cc163b5..3300fa8fd1 100644 --- a/framework/src/android/net/IConnectivityManager.aidl +++ b/framework/src/android/net/IConnectivityManager.aidl @@ -20,6 +20,7 @@ import android.app.PendingIntent; import android.net.ConnectionInfo; import android.net.ConnectivityDiagnosticsManager; import android.net.IConnectivityDiagnosticsCallback; +import android.net.INetworkAgent; import android.net.IOnCompleteListener; import android.net.INetworkActivityListener; import android.net.IQosCallback; @@ -45,8 +46,6 @@ import android.os.PersistableBundle; import android.os.ResultReceiver; import android.os.UserHandle; -import com.android.connectivity.aidl.INetworkAgent; - /** * Interface that answers queries about, and allows changing, the * state of network connectivity. @@ -220,4 +219,6 @@ interface IConnectivityManager void setProfileNetworkPreference(in UserHandle profile, int preference, in IOnCompleteListener listener); + + int getRestrictBackgroundStatusByCaller(); } diff --git a/framework/src/com/android/connectivity/aidl/INetworkAgent.aidl b/framework/src/android/net/INetworkAgent.aidl similarity index 95% rename from framework/src/com/android/connectivity/aidl/INetworkAgent.aidl rename to framework/src/android/net/INetworkAgent.aidl index 64b556720c..1f66e18717 100644 --- a/framework/src/com/android/connectivity/aidl/INetworkAgent.aidl +++ b/framework/src/android/net/INetworkAgent.aidl @@ -13,13 +13,13 @@ * See the License for the specific language governing perNmissions and * limitations under the License. */ -package com.android.connectivity.aidl; +package android.net; import android.net.NattKeepalivePacketData; import android.net.QosFilterParcelable; import android.net.TcpKeepalivePacketData; -import com.android.connectivity.aidl.INetworkAgentRegistry; +import android.net.INetworkAgentRegistry; /** * Interface to notify NetworkAgent of connectivity events. diff --git a/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl b/framework/src/android/net/INetworkAgentRegistry.aidl similarity index 97% rename from framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl rename to framework/src/android/net/INetworkAgentRegistry.aidl index 18d26a7e4b..c5464d3241 100644 --- a/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl +++ b/framework/src/android/net/INetworkAgentRegistry.aidl @@ -13,7 +13,7 @@ * See the License for the specific language governing perNmissions and * limitations under the License. */ -package com.android.connectivity.aidl; +package android.net; import android.net.LinkProperties; import android.net.Network; diff --git a/framework/src/android/net/NetworkAgent.java b/framework/src/android/net/NetworkAgent.java index a127c6f6de..1416bb9775 100644 --- a/framework/src/android/net/NetworkAgent.java +++ b/framework/src/android/net/NetworkAgent.java @@ -34,8 +34,6 @@ import android.os.RemoteException; import android.telephony.data.EpsBearerQosSessionAttributes; import android.util.Log; -import com.android.connectivity.aidl.INetworkAgent; -import com.android.connectivity.aidl.INetworkAgentRegistry; import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; diff --git a/framework/src/android/net/apf/ApfCapabilities.java b/framework/src/android/net/apf/ApfCapabilities.java index bf5b26e278..85b24713f2 100644 --- a/framework/src/android/net/apf/ApfCapabilities.java +++ b/framework/src/android/net/apf/ApfCapabilities.java @@ -19,12 +19,12 @@ package android.net.apf; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.content.Context; import android.content.res.Resources; +import android.net.ConnectivityResources; import android.os.Parcel; import android.os.Parcelable; -import com.android.internal.R; - /** * APF program support capabilities. APF stands for Android Packet Filtering and it is a flexible * way to drop unwanted network packets to save power. @@ -36,6 +36,8 @@ import com.android.internal.R; */ @SystemApi public final class ApfCapabilities implements Parcelable { + private static ConnectivityResources sResources; + /** * Version of APF instruction set supported for packet filtering. 0 indicates no support for * packet filtering using APF programs. @@ -65,6 +67,14 @@ public final class ApfCapabilities implements Parcelable { apfPacketFormat = in.readInt(); } + @NonNull + private static synchronized ConnectivityResources getResources(@NonNull Context ctx) { + if (sResources == null) { + sResources = new ConnectivityResources(ctx); + } + return sResources; + } + @Override public int describeContents() { @@ -121,13 +131,43 @@ public final class ApfCapabilities implements Parcelable { * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames. */ public static boolean getApfDrop8023Frames() { - return Resources.getSystem().getBoolean(R.bool.config_apfDrop802_3Frames); + // TODO(b/183076074): remove reading resources from system resources + final Resources systemRes = Resources.getSystem(); + final int id = systemRes.getIdentifier("config_apfDrop802_3Frames", "bool", "android"); + return systemRes.getBoolean(id); + } + + /** + * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames. + * @hide + */ + public static boolean getApfDrop8023Frames(@NonNull Context context) { + final ConnectivityResources res = getResources(context); + // TODO(b/183076074): use R.bool.config_apfDrop802_3Frames directly + final int id = res.get().getIdentifier("config_apfDrop802_3Frames", "bool", + res.getResourcesContext().getPackageName()); + return res.get().getBoolean(id); } /** * @return An array of denylisted EtherType, packets with EtherTypes within it will be dropped. */ public static @NonNull int[] getApfEtherTypeBlackList() { - return Resources.getSystem().getIntArray(R.array.config_apfEthTypeBlackList); + // TODO(b/183076074): remove reading resources from system resources + final Resources systemRes = Resources.getSystem(); + final int id = systemRes.getIdentifier("config_apfEthTypeBlackList", "array", "android"); + return systemRes.getIntArray(id); + } + + /** + * @return An array of denylisted EtherType, packets with EtherTypes within it will be dropped. + * @hide + */ + public static @NonNull int[] getApfEtherTypeDenyList(@NonNull Context context) { + final ConnectivityResources res = getResources(context); + // TODO(b/183076074): use R.array.config_apfEthTypeDenyList directly + final int id = res.get().getIdentifier("config_apfEthTypeDenyList", "array", + res.getResourcesContext().getPackageName()); + return res.get().getIntArray(id); } } diff --git a/framework/src/android/net/util/KeepaliveUtils.java b/framework/src/android/net/util/KeepaliveUtils.java index bfc4563fbf..8d7a0b3d02 100644 --- a/framework/src/android/net/util/KeepaliveUtils.java +++ b/framework/src/android/net/util/KeepaliveUtils.java @@ -19,12 +19,11 @@ package android.net.util; import android.annotation.NonNull; import android.content.Context; import android.content.res.Resources; +import android.net.ConnectivityResources; import android.net.NetworkCapabilities; import android.text.TextUtils; import android.util.AndroidRuntimeException; -import com.android.internal.R; - /** * Collection of utilities for socket keepalive offload. * @@ -52,8 +51,11 @@ public final class KeepaliveUtils { public static int[] getSupportedKeepalives(@NonNull Context context) { String[] res = null; try { - res = context.getResources().getStringArray( - R.array.config_networkSupportedKeepaliveCount); + final ConnectivityResources connRes = new ConnectivityResources(context); + // TODO: use R.id.config_networkSupportedKeepaliveCount directly + final int id = connRes.get().getIdentifier("config_networkSupportedKeepaliveCount", + "array", connRes.getResourcesContext().getPackageName()); + res = new ConnectivityResources(context).get().getStringArray(id); } catch (Resources.NotFoundException unused) { } if (res == null) throw new KeepaliveDeviceConfigurationException("invalid resource"); diff --git a/framework/src/android/net/util/MultinetworkPolicyTracker.java b/framework/src/android/net/util/MultinetworkPolicyTracker.java index 6a49aa2576..0b42a00369 100644 --- a/framework/src/android/net/util/MultinetworkPolicyTracker.java +++ b/framework/src/android/net/util/MultinetworkPolicyTracker.java @@ -27,6 +27,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.database.ContentObserver; +import android.net.ConnectivityResources; import android.net.Uri; import android.os.Handler; import android.provider.Settings; @@ -35,7 +36,6 @@ import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.util.Log; -import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; @@ -64,6 +64,7 @@ public class MultinetworkPolicyTracker { private static String TAG = MultinetworkPolicyTracker.class.getSimpleName(); private final Context mContext; + private final ConnectivityResources mResources; private final Handler mHandler; private final Runnable mAvoidBadWifiCallback; private final List mSettingsUris; @@ -107,6 +108,7 @@ public class MultinetworkPolicyTracker { public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) { mContext = ctx; + mResources = new ConnectivityResources(ctx); mHandler = handler; mAvoidBadWifiCallback = avoidBadWifiCallback; mSettingsUris = Arrays.asList( @@ -160,12 +162,16 @@ public class MultinetworkPolicyTracker { * Whether the device or carrier configuration disables avoiding bad wifi by default. */ public boolean configRestrictsAvoidBadWifi() { - return (getResourcesForActiveSubId().getInteger(R.integer.config_networkAvoidBadWifi) == 0); + // TODO: use R.integer.config_networkAvoidBadWifi directly + final int id = mResources.get().getIdentifier("config_networkAvoidBadWifi", + "integer", mResources.getResourcesContext().getPackageName()); + return (getResourcesForActiveSubId().getInteger(id) == 0); } @NonNull private Resources getResourcesForActiveSubId() { - return SubscriptionManager.getResourcesForSubId(mContext, mActiveSubId); + return SubscriptionManager.getResourcesForSubId( + mResources.getResourcesContext(), mActiveSubId); } /** @@ -205,8 +211,10 @@ public class MultinetworkPolicyTracker { * The default (device and carrier-dependent) value for metered multipath preference. */ public int configMeteredMultipathPreference() { - return mContext.getResources().getInteger( - R.integer.config_networkMeteredMultipathPreference); + // TODO: use R.integer.config_networkMeteredMultipathPreference directly + final int id = mResources.get().getIdentifier("config_networkMeteredMultipathPreference", + "integer", mResources.getResourcesContext().getPackageName()); + return mResources.get().getInteger(id); } public void updateMeteredMultipathPreference() { diff --git a/service/ServiceConnectivityResources/Android.bp b/service/ServiceConnectivityResources/Android.bp index f2446b7f7e..fa4501ac7f 100644 --- a/service/ServiceConnectivityResources/Android.bp +++ b/service/ServiceConnectivityResources/Android.bp @@ -21,7 +21,7 @@ package { android_app { name: "ServiceConnectivityResources", - sdk_version: "system_current", + sdk_version: "module_current", resource_dirs: [ "res", ], diff --git a/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml b/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml new file mode 100644 index 0000000000..7e7025fb04 --- /dev/null +++ b/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml @@ -0,0 +1,27 @@ + + + + + + + 0 + \ No newline at end of file diff --git a/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml b/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml new file mode 100644 index 0000000000..7e7025fb04 --- /dev/null +++ b/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml @@ -0,0 +1,27 @@ + + + + + + + 0 + \ No newline at end of file diff --git a/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml b/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml new file mode 100644 index 0000000000..7e7025fb04 --- /dev/null +++ b/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml @@ -0,0 +1,27 @@ + + + + + + + 0 + \ No newline at end of file diff --git a/service/ServiceConnectivityResources/res/values/config.xml b/service/ServiceConnectivityResources/res/values/config.xml index 06c81921fd..71674e4dc6 100644 --- a/service/ServiceConnectivityResources/res/values/config.xml +++ b/service/ServiceConnectivityResources/res/values/config.xml @@ -52,4 +52,41 @@ 12,60000 - \ No newline at end of file + + true + + + + 0x88A2 + 0x88A4 + 0x88B8 + 0x88CD + 0x88E3 + + + + + + 0,1 + 1,3 + + + + + 0 + + + 1 + + diff --git a/service/ServiceConnectivityResources/res/values/overlayable.xml b/service/ServiceConnectivityResources/res/values/overlayable.xml index da8aee5627..25e19cedbb 100644 --- a/service/ServiceConnectivityResources/res/values/overlayable.xml +++ b/service/ServiceConnectivityResources/res/values/overlayable.xml @@ -21,6 +21,11 @@ + + + + + diff --git a/service/ServiceConnectivityResources/res/values/strings.xml b/service/ServiceConnectivityResources/res/values/strings.xml index 7a9cf57afc..b2fa5f5b41 100644 --- a/service/ServiceConnectivityResources/res/values/strings.xml +++ b/service/ServiceConnectivityResources/res/values/strings.xml @@ -68,8 +68,6 @@ VPN - - an unknown network type diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f527da5829..d254d7eccc 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -106,6 +106,8 @@ import android.net.ConnectivityDiagnosticsManager.ConnectivityReport; import android.net.ConnectivityDiagnosticsManager.DataStallReport; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; +import android.net.ConnectivityManager.RestrictBackgroundStatus; +import android.net.ConnectivityResources; import android.net.ConnectivitySettingsManager; import android.net.DataStallReportParcelable; import android.net.DnsResolverServiceManager; @@ -115,6 +117,7 @@ import android.net.IConnectivityManager; import android.net.IDnsResolver; import android.net.INetd; import android.net.INetworkActivityListener; +import android.net.INetworkAgent; import android.net.INetworkMonitor; import android.net.INetworkMonitorCallbacks; import android.net.IOnCompleteListener; @@ -208,7 +211,6 @@ import android.util.Pair; import android.util.SparseArray; import android.util.SparseIntArray; -import com.android.connectivity.aidl.INetworkAgent; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; @@ -222,7 +224,6 @@ import com.android.net.module.util.LocationPermissionChecker; import com.android.net.module.util.NetworkCapabilitiesUtils; import com.android.net.module.util.PermissionUtils; import com.android.server.connectivity.AutodestructReference; -import com.android.server.connectivity.ConnectivityResources; import com.android.server.connectivity.DnsManager; import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; import com.android.server.connectivity.KeepaliveTracker; @@ -237,7 +238,6 @@ import com.android.server.connectivity.PermissionMonitor; import com.android.server.connectivity.ProfileNetworkPreferences; import com.android.server.connectivity.ProxyTracker; import com.android.server.connectivity.QosCallbackTracker; -import com.android.server.net.NetworkPolicyManagerInternal; import libcore.io.IoUtils; @@ -350,7 +350,6 @@ public class ConnectivityService extends IConnectivityManager.Stub protected INetd mNetd; private NetworkStatsManager mStatsManager; private NetworkPolicyManager mPolicyManager; - private NetworkPolicyManagerInternal mPolicyManagerInternal; private final NetdCallback mNetdCallback; /** @@ -1237,9 +1236,6 @@ public class ConnectivityService extends IConnectivityManager.Stub mStatsManager = mContext.getSystemService(NetworkStatsManager.class); mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); - mPolicyManagerInternal = Objects.requireNonNull( - LocalServices.getService(NetworkPolicyManagerInternal.class), - "missing NetworkPolicyManagerInternal"); mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver"); mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); @@ -1997,6 +1993,18 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + @Override + public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() { + enforceAccessPermission(); + final int callerUid = Binder.getCallingUid(); + final long token = Binder.clearCallingIdentity(); + try { + return mPolicyManager.getRestrictBackgroundStatus(callerUid); + } finally { + Binder.restoreCallingIdentity(token); + } + } + // TODO: Consider delete this function or turn it into a no-op method. @Override public NetworkState[] getAllNetworkState() { @@ -4407,7 +4415,13 @@ public class ConnectivityService extends IConnectivityManager.Stub final NetworkPolicyManager netPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); - final int networkPreference = netPolicyManager.getMultipathPreference(network); + final long token = Binder.clearCallingIdentity(); + final int networkPreference; + try { + networkPreference = netPolicyManager.getMultipathPreference(network); + } finally { + Binder.restoreCallingIdentity(token); + } if (networkPreference != 0) { return networkPreference; } diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index fde4f5d87e..103ab957f3 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -25,6 +25,8 @@ import android.content.Context; import android.net.CaptivePortalData; import android.net.IDnsResolver; import android.net.INetd; +import android.net.INetworkAgent; +import android.net.INetworkAgentRegistry; import android.net.INetworkMonitor; import android.net.LinkProperties; import android.net.NattKeepalivePacketData; @@ -51,8 +53,6 @@ import android.util.Log; import android.util.Pair; import android.util.SparseArray; -import com.android.connectivity.aidl.INetworkAgent; -import com.android.connectivity.aidl.INetworkAgentRegistry; import com.android.internal.util.WakeupMessage; import com.android.server.ConnectivityService; diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java index 181a10d2a6..0c0d45995a 100644 --- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java +++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java @@ -28,6 +28,8 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.graphics.drawable.Icon; +import android.net.ConnectivityResources; import android.net.NetworkSpecifier; import android.net.TelephonyNetworkSpecifier; import android.net.wifi.WifiInfo; @@ -40,7 +42,7 @@ import android.util.SparseArray; import android.util.SparseIntArray; import android.widget.Toast; -import com.android.internal.R; +import com.android.connectivity.resources.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; @@ -82,6 +84,7 @@ public class NetworkNotificationManager { // The context is for the current user (system server) private final Context mContext; + private final Resources mResources; private final TelephonyManager mTelephonyManager; // The notification manager is created from a context for User.ALL, so notifications // will be sent to all users. @@ -96,6 +99,7 @@ public class NetworkNotificationManager { (NotificationManager) c.createContextAsUser(UserHandle.ALL, 0 /* flags */) .getSystemService(Context.NOTIFICATION_SERVICE); mNotificationTypeMap = new SparseIntArray(); + mResources = new ConnectivityResources(mContext).get(); } @VisibleForTesting @@ -113,20 +117,19 @@ public class NetworkNotificationManager { return -1; } - private static String getTransportName(final int transportType) { - Resources r = Resources.getSystem(); - String[] networkTypes = r.getStringArray(R.array.network_switch_type_name); + private String getTransportName(final int transportType) { + String[] networkTypes = mResources.getStringArray(R.array.network_switch_type_name); try { return networkTypes[transportType]; } catch (IndexOutOfBoundsException e) { - return r.getString(R.string.network_switch_type_name_unknown); + return mResources.getString(R.string.network_switch_type_name_unknown); } } private static int getIcon(int transportType) { return (transportType == TRANSPORT_WIFI) - ? R.drawable.stat_notify_wifi_in_range : // TODO: Distinguish ! from ?. - R.drawable.stat_notify_rssi_in_range; + ? R.drawable.stat_notify_wifi_in_range // TODO: Distinguish ! from ?. + : R.drawable.stat_notify_rssi_in_range; } /** @@ -194,10 +197,10 @@ public class NetworkNotificationManager { tag, nameOf(eventId), getTransportName(transportType), name, highPriority)); } - Resources r = mContext.getResources(); + final Resources r = mResources; final CharSequence title; final CharSequence details; - int icon = getIcon(transportType); + Icon icon = Icon.createWithResource(r, getIcon(transportType)); if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) { title = r.getString(R.string.wifi_no_internet, name); details = r.getString(R.string.wifi_no_internet_detailed); @@ -272,8 +275,7 @@ public class NetworkNotificationManager { .setSmallIcon(icon) .setAutoCancel(true) .setTicker(title) - .setColor(mContext.getColor( - com.android.internal.R.color.system_notification_accent_color)) + .setColor(mContext.getColor(android.R.color.system_notification_accent_color)) .setContentTitle(title) .setContentIntent(intent) .setLocalOnly(true) @@ -353,7 +355,7 @@ public class NetworkNotificationManager { public void showToast(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) { String fromTransport = getTransportName(approximateTransportType(fromNai)); String toTransport = getTransportName(approximateTransportType(toNai)); - String text = mContext.getResources().getString( + String text = mResources.getString( R.string.network_switch_metered_toast, fromTransport, toTransport); Toast.makeText(mContext, text, Toast.LENGTH_LONG).show(); } diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt index 2a2dc5628e..db49e0b004 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt +++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt @@ -44,12 +44,10 @@ import android.util.Log import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.android.server.ConnectivityService -import com.android.server.LocalServices import com.android.server.NetworkAgentWrapper import com.android.server.TestNetIdManager import com.android.server.connectivity.MockableSystemProperties import com.android.server.connectivity.ProxyTracker -import com.android.server.net.NetworkPolicyManagerInternal import com.android.testutils.TestableNetworkCallback import org.junit.After import org.junit.Before @@ -162,10 +160,6 @@ class ConnectivityServiceIntegrationTest { networkStackClient.init() networkStackClient.start() - LocalServices.removeServiceForTest(NetworkPolicyManagerInternal::class.java) - LocalServices.addService(NetworkPolicyManagerInternal::class.java, - mock(NetworkPolicyManagerInternal::class.java)) - service = TestConnectivityService(makeDependencies()) cm = ConnectivityManager(context, service) context.addMockSystemService(Context.CONNECTIVITY_SERVICE, cm) diff --git a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt index 8ea226db93..b62bdbcfb5 100644 --- a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt +++ b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt @@ -18,6 +18,7 @@ package android.net.util import android.content.Context import android.content.res.Resources +import android.net.ConnectivityResources import android.net.NetworkCapabilities import android.net.NetworkCapabilities.MAX_TRANSPORT import android.net.NetworkCapabilities.TRANSPORT_CELLULAR @@ -26,13 +27,15 @@ import android.net.NetworkCapabilities.TRANSPORT_VPN import android.net.NetworkCapabilities.TRANSPORT_WIFI import androidx.test.filters.SmallTest import com.android.internal.R +import org.junit.After import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.fail import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 -import org.mockito.ArgumentMatchers +import org.mockito.ArgumentMatchers.eq +import org.mockito.Mockito.any import org.mockito.Mockito.doReturn import org.mockito.Mockito.mock @@ -47,21 +50,33 @@ import org.mockito.Mockito.mock class KeepaliveUtilsTest { // Prepare mocked context with given resource strings. - private fun getMockedContextWithStringArrayRes(id: Int, res: Array?): Context { + private fun getMockedContextWithStringArrayRes( + id: Int, + name: String, + res: Array? + ): Context { val mockRes = mock(Resources::class.java) - doReturn(res).`when`(mockRes).getStringArray(ArgumentMatchers.eq(id)) + doReturn(res).`when`(mockRes).getStringArray(eq(id)) + doReturn(id).`when`(mockRes).getIdentifier(eq(name), any(), any()) return mock(Context::class.java).apply { doReturn(mockRes).`when`(this).getResources() + ConnectivityResources.setResourcesContextForTest(this) } } + @After + fun tearDown() { + ConnectivityResources.setResourcesContextForTest(null) + } + @Test fun testGetSupportedKeepalives() { fun assertRunWithException(res: Array?) { try { val mockContext = getMockedContextWithStringArrayRes( - R.array.config_networkSupportedKeepaliveCount, res) + R.array.config_networkSupportedKeepaliveCount, + "config_networkSupportedKeepaliveCount", res) KeepaliveUtils.getSupportedKeepalives(mockContext) fail("Expected KeepaliveDeviceConfigurationException") } catch (expected: KeepaliveUtils.KeepaliveDeviceConfigurationException) { @@ -89,7 +104,8 @@ class KeepaliveUtilsTest { val expectedValidRes = intArrayOf(3, 0, 0, 0, 4, 0, 0, 0) val mockContext = getMockedContextWithStringArrayRes( - R.array.config_networkSupportedKeepaliveCount, validRes) + R.array.config_networkSupportedKeepaliveCount, + "config_networkSupportedKeepaliveCount", validRes) val actual = KeepaliveUtils.getSupportedKeepalives(mockContext) assertArrayEquals(expectedValidRes, actual) } diff --git a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt index 1945ce7ba9..25aa626657 100644 --- a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt +++ b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt @@ -21,6 +21,7 @@ import android.content.res.Resources import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY +import android.net.ConnectivityResources import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI import android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener @@ -31,8 +32,9 @@ import android.telephony.TelephonyManager import android.test.mock.MockContentResolver import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 -import com.android.internal.R +import com.android.connectivity.resources.R import com.android.internal.util.test.FakeSettingsProvider +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue @@ -41,6 +43,7 @@ import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.argThat +import org.mockito.ArgumentMatchers.eq import org.mockito.Mockito.any import org.mockito.Mockito.doReturn import org.mockito.Mockito.mock @@ -57,6 +60,8 @@ import org.mockito.Mockito.verify @SmallTest class MultinetworkPolicyTrackerTest { private val resources = mock(Resources::class.java).also { + doReturn(R.integer.config_networkAvoidBadWifi).`when`(it).getIdentifier( + eq("config_networkAvoidBadWifi"), eq("integer"), any()) doReturn(0).`when`(it).getInteger(R.integer.config_networkAvoidBadWifi) } private val telephonyManager = mock(TelephonyManager::class.java) @@ -75,6 +80,7 @@ class MultinetworkPolicyTrackerTest { doReturn(resources).`when`(it).resources doReturn(it).`when`(it).createConfigurationContext(any()) Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1") + ConnectivityResources.setResourcesContextForTest(it) } private val tracker = MultinetworkPolicyTracker(context, null /* handler */) @@ -85,6 +91,11 @@ class MultinetworkPolicyTrackerTest { assertEquals(preference, tracker.meteredMultipathPreference) } + @After + fun tearDown() { + ConnectivityResources.setResourcesContextForTest(null) + } + @Test fun testUpdateMeteredMultipathPreference() { assertMultipathPreference(MULTIPATH_PREFERENCE_HANDOVER) diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index c4f3fea770..f489c9866e 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -179,6 +179,7 @@ import android.net.ConnectivityManager.NetworkCallback; import android.net.ConnectivityManager.PacketKeepalive; import android.net.ConnectivityManager.PacketKeepaliveCallback; import android.net.ConnectivityManager.TooManyRequestsException; +import android.net.ConnectivityResources; import android.net.ConnectivitySettingsManager; import android.net.ConnectivityThread; import android.net.DataStallReportParcelable; @@ -273,6 +274,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.connectivity.resources.R; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; import com.android.internal.util.ArrayUtils; @@ -282,7 +284,6 @@ import com.android.internal.util.test.FakeSettingsProvider; import com.android.net.module.util.ArrayTrackRecord; import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo; import com.android.server.connectivity.ConnectivityConstants; -import com.android.server.connectivity.ConnectivityResources; import com.android.server.connectivity.MockableSystemProperties; import com.android.server.connectivity.Nat464Xlat; import com.android.server.connectivity.NetworkAgentInfo; @@ -292,7 +293,6 @@ import com.android.server.connectivity.QosCallbackTracker; import com.android.server.connectivity.Vpn; import com.android.server.connectivity.VpnProfileStore; import com.android.server.net.NetworkPinner; -import com.android.server.net.NetworkPolicyManagerInternal; import com.android.testutils.ExceptionUtils; import com.android.testutils.HandlerUtils; import com.android.testutils.RecorderCallback.CallbackEntry; @@ -1501,9 +1501,6 @@ public class ConnectivityServiceTest { mServiceContext = new MockContext(InstrumentationRegistry.getContext(), new FakeSettingsProvider()); mServiceContext.setUseRegisteredHandlers(true); - LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); - LocalServices.addService( - NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class)); mAlarmManagerThread = new HandlerThread("TestAlarmManager"); mAlarmManagerThread.start(); @@ -1570,11 +1567,27 @@ public class ConnectivityServiceTest { com.android.connectivity.resources.R.string.config_networkCaptivePortalServerUrl); doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray( com.android.connectivity.resources.R.array.config_wakeonlan_supported_interfaces); - final com.android.server.connectivity.ConnectivityResources connRes = mock( - ConnectivityResources.class); + doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray( + com.android.connectivity.resources.R.array.config_networkSupportedKeepaliveCount); + doReturn(com.android.connectivity.resources.R.array.config_networkSupportedKeepaliveCount) + .when(mResources).getIdentifier(eq("config_networkSupportedKeepaliveCount"), + eq("array"), any()); + doReturn(com.android.connectivity.resources.R.array.network_switch_type_name) + .when(mResources).getIdentifier(eq("network_switch_type_name"), + eq("array"), any()); + + // We don't test the actual notification value strings, so just return an empty array. + // It doesn't matter what the values are as long as it's not null. + doReturn(new String[0]).when(mResources).getStringArray(R.array.network_switch_type_name); + + final ConnectivityResources connRes = mock(ConnectivityResources.class); doReturn(mResources).when(connRes).get(); doReturn(connRes).when(deps).getResources(any()); + final Context mockResContext = mock(Context.class); + doReturn(mResources).when(mockResContext).getResources(); + ConnectivityResources.setResourcesContextForTest(mockResContext); + return deps; } @@ -1630,6 +1643,7 @@ public class ConnectivityServiceTest { waitForIdle(); FakeSettingsProvider.clearSettingsProvider(); + ConnectivityResources.setResourcesContextForTest(null); mCsHandlerThread.quitSafely(); mAlarmManagerThread.quitSafely(); diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java index ff8c632833..3adf08c199 100644 --- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java @@ -20,6 +20,7 @@ import static com.android.server.connectivity.NetworkNotificationManager.Notific import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; @@ -35,6 +36,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.net.ConnectivityResources; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.os.UserHandle; @@ -43,9 +45,10 @@ import android.telephony.TelephonyManager; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.R; +import com.android.connectivity.resources.R; import com.android.server.connectivity.NetworkNotificationManager.NotificationType; +import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -119,11 +122,25 @@ public class NetworkNotificationManagerTest { when(mCtx.getSystemService(eq(Context.NOTIFICATION_SERVICE))) .thenReturn(mNotificationManager); when(mNetworkInfo.getExtraInfo()).thenReturn(TEST_EXTRA_INFO); + ConnectivityResources.setResourcesContextForTest(mCtx); when(mResources.getColor(anyInt(), any())).thenReturn(0xFF607D8B); + // Come up with some credible-looking transport names. The actual values do not matter. + String[] transportNames = new String[NetworkCapabilities.MAX_TRANSPORT + 1]; + for (int transport = 0; transport <= NetworkCapabilities.MAX_TRANSPORT; transport++) { + transportNames[transport] = NetworkCapabilities.transportNameOf(transport); + } + when(mResources.getStringArray(R.array.network_switch_type_name)) + .thenReturn(transportNames); + mManager = new NetworkNotificationManager(mCtx, mTelephonyManager); } + @After + public void tearDown() { + ConnectivityResources.setResourcesContextForTest(null); + } + private void verifyTitleByNetwork(final int id, final NetworkAgentInfo nai, final int title) { final String tag = NetworkNotificationManager.tagFor(id); mManager.showNotification(id, PRIVATE_DNS_BROKEN, nai, null, null, true); @@ -142,15 +159,15 @@ public class NetworkNotificationManagerTest { public void testTitleOfPrivateDnsBroken() { // Test the title of mobile data. verifyTitleByNetwork(100, mCellNai, R.string.mobile_no_internet); - reset(mResources); + clearInvocations(mResources); // Test the title of wifi. verifyTitleByNetwork(101, mWifiNai, R.string.wifi_no_internet); - reset(mResources); + clearInvocations(mResources); // Test the title of other networks. verifyTitleByNetwork(102, mVpnNai, R.string.other_networks_no_internet); - reset(mResources); + clearInvocations(mResources); } @Test