use of com.android.server.connectivity.NetworkAgentInfo in project android_frameworks_base by crdroidandroid.
the class ConnectivityService method rematchAllNetworksAndRequests.
/**
* Attempt to rematch all Networks with NetworkRequests. This may result in Networks
* being disconnected.
* @param changed If only one Network's score or capabilities have been modified since the last
* time this function was called, pass this Network in this argument, otherwise pass
* null.
* @param oldScore If only one Network has been changed but its NetworkCapabilities have not
* changed, pass in the Network's score (from getCurrentScore()) prior to the change via
* this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if
* {@code changed} is {@code null}. This is because NetworkCapabilities influence a
* network's score.
*/
private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) {
// TODO: This may get slow. The "changed" parameter is provided for future optimization
// to avoid the slowness. It is not simply enough to process just "changed", for
// example in the case where "changed"'s score decreases and another network should begin
// satifying a NetworkRequest that "changed" currently satisfies.
// Optimization: Only reprocess "changed" if its score improved. This is safe because it
// can only add more NetworkRequests satisfied by "changed", and this is exactly what
// rematchNetworkAndRequests() handles.
final long now = SystemClock.elapsedRealtime();
if (changed != null && oldScore < changed.getCurrentScore()) {
rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now);
} else {
final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray(new NetworkAgentInfo[mNetworkAgentInfos.size()]);
// Rematch higher scoring networks first to prevent requests first matching a lower
// scoring network and then a higher scoring network, which could produce multiple
// callbacks and inadvertently unlinger networks.
Arrays.sort(nais);
for (NetworkAgentInfo nai : nais) {
rematchNetworkAndRequests(nai, // rematched.
(nai != nais[nais.length - 1]) ? ReapUnvalidatedNetworks.DONT_REAP : ReapUnvalidatedNetworks.REAP, now);
}
}
}
use of com.android.server.connectivity.NetworkAgentInfo in project android_frameworks_base by crdroidandroid.
the class ConnectivityService method handleReleaseNetworkRequest.
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
final NetworkRequestInfo nri = getNriForAppRequest(request, callingUid, "release NetworkRequest");
if (nri == null)
return;
if (VDBG || (DBG && nri.request.isRequest()))
log("releasing " + request);
nri.unlinkDeathRecipient();
mNetworkRequests.remove(request);
synchronized (mUidToNetworkRequestCount) {
int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
if (requests < 1) {
Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " + nri.mUid);
} else if (requests == 1) {
mUidToNetworkRequestCount.removeAt(mUidToNetworkRequestCount.indexOfKey(nri.mUid));
} else {
mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
}
}
mNetworkRequestInfoLogs.log("RELEASE " + nri);
if (nri.request.isRequest()) {
boolean wasKept = false;
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
if (nai != null) {
boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
nai.removeRequest(nri.request.requestId);
if (VDBG) {
log(" Removing from current network " + nai.name() + ", leaving " + nai.numNetworkRequests() + " requests.");
}
// If there are still lingered requests on this network, don't tear it down,
// but resume lingering instead.
updateLingerState(nai, SystemClock.elapsedRealtime());
if (unneeded(nai, UnneededFor.TEARDOWN)) {
if (DBG)
log("no live requests for " + nai.name() + "; disconnecting");
teardownUnneededNetwork(nai);
} else {
wasKept = true;
}
mNetworkForRequestId.remove(nri.request.requestId);
if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
// Went from foreground to background.
updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
}
}
// network satisfying it, so this loop is wasteful
for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) {
if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) {
Slog.wtf(TAG, "Request " + nri.request + " satisfied by " + otherNai.name() + ", but mNetworkAgentInfos says " + (nai != null ? nai.name() : "null"));
}
}
// phantom disconnect for this type.
if (nri.request.legacyType != TYPE_NONE && nai != null) {
boolean doRemove = true;
if (wasKept) {
// same legacy type - if so, don't remove the nai
for (int i = 0; i < nai.numNetworkRequests(); i++) {
NetworkRequest otherRequest = nai.requestAt(i);
if (otherRequest.legacyType == nri.request.legacyType && otherRequest.isRequest()) {
if (DBG)
log(" still have other legacy request - leaving");
doRemove = false;
}
}
}
if (doRemove) {
mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
}
}
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, nri.request);
}
} else {
// if this listen request applies and remove it.
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
nai.removeRequest(nri.request.requestId);
if (nri.request.networkCapabilities.hasSignalStrength() && nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
}
}
}
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED, 0);
}
use of com.android.server.connectivity.NetworkAgentInfo in project android_frameworks_base by crdroidandroid.
the class ConnectivityService method updateDnses.
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
// no updating necessary
return;
}
Collection<InetAddress> dnses = newLp.getDnsServers();
if (DBG)
log("Setting DNS servers for network " + netId + " to " + dnses);
try {
mNetd.setDnsConfigurationForNetwork(netId, NetworkUtils.makeStrings(dnses), newLp.getDomains());
} catch (Exception e) {
loge("Exception in setDnsConfigurationForNetwork: " + e);
}
final NetworkAgentInfo defaultNai = getDefaultNetwork();
if (defaultNai != null && defaultNai.network.netId == netId) {
setDefaultDnsSystemProperties(dnses);
}
flushVmDnsCache();
}
use of com.android.server.connectivity.NetworkAgentInfo in project android_frameworks_base by crdroidandroid.
the class ConnectivityService method handleRegisterNetworkRequest.
private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
mNetworkRequests.put(nri.request, nri);
mNetworkRequestInfoLogs.log("REGISTER " + nri);
if (nri.request.isListen()) {
for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
if (nri.request.networkCapabilities.hasSignalStrength() && network.satisfiesImmutableCapabilitiesOf(nri.request)) {
updateSignalStrengthThresholds(network, "REGISTER", nri.request);
}
}
}
rematchAllNetworksAndRequests(null, 0);
if (nri.request.isRequest() && mNetworkForRequestId.get(nri.request.requestId) == null) {
sendUpdatedScoreToFactories(nri.request, 0);
}
}
use of com.android.server.connectivity.NetworkAgentInfo in project android_frameworks_base by crdroidandroid.
the class ConnectivityService method reportNetworkConnectivity.
@Override
public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
enforceAccessPermission();
enforceInternetPermission();
// TODO: execute this logic on ConnectivityService handler.
final NetworkAgentInfo nai;
if (network == null) {
nai = getDefaultNetwork();
} else {
nai = getNetworkAgentInfoForNetwork(network);
}
if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
return;
}
// Revalidate if the app report does not match our current validated state.
if (hasConnectivity == nai.lastValidated) {
return;
}
final int uid = Binder.getCallingUid();
if (DBG) {
log("reportNetworkConnectivity(" + nai.network.netId + ", " + hasConnectivity + ") by " + uid);
}
// rematchNetworkAndRequests() which is not meant to work on such networks.
if (!nai.everConnected) {
return;
}
LinkProperties lp = getLinkProperties(nai);
if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) {
return;
}
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid);
}
Aggregations