Make NetworkAgent stop subclassing Handler.

Subclassing Handler is not appropriate for a system API because
it is an implementation detail and allows users of this class to
post messages to the handler in ways that allow inappropriate
access to internals that aren't part of the API contract.

Also fix some lint errors.

Test: builds
Bug: 138306002
Change-Id: I79478ceff6bbcae879d1025098d177de0d15dbee
This commit is contained in:
Lorenzo Colitti
2020-01-12 20:27:32 +09:00
parent 8ae3471952
commit c58ecd5f33

View File

@@ -43,11 +43,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
* *
* @hide * @hide
*/ */
public abstract class NetworkAgent extends Handler { public abstract class NetworkAgent {
// Guaranteed to be valid (not NETID_UNSET), otherwise registerNetworkAgent() would have thrown // Guaranteed to be valid (not NETID_UNSET), otherwise registerNetworkAgent() would have thrown
// an exception. // an exception.
public final int netId; public final int netId;
private final Handler mHandler;
private volatile AsyncChannel mAsyncChannel; private volatile AsyncChannel mAsyncChannel;
private final String LOG_TAG; private final String LOG_TAG;
private static final boolean DBG = true; private static final boolean DBG = true;
@@ -234,7 +235,7 @@ public abstract class NetworkAgent extends Handler {
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc, NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc,
int providerId) { int providerId) {
super(looper); mHandler = new NetworkAgentHandler(looper);
LOG_TAG = logTag; LOG_TAG = logTag;
mContext = context; mContext = context;
mProviderId = providerId; mProviderId = providerId;
@@ -245,116 +246,124 @@ public abstract class NetworkAgent extends Handler {
if (VDBG) log("Registering NetworkAgent"); if (VDBG) log("Registering NetworkAgent");
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService( ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
Context.CONNECTIVITY_SERVICE); Context.CONNECTIVITY_SERVICE);
netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni), netId = cm.registerNetworkAgent(new Messenger(mHandler), new NetworkInfo(ni),
new LinkProperties(lp), new NetworkCapabilities(nc), score, misc, providerId); new LinkProperties(lp), new NetworkCapabilities(nc), score, misc,
providerId);
} }
@Override private class NetworkAgentHandler extends Handler {
public void handleMessage(Message msg) { NetworkAgentHandler(Looper looper) {
switch (msg.what) { super(looper);
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { }
if (mAsyncChannel != null) {
log("Received new connection while already connected!");
} else {
if (VDBG) log("NetworkAgent fully connected");
AsyncChannel ac = new AsyncChannel();
ac.connected(null, this, msg.replyTo);
ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
AsyncChannel.STATUS_SUCCESSFUL);
synchronized (mPreConnectedQueue) {
mAsyncChannel = ac;
for (Message m : mPreConnectedQueue) {
ac.sendMessage(m);
}
mPreConnectedQueue.clear();
}
}
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
if (VDBG) log("CMD_CHANNEL_DISCONNECT");
if (mAsyncChannel != null) mAsyncChannel.disconnect();
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
if (DBG) log("NetworkAgent channel lost");
// let the client know CS is done with us.
unwanted();
synchronized (mPreConnectedQueue) {
mAsyncChannel = null;
}
break;
}
case CMD_SUSPECT_BAD: {
log("Unhandled Message " + msg);
break;
}
case CMD_REQUEST_BANDWIDTH_UPDATE: {
long currentTimeMs = System.currentTimeMillis();
if (VDBG) {
log("CMD_REQUEST_BANDWIDTH_UPDATE request received.");
}
if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
mPollLceScheduled = false;
if (mPollLcePending.getAndSet(true) == false) {
pollLceData();
}
} else {
// deliver the request at a later time rather than discard it completely.
if (!mPollLceScheduled) {
long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS -
currentTimeMs + 1;
mPollLceScheduled = sendEmptyMessageDelayed(
CMD_REQUEST_BANDWIDTH_UPDATE, waitTime);
}
}
break;
}
case CMD_REPORT_NETWORK_STATUS: {
String redirectUrl = ((Bundle)msg.obj).getString(REDIRECT_URL_KEY);
if (VDBG) {
log("CMD_REPORT_NETWORK_STATUS(" +
(msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ") + redirectUrl);
}
networkStatus(msg.arg1, redirectUrl);
break;
}
case CMD_SAVE_ACCEPT_UNVALIDATED: {
saveAcceptUnvalidated(msg.arg1 != 0);
break;
}
case CMD_START_SOCKET_KEEPALIVE: {
startSocketKeepalive(msg);
break;
}
case CMD_STOP_SOCKET_KEEPALIVE: {
stopSocketKeepalive(msg);
break;
}
case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: { @Override
ArrayList<Integer> thresholds = public void handleMessage(Message msg) {
((Bundle) msg.obj).getIntegerArrayList("thresholds"); switch (msg.what) {
// TODO: Change signal strength thresholds API to use an ArrayList<Integer> case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
// rather than convert to int[]. if (mAsyncChannel != null) {
int[] intThresholds = new int[(thresholds != null) ? thresholds.size() : 0]; log("Received new connection while already connected!");
for (int i = 0; i < intThresholds.length; i++) { } else {
intThresholds[i] = thresholds.get(i); if (VDBG) log("NetworkAgent fully connected");
AsyncChannel ac = new AsyncChannel();
ac.connected(null, this, msg.replyTo);
ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
AsyncChannel.STATUS_SUCCESSFUL);
synchronized (mPreConnectedQueue) {
mAsyncChannel = ac;
for (Message m : mPreConnectedQueue) {
ac.sendMessage(m);
}
mPreConnectedQueue.clear();
}
}
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
if (VDBG) log("CMD_CHANNEL_DISCONNECT");
if (mAsyncChannel != null) mAsyncChannel.disconnect();
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
if (DBG) log("NetworkAgent channel lost");
// let the client know CS is done with us.
unwanted();
synchronized (mPreConnectedQueue) {
mAsyncChannel = null;
}
break;
}
case CMD_SUSPECT_BAD: {
log("Unhandled Message " + msg);
break;
}
case CMD_REQUEST_BANDWIDTH_UPDATE: {
long currentTimeMs = System.currentTimeMillis();
if (VDBG) {
log("CMD_REQUEST_BANDWIDTH_UPDATE request received.");
}
if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
mPollLceScheduled = false;
if (!mPollLcePending.getAndSet(true)) {
pollLceData();
}
} else {
// deliver the request at a later time rather than discard it completely.
if (!mPollLceScheduled) {
long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS
- currentTimeMs + 1;
mPollLceScheduled = sendEmptyMessageDelayed(
CMD_REQUEST_BANDWIDTH_UPDATE, waitTime);
}
}
break;
}
case CMD_REPORT_NETWORK_STATUS: {
String redirectUrl = ((Bundle) msg.obj).getString(REDIRECT_URL_KEY);
if (VDBG) {
log("CMD_REPORT_NETWORK_STATUS("
+ (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ")
+ redirectUrl);
}
networkStatus(msg.arg1, redirectUrl);
break;
}
case CMD_SAVE_ACCEPT_UNVALIDATED: {
saveAcceptUnvalidated(msg.arg1 != 0);
break;
}
case CMD_START_SOCKET_KEEPALIVE: {
startSocketKeepalive(msg);
break;
}
case CMD_STOP_SOCKET_KEEPALIVE: {
stopSocketKeepalive(msg);
break;
}
case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: {
ArrayList<Integer> thresholds =
((Bundle) msg.obj).getIntegerArrayList("thresholds");
// TODO: Change signal strength thresholds API to use an ArrayList<Integer>
// rather than convert to int[].
int[] intThresholds = new int[(thresholds != null) ? thresholds.size() : 0];
for (int i = 0; i < intThresholds.length; i++) {
intThresholds[i] = thresholds.get(i);
}
setSignalStrengthThresholds(intThresholds);
break;
}
case CMD_PREVENT_AUTOMATIC_RECONNECT: {
preventAutomaticReconnect();
break;
}
case CMD_ADD_KEEPALIVE_PACKET_FILTER: {
addKeepalivePacketFilter(msg);
break;
}
case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: {
removeKeepalivePacketFilter(msg);
break;
} }
setSignalStrengthThresholds(intThresholds);
break;
}
case CMD_PREVENT_AUTOMATIC_RECONNECT: {
preventAutomaticReconnect();
break;
}
case CMD_ADD_KEEPALIVE_PACKET_FILTER: {
addKeepalivePacketFilter(msg);
break;
}
case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: {
removeKeepalivePacketFilter(msg);
break;
} }
} }
} }