Don't crash ConnectivityService if the network stack crashes.
When the network stack crashes, the system will rebind to it. Existing references are no longer useful (they just throw RemoteException) but if the system is still up, then the user can at least recover the situation by taking actions such as going into airplane mode, toggling wifi, etc. This CL stops ConnectivityService from crashing the system when it cannot talk to NetworkMonitor. This is arguably better than crashing the system, because crashing the system is disruptive and carries the serious risk of a bootloop from which it is not possible to recover. NetworkStackClient already contains code to crash the system when the network stack crashes. This change help ensure that if a crash occurs, it is the result of an explicit decision by that code instead of an unchecked exception in one of the callers of the network stack. Bug: 133725814 Test: builds, boots Test: atest FrameworksNetTests NetworkStackTests Change-Id: Ib9a15fececd8579fc5b139fe0341275a45512e0f
This commit is contained in:
@@ -91,6 +91,7 @@ import android.net.NetworkFactory;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.NetworkInfo.DetailedState;
|
||||
import android.net.NetworkMisc;
|
||||
import android.net.NetworkMonitorManager;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkQuotaInfo;
|
||||
import android.net.NetworkRequest;
|
||||
@@ -1784,8 +1785,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// callback from each caller type. Need to re-factor NetdEventListenerService to allow
|
||||
// multiple NetworkMonitor registrants.
|
||||
if (nai != null && nai.satisfies(mDefaultRequest)) {
|
||||
Binder.withCleanCallingIdentity(() ->
|
||||
nai.networkMonitor().notifyDnsResponse(returnCode));
|
||||
nai.networkMonitor().notifyDnsResponse(returnCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2852,11 +2852,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
|
||||
// schedule DNS resolutions. If a DNS resolution is required the
|
||||
// result will be sent back to us.
|
||||
try {
|
||||
nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
|
||||
|
||||
// With Private DNS bypass support, we can proceed to update the
|
||||
// Private DNS config immediately, even if we're in strict mode
|
||||
@@ -3022,11 +3018,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// Disable wakeup packet monitoring for each interface.
|
||||
wakeupModifyInterface(iface, nai.networkCapabilities, false);
|
||||
}
|
||||
try {
|
||||
nai.networkMonitor().notifyNetworkDisconnected();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
nai.networkMonitor().notifyNetworkDisconnected();
|
||||
mNetworkAgentInfos.remove(nai.messenger);
|
||||
nai.clatd.update();
|
||||
synchronized (mNetworkForNetId) {
|
||||
@@ -3439,11 +3431,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
//
|
||||
// TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
|
||||
// per network. Therefore, NetworkMonitor may still do https probe.
|
||||
try {
|
||||
nai.networkMonitor().setAcceptPartialConnectivity();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
nai.networkMonitor().setAcceptPartialConnectivity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3475,11 +3463,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
||||
if (nai == null) return;
|
||||
if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
|
||||
try {
|
||||
nai.networkMonitor().launchCaptivePortalApp();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
nai.networkMonitor().launchCaptivePortalApp();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3514,7 +3498,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appResponse(final int response) throws RemoteException {
|
||||
public void appResponse(final int response) {
|
||||
if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
|
||||
enforceSettingsPermission();
|
||||
}
|
||||
@@ -3524,16 +3508,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (nai == null) return;
|
||||
|
||||
// nai.networkMonitor() is thread-safe
|
||||
final INetworkMonitor nm = nai.networkMonitor();
|
||||
final NetworkMonitorManager nm = nai.networkMonitor();
|
||||
if (nm == null) return;
|
||||
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
nm.notifyCaptivePortalAppFinished(response);
|
||||
} finally {
|
||||
// Not using Binder.withCleanCallingIdentity() to keep the checked RemoteException
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
nm.notifyCaptivePortalAppFinished(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4104,11 +4081,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
nai.networkMonitor().forceReevaluation(uid);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
nai.networkMonitor().forceReevaluation(uid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5541,11 +5514,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// Start or stop DNS64 detection and 464xlat according to network state.
|
||||
networkAgent.clatd.update();
|
||||
notifyIfacesChangedForNetworkStats();
|
||||
try {
|
||||
networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
}
|
||||
networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
|
||||
if (networkAgent.everConnected) {
|
||||
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
|
||||
}
|
||||
@@ -6529,15 +6498,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// command must be sent after updating LinkProperties to maximize chances of
|
||||
// NetworkMonitor seeing the correct LinkProperties when starting.
|
||||
// TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
|
||||
try {
|
||||
if (networkAgent.networkMisc.acceptPartialConnectivity) {
|
||||
networkAgent.networkMonitor().setAcceptPartialConnectivity();
|
||||
}
|
||||
networkAgent.networkMonitor().notifyNetworkConnected(
|
||||
networkAgent.linkProperties, networkAgent.networkCapabilities);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowAsRuntimeException();
|
||||
if (networkAgent.networkMisc.acceptPartialConnectivity) {
|
||||
networkAgent.networkMonitor().setAcceptPartialConnectivity();
|
||||
}
|
||||
networkAgent.networkMonitor().notifyNetworkConnected(
|
||||
networkAgent.linkProperties, networkAgent.networkCapabilities);
|
||||
scheduleUnvalidatedPrompt(networkAgent);
|
||||
|
||||
// Whether a particular NetworkRequest listen should cause signal strength thresholds to
|
||||
|
||||
@@ -25,12 +25,12 @@ import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.NetworkMisc;
|
||||
import android.net.NetworkMonitorManager;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.NetworkState;
|
||||
import android.os.Handler;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
@@ -247,7 +247,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
public final Nat464Xlat clatd;
|
||||
|
||||
// Set after asynchronous creation of the NetworkMonitor.
|
||||
private volatile INetworkMonitor mNetworkMonitor;
|
||||
private volatile NetworkMonitorManager mNetworkMonitor;
|
||||
|
||||
private static final String TAG = ConnectivityService.class.getSimpleName();
|
||||
private static final boolean VDBG = false;
|
||||
@@ -278,7 +278,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
* Inform NetworkAgentInfo that a new NetworkMonitor was created.
|
||||
*/
|
||||
public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
|
||||
mNetworkMonitor = networkMonitor;
|
||||
mNetworkMonitor = new NetworkMonitorManager(networkMonitor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,13 +290,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
*/
|
||||
public void setNetworkCapabilities(NetworkCapabilities nc) {
|
||||
networkCapabilities = nc;
|
||||
final INetworkMonitor nm = mNetworkMonitor;
|
||||
final NetworkMonitorManager nm = mNetworkMonitor;
|
||||
if (nm != null) {
|
||||
try {
|
||||
nm.notifyNetworkCapabilitiesChanged(nc);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error notifying NetworkMonitor of updated NetworkCapabilities", e);
|
||||
}
|
||||
nm.notifyNetworkCapabilitiesChanged(nc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,11 +313,11 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the INetworkMonitor in this NetworkAgentInfo.
|
||||
* Get the NetworkMonitorManager in this NetworkAgentInfo.
|
||||
*
|
||||
* <p>This will be null before {@link #onNetworkMonitorCreated(INetworkMonitor)} is called.
|
||||
*/
|
||||
public INetworkMonitor networkMonitor() {
|
||||
public NetworkMonitorManager networkMonitor() {
|
||||
return mNetworkMonitor;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user