diff options
author | evitayan <evitayan@google.com> | 2020-03-19 18:28:44 -0700 |
---|---|---|
committer | evitayan <evitayan@google.com> | 2020-03-20 19:09:29 -0700 |
commit | c1b5a6e57fd96df0ff8bcad4f18affd67c94e5a6 (patch) | |
tree | 31a97122e6e081a02120f32d7ede82e4a123e91f | |
parent | c1d972815b8ccbf890715494ac643b80a4a96abf (diff) | |
download | ike-c1b5a6e57fd96df0ff8bcad4f18affd67c94e5a6.tar.gz |
Create an alarm receiver for IKE library
Create an alarm receiver to handle all alarms scheduled
by IKE Sessions
Bug: 151946188
Test: FrameworksIkeTests
Change-Id: I9a63f3e16308906c3a844e3ecb3ce51e91673c62
-rw-r--r-- | src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java | 45 | ||||
-rw-r--r-- | src/java/com/android/internal/net/ipsec/ike/utils/IkeAlarmReceiver.java | 51 |
2 files changed, 96 insertions, 0 deletions
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 7856eb08..f8021839 100644 --- a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java +++ b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java @@ -41,6 +41,7 @@ import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE import android.annotation.IntDef; import android.content.Context; +import android.content.IntentFilter; import android.net.IpSecManager; import android.net.IpSecManager.ResourceUnavailableException; import android.net.IpSecManager.UdpEncapsulationSocket; @@ -111,6 +112,7 @@ import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform; import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IkeProposal; import com.android.internal.net.ipsec.ike.message.IkeTsPayload; import com.android.internal.net.ipsec.ike.message.IkeVendorPayload; +import com.android.internal.net.ipsec.ike.utils.IkeAlarmReceiver; import com.android.internal.net.ipsec.ike.utils.Retransmitter; import com.android.internal.util.State; @@ -158,6 +160,23 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { // TODO: b/140579254 Allow users to configure fragment size. + private static final Object IKE_SESSION_LOCK = new Object(); + + @GuardedBy("IKE_SESSION_LOCK") + private static final HashMap<Context, Set<IkeSessionStateMachine>> sContextToIkeSmMap = + new HashMap<>(); + + /** Alarm receiver that will be shared by all IkeSessionStateMachine */ + private static final IkeAlarmReceiver sIkeAlarmReceiver = new IkeAlarmReceiver(); + + /** Intent filter for all Intents that should be received by sIkeAlarmReceiver */ + private static final IntentFilter sIntentFiler; + + static { + sIntentFiler = new IntentFilter(); + sIntentFiler.addCategory(TAG); + } + // Default fragment size in bytes. @VisibleForTesting static final int DEFAULT_FRAGMENT_SIZE = 1280; @@ -401,6 +420,22 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { IkeEapAuthenticatorFactory eapAuthenticatorFactory) { super(TAG, looper); + synchronized (IKE_SESSION_LOCK) { + if (!sContextToIkeSmMap.containsKey(context)) { + // Pass in a Handler so #onReceive will run on the StateMachine thread + context.registerReceiver( + sIkeAlarmReceiver, + sIntentFiler, + null /*broadcastPermission*/, + new Handler(getHandler().getLooper())); + sContextToIkeSmMap.put(context, new HashSet<IkeSessionStateMachine>()); + } + sContextToIkeSmMap.get(context).add(this); + + // TODO: Statically store the ikeSessionCallback to prevent user from providing the same + // callback instance in the future + } + mIkeSessionParams = ikeParams; mEapAuthenticatorFactory = eapAuthenticatorFactory; @@ -920,6 +955,16 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine { if (mIkeSocket == null) return; mIkeSocket.releaseReference(this); + + synchronized (IKE_SESSION_LOCK) { + Set<IkeSessionStateMachine> ikeSet = sContextToIkeSmMap.get(mContext); + ikeSet.remove(this); + if (ikeSet.isEmpty()) { + mContext.unregisterReceiver(sIkeAlarmReceiver); + sContextToIkeSmMap.remove(mContext); + } + // TODO: Remove the stored ikeSessionCallback + } } private void closeAllSaRecords(boolean expectSaClosed) { diff --git a/src/java/com/android/internal/net/ipsec/ike/utils/IkeAlarmReceiver.java b/src/java/com/android/internal/net/ipsec/ike/utils/IkeAlarmReceiver.java new file mode 100644 index 00000000..60c9b2c5 --- /dev/null +++ b/src/java/com/android/internal/net/ipsec/ike/utils/IkeAlarmReceiver.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.net.ipsec.ike.utils; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Message; + +/** + * IkeAlarmReceiver represents a class that receives all the alarms set by IKE library + * + * <p>Alarm Manager holds a CPU wake lock as long as the alarm receiver's onReceive() method is + * executing. Once onReceive() returns, the Alarm Manager releases this wake lock. Thus actions that + * contain asynchronous process to complete might need acquire a wake lock later. + */ +public class IkeAlarmReceiver extends BroadcastReceiver { + /** Broadcast intent action when the DPD alarm is fired */ + public static final String ACTION_FIRE_DPD = "IkeAlarmReceiver.FIRE_DPD"; + + /** Parcelable name for DPD Message */ + public static final String PARCELABLE_NAME_DPD_MESSAGE = + "IkeAlarmReceiver.PARCELABLE_NAME_DPD_MESSAGE"; + + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(ACTION_FIRE_DPD)) { + Message message = + (Message) intent.getExtras().getParcelable(PARCELABLE_NAME_DPD_MESSAGE); + + // Use #dispatchMessage so that this method won't return util the message is processed + message.getTarget().dispatchMessage(message); + return; + } + } +} |