Merge "Cache network capabilities." into rvc-qpr-dev
This commit is contained in:
@@ -22,6 +22,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
|||||||
|
|
||||||
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
|
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.app.job.JobInfo;
|
import android.app.job.JobInfo;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
@@ -86,9 +87,12 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final SparseArray<ArraySet<JobStatus>> mRequestedWhitelistJobs = new SparseArray<>();
|
private final SparseArray<ArraySet<JobStatus>> mRequestedWhitelistJobs = new SparseArray<>();
|
||||||
|
|
||||||
/** List of currently available networks. */
|
/**
|
||||||
|
* Set of currently available networks mapped to their latest network capabilities. Cache the
|
||||||
|
* latest capabilities to avoid unnecessary calls into ConnectivityManager.
|
||||||
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final ArraySet<Network> mAvailableNetworks = new ArraySet<>();
|
private final ArrayMap<Network, NetworkCapabilities> mAvailableNetworks = new ArrayMap<>();
|
||||||
|
|
||||||
private static final int MSG_DATA_SAVER_TOGGLED = 0;
|
private static final int MSG_DATA_SAVER_TOGGLED = 0;
|
||||||
private static final int MSG_UID_RULES_CHANGES = 1;
|
private static final int MSG_UID_RULES_CHANGES = 1;
|
||||||
@@ -165,9 +169,8 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
public boolean isNetworkAvailable(JobStatus job) {
|
public boolean isNetworkAvailable(JobStatus job) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (int i = 0; i < mAvailableNetworks.size(); ++i) {
|
for (int i = 0; i < mAvailableNetworks.size(); ++i) {
|
||||||
final Network network = mAvailableNetworks.valueAt(i);
|
final Network network = mAvailableNetworks.keyAt(i);
|
||||||
final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(
|
final NetworkCapabilities capabilities = mAvailableNetworks.valueAt(i);
|
||||||
network);
|
|
||||||
final boolean satisfied = isSatisfied(job, network, capabilities, mConstants);
|
final boolean satisfied = isSatisfied(job, network, capabilities, mConstants);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.v(TAG, "isNetworkAvailable(" + job + ") with network " + network
|
Slog.v(TAG, "isNetworkAvailable(" + job + ") with network " + network
|
||||||
@@ -427,9 +430,33 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private NetworkCapabilities getNetworkCapabilities(@Nullable Network network) {
|
||||||
|
if (network == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
synchronized (mLock) {
|
||||||
|
// There is technically a race here if the Network object is reused. This can happen
|
||||||
|
// only if that Network disconnects and the auto-incrementing network ID in
|
||||||
|
// ConnectivityService wraps. This should no longer be a concern if/when we only make
|
||||||
|
// use of asynchronous calls.
|
||||||
|
if (mAvailableNetworks.get(network) != null) {
|
||||||
|
return mAvailableNetworks.get(network);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should almost never happen because any time a new network connects, the
|
||||||
|
// NetworkCallback would populate mAvailableNetworks. However, it's currently necessary
|
||||||
|
// because we also call synchronous methods such as getActiveNetworkForUid.
|
||||||
|
// TODO(134978280): remove after switching to callback-based APIs
|
||||||
|
final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
|
||||||
|
mAvailableNetworks.put(network, capabilities);
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
|
private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
|
||||||
final Network network = mConnManager.getActiveNetworkForUid(jobStatus.getSourceUid());
|
final Network network = mConnManager.getActiveNetworkForUid(jobStatus.getSourceUid());
|
||||||
final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
|
final NetworkCapabilities capabilities = getNetworkCapabilities(network);
|
||||||
return updateConstraintsSatisfied(jobStatus, network, capabilities);
|
return updateConstraintsSatisfied(jobStatus, network, capabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,19 +497,13 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
*/
|
*/
|
||||||
private void updateTrackedJobs(int filterUid, Network filterNetwork) {
|
private void updateTrackedJobs(int filterUid, Network filterNetwork) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
// Since this is a really hot codepath, temporarily cache any
|
|
||||||
// answers that we get from ConnectivityManager.
|
|
||||||
final ArrayMap<Network, NetworkCapabilities> networkToCapabilities = new ArrayMap<>();
|
|
||||||
|
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if (filterUid == -1) {
|
if (filterUid == -1) {
|
||||||
for (int i = mTrackedJobs.size() - 1; i >= 0; i--) {
|
for (int i = mTrackedJobs.size() - 1; i >= 0; i--) {
|
||||||
changed |= updateTrackedJobsLocked(mTrackedJobs.valueAt(i),
|
changed |= updateTrackedJobsLocked(mTrackedJobs.valueAt(i), filterNetwork);
|
||||||
filterNetwork, networkToCapabilities);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
changed = updateTrackedJobsLocked(mTrackedJobs.get(filterUid),
|
changed = updateTrackedJobsLocked(mTrackedJobs.get(filterUid), filterNetwork);
|
||||||
filterNetwork, networkToCapabilities);
|
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
mStateChangedListener.onControllerStateChanged();
|
mStateChangedListener.onControllerStateChanged();
|
||||||
@@ -490,18 +511,13 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork,
|
private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork) {
|
||||||
ArrayMap<Network, NetworkCapabilities> networkToCapabilities) {
|
|
||||||
if (jobs == null || jobs.size() == 0) {
|
if (jobs == null || jobs.size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Network network = mConnManager.getActiveNetworkForUid(jobs.valueAt(0).getSourceUid());
|
final Network network = mConnManager.getActiveNetworkForUid(jobs.valueAt(0).getSourceUid());
|
||||||
NetworkCapabilities capabilities = networkToCapabilities.get(network);
|
final NetworkCapabilities capabilities = getNetworkCapabilities(network);
|
||||||
if (capabilities == null) {
|
|
||||||
capabilities = mConnManager.getNetworkCapabilities(network);
|
|
||||||
networkToCapabilities.put(network, capabilities);
|
|
||||||
}
|
|
||||||
final boolean networkMatch = (filterNetwork == null
|
final boolean networkMatch = (filterNetwork == null
|
||||||
|| Objects.equals(filterNetwork, network));
|
|| Objects.equals(filterNetwork, network));
|
||||||
|
|
||||||
@@ -544,9 +560,9 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
@Override
|
@Override
|
||||||
public void onAvailable(Network network) {
|
public void onAvailable(Network network) {
|
||||||
if (DEBUG) Slog.v(TAG, "onAvailable: " + network);
|
if (DEBUG) Slog.v(TAG, "onAvailable: " + network);
|
||||||
synchronized (mLock) {
|
// Documentation says not to call getNetworkCapabilities here but wait for
|
||||||
mAvailableNetworks.add(network);
|
// onCapabilitiesChanged instead. onCapabilitiesChanged should be called immediately
|
||||||
}
|
// after this, so no need to update mAvailableNetworks here.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -554,6 +570,9 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.v(TAG, "onCapabilitiesChanged: " + network);
|
Slog.v(TAG, "onCapabilitiesChanged: " + network);
|
||||||
}
|
}
|
||||||
|
synchronized (mLock) {
|
||||||
|
mAvailableNetworks.put(network, capabilities);
|
||||||
|
}
|
||||||
updateTrackedJobs(-1, network);
|
updateTrackedJobs(-1, network);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,6 +649,8 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
pw.println("Available networks:");
|
pw.println("Available networks:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
for (int i = 0; i < mAvailableNetworks.size(); i++) {
|
for (int i = 0; i < mAvailableNetworks.size(); i++) {
|
||||||
|
pw.print(mAvailableNetworks.keyAt(i));
|
||||||
|
pw.print(": ");
|
||||||
pw.println(mAvailableNetworks.valueAt(i));
|
pw.println(mAvailableNetworks.valueAt(i));
|
||||||
}
|
}
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
@@ -667,7 +688,7 @@ public final class ConnectivityController extends RestrictingController implemen
|
|||||||
mRequestedWhitelistJobs.keyAt(i));
|
mRequestedWhitelistJobs.keyAt(i));
|
||||||
}
|
}
|
||||||
for (int i = 0; i < mAvailableNetworks.size(); i++) {
|
for (int i = 0; i < mAvailableNetworks.size(); i++) {
|
||||||
Network network = mAvailableNetworks.valueAt(i);
|
Network network = mAvailableNetworks.keyAt(i);
|
||||||
if (network != null) {
|
if (network != null) {
|
||||||
network.dumpDebug(proto,
|
network.dumpDebug(proto,
|
||||||
StateControllerProto.ConnectivityController.AVAILABLE_NETWORKS);
|
StateControllerProto.ConnectivityController.AVAILABLE_NETWORKS);
|
||||||
|
|||||||
Reference in New Issue
Block a user