From 1d3acf930f1e5620b072d3f63c8368d887d57ade Mon Sep 17 00:00:00 2001 From: Jeremy Joslin Date: Wed, 3 Dec 2014 17:15:28 -0800 Subject: [PATCH] Don't send the same PendingIntent more than once. Fixing a bug where a NetworkRequest's PendingIntent can be sent more than once when networks are rematched before the intent completes. Added a small delay before removing the request to give the receiving client an opportunity to put in its own request. The delay value is configurable via Settings.Secure. Bug: 18614074 Change-Id: Iac7c5e5a04f42f2b6794e9e22349cc631bebeab7 --- .../android/server/ConnectivityService.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 348aa1bb5c..a110964c0e 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -215,6 +215,10 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE = 0; + // How long to delay to removal of a pending intent based request. + // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS + private final int mReleasePendingIntentDelayMs; + private PendingIntent mSampleIntervalElapsedIntent; // Set network sampling interval at 12 minutes, this way, even if the timers get @@ -645,6 +649,9 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Error setting defaultDns using " + dns); } + mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), + Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); + mContext = checkNotNull(context, "missing Context"); mNetd = checkNotNull(netManager, "missing INetworkManagementService"); mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager"); @@ -3409,6 +3416,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final NetworkRequest request; final PendingIntent mPendingIntent; + boolean mPendingIntentSent; private final IBinder mBinder; final int mPid; final int mUid; @@ -3530,6 +3538,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return networkRequest; } + private void releasePendingNetworkRequestWithDelay(PendingIntent operation) { + mHandler.sendMessageDelayed( + mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, + getCallingUid(), 0, operation), mReleasePendingIntentDelayMs); + } + @Override public void releasePendingNetworkRequest(PendingIntent operation) { mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT, @@ -3843,10 +3857,11 @@ public class ConnectivityService extends IConnectivityManager.Stub private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType) { - if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE) { + if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) { Intent intent = new Intent(); intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network); intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.request); + nri.mPendingIntentSent = true; sendIntent(nri.mPendingIntent, intent); } // else not handled @@ -3870,7 +3885,9 @@ public class ConnectivityService extends IConnectivityManager.Stub String resultData, Bundle resultExtras) { if (DBG) log("Finished sending " + pendingIntent); mPendingIntentWakeLock.release(); - releasePendingNetworkRequest(pendingIntent); + // Release with a delay so the receiving client has an opportunity to put in its + // own request. + releasePendingNetworkRequestWithDelay(pendingIntent); } private void callCallbackForRequest(NetworkRequestInfo nri,