diff options
42 files changed, 759 insertions, 547 deletions
diff --git a/Android.bp b/Android.bp index 84f3fad7306b..b63b48c3004b 100644 --- a/Android.bp +++ b/Android.bp @@ -520,7 +520,6 @@ java_library { ], installable: false, plugins: [ - "unsupportedappusage-annotation-processor", "compat-changeid-annotation-processor", ], } diff --git a/api/current.txt b/api/current.txt index 4fdd5297e541..21e003436433 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9775,7 +9775,6 @@ package android.content { method public abstract void sendOrderedBroadcast(@RequiresPermission android.content.Intent, @Nullable String); method public abstract void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method public void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); - method public void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendOrderedBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method @Deprecated @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY) public abstract void sendStickyBroadcast(@RequiresPermission android.content.Intent); method @Deprecated @RequiresPermission(allOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.BROADCAST_STICKY}) public abstract void sendStickyBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle); @@ -9980,6 +9979,7 @@ package android.content { method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle, String); method public void sendOrderedBroadcast(android.content.Intent, String); method public void sendOrderedBroadcast(android.content.Intent, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle); + method public void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, int, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, @Nullable String, @Nullable android.os.Bundle, @Nullable android.os.Bundle); method public void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, String, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle); method @Deprecated public void sendStickyBroadcast(android.content.Intent); method @Deprecated public void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle); @@ -29201,6 +29201,7 @@ package android.net { } @Deprecated public class NetworkInfo implements android.os.Parcelable { + ctor @Deprecated public NetworkInfo(int, int, @Nullable String, @Nullable String); method @Deprecated public int describeContents(); method @Deprecated @NonNull public android.net.NetworkInfo.DetailedState getDetailedState(); method @Deprecated public String getExtraInfo(); @@ -29215,6 +29216,7 @@ package android.net { method @Deprecated public boolean isConnectedOrConnecting(); method @Deprecated public boolean isFailover(); method @Deprecated public boolean isRoaming(); + method @Deprecated public void setDetailedState(@NonNull android.net.NetworkInfo.DetailedState, @Nullable String, @Nullable String); method @Deprecated public void writeToParcel(android.os.Parcel, int); field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR; } @@ -45919,6 +45921,7 @@ package android.telephony { method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String); method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String); method public boolean isConcurrentVoiceAndDataSupported(); + method public boolean isDataCapable(); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled(); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled(); method public boolean isEmergencyNumber(@NonNull String); diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 1b72fc3db058..85c378006fa0 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -47,6 +47,7 @@ package android.net { method @NonNull public String[] getTetheredIfaces(); method @NonNull public String[] getTetheringErroredIfaces(); method public boolean isTetheringSupported(); + method public boolean isTetheringSupported(@NonNull String); method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback); method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener); method public void requestLatestTetheringEntitlementResult(int, @NonNull android.os.ResultReceiver, boolean); diff --git a/api/system-current.txt b/api/system-current.txt index d19e1ec4ba77..990ae45b14e4 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4611,6 +4611,7 @@ package android.net { public abstract class NetworkAgent { ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider); + method @Nullable public android.net.Network getNetwork(); method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData); method public void onAutomaticReconnectDisabled(); method public void onBandwidthUpdateRequested(); @@ -4621,6 +4622,7 @@ package android.net { method public void onStartSocketKeepalive(int, int, @NonNull android.net.KeepalivePacketData); method public void onStopSocketKeepalive(int); method public void onValidationStatus(int, @Nullable String); + method @NonNull public android.net.Network register(); method public void sendLinkProperties(@NonNull android.net.LinkProperties); method public void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities); method public void sendNetworkScore(int); @@ -4631,7 +4633,6 @@ package android.net { method public void unregister(); field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2 field public static final int VALIDATION_STATUS_VALID = 1; // 0x1 - field @NonNull public final android.net.Network network; field public final int providerId; } @@ -4640,8 +4641,11 @@ package android.net { method public int getLegacyType(); method @NonNull public String getLegacyTypeName(); method @Nullable public String getSubscriberId(); + method public boolean isExplicitlySelected(); method public boolean isNat64DetectionEnabled(); + method public boolean isPartialConnectivityAcceptable(); method public boolean isProvisioningNotificationEnabled(); + method public boolean isUnvalidatedConnectivityAcceptable(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR; } @@ -4651,9 +4655,12 @@ package android.net { method @NonNull public android.net.NetworkAgentConfig build(); method @NonNull public android.net.NetworkAgentConfig.Builder disableNat64Detection(); method @NonNull public android.net.NetworkAgentConfig.Builder disableProvisioningNotification(); + method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int); method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String); + method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean); method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String); + method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean); } public final class NetworkCapabilities implements android.os.Parcelable { @@ -9438,6 +9445,8 @@ package android.telephony { field public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; field public static final String ACTION_CARRIER_SIGNAL_RESET = "com.android.internal.telephony.CARRIER_SIGNAL_RESET"; field public static final String ACTION_EMERGENCY_ASSISTANCE = "android.telephony.action.EMERGENCY_ASSISTANCE"; + field public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED"; + field public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED"; field public static final String ACTION_SERVICE_PROVIDERS_UPDATED = "android.telephony.action.SERVICE_PROVIDERS_UPDATED"; field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED"; field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED"; @@ -9474,6 +9483,8 @@ package android.telephony { field public static final String EXTRA_ERROR_CODE = "errorCode"; field public static final String EXTRA_PCO_ID = "pcoId"; field public static final String EXTRA_PCO_VALUE = "pcoValue"; + field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE"; + field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL"; field public static final String EXTRA_PLMN = "android.telephony.extra.PLMN"; field public static final String EXTRA_REDIRECTION_URL = "redirectionUrl"; field public static final String EXTRA_SHOW_PLMN = "android.telephony.extra.SHOW_PLMN"; @@ -9590,6 +9601,23 @@ package android.telephony.cdma { package android.telephony.data { + public class ApnSetting implements android.os.Parcelable { + method @NonNull public static String getApnTypesStringFromBitmask(int); + field public static final String TYPE_ALL_STRING = "*"; + field public static final String TYPE_CBS_STRING = "cbs"; + field public static final String TYPE_DEFAULT_STRING = "default"; + field public static final String TYPE_DUN_STRING = "dun"; + field public static final String TYPE_EMERGENCY_STRING = "emergency"; + field public static final String TYPE_FOTA_STRING = "fota"; + field public static final String TYPE_HIPRI_STRING = "hipri"; + field public static final String TYPE_IA_STRING = "ia"; + field public static final String TYPE_IMS_STRING = "ims"; + field public static final String TYPE_MCX_STRING = "mcx"; + field public static final String TYPE_MMS_STRING = "mms"; + field public static final String TYPE_SUPL_STRING = "supl"; + field public static final String TYPE_XCAP_STRING = "xcap"; + } + public final class DataCallResponse implements android.os.Parcelable { method public int describeContents(); method @NonNull public java.util.List<android.net.LinkAddress> getAddresses(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index ce4d312318d4..90dbe3c5b10f 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1351,9 +1351,9 @@ class ContextImpl extends Context { } @Override - public void sendOrderedBroadcast(Intent intent, String receiverPermission, String receiverAppOp, - Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, - String initialData, @Nullable Bundle initialExtras) { + public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission, + String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, + String initialData, @Nullable Bundle initialExtras, Bundle options) { int intAppOp = AppOpsManager.OP_NONE; if (!TextUtils.isEmpty(receiverAppOp)) { intAppOp = AppOpsManager.strOpToOp(receiverAppOp); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 8794173cb92e..9edbad3e381a 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2470,12 +2470,13 @@ public abstract class Context { * * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) * @see android.app.BroadcastOptions + * @hide */ - public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, + public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, int initialCode, @Nullable String receiverPermission, @Nullable String receiverAppOp, - @Nullable Bundle options, @Nullable BroadcastReceiver resultReceiver, - @Nullable Handler scheduler, int initialCode, @Nullable String initialData, - @Nullable Bundle initialExtras) { + @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, + @Nullable String initialData, @Nullable Bundle initialExtras, + @Nullable Bundle options) { throw new RuntimeException("Not implemented. Must override in a subclass."); } diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 72cc021b6ea4..33e86d52e657 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -583,13 +583,13 @@ public class ContextWrapper extends Context { } @Override - public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, + public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, int initialCode, @Nullable String receiverPermission, @Nullable String receiverAppOp, - @Nullable Bundle options, @Nullable BroadcastReceiver resultReceiver, - @Nullable Handler scheduler, int initialCode, @Nullable String initialData, - @Nullable Bundle initialExtras) { - mBase.sendOrderedBroadcast(intent, receiverPermission, receiverAppOp, options, - resultReceiver, scheduler, initialCode, initialData, initialExtras); + @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, + @Nullable String initialData, @Nullable Bundle initialExtras, + @Nullable Bundle options) { + mBase.sendOrderedBroadcast(intent, initialCode, receiverPermission, receiverAppOp, + resultReceiver, scheduler, initialData, initialExtras, options); } @Override diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index c063b396aa19..7cc569a42b0b 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -51,8 +51,8 @@ public abstract class NetworkAgent { /** * The {@link Network} corresponding to this object. */ - @NonNull - public final Network network; + @Nullable + private volatile Network mNetwork; // Whether this NetworkAgent is using the legacy (never unhidden) API. The difference is // that the legacy API uses NetworkInfo to convey the state, while the current API is @@ -65,7 +65,6 @@ public abstract class NetworkAgent { private final String LOG_TAG; private static final boolean DBG = true; private static final boolean VDBG = false; - private final Context mContext; private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>(); private volatile long mLastBwRefreshTime = 0; private static final long BW_REFRESH_MIN_WIN_MS = 500; @@ -277,18 +276,21 @@ public abstract class NetworkAgent { public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score) { this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE); + // Register done by the constructor called in the previous line } /** @hide TODO: remove and replace usage with the public constructor. */ public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config) { this(looper, context, logTag, ni, nc, lp, score, config, NetworkProvider.ID_NONE); + // Register done by the constructor called in the previous line } /** @hide TODO: remove and replace usage with the public constructor. */ public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, int providerId) { this(looper, context, logTag, ni, nc, lp, score, null, providerId); + // Register done by the constructor called in the previous line } /** @hide TODO: remove and replace usage with the public constructor. */ @@ -296,6 +298,7 @@ public abstract class NetworkAgent { NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config, int providerId) { this(looper, context, logTag, nc, lp, score, config, providerId, ni, true /* legacy */); + register(); } private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) { @@ -327,12 +330,32 @@ public abstract class NetworkAgent { getLegacyNetworkInfo(config), false /* legacy */); } - private NetworkAgent(Looper looper, Context context, String logTag, NetworkCapabilities nc, - LinkProperties lp, int score, NetworkAgentConfig config, int providerId, - NetworkInfo ni, boolean legacy) { + private static class InitialConfiguration { + public final Context context; + public final NetworkCapabilities capabilities; + public final LinkProperties properties; + public final int score; + public final NetworkAgentConfig config; + public final NetworkInfo info; + InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities, + @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config, + @NonNull NetworkInfo info) { + this.context = context; + this.capabilities = capabilities; + this.properties = properties; + this.score = score; + this.config = config; + this.info = info; + } + } + private volatile InitialConfiguration mInitialConfiguration; + + private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag, + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, + @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni, + boolean legacy) { mHandler = new NetworkAgentHandler(looper); LOG_TAG = logTag; - mContext = context; mIsLegacy = legacy; mNetworkInfo = new NetworkInfo(ni); this.providerId = providerId; @@ -340,12 +363,8 @@ public abstract class NetworkAgent { throw new IllegalArgumentException(); } - if (VDBG) log("Registering NetworkAgent"); - ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService( - Context.CONNECTIVITY_SERVICE); - network = cm.registerNetworkAgent(new Messenger(mHandler), new NetworkInfo(ni), - new LinkProperties(lp), new NetworkCapabilities(nc), score, config, - providerId); + mInitialConfiguration = new InitialConfiguration(context, new NetworkCapabilities(nc), + new LinkProperties(lp), score, config, ni); } private class NetworkAgentHandler extends Handler { @@ -467,6 +486,32 @@ public abstract class NetworkAgent { } } + /** + * Register this network agent with ConnectivityService. + * @return the Network associated with this network agent (which can also be obtained later + * by calling getNetwork() on this agent). + */ + @NonNull + public Network register() { + if (VDBG) log("Registering NetworkAgent"); + final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context + .getSystemService(Context.CONNECTIVITY_SERVICE); + mNetwork = cm.registerNetworkAgent(new Messenger(mHandler), + new NetworkInfo(mInitialConfiguration.info), + mInitialConfiguration.properties, mInitialConfiguration.capabilities, + mInitialConfiguration.score, mInitialConfiguration.config, providerId); + mInitialConfiguration = null; // All this memory can now be GC'd + return mNetwork; + } + + /** + * @return The Network associated with this agent, or null if it's not registered yet. + */ + @Nullable + public Network getNetwork() { + return mNetwork; + } + private void queueOrSendMessage(int what, Object obj) { queueOrSendMessage(what, 0, 0, obj); } diff --git a/core/java/android/net/NetworkAgentConfig.java b/core/java/android/net/NetworkAgentConfig.java index 2c5a113a93da..7e2db4a4fa95 100644 --- a/core/java/android/net/NetworkAgentConfig.java +++ b/core/java/android/net/NetworkAgentConfig.java @@ -22,6 +22,8 @@ import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.util.Objects; + /** * Allows a network transport to provide the system with policy and configuration information about * a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered. @@ -52,23 +54,47 @@ public final class NetworkAgentConfig implements Parcelable { public boolean explicitlySelected; /** + * @return whether this network was explicitly selected by the user. + */ + public boolean isExplicitlySelected() { + return explicitlySelected; + } + + /** * Set if the user desires to use this network even if it is unvalidated. This field has meaning * only if {@link explicitlySelected} is true. If it is, this field must also be set to the * appropriate value based on previous user choice. * + * TODO : rename this field to match its accessor * @hide */ public boolean acceptUnvalidated; /** + * @return whether the system should accept this network even if it doesn't validate. + */ + public boolean isUnvalidatedConnectivityAcceptable() { + return acceptUnvalidated; + } + + /** * Whether the user explicitly set that this network should be validated even if presence of * only partial internet connectivity. * + * TODO : rename this field to match its accessor * @hide */ public boolean acceptPartialConnectivity; /** + * @return whether the system should validate this network even if it only offers partial + * Internet connectivity. + */ + public boolean isPartialConnectivityAcceptable() { + return acceptPartialConnectivity; + } + + /** * Set to avoid surfacing the "Sign in to network" notification. * if carrier receivers/apps are registered to handle the carrier-specific provisioning * procedure, a carrier specific provisioning notification will be placed. @@ -134,9 +160,11 @@ public final class NetworkAgentConfig implements Parcelable { * Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network. * Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode. * + * This is not parceled, because it would not make sense. + * * @hide */ - public boolean hasShownBroken; + public transient boolean hasShownBroken; /** * The name of the legacy network type. It's a free-form string used in logging. @@ -163,6 +191,7 @@ public final class NetworkAgentConfig implements Parcelable { allowBypass = nac.allowBypass; explicitlySelected = nac.explicitlySelected; acceptUnvalidated = nac.acceptUnvalidated; + acceptPartialConnectivity = nac.acceptPartialConnectivity; subscriberId = nac.subscriberId; provisioningNotificationDisabled = nac.provisioningNotificationDisabled; skip464xlat = nac.skip464xlat; @@ -178,6 +207,43 @@ public final class NetworkAgentConfig implements Parcelable { private final NetworkAgentConfig mConfig = new NetworkAgentConfig(); /** + * Sets whether the network was explicitly selected by the user. + * + * @return this builder, to facilitate chaining. + */ + @NonNull + public Builder setExplicitlySelected(final boolean explicitlySelected) { + mConfig.explicitlySelected = explicitlySelected; + return this; + } + + /** + * Sets whether the system should validate this network even if it is found not to offer + * Internet connectivity. + * + * @return this builder, to facilitate chaining. + */ + @NonNull + public Builder setUnvalidatedConnectivityAcceptable( + final boolean unvalidatedConnectivityAcceptable) { + mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable; + return this; + } + + /** + * Sets whether the system should validate this network even if it is found to only offer + * partial Internet connectivity. + * + * @return this builder, to facilitate chaining. + */ + @NonNull + public Builder setPartialConnectivityAcceptable( + final boolean partialConnectivityAcceptable) { + mConfig.acceptPartialConnectivity = partialConnectivityAcceptable; + return this; + } + + /** * Sets the subscriber ID for this network. * * @return this builder, to facilitate chaining. @@ -245,6 +311,45 @@ public final class NetworkAgentConfig implements Parcelable { } @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final NetworkAgentConfig that = (NetworkAgentConfig) o; + return allowBypass == that.allowBypass + && explicitlySelected == that.explicitlySelected + && acceptUnvalidated == that.acceptUnvalidated + && acceptPartialConnectivity == that.acceptPartialConnectivity + && provisioningNotificationDisabled == that.provisioningNotificationDisabled + && skip464xlat == that.skip464xlat + && legacyType == that.legacyType + && Objects.equals(subscriberId, that.subscriberId) + && Objects.equals(legacyTypeName, that.legacyTypeName); + } + + @Override + public int hashCode() { + return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated, + acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId, + skip464xlat, legacyType, legacyTypeName); + } + + @Override + public String toString() { + return "NetworkAgentConfig {" + + " allowBypass = " + allowBypass + + ", explicitlySelected = " + explicitlySelected + + ", acceptUnvalidated = " + acceptUnvalidated + + ", acceptPartialConnectivity = " + acceptPartialConnectivity + + ", provisioningNotificationDisabled = " + provisioningNotificationDisabled + + ", subscriberId = '" + subscriberId + '\'' + + ", skip464xlat = " + skip464xlat + + ", legacyType = " + legacyType + + ", hasShownBroken = " + hasShownBroken + + ", legacyTypeName = '" + legacyTypeName + '\'' + + "}"; + } + + @Override public int describeContents() { return 0; } @@ -254,9 +359,12 @@ public final class NetworkAgentConfig implements Parcelable { out.writeInt(allowBypass ? 1 : 0); out.writeInt(explicitlySelected ? 1 : 0); out.writeInt(acceptUnvalidated ? 1 : 0); + out.writeInt(acceptPartialConnectivity ? 1 : 0); out.writeString(subscriberId); out.writeInt(provisioningNotificationDisabled ? 1 : 0); out.writeInt(skip464xlat ? 1 : 0); + out.writeInt(legacyType); + out.writeString(legacyTypeName); } public static final @NonNull Creator<NetworkAgentConfig> CREATOR = @@ -267,9 +375,12 @@ public final class NetworkAgentConfig implements Parcelable { networkAgentConfig.allowBypass = in.readInt() != 0; networkAgentConfig.explicitlySelected = in.readInt() != 0; networkAgentConfig.acceptUnvalidated = in.readInt() != 0; + networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0; networkAgentConfig.subscriberId = in.readString(); networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0; networkAgentConfig.skip464xlat = in.readInt() != 0; + networkAgentConfig.legacyType = in.readInt(); + networkAgentConfig.legacyTypeName = in.readString(); return networkAgentConfig; } diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java deleted file mode 100644 index e27103755e6d..000000000000 --- a/core/java/android/net/NetworkFactory.java +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright (C) 2014 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.annotation.NonNull; -import android.compat.annotation.UnsupportedAppUsage; -import android.content.Context; -import android.os.Build; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.Messenger; -import android.util.Log; -import android.util.SparseArray; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.IndentingPrintWriter; -import com.android.internal.util.Protocol; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * A NetworkFactory is an entity that creates NetworkAgent objects. - * The bearers register with ConnectivityService using {@link #register} and - * their factory will start receiving scored NetworkRequests. NetworkRequests - * can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by - * overridden function. All of these can be dynamic - changing NetworkCapabilities - * or score forces re-evaluation of all current requests. - * - * If any requests pass the filter some overrideable functions will be called. - * If the bearer only cares about very simple start/stopNetwork callbacks, those - * functions can be overridden. If the bearer needs more interaction, it can - * override addNetworkRequest and removeNetworkRequest which will give it each - * request that passes their current filters. - * @hide - **/ -public class NetworkFactory extends Handler { - /* TODO: delete when all callers have migrated to NetworkProvider IDs. */ - public static class SerialNumber { - // Guard used by no network factory. - public static final int NONE = -1; - // A hardcoded serial number for NetworkAgents representing VPNs. These agents are - // not created by any factory, so they use this constant for clarity instead of NONE. - public static final int VPN = -2; - private static final AtomicInteger sNetworkFactorySerialNumber = new AtomicInteger(1); - /** Returns a unique serial number for a factory. */ - public static final int nextSerialNumber() { - return sNetworkFactorySerialNumber.getAndIncrement(); - } - } - - private static final boolean DBG = true; - private static final boolean VDBG = false; - - private static final int BASE = Protocol.BASE_NETWORK_FACTORY; - /** - * Pass a network request to the bearer. If the bearer believes it can - * satisfy the request it should connect to the network and create a - * NetworkAgent. Once the NetworkAgent is fully functional it will - * register itself with ConnectivityService using registerNetworkAgent. - * If the bearer cannot immediately satisfy the request (no network, - * user disabled the radio, lower-scored network) it should remember - * any NetworkRequests it may be able to satisfy in the future. It may - * disregard any that it will never be able to service, for example - * those requiring a different bearer. - * msg.obj = NetworkRequest - * msg.arg1 = score - the score of the network currently satisfying this - * request. If this bearer knows in advance it cannot - * exceed this score it should not try to connect, holding the request - * for the future. - * Note that subsequent events may give a different (lower - * or higher) score for this request, transmitted to each - * NetworkFactory through additional CMD_REQUEST_NETWORK msgs - * with the same NetworkRequest but an updated score. - * Also, network conditions may change for this bearer - * allowing for a better score in the future. - * msg.arg2 = the ID of the NetworkProvider currently responsible for the - * NetworkAgent handling this request, or NetworkProvider.ID_NONE if none. - */ - public static final int CMD_REQUEST_NETWORK = BASE; - - /** - * Cancel a network request - * msg.obj = NetworkRequest - */ - public static final int CMD_CANCEL_REQUEST = BASE + 1; - - /** - * Internally used to set our best-guess score. - * msg.arg1 = new score - */ - private static final int CMD_SET_SCORE = BASE + 2; - - /** - * Internally used to set our current filter for coarse bandwidth changes with - * technology changes. - * msg.obj = new filter - */ - private static final int CMD_SET_FILTER = BASE + 3; - - private final Context mContext; - private final ArrayList<Message> mPreConnectedQueue = new ArrayList<Message>(); - private final String LOG_TAG; - - private final SparseArray<NetworkRequestInfo> mNetworkRequests = - new SparseArray<NetworkRequestInfo>(); - - private int mScore; - private NetworkCapabilities mCapabilityFilter; - - private int mRefCount = 0; - private Messenger mMessenger = null; - private NetworkProvider mProvider = null; - private int mProviderId; - - @UnsupportedAppUsage - public NetworkFactory(Looper looper, Context context, String logTag, - NetworkCapabilities filter) { - super(looper); - LOG_TAG = logTag; - mContext = context; - mCapabilityFilter = filter; - } - - public void register() { - if (mProvider != null) { - Log.e(LOG_TAG, "Ignoring attempt to register already-registered NetworkFactory"); - return; - } - if (DBG) log("Registering NetworkFactory"); - - mProvider = new NetworkProvider(mContext, NetworkFactory.this.getLooper(), LOG_TAG) { - @Override - public void onNetworkRequested(@NonNull NetworkRequest request, int score, - int servingProviderId) { - handleAddRequest((NetworkRequest) request, score, servingProviderId); - } - - @Override - public void onRequestWithdrawn(@NonNull NetworkRequest request) { - handleRemoveRequest(request); - } - }; - - mMessenger = new Messenger(this); - mProviderId = ConnectivityManager.from(mContext).registerNetworkProvider(mProvider); - } - - public void unregister() { - if (mProvider == null) { - Log.e(LOG_TAG, "Ignoring attempt to unregister unregistered NetworkFactory"); - return; - } - if (DBG) log("Unregistering NetworkFactory"); - - ConnectivityManager.from(mContext).unregisterNetworkProvider(mProvider); - mProvider = null; - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case CMD_REQUEST_NETWORK: { - handleAddRequest((NetworkRequest) msg.obj, msg.arg1, msg.arg2); - break; - } - case CMD_CANCEL_REQUEST: { - handleRemoveRequest((NetworkRequest) msg.obj); - break; - } - case CMD_SET_SCORE: { - handleSetScore(msg.arg1); - break; - } - case CMD_SET_FILTER: { - handleSetFilter((NetworkCapabilities) msg.obj); - break; - } - } - } - - private class NetworkRequestInfo { - public final NetworkRequest request; - public int score; - public boolean requested; // do we have a request outstanding, limited by score - public int providerId; - - NetworkRequestInfo(NetworkRequest request, int score, int providerId) { - this.request = request; - this.score = score; - this.requested = false; - this.providerId = providerId; - } - - @Override - public String toString() { - return "{" + request + ", score=" + score + ", requested=" + requested + "}"; - } - } - - /** - * Add a NetworkRequest that the bearer may want to attempt to satisfy. - * @see #CMD_REQUEST_NETWORK - * - * @param request the request to handle. - * @param score the score of the NetworkAgent currently satisfying this request. - */ - // TODO : remove this method. It is a stopgap measure to help sheperding a number - // of dependent changes that would conflict throughout the automerger graph. Having this - // temporarily helps with the process of going through with all these dependent changes across - // the entire tree. - @VisibleForTesting - protected void handleAddRequest(NetworkRequest request, int score) { - handleAddRequest(request, score, NetworkProvider.ID_NONE); - } - - /** - * Add a NetworkRequest that the bearer may want to attempt to satisfy. - * @see #CMD_REQUEST_NETWORK - * - * @param request the request to handle. - * @param score the score of the NetworkAgent currently satisfying this request. - * @param servingProviderId the ID of the NetworkProvider that created the NetworkAgent - * currently satisfying this request. - */ - @VisibleForTesting - protected void handleAddRequest(NetworkRequest request, int score, int servingProviderId) { - NetworkRequestInfo n = mNetworkRequests.get(request.requestId); - if (n == null) { - if (DBG) { - log("got request " + request + " with score " + score - + " and providerId " + servingProviderId); - } - n = new NetworkRequestInfo(request, score, servingProviderId); - mNetworkRequests.put(n.request.requestId, n); - } else { - if (VDBG) { - log("new score " + score + " for exisiting request " + request - + " and providerId " + servingProviderId); - } - n.score = score; - n.providerId = servingProviderId; - } - if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter); - - evalRequest(n); - } - - @VisibleForTesting - protected void handleRemoveRequest(NetworkRequest request) { - NetworkRequestInfo n = mNetworkRequests.get(request.requestId); - if (n != null) { - mNetworkRequests.remove(request.requestId); - if (n.requested) releaseNetworkFor(n.request); - } - } - - private void handleSetScore(int score) { - mScore = score; - evalRequests(); - } - - private void handleSetFilter(NetworkCapabilities netCap) { - mCapabilityFilter = netCap; - evalRequests(); - } - - /** - * Overridable function to provide complex filtering. - * Called for every request every time a new NetworkRequest is seen - * and whenever the filterScore or filterNetworkCapabilities change. - * - * acceptRequest can be overridden to provide complex filter behavior - * for the incoming requests - * - * For output, this class will call {@link #needNetworkFor} and - * {@link #releaseNetworkFor} for every request that passes the filters. - * If you don't need to see every request, you can leave the base - * implementations of those two functions and instead override - * {@link #startNetwork} and {@link #stopNetwork}. - * - * If you want to see every score fluctuation on every request, set - * your score filter to a very high number and watch {@link #needNetworkFor}. - * - * @return {@code true} to accept the request. - */ - public boolean acceptRequest(NetworkRequest request, int score) { - return true; - } - - private void evalRequest(NetworkRequestInfo n) { - if (VDBG) { - log("evalRequest"); - log(" n.requests = " + n.requested); - log(" n.score = " + n.score); - log(" mScore = " + mScore); - log(" n.providerId = " + n.providerId); - log(" mProviderId = " + mProviderId); - } - if (shouldNeedNetworkFor(n)) { - if (VDBG) log(" needNetworkFor"); - needNetworkFor(n.request, n.score); - n.requested = true; - } else if (shouldReleaseNetworkFor(n)) { - if (VDBG) log(" releaseNetworkFor"); - releaseNetworkFor(n.request); - n.requested = false; - } else { - if (VDBG) log(" done"); - } - } - - private boolean shouldNeedNetworkFor(NetworkRequestInfo n) { - // If this request is already tracked, it doesn't qualify for need - return !n.requested - // If the score of this request is higher or equal to that of this factory and some - // other factory is responsible for it, then this factory should not track the request - // because it has no hope of satisfying it. - && (n.score < mScore || n.providerId == mProviderId) - // If this factory can't satisfy the capability needs of this request, then it - // should not be tracked. - && n.request.networkCapabilities.satisfiedByNetworkCapabilities(mCapabilityFilter) - // Finally if the concrete implementation of the factory rejects the request, then - // don't track it. - && acceptRequest(n.request, n.score); - } - - private boolean shouldReleaseNetworkFor(NetworkRequestInfo n) { - // Don't release a request that's not tracked. - return n.requested - // The request should be released if it can't be satisfied by this factory. That - // means either of the following conditions are met : - // - Its score is too high to be satisfied by this factory and it's not already - // assigned to the factory - // - This factory can't satisfy the capability needs of the request - // - The concrete implementation of the factory rejects the request - && ((n.score > mScore && n.providerId != mProviderId) - || !n.request.networkCapabilities.satisfiedByNetworkCapabilities( - mCapabilityFilter) - || !acceptRequest(n.request, n.score)); - } - - private void evalRequests() { - for (int i = 0; i < mNetworkRequests.size(); i++) { - NetworkRequestInfo n = mNetworkRequests.valueAt(i); - evalRequest(n); - } - } - - /** - * Post a command, on this NetworkFactory Handler, to re-evaluate all - * oustanding requests. Can be called from a factory implementation. - */ - protected void reevaluateAllRequests() { - post(() -> { - evalRequests(); - }); - } - - /** - * Can be called by a factory to release a request as unfulfillable: the request will be - * removed, and the caller will get a - * {@link ConnectivityManager.NetworkCallback#onUnavailable()} callback after this function - * returns. - * - * Note: this should only be called by factory which KNOWS that it is the ONLY factory which - * is able to fulfill this request! - */ - protected void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) { - post(() -> { - if (DBG) log("releaseRequestAsUnfulfillableByAnyFactory: " + r); - ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(r); - }); - } - - // override to do simple mode (request independent) - protected void startNetwork() { } - protected void stopNetwork() { } - - // override to do fancier stuff - protected void needNetworkFor(NetworkRequest networkRequest, int score) { - if (++mRefCount == 1) startNetwork(); - } - - protected void releaseNetworkFor(NetworkRequest networkRequest) { - if (--mRefCount == 0) stopNetwork(); - } - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public void setScoreFilter(int score) { - sendMessage(obtainMessage(CMD_SET_SCORE, score, 0)); - } - - public void setCapabilityFilter(NetworkCapabilities netCap) { - sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap))); - } - - @VisibleForTesting - protected int getRequestCount() { - return mNetworkRequests.size(); - } - - /* TODO: delete when all callers have migrated to NetworkProvider IDs. */ - public int getSerialNumber() { - return mProviderId; - } - - public int getProviderId() { - return mProviderId; - } - - protected void log(String s) { - Log.d(LOG_TAG, s); - } - - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { - final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); - pw.println(toString()); - pw.increaseIndent(); - for (int i = 0; i < mNetworkRequests.size(); i++) { - pw.println(mNetworkRequests.valueAt(i)); - } - pw.decreaseIndent(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - mProviderId=") - .append(mProviderId).append(", ScoreFilter=") - .append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=") - .append(mNetworkRequests.size()).append(", refCount=").append(mRefCount) - .append("}"); - return sb.toString(); - } -} diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java index d0c536316527..08fe159b276e 100644 --- a/core/java/android/net/NetworkInfo.java +++ b/core/java/android/net/NetworkInfo.java @@ -17,9 +17,11 @@ package android.net; import android.annotation.NonNull; +import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.NetworkType; import com.android.internal.annotations.VisibleForTesting; @@ -150,10 +152,19 @@ public class NetworkInfo implements Parcelable { private boolean mIsRoaming; /** - * @hide + * Create a new instance of NetworkInfo. + * + * This may be useful for apps to write unit tests. + * + * @param type the legacy type of the network, as one of the ConnectivityManager.TYPE_* + * constants. + * @param subtype the subtype if applicable, as one of the TelephonyManager.NETWORK_TYPE_* + * constants. + * @param typeName a human-readable string for the network type, or an empty string or null. + * @param subtypeName a human-readable string for the subtype, or an empty string or null. */ - @UnsupportedAppUsage - public NetworkInfo(int type, int subtype, String typeName, String subtypeName) { + public NetworkInfo(int type, @NetworkType int subtype, + @Nullable String typeName, @Nullable String subtypeName) { if (!ConnectivityManager.isNetworkTypeValid(type) && type != ConnectivityManager.TYPE_NONE) { throw new IllegalArgumentException("Invalid network type: " + type); @@ -462,17 +473,19 @@ public class NetworkInfo implements Parcelable { /** * Sets the fine-grained state of the network. + * + * This is only useful for testing. + * * @param detailedState the {@link DetailedState}. * @param reason a {@code String} indicating the reason for the state change, * if one was supplied. May be {@code null}. * @param extraInfo an optional {@code String} providing addditional network state * information passed up from the lower networking layers. * @deprecated Use {@link NetworkCapabilities} instead. - * @hide */ @Deprecated - @UnsupportedAppUsage - public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) { + public void setDetailedState(@NonNull DetailedState detailedState, @Nullable String reason, + @Nullable String extraInfo) { synchronized (this) { this.mDetailedState = detailedState; this.mState = stateMap.get(detailedState); diff --git a/core/java/com/android/internal/util/ContrastColorUtil.java b/core/java/com/android/internal/util/ContrastColorUtil.java index bf088e0a2755..8508a8dd71a4 100644 --- a/core/java/com/android/internal/util/ContrastColorUtil.java +++ b/core/java/com/android/internal/util/ContrastColorUtil.java @@ -73,7 +73,7 @@ public class ContrastColorUtil { private ContrastColorUtil(Context context) { mGrayscaleIconMaxSize = context.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.notification_large_icon_width); + com.android.internal.R.dimen.notification_grayscale_icon_max_size); } /** diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 1b45d407c86c..c52c53f9549a 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3043,10 +3043,6 @@ <!-- Whether to use voip audio mode for ims call --> <bool name="config_use_voip_mode_for_ims">false</bool> - <!-- Boolean indicating USSD over IMS is allowed. - If it is not supported due to modem limitations, USSD send over the CS pipe instead.--> - <bool name="config_allow_ussd_over_ims">false</bool> - <!-- String array containing numbers that shouldn't be logged. Country-specific. --> <string-array name="unloggable_phone_numbers" /> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 609659b62948..1f7a120d8e4c 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -680,6 +680,8 @@ <dimen name="notification_media_image_max_width_low_ram">100dp</dimen> <!-- The size of the right icon image when on low ram --> <dimen name="notification_right_icon_size_low_ram">@dimen/notification_right_icon_size</dimen> + <!-- The maximum size of the grayscale icon --> + <dimen name="notification_grayscale_icon_max_size">256dp</dimen> <dimen name="messaging_avatar_size">@dimen/notification_right_icon_size</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 188d92462eb2..2e9811aa7d33 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2627,7 +2627,6 @@ <java-symbol type="bool" name="config_device_wfc_ims_available" /> <java-symbol type="bool" name="config_carrier_wfc_ims_available" /> <java-symbol type="bool" name="config_use_voip_mode_for_ims" /> - <java-symbol type="bool" name="config_allow_ussd_over_ims" /> <java-symbol type="attr" name="touchscreenBlocksFocus" /> <java-symbol type="layout" name="resolver_list_with_default" /> <java-symbol type="string" name="activity_resolver_set_always" /> @@ -3389,6 +3388,7 @@ <java-symbol type="dimen" name="notification_media_image_max_width_low_ram"/> <java-symbol type="dimen" name="notification_media_image_max_height_low_ram"/> <java-symbol type="dimen" name="notification_right_icon_size_low_ram"/> + <java-symbol type="dimen" name="notification_grayscale_icon_max_size"/> <java-symbol type="dimen" name="notification_custom_view_max_image_height_low_ram"/> <java-symbol type="dimen" name="notification_custom_view_max_image_width_low_ram"/> diff --git a/packages/CarrierDefaultApp/OWNERS b/packages/CarrierDefaultApp/OWNERS index 0d8e69b447e8..56688409bf78 100644 --- a/packages/CarrierDefaultApp/OWNERS +++ b/packages/CarrierDefaultApp/OWNERS @@ -1,8 +1,8 @@ +set noparent tgunn@google.com breadley@google.com hallliu@google.com rgreenwalt@google.com -mpq@google.com amitmahajan@google.com fionaxu@google.com jackyu@google.com @@ -12,3 +12,6 @@ shuoq@google.com refuhoo@google.com nazaninb@google.com sarahchin@google.com +dbright@google.com +xiaotonj@google.com + diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java index 2697a1066ed2..cb062a63541e 100644 --- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java +++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java @@ -30,8 +30,6 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; -import com.android.internal.telephony.PhoneConstants; - /** * This util class provides common logic for carrier actions */ @@ -103,7 +101,7 @@ public class CarrierActionUtils { } private static void onDisableAllMeteredApns(Intent intent, Context context) { - int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, + int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.getDefaultVoiceSubscriptionId()); logd("onDisableAllMeteredApns subId: " + subId); final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); @@ -111,7 +109,7 @@ public class CarrierActionUtils { } private static void onEnableAllMeteredApns(Intent intent, Context context) { - int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, + int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.getDefaultVoiceSubscriptionId()); logd("onEnableAllMeteredApns subId: " + subId); final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); @@ -135,7 +133,7 @@ public class CarrierActionUtils { } private static void onRegisterDefaultNetworkAvail(Intent intent, Context context) { - int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, + int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.getDefaultVoiceSubscriptionId()); logd("onRegisterDefaultNetworkAvail subId: " + subId); final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); @@ -143,7 +141,7 @@ public class CarrierActionUtils { } private static void onDeregisterDefaultNetworkAvail(Intent intent, Context context) { - int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, + int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.getDefaultVoiceSubscriptionId()); logd("onDeregisterDefaultNetworkAvail subId: " + subId); final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); @@ -151,7 +149,7 @@ public class CarrierActionUtils { } private static void onDisableRadio(Intent intent, Context context) { - int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, + int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.getDefaultVoiceSubscriptionId()); logd("onDisableRadio subId: " + subId); final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); @@ -159,7 +157,7 @@ public class CarrierActionUtils { } private static void onEnableRadio(Intent intent, Context context) { - int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, + int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.getDefaultVoiceSubscriptionId()); logd("onEnableRadio subId: " + subId); final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); @@ -202,7 +200,7 @@ public class CarrierActionUtils { } private static void onResetAllCarrierActions(Intent intent, Context context) { - int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, + int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.getDefaultVoiceSubscriptionId()); logd("onResetAllCarrierActions subId: " + subId); final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class); diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java index 086a287fd243..6229434d1d86 100644 --- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java +++ b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java @@ -15,6 +15,7 @@ */ package com.android.carrierdefaultapp; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; @@ -26,11 +27,10 @@ import android.app.PendingIntent; import android.content.Intent; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.test.InstrumentationTestCase; -import com.android.internal.telephony.PhoneConstants; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -69,6 +69,7 @@ public class CarrierDefaultReceiverTest extends InstrumentationTestCase { mContext.injectSystemService(NotificationManager.class, mNotificationMgr); mContext.injectSystemService(TelephonyManager.class, mTelephonyMgr); mContext.injectSystemService(CarrierConfigManager.class, mCarrierConfigMgr); + doReturn(mTelephonyMgr).when(mTelephonyMgr).createForSubscriptionId(anyInt()); mReceiver = new CarrierDefaultBroadcastReceiver(); } @@ -88,7 +89,7 @@ public class CarrierDefaultReceiverTest extends InstrumentationTestCase { doReturn(b).when(mCarrierConfigMgr).getConfig(); Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED); - intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); + intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); mReceiver.onReceive(mContext, intent); mContext.waitForMs(100); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java index 1ebe91736ba1..c9c847ff7194 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java @@ -164,7 +164,9 @@ public class A2dpProfile implements LocalBluetoothProfile { if (mBluetoothAdapter == null) { return false; } - return mBluetoothAdapter.setActiveDevice(device, ACTIVE_DEVICE_AUDIO); + return device == null + ? mBluetoothAdapter.removeActiveDevice(ACTIVE_DEVICE_AUDIO) + : mBluetoothAdapter.setActiveDevice(device, ACTIVE_DEVICE_AUDIO); } public BluetoothDevice getActiveDevice() { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java index 9dfc4d986745..9dd329ed7cd7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java @@ -125,7 +125,10 @@ public class HeadsetProfile implements LocalBluetoothProfile { if (mBluetoothAdapter == null) { return false; } - return mBluetoothAdapter.setActiveDevice(device, ACTIVE_DEVICE_PHONE_CALL); + + return device == null + ? mBluetoothAdapter.removeActiveDevice(ACTIVE_DEVICE_PHONE_CALL) + : mBluetoothAdapter.setActiveDevice(device, ACTIVE_DEVICE_PHONE_CALL); } public BluetoothDevice getActiveDevice() { diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java index a3b68b4b90b3..d17f242d5d63 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java @@ -162,7 +162,9 @@ public class HearingAidProfile implements LocalBluetoothProfile { if (mBluetoothAdapter == null) { return false; } - return mBluetoothAdapter.setActiveDevice(device, ACTIVE_DEVICE_ALL); + return device == null + ? mBluetoothAdapter.removeActiveDevice(ACTIVE_DEVICE_ALL) + : mBluetoothAdapter.setActiveDevice(device, ACTIVE_DEVICE_ALL); } public List<BluetoothDevice> getActiveDevices() { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java index c555cbec4bab..414c39bc0ce9 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java @@ -203,4 +203,10 @@ public class A2dpProfileTest { assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo( String.format(KNOWN_CODEC_LABEL, config.getCodecName())); } + + @Test + public void setActiveDevice_returnTrue() { + assertThat(mProfile.setActiveDevice(null)).isTrue(); + assertThat(mProfile.setActiveDevice(mDevice)).isTrue(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java index 9adef8287355..30182c476855 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java @@ -75,4 +75,10 @@ public class HeadsetProfileTest { assertThat(mProfile.getAudioState(mBluetoothDevice)). isEqualTo(BluetoothHeadset.STATE_AUDIO_CONNECTED); } + + @Test + public void setActiveDevice_returnTrue() { + assertThat(mProfile.setActiveDevice(null)).isTrue(); + assertThat(mProfile.setActiveDevice(mBluetoothDevice)).isTrue(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidProfileTest.java new file mode 100644 index 000000000000..be3a51788d24 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidProfileTest.java @@ -0,0 +1,77 @@ +/* + * 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 com.android.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHearingAid; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; + +@RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothAdapter.class}) +public class HearingAidProfileTest { + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothHearingAid mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + + private BluetoothProfile.ServiceListener mServiceListener; + private HearingAidProfile mProfile; + private ShadowBluetoothAdapter mShadowBluetoothAdapter; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + Context context = spy(RuntimeEnvironment.application); + mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + + when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); + + mProfile = new HearingAidProfile(context, mDeviceManager, mProfileManager); + mServiceListener = mShadowBluetoothAdapter.getServiceListener(); + mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, mService); + } + + @Test + public void setActiveDevice_returnTrue() { + assertThat(mProfile.setActiveDevice(null)).isTrue(); + assertThat(mProfile.setActiveDevice(mBluetoothDevice)).isTrue(); + } +} diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java new file mode 100644 index 000000000000..36ef18d100e0 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java @@ -0,0 +1,90 @@ +/* + * 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 com.android.settingslib.testutils.shadow; + +import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_ALL; +import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_AUDIO; +import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import java.util.List; + +@Implements(value = BluetoothAdapter.class) +public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBluetoothAdapter { + + private List<Integer> mSupportedProfiles; + private List<BluetoothDevice> mMostRecentlyConnectedDevices; + private BluetoothProfile.ServiceListener mServiceListener; + + @Implementation + protected boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener, + int profile) { + mServiceListener = listener; + return true; + } + + public BluetoothProfile.ServiceListener getServiceListener() { + return mServiceListener; + } + + @Implementation + protected List<Integer> getSupportedProfiles() { + return mSupportedProfiles; + } + + public void setSupportedProfiles(List<Integer> supportedProfiles) { + mSupportedProfiles = supportedProfiles; + } + + @Implementation + protected List<BluetoothDevice> getMostRecentlyConnectedDevices() { + return mMostRecentlyConnectedDevices; + } + + public void setMostRecentlyConnectedDevices(List<BluetoothDevice> list) { + mMostRecentlyConnectedDevices = list; + } + + @Implementation + protected boolean removeActiveDevice(@BluetoothAdapter.ActiveDeviceUse int profiles) { + if (profiles != ACTIVE_DEVICE_AUDIO && profiles != ACTIVE_DEVICE_PHONE_CALL + && profiles != ACTIVE_DEVICE_ALL) { + return false; + } + return true; + } + + @Implementation + protected boolean setActiveDevice(BluetoothDevice device, + @BluetoothAdapter.ActiveDeviceUse int profiles) { + if (device == null) { + return false; + } + if (profiles != ACTIVE_DEVICE_AUDIO && profiles != ACTIVE_DEVICE_PHONE_CALL + && profiles != ACTIVE_DEVICE_ALL) { + return false; + } + return true; + } +} diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 5e6ccc07c4da..8b22bdf49e9e 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -192,6 +192,7 @@ <!-- Permission needed to run network tests in CTS --> <uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" /> + <uses-permission android:name="android.permission.NETWORK_STACK" /> <!-- Permission needed to test tcp keepalive offload. --> <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" /> diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 589b24a04f8c..817e3eff80c5 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -55,7 +55,6 @@ import android.service.dreams.IDreamManager; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.TelephonyManager; -import android.text.TextUtils; import android.util.ArraySet; import android.util.FeatureFlagUtils; import android.util.Log; @@ -1394,8 +1393,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) { // Airplane mode can be changed after ECM exits if airplane toggle button // is pressed during ECM mode - if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) && - mIsWaitingForEcmExit) { + if (!(intent.getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false)) + && mIsWaitingForEcmExit) { mIsWaitingForEcmExit = false; changeAirplaneModeSystemSetting(true); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java index f91deeadba7b..9c96d2f0229c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java @@ -30,12 +30,12 @@ import android.telephony.CellSignalStrength; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; -import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.settingslib.graph.SignalDrawable; import com.android.settingslib.net.DataUsageController; @@ -418,7 +418,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { intent.putExtra(TelephonyIntents.EXTRA_SHOW_PLMN, showPlmn); intent.putExtra(TelephonyIntents.EXTRA_PLMN, plmn); - intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, mSubId); + SubscriptionManager.putSubscriptionIdExtra(intent, mSubId); return intent; } diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index bfa962a18c9a..2cf49a115dc6 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java @@ -1131,6 +1131,25 @@ public class TetheringManager { public boolean isTetheringSupported() { final String callerPkg = mContext.getOpPackageName(); + return isTetheringSupported(callerPkg); + } + + /** + * Check if the device allows for tethering. It may be disabled via {@code ro.tether.denied} + * system property, Settings.TETHER_SUPPORTED or due to device configuration. This is useful + * for system components that query this API on behalf of an app. In particular, Bluetooth + * has @UnsupportedAppUsage calls that will let apps turn on bluetooth tethering if they have + * the right permissions, but such an app needs to know whether it can (permissions as well + * as support from the device) turn on tethering in the first place to show the appropriate UI. + * + * @param callerPkg The caller package name, if it is not matching the calling uid, + * SecurityException would be thrown. + * @return a boolean - {@code true} indicating Tethering is supported. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public boolean isTetheringSupported(@NonNull final String callerPkg) { + final RequestDispatcher dispatcher = new RequestDispatcher(); final int ret = dispatcher.waitForResult((connector, listener) -> { try { diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java index a7e36b23a98b..95ac900d0535 100644 --- a/services/core/java/com/android/server/TestNetworkService.java +++ b/services/core/java/com/android/server/TestNetworkService.java @@ -219,7 +219,7 @@ class TestNetworkService extends ITestNetworkManager.Stub { // Has to be in TestNetworkAgent to ensure all teardown codepaths properly clean up // resources, even for binder death or unwanted calls. synchronized (mTestNetworkTracker) { - mTestNetworkTracker.remove(network.netId); + mTestNetworkTracker.remove(getNetwork().netId); } } } @@ -338,7 +338,7 @@ class TestNetworkService extends ITestNetworkManager.Stub { callingUid, binder); - mTestNetworkTracker.put(agent.network.netId, agent); + mTestNetworkTracker.put(agent.getNetwork().netId, agent); } } catch (SocketException e) { throw new UncheckedIOException(e); diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index e6c1aa475321..43b54af29155 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -985,7 +985,11 @@ public class Vpn { } public int getNetId() { - return mNetworkAgent != null ? mNetworkAgent.network.netId : NETID_UNSET; + final NetworkAgent agent = mNetworkAgent; + if (null == agent) return NETID_UNSET; + final Network network = agent.getNetwork(); + if (null == network) return NETID_UNSET; + return network.netId; } private LinkProperties makeLinkProperties() { diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java index 68ba8a467f26..3aef7e5d71e9 100644 --- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java +++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java @@ -746,8 +746,8 @@ class LegacyGlobalActions implements DialogInterface.OnDismissListener, DialogIn } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) { // Airplane mode can be changed after ECM exits if airplane toggle button // is pressed during ECM mode - if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) && - mIsWaitingForEcmExit) { + if (!(intent.getBooleanExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false)) + && mIsWaitingForEcmExit) { mIsWaitingForEcmExit = false; changeAirplaneModeSystemSetting(true); } diff --git a/services/net/Android.bp b/services/net/Android.bp index cf84bdfb5b6f..dbc2df8369f8 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -16,6 +16,7 @@ java_library_static { "netd_aidl_interface-unstable-java", "netlink-client", "networkstack-client", + "net-utils-services-common", ], } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 8cf113f5561e..7a351d65379e 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -2972,6 +2972,13 @@ public class CarrierConfigManager { "ascii_7_bit_support_for_long_message_bool"; /** + * Controls whether to show wifi calling icon in statusbar when wifi calling is available. + * @hide + */ + public static final String KEY_SHOW_WIFI_CALLING_ICON_IN_STATUS_BAR_BOOL = + "show_wifi_calling_icon_in_status_bar_bool"; + + /** * Controls RSRP threshold at which OpportunisticNetworkService will decide whether * the opportunistic network is good enough for internet data. */ @@ -3942,6 +3949,7 @@ public class CarrierConfigManager { "connected_mmwave:5G,connected:5G"); sDefaults.putInt(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0); sDefaults.putBoolean(KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL, false); + sDefaults.putBoolean(KEY_SHOW_WIFI_CALLING_ICON_IN_STATUS_BAR_BOOL, false); /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -108); /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_MODERATE */ diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index ef035456d32a..de40df61aa09 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -2144,10 +2144,9 @@ public class SubscriptionManager { @UnsupportedAppUsage public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) { if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId); - intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); - intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId); intent.putExtra(EXTRA_SLOT_INDEX, phoneId); intent.putExtra(PhoneConstants.PHONE_KEY, phoneId); + putSubscriptionIdExtra(intent, subId); } /** @@ -3324,4 +3323,19 @@ public class SubscriptionManager { } return SubscriptionManager.INVALID_SUBSCRIPTION_ID; } + + /** + * Helper method that puts a subscription id on an intent with the constants: + * PhoneConstant.SUBSCRIPTION_KEY and SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX. + * Both constants are used to support backwards compatibility. Once we know we got all places, + * we can remove PhoneConstants.SUBSCRIPTION_KEY. + * @param intent Intent to put sub id on. + * @param subId SubscriptionId to put on intent. + * + * @hide + */ + public static void putSubscriptionIdExtra(Intent intent, int subId) { + intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); + intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); + } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 7f7833b1a8ae..1a73d518df07 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1530,6 +1530,40 @@ public class TelephonyManager { "android.telephony.extra.SIM_COMBINATION_NAMES"; /** + * <p>Broadcast Action: The emergency callback mode is changed. + * <ul> + * <li><em>EXTRA_PHONE_IN_ECM_STATE</em> - A boolean value,true=phone in ECM, + * false=ECM off</li> + * </ul> + * <p class="note"> + * You can <em>not</em> receive this through components declared + * in manifests, only by explicitly registering for it with + * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver, + * android.content.IntentFilter) Context.registerReceiver()}. + * + * <p class="note">This is a protected intent that can only be sent by the system. + * + * @see #EXTRA_PHONE_IN_ECM_STATE + * + * @hide + */ + @SystemApi + @SuppressLint("ActionValue") + public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = + "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED"; + + + /** + * Extra included in {@link #ACTION_EMERGENCY_CALLBACK_MODE_CHANGED}. + * Indicates whether the phone is in an emergency phone state. + * + * @hide + */ + @SystemApi + public static final String EXTRA_PHONE_IN_ECM_STATE = + "android.telephony.extra.PHONE_IN_ECM_STATE"; + + /** * <p>Broadcast Action: when data connections get redirected with validation failure. * intended for sim/account status checks and only sent to the specified carrier app * The intent will have the following extra values:</p> @@ -1716,6 +1750,40 @@ public class TelephonyManager { @SuppressLint("ActionValue") public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable"; + /** + * <p>Broadcast Action: The emergency call state is changed. + * <ul> + * <li><em>EXTRA_PHONE_IN_EMERGENCY_CALL</em> - A boolean value, true if phone in emergency + * call, false otherwise</li> + * </ul> + * <p class="note"> + * You can <em>not</em> receive this through components declared + * in manifests, only by explicitly registering for it with + * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver, + * android.content.IntentFilter) Context.registerReceiver()}. + * + * <p class="note">This is a protected intent that can only be sent by the system. + * + * @see #EXTRA_PHONE_IN_EMERGENCY_CALL + * + * @hide + */ + @SystemApi + @SuppressLint("ActionValue") + public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = + "android.intent.action.EMERGENCY_CALL_STATE_CHANGED"; + + + /** + * Extra included in {@link #ACTION_EMERGENCY_CALL_STATE_CHANGED}. + * It indicates whether the phone is making an emergency call. + * + * @hide + */ + @SystemApi + public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = + "android.telephony.extra.PHONE_IN_EMERGENCY_CALL"; + // // // Device Info @@ -11011,9 +11079,15 @@ public class TelephonyManager { } /** - * Checks if FEATURE_TELEPHONY_DATA is enabled. - * - * @hide + * @return true if the current device is "data capable" over a radio on the device. + * <p> + * "Data capable" means that this device supports packet-switched + * data connections over the telephony network. + * <p> + * Note: the meaning of this flag is subtly different from the + * PackageManager.FEATURE_TELEPHONY system feature, which is available + * on any device with a telephony radio, even if the device is + * voice-only. */ public boolean isDataCapable() { if (mContext == null) return true; diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index de4b61163fb5..6e630e3a7024 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -18,6 +18,7 @@ package android.telephony.data; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.content.ContentValues; import android.database.Cursor; import android.hardware.radio.V1_5.ApnTypes; @@ -124,6 +125,122 @@ public class ApnSetting implements Parcelable { /** Authentication type for PAP or CHAP. */ public static final int AUTH_TYPE_PAP_OR_CHAP = 3; + /** + * APN types for data connections. These are usage categories for an APN + * entry. One APN entry may support multiple APN types, eg, a single APN + * may service regular internet traffic ("default") as well as MMS-specific + * connections.<br/> + * APN_TYPE_ALL is a special type to indicate that this APN entry can + * service all data connections. + * <p> + * Note: The goal is to deprecate this. Due to the Carrier Table being used + * directly, this isn't feasible right now. + * + * @hide + */ + @SystemApi + public static final String TYPE_ALL_STRING = "*"; + + /** + * APN type for default data traffic + * + * @hide + */ + @SystemApi + public static final String TYPE_DEFAULT_STRING = "default"; + + + /** + * APN type for MMS traffic + * + * @hide + */ + @SystemApi + public static final String TYPE_MMS_STRING = "mms"; + + + /** + * APN type for SUPL assisted GPS + * + * @hide + */ + @SystemApi + public static final String TYPE_SUPL_STRING = "supl"; + + /** + * APN type for DUN traffic + * + * @hide + */ + @SystemApi + public static final String TYPE_DUN_STRING = "dun"; + + /** + * APN type for HiPri traffic + * + * @hide + */ + @SystemApi + public static final String TYPE_HIPRI_STRING = "hipri"; + + /** + * APN type for FOTA + * + * @hide + */ + @SystemApi + public static final String TYPE_FOTA_STRING = "fota"; + + /** + * APN type for IMS + * + * @hide + */ + @SystemApi + public static final String TYPE_IMS_STRING = "ims"; + + /** + * APN type for CBS + * + * @hide + */ + @SystemApi + public static final String TYPE_CBS_STRING = "cbs"; + + /** + * APN type for IA Initial Attach APN + * + * @hide + */ + @SystemApi + public static final String TYPE_IA_STRING = "ia"; + + /** + * APN type for Emergency PDN. This is not an IA apn, but is used + * for access to carrier services in an emergency call situation. + * + * @hide + */ + @SystemApi + public static final String TYPE_EMERGENCY_STRING = "emergency"; + + /** + * APN type for Mission Critical Services + * + * @hide + */ + @SystemApi + public static final String TYPE_MCX_STRING = "mcx"; + + /** + * APN type for XCAP + * + * @hide + */ + @SystemApi + public static final String TYPE_XCAP_STRING = "xcap"; + + /** @hide */ @IntDef(prefix = { "AUTH_TYPE_" }, value = { AUTH_TYPE_NONE, @@ -1290,10 +1407,13 @@ public class ApnSetting implements Parcelable { } /** + * Converts the integer value of an APN type to the string version. * @param apnTypeBitmask bitmask of APN types. * @return comma delimited list of APN types. * @hide */ + @SystemApi + @NonNull public static String getApnTypesStringFromBitmask(int apnTypeBitmask) { List<String> types = new ArrayList<>(); for (Integer type : APN_TYPE_INT_MAP.keySet()) { diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index 7ec22698edb4..6eea88f4c103 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -16,6 +16,7 @@ package com.android.internal.telephony; import android.compat.annotation.UnsupportedAppUsage; +import android.telephony.data.ApnSetting; /** * @hide @@ -103,9 +104,6 @@ public class PhoneConstants { public static final String DATA_APN_TYPE_KEY = "apnType"; public static final String DATA_APN_KEY = "apn"; - public static final String PHONE_IN_ECM_STATE = "phoneinECMState"; - public static final String PHONE_IN_EMERGENCY_CALL = "phoneInEmergencyCall"; - /** * Return codes for supplyPinReturnResult and * supplyPukReturnResult APIs @@ -131,32 +129,32 @@ public class PhoneConstants { * APN_TYPE_ALL is a special type to indicate that this APN entry can * service all data connections. */ - public static final String APN_TYPE_ALL = "*"; + public static final String APN_TYPE_ALL = ApnSetting.TYPE_ALL_STRING; /** APN type for default data traffic */ - public static final String APN_TYPE_DEFAULT = "default"; + public static final String APN_TYPE_DEFAULT = ApnSetting.TYPE_DEFAULT_STRING; /** APN type for MMS traffic */ - public static final String APN_TYPE_MMS = "mms"; + public static final String APN_TYPE_MMS = ApnSetting.TYPE_MMS_STRING; /** APN type for SUPL assisted GPS */ - public static final String APN_TYPE_SUPL = "supl"; + public static final String APN_TYPE_SUPL = ApnSetting.TYPE_SUPL_STRING; /** APN type for DUN traffic */ - public static final String APN_TYPE_DUN = "dun"; + public static final String APN_TYPE_DUN = ApnSetting.TYPE_DUN_STRING; /** APN type for HiPri traffic */ - public static final String APN_TYPE_HIPRI = "hipri"; + public static final String APN_TYPE_HIPRI = ApnSetting.TYPE_HIPRI_STRING; /** APN type for FOTA */ - public static final String APN_TYPE_FOTA = "fota"; + public static final String APN_TYPE_FOTA = ApnSetting.TYPE_FOTA_STRING; /** APN type for IMS */ - public static final String APN_TYPE_IMS = "ims"; + public static final String APN_TYPE_IMS = ApnSetting.TYPE_IMS_STRING; /** APN type for CBS */ - public static final String APN_TYPE_CBS = "cbs"; + public static final String APN_TYPE_CBS = ApnSetting.TYPE_CBS_STRING; /** APN type for IA Initial Attach APN */ - public static final String APN_TYPE_IA = "ia"; + public static final String APN_TYPE_IA = ApnSetting.TYPE_IA_STRING; /** APN type for Emergency PDN. This is not an IA apn, but is used * for access to carrier services in an emergency call situation. */ - public static final String APN_TYPE_EMERGENCY = "emergency"; + public static final String APN_TYPE_EMERGENCY = ApnSetting.TYPE_EMERGENCY_STRING; /** APN type for Mission Critical Services */ - public static final String APN_TYPE_MCX = "mcx"; + public static final String APN_TYPE_MCX = ApnSetting.TYPE_MCX_STRING; /** APN type for XCAP */ - public static final String APN_TYPE_XCAP = "xcap"; + public static final String APN_TYPE_XCAP = ApnSetting.TYPE_XCAP_STRING; /** Array of all APN types */ public static final String[] APN_TYPES = {APN_TYPE_DEFAULT, APN_TYPE_MMS, diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java index 0208c3a0a0de..a458e71e4767 100644 --- a/test-mock/src/android/test/mock/MockContext.java +++ b/test-mock/src/android/test/mock/MockContext.java @@ -469,10 +469,11 @@ public class MockContext extends Context { throw new UnsupportedOperationException(); } + /** @hide */ @Override - public void sendOrderedBroadcast(Intent intent, String receiverPermission, String receiverAppOp, - Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, - String initialData, Bundle initialExtras) { + public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission, + String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, + String initialData, Bundle initialExtras, Bundle options) { throw new UnsupportedOperationException(); } diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt new file mode 100644 index 000000000000..d250ad3a2b12 --- /dev/null +++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 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 androidx.test.filters.SmallTest +import androidx.test.runner.AndroidJUnit4 +import com.android.testutils.assertParcelSane +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +@SmallTest +class NetworkAgentConfigTest { + @Test + fun testParcelNetworkAgentConfig() { + val config = NetworkAgentConfig.Builder().apply { + setExplicitlySelected(true) + setLegacyType(ConnectivityManager.TYPE_ETHERNET) + setSubscriberId("MySubId") + setPartialConnectivityAcceptable(false) + setUnvalidatedConnectivityAcceptable(true) + }.build() + assertParcelSane(config, 9) + } +} diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java index 1c6920986318..a35fb407bca9 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java @@ -222,7 +222,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { @Override public Network getNetwork() { - return mNetworkAgent.network; + return mNetworkAgent.getNetwork(); } public void expectPreventReconnectReceived(long timeoutMs) { diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 141e68a07f56..4236b9d43e90 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -647,7 +647,7 @@ public class ConnectivityServiceTest { } }; - assertEquals(na.network.netId, nmNetworkCaptor.getValue().netId); + assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId); mNmCallbacks = nmCbCaptor.getValue(); mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor); |