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:
Robert Greenwalt
2010-06-15 12:19:37 -07:00
parent 7f132d9680
commit 93dc104209
3 changed files with 87 additions and 5 deletions

View File

@@ -524,5 +524,20 @@ public class ConnectivityManager
} catch (RemoteException e) {
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;
}
}
}

View File

@@ -72,4 +72,6 @@ interface IConnectivityManager
String[] getTetherableUsbRegexs();
String[] getTetherableWifiRegexs();
void requestNetworkTransitionWakelock(in String forWhom);
}

View File

@@ -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,9 +1170,17 @@ 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;
}
}