Move the net transition wakelock to ConnService.
When the default network goes down we lose the wake-on-incoming-data capability until the new net is brought up and apps rebuild their connections. We fixed this in Wifi, but it's a general connectivity issue, not a wifi issue so moving the mechanism to connecitivty so other networks can use it. bug:2734419 Change-Id: I39b5d825eb6b548bd9bb8f179b89254f4db53147
This commit is contained in:
@@ -525,4 +525,19 @@ public class ConnectivityManager
|
||||
return TETHER_ERROR_SERVICE_UNAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the device stays awake until we connect with the next network
|
||||
* @param forWhome The name of the network going down for logging purposes
|
||||
* @return {@code true} on success, {@code false} on failure
|
||||
* {@hide}
|
||||
*/
|
||||
public boolean requestNetworkTransitionWakelock(String forWhom) {
|
||||
try {
|
||||
mService.requestNetworkTransitionWakelock(forWhom);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,4 +72,6 @@ interface IConnectivityManager
|
||||
String[] getTetherableUsbRegexs();
|
||||
|
||||
String[] getTetherableWifiRegexs();
|
||||
|
||||
void requestNetworkTransitionWakelock(in String forWhom);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemProperties;
|
||||
@@ -67,7 +68,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
|
||||
"android.telephony.apn-restore";
|
||||
|
||||
|
||||
private Tethering mTethering;
|
||||
private boolean mTetheringConfigValid = false;
|
||||
|
||||
@@ -107,6 +107,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
private boolean mSystemReady;
|
||||
private Intent mInitialBroadcast;
|
||||
|
||||
private PowerManager.WakeLock mNetTransitionWakeLock;
|
||||
private String mNetTransitionWakeLockCausedBy = "";
|
||||
private int mNetTransitionWakeLockSerialNumber;
|
||||
private int mNetTransitionWakeLockTimeout;
|
||||
|
||||
private static class NetworkAttributes {
|
||||
/**
|
||||
* Class for holding settings read from resources.
|
||||
@@ -197,6 +202,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
}
|
||||
|
||||
mContext = context;
|
||||
|
||||
PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
|
||||
mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||
mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_networkTransitionTimeout);
|
||||
|
||||
mNetTrackers = new NetworkStateTracker[
|
||||
ConnectivityManager.MAX_NETWORK_TYPE+1];
|
||||
mHandler = new MyHandler();
|
||||
@@ -878,6 +889,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
"ConnectivityService");
|
||||
}
|
||||
|
||||
private void enforceConnectivityInternalPermission() {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.CONNECTIVITY_INTERNAL,
|
||||
"ConnectivityService");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a {@code DISCONNECTED} event. If this pertains to the non-active
|
||||
* network, we ignore it. If it is for the active network, we send out a
|
||||
@@ -1153,10 +1170,18 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
Slog.e(TAG, "Network declined teardown request");
|
||||
return;
|
||||
}
|
||||
if (isFailover) {
|
||||
otherNet.releaseWakeLock();
|
||||
}
|
||||
}
|
||||
synchronized (ConnectivityService.this) {
|
||||
// have a new default network, release the transition wakelock in a second
|
||||
// if it's held. The second pause is to allow apps to reconnect over the
|
||||
// new network
|
||||
if (mNetTransitionWakeLock.isHeld()) {
|
||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(
|
||||
NetworkStateTracker.EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
|
||||
mNetTransitionWakeLockSerialNumber, 0),
|
||||
1000);
|
||||
}
|
||||
}
|
||||
mActiveDefaultNetwork = type;
|
||||
}
|
||||
@@ -1546,6 +1571,13 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
}
|
||||
pw.println();
|
||||
|
||||
synchronized (this) {
|
||||
pw.println("NetworkTranstionWakeLock is currently " +
|
||||
(mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
|
||||
pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
|
||||
}
|
||||
pw.println();
|
||||
|
||||
mTethering.dump(fd, pw, args);
|
||||
}
|
||||
|
||||
@@ -1637,6 +1669,20 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
FeatureUser u = (FeatureUser)msg.obj;
|
||||
u.expire();
|
||||
break;
|
||||
case NetworkStateTracker.EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
|
||||
String causedBy = null;
|
||||
synchronized (ConnectivityService.this) {
|
||||
if (msg.arg1 == mNetTransitionWakeLockSerialNumber &&
|
||||
mNetTransitionWakeLock.isHeld()) {
|
||||
mNetTransitionWakeLock.release();
|
||||
causedBy = mNetTransitionWakeLockCausedBy;
|
||||
}
|
||||
}
|
||||
if (causedBy != null) {
|
||||
Slog.d(TAG, "NetTransition Wakelock for " +
|
||||
causedBy + " released by timeout");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1720,4 +1766,23 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
|
||||
return tetherEnabledInSettings && mTetheringConfigValid;
|
||||
}
|
||||
|
||||
// An API NetworkStateTrackers can call when they lose their network.
|
||||
// This will automatically be cleared after X seconds or a network becomes CONNECTED,
|
||||
// whichever happens first. The timer is started by the first caller and not
|
||||
// restarted by subsequent callers.
|
||||
public void requestNetworkTransitionWakelock(String forWhom) {
|
||||
enforceConnectivityInternalPermission();
|
||||
synchronized (this) {
|
||||
if (mNetTransitionWakeLock.isHeld()) return;
|
||||
mNetTransitionWakeLockSerialNumber++;
|
||||
mNetTransitionWakeLock.acquire();
|
||||
mNetTransitionWakeLockCausedBy = forWhom;
|
||||
}
|
||||
mHandler.sendMessageDelayed(mHandler.obtainMessage(
|
||||
NetworkStateTracker.EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
|
||||
mNetTransitionWakeLockSerialNumber, 0),
|
||||
mNetTransitionWakeLockTimeout);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user