From bce963be7ab073b77d5fac4809e6ba5e6359214e Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Thu, 30 Apr 2020 17:13:22 -0700 Subject: Add a busy-wakelock to IkeSessionStateMachine This change adds a wakelock to ensure that the device does not go to sleep in the middle of an exchange. Otherwise, the IKE session will be left in a non-deterministic state Bug: 152236790 Test: FrameworkIkeTests passing Change-Id: Ia57bb27ac75891cb47237596580792d58bfaf693 Merged-In: Ia57bb27ac75891cb47237596580792d58bfaf693 --- .../net/ipsec/ike/IkeLocalRequestScheduler.java | 7 +++++-- .../internal/net/ipsec/ike/IkeSessionStateMachine.java | 18 +++++++++++++++++- tests/iketests/AndroidManifest.xml | 2 ++ .../net/ipsec/ike/IkeSessionStateMachineTest.java | 12 ++++++++++++ .../internal/net/ipsec/ike/IkeSessionTestBase.java | 12 ++++++++++++ 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java b/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java index e86df232..f8008fbe 100644 --- a/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java +++ b/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java @@ -64,15 +64,18 @@ public final class IkeLocalRequestScheduler { * Notifies the scheduler that the caller is ready for a new procedure * *

Synchronously triggers the call to onNewProcedureReady. + * + * @return whether or not a new procedure was scheduled. */ - public void readyForNextProcedure() { + public boolean readyForNextProcedure() { while (!mRequestQueue.isEmpty()) { LocalRequest request = mRequestQueue.poll(); if (!request.isCancelled()) { mConsumer.onNewProcedureReady(request); - return; + return true; } } + return false; } /** diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java index 5fbcda89..46517159 100644 --- a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java +++ b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java @@ -22,6 +22,7 @@ import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_I import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS; import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; import static android.net.ipsec.ike.exceptions.IkeProtocolException.ErrorType; +import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_TYPE_REPLY; import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL; @@ -74,6 +75,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.PowerManager; import android.os.SystemClock; import android.system.ErrnoException; import android.system.Os; @@ -368,6 +370,9 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { */ private final IpSecSpiGenerator mIpSecSpiGenerator; + /** Ensures that the system does not go to sleep in the middle of an exchange. */ + private final PowerManager.WakeLock mBusyWakeLock; + @VisibleForTesting @GuardedBy("mChildCbToSessions") final HashMap mChildCbToSessions = @@ -495,6 +500,10 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { // callback instance in the future } + PowerManager pm = context.getSystemService(PowerManager.class); + mBusyWakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, TAG + "mBusyWakeLock"); + mBusyWakeLock.setReferenceCounted(false); + mIkeSessionId = sIkeSessionIdGenerator.getAndIncrement(); sIkeAlarmReceiver.registerIkeSession(mIkeSessionId, getHandler()); @@ -551,6 +560,7 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { sendMessageAtFrontOfQueue(CMD_EXECUTE_LOCAL_REQ, localReq); }); + mBusyWakeLock.acquire(); start(); } @@ -963,6 +973,8 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { } // TODO: Remove the stored ikeSessionCallback } + + mBusyWakeLock.release(); } private void closeAllSaRecords(boolean expectSaClosed) { @@ -1065,7 +1077,9 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { @Override public void enterState() { - mScheduler.readyForNextProcedure(); + if (!mScheduler.readyForNextProcedure()) { + mBusyWakeLock.release(); + } if (mDpdIntent == null) { long remoteIkeSpi = mCurrentIkeSaRecord.getRemoteSpi(); @@ -1097,6 +1111,8 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { // #exitState is guaranteed to be invoked when quit() or quitNow() is called mAlarmManager.cancel(mDpdIntent); logd("DPD Alarm canceled"); + + mBusyWakeLock.acquire(); } @Override diff --git a/tests/iketests/AndroidManifest.xml b/tests/iketests/AndroidManifest.xml index 0abddbaa..bdcfdb71 100644 --- a/tests/iketests/AndroidManifest.xml +++ b/tests/iketests/AndroidManifest.xml @@ -22,6 +22,8 @@ + +