diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 5167570fc0..4d4dacf24a 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -330,9 +330,9 @@ import com.android.net.module.util.InterfaceParams; import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult; import com.android.net.module.util.LinkPropertiesUtils.CompareResult; import com.android.net.module.util.LocationPermissionChecker; -import com.android.net.module.util.RoutingCoordinatorService; import com.android.net.module.util.PerUidCounter; import com.android.net.module.util.PermissionUtils; +import com.android.net.module.util.RoutingCoordinatorService; import com.android.net.module.util.TcUtils; import com.android.net.module.util.netlink.InetDiagMessage; import com.android.networkstack.apishim.BroadcastOptionsShimImpl; @@ -7779,6 +7779,11 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + boolean isCallbackOverridden(int callbackId) { + return !mUseDeclaredMethodsForCallbacksEnabled + || (mDeclaredMethodsFlags & (1 << callbackId)) != 0; + } + boolean hasHigherOrderThan(@NonNull final NetworkRequestInfo target) { // Compare two preference orders. return mPreferenceOrder < target.mPreferenceOrder; @@ -10248,6 +10253,18 @@ public class ConnectivityService extends IConnectivityManager.Stub return new LocalNetworkInfo.Builder().setUpstreamNetwork(upstream).build(); } + private Bundle makeCommonBundleForCallback(@NonNull final NetworkRequestInfo nri, + @Nullable Network network) { + final Bundle bundle = new Bundle(); + // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. + // TODO: check if defensive copies of data is needed. + putParcelable(bundle, nri.getNetworkRequestForCallback()); + if (network != null) { + putParcelable(bundle, network); + } + return bundle; + } + // networkAgent is only allowed to be null if notificationType is // CALLBACK_UNAVAIL. This is because UNAVAIL is about no network being // available, while all other cases are about some particular network. @@ -10260,22 +10277,17 @@ public class ConnectivityService extends IConnectivityManager.Stub // are Type.LISTEN, but should not have NetworkCallbacks invoked. return; } - if (mUseDeclaredMethodsForCallbacksEnabled - && (nri.mDeclaredMethodsFlags & (1 << notificationType)) == 0) { + if (!nri.isCallbackOverridden(notificationType)) { // No need to send the notification as the recipient method is not overridden return; } - final Bundle bundle = new Bundle(); - // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects. - // TODO: check if defensive copies of data is needed. - final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback(); - putParcelable(bundle, nrForCallback); - Message msg = Message.obtain(); - if (notificationType != CALLBACK_UNAVAIL) { - putParcelable(bundle, networkAgent.network); - } + final Network bundleNetwork = notificationType == CALLBACK_UNAVAIL + ? null + : networkAgent.network; + final Bundle bundle = makeCommonBundleForCallback(nri, bundleNetwork); final boolean includeLocationSensitiveInfo = (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0; + final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback(); switch (notificationType) { case CALLBACK_AVAILABLE: { final NetworkCapabilities nc = @@ -10292,12 +10304,6 @@ public class ConnectivityService extends IConnectivityManager.Stub // method here. bundle.putParcelable(LocalNetworkInfo.class.getSimpleName(), localNetworkInfoForNai(networkAgent)); - // For this notification, arg1 contains the blocked status. - msg.arg1 = arg1; - break; - } - case CALLBACK_LOSING: { - msg.arg1 = arg1; break; } case CALLBACK_CAP_CHANGED: { @@ -10320,7 +10326,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } case CALLBACK_BLK_CHANGED: { maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1); - msg.arg1 = arg1; break; } case CALLBACK_LOCAL_NETWORK_INFO_CHANGED: { @@ -10332,17 +10337,26 @@ public class ConnectivityService extends IConnectivityManager.Stub break; } } + callCallbackForRequest(nri, notificationType, bundle, arg1); + } + + private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri, int notificationType, + Bundle bundle, int arg1) { + Message msg = Message.obtain(); + msg.arg1 = arg1; msg.what = notificationType; msg.setData(bundle); try { if (VDBG) { String notification = ConnectivityManager.getCallbackName(notificationType); - log("sending notification " + notification + " for " + nrForCallback); + log("sending notification " + notification + " for " + + nri.getNetworkRequestForCallback()); } nri.mMessenger.send(msg); } catch (RemoteException e) { // may occur naturally in the race of binder death. - loge("RemoteException caught trying to send a callback msg for " + nrForCallback); + loge("RemoteException caught trying to send a callback msg for " + + nri.getNetworkRequestForCallback()); } } @@ -11431,11 +11445,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } - final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE); - final boolean metered = nai.networkCapabilities.isMetered(); - final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges); - callCallbackForRequest(nri, nai, CALLBACK_AVAILABLE, - getBlockedState(nri.mAsUid, blockedReasons, metered, vpnBlocked)); + callCallbackForRequest(nri, nai, CALLBACK_AVAILABLE, getBlockedState(nai, nri.mAsUid)); } // Notify the requests on this NAI that the network is now lingered. @@ -11465,6 +11475,13 @@ public class ConnectivityService extends IConnectivityManager.Stub : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN; } + private int getBlockedState(@NonNull NetworkAgentInfo nai, int uid) { + final boolean metered = nai.networkCapabilities.isMetered(); + final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges); + final int blockedReasons = mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE); + return getBlockedState(uid, blockedReasons, metered, vpnBlocked); + } + private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) { if (blockedReasons == BLOCKED_REASON_NONE) { mUidBlockedReasons.delete(uid);