Add a new WakeupMessage class and use it in two places.

This is useful when using the new AlarmManager direct callback
interface to wake up the system and request that an object whose
API consists of messages (such as a StateMachine) perform some
action.

In this situation, using AlarmManager.onAlarmListener by itself
will wake up the system to send the message, but does not
guarantee that the system will be awake until the target object
has processed it. This is because as soon as the onAlarmListener
sends the message and returns, the system is free to go to sleep
again.

Bug: 20157436
Bug: 25823676
Change-Id: Idff20029d287f26347441a2523b7fb20eda6a8b0
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 5108564..3a10dbe 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -62,6 +62,7 @@
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.internal.util.WakeupMessage;
 import com.android.server.connectivity.NetworkAgentInfo;
 
 import java.io.IOException;
@@ -565,19 +566,14 @@
     private class LingeringState extends State {
         private static final String ACTION_LINGER_EXPIRED = "android.net.netmon.lingerExpired";
 
-        private CustomIntentReceiver mBroadcastReceiver;
-        private PendingIntent mIntent;
+        private WakeupMessage mWakeupMessage;
 
         @Override
         public void enter() {
-            mLingerToken = new Random().nextInt();
-            mBroadcastReceiver = new CustomIntentReceiver(ACTION_LINGER_EXPIRED, mLingerToken,
-                    CMD_LINGER_EXPIRED);
-            mIntent = mBroadcastReceiver.getPendingIntent();
+            final String cmdName = ACTION_LINGER_EXPIRED + "." + mNetworkAgentInfo.network.netId;
+            mWakeupMessage = new WakeupMessage(mContext, getHandler(), cmdName, CMD_LINGER_EXPIRED);
             long wakeupTime = SystemClock.elapsedRealtime() + mLingerDelayMs;
-            mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeupTime,
-                    // Give a specific window so we aren't subject to unknown inexactitude.
-                    mLingerDelayMs / 6, mIntent);
+            mWakeupMessage.schedule(wakeupTime);
         }
 
         @Override
@@ -592,8 +588,6 @@
                     }
                     return NOT_HANDLED;
                 case CMD_LINGER_EXPIRED:
-                    if (message.arg1 != mLingerToken)
-                        return HANDLED;
                     mConnectivityServiceHandler.sendMessage(
                             obtainMessage(EVENT_NETWORK_LINGER_COMPLETE, mNetworkAgentInfo));
                     return HANDLED;
@@ -624,8 +618,7 @@
 
         @Override
         public void exit() {
-            mAlarmManager.cancel(mIntent);
-            mContext.unregisterReceiver(mBroadcastReceiver);
+            mWakeupMessage.cancel();
         }
     }