aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorevitayan <evitayan@google.com>2020-03-19 18:28:44 -0700
committerevitayan <evitayan@google.com>2020-03-20 19:09:29 -0700
commitc1b5a6e57fd96df0ff8bcad4f18affd67c94e5a6 (patch)
tree31a97122e6e081a02120f32d7ede82e4a123e91f
parentc1d972815b8ccbf890715494ac643b80a4a96abf (diff)
downloadike-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.java45
-rw-r--r--src/java/com/android/internal/net/ipsec/ike/utils/IkeAlarmReceiver.java51
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;
+ }
+ }
+}