1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.net.ipsec.ike.utils; 18 19 import static android.net.ipsec.ike.IkeManager.getIkeLog; 20 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.os.Handler; 25 import android.os.Message; 26 import android.util.SparseArray; 27 28 import java.util.HashSet; 29 30 /** 31 * IkeAlarmReceiver represents a class that receives all the alarms set by IKE library 32 * 33 * <p>Alarm Manager holds a CPU wake lock as long as the alarm receiver's onReceive() method is 34 * executing. Once onReceive() returns, the Alarm Manager releases this wake lock. Thus actions that 35 * contain asynchronous process to complete might need acquire a wake lock later. 36 */ 37 public class IkeAlarmReceiver extends BroadcastReceiver { 38 // Broadcast intent actions when an IKE Session event alarm is fired 39 public static final String ACTION_DELETE_CHILD = "IkeAlarmReceiver.ACTION_DELETE_CHILD"; 40 public static final String ACTION_REKEY_CHILD = "IkeAlarmReceiver.ACTION_REKEY_CHILD"; 41 public static final String ACTION_DELETE_IKE = "IkeAlarmReceiver.ACTION_DELETE_IKE"; 42 public static final String ACTION_REKEY_IKE = "IkeAlarmReceiver.ACTION_REKEY_IKE"; 43 public static final String ACTION_DPD = "IkeAlarmReceiver.ACTION_DPD"; 44 public static final String ACTION_KEEPALIVE = "IkeAlarmReceiver.ACTION_KEEPALIVE"; 45 46 private static final HashSet<String> sIkeSessionActionsSet = new HashSet<>(); 47 48 static { 49 sIkeSessionActionsSet.add(ACTION_DELETE_CHILD); 50 sIkeSessionActionsSet.add(ACTION_REKEY_CHILD); 51 sIkeSessionActionsSet.add(ACTION_DELETE_IKE); 52 sIkeSessionActionsSet.add(ACTION_REKEY_IKE); 53 sIkeSessionActionsSet.add(ACTION_DPD); 54 } 55 56 /** Parcelable name of Message that is owned by IKE Session StateMachine */ 57 public static final String PARCELABLE_NAME_IKE_SESSION_MSG = 58 "IkeAlarmReceiver.PARCELABLE_NAME_IKE_SESSION_MSG"; 59 60 private final SparseArray<Handler> mIkeSessionIdToHandlerMap = new SparseArray<>(); 61 62 /** 63 * Called when an alarm fires. 64 * 65 * <p>This is method is guaranteed to run on IkeSessionStateMachine thread since 66 * IkeAlarmReceiver is registered with IkeSessionStateMachine Handler 67 */ 68 @Override onReceive(Context context, Intent intent)69 public void onReceive(Context context, Intent intent) { 70 final String action = intent.getAction(); 71 getIkeLog() 72 .d( 73 "IkeAlarmReceiver", 74 "Alarm fired: action " + action + " id " + intent.getIdentifier()); 75 switch (action) { 76 case ACTION_DELETE_CHILD: // fallthrough 77 case ACTION_REKEY_CHILD: // fallthrough 78 case ACTION_DELETE_IKE: // fallthrough 79 case ACTION_REKEY_IKE: // fallthrough 80 case ACTION_DPD: // fallthrough 81 case ACTION_KEEPALIVE: 82 // This Message has lost its target information after being sent as a Broadcast 83 Message message = 84 (Message) intent.getExtras().getParcelable(PARCELABLE_NAME_IKE_SESSION_MSG); 85 Handler ikeHandler = mIkeSessionIdToHandlerMap.get(message.arg1); 86 87 if (ikeHandler != null) { 88 // Use #dispatchMessage so that this method won't return until the message is 89 // processed 90 ikeHandler.dispatchMessage(message); 91 } 92 return; 93 default: 94 getIkeLog().d("IkeAlarmReceiver", "Received unrecognized alarm intent"); 95 } 96 } 97 98 /** Register a newly created IkeSessionStateMachine handler */ registerIkeSession(int ikeSessionId, Handler ikeSesisonHandler)99 public void registerIkeSession(int ikeSessionId, Handler ikeSesisonHandler) { 100 mIkeSessionIdToHandlerMap.put(ikeSessionId, ikeSesisonHandler); 101 } 102 103 /** Unregistered the deleted IkeSessionStateMachine */ unregisterIkeSession(int ikeSessionId)104 public void unregisterIkeSession(int ikeSessionId) { 105 mIkeSessionIdToHandlerMap.remove(ikeSessionId); 106 } 107 } 108