Added reset geo-fencing checking after airplane mode support

The out-of-polygon cell broadcast messages will not be
considered for rebroadcasting after airplane mode turned on
or reboot.

Bug: 143614007
Test: Unit tests
Change-Id: Id54bc210958ddf440efea5c3e042e33ba6936a29
(cherry picked from commit 7afa1c0dca8361c50f649610f07aac79084ecbd1)
Merged-in: Id54bc210958ddf440efea5c3e042e33ba6936a29
diff --git a/src/com/android/cellbroadcastservice/CdmaServiceCategoryProgramHandler.java b/src/com/android/cellbroadcastservice/CdmaServiceCategoryProgramHandler.java
index 4b254b7..212962e 100644
--- a/src/com/android/cellbroadcastservice/CdmaServiceCategoryProgramHandler.java
+++ b/src/com/android/cellbroadcastservice/CdmaServiceCategoryProgramHandler.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Looper;
 import android.os.Message;
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.SubscriptionManager;
@@ -44,7 +45,7 @@
      * Create a new CDMA inbound SMS handler.
      */
     CdmaServiceCategoryProgramHandler(Context context) {
-        super("CdmaServiceCategoryProgramHandler", context);
+        super("CdmaServiceCategoryProgramHandler", context, Looper.myLooper());
         mContext = context;
     }
 
diff --git a/src/com/android/cellbroadcastservice/CellBroadcastHandler.java b/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
index a5d1c8a..56a89c4 100644
--- a/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
+++ b/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
@@ -37,9 +37,11 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -102,7 +104,7 @@
     public final LocationRequester mLocationRequester;
 
     /** Timestamp of last airplane mode on */
-    private long mLastAirplaneModeTime = 0;
+    protected long mLastAirplaneModeTime = 0;
 
     /** Resource cache */
     private final Map<Integer, Resources> mResourcesCache = new HashMap<>();
@@ -117,11 +119,11 @@
     private final Map<Integer, Integer> mServiceCategoryCrossRATMap;
 
     private CellBroadcastHandler(Context context) {
-        this("CellBroadcastHandler", context);
+        this("CellBroadcastHandler", context, Looper.myLooper());
     }
 
-    protected CellBroadcastHandler(String debugTag, Context context) {
-        super(debugTag, context);
+    protected CellBroadcastHandler(String debugTag, Context context, Looper looper) {
+        super(debugTag, context, looper);
         mLocationRequester = new LocationRequester(
                 context,
                 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE),
@@ -318,9 +320,11 @@
         long expirationDuration = res.getInteger(R.integer.message_expiration_time);
         long dupCheckTime = System.currentTimeMillis() - expirationDuration;
 
-        // Some carriers require reset duplication detection after airplane mode.
-        if (res.getBoolean(R.bool.reset_duplicate_detection_on_airplane_mode)) {
+        // Some carriers require reset duplication detection after airplane mode or reboot.
+        if (res.getBoolean(R.bool.reset_on_power_cycle_or_airplane_mode)) {
             dupCheckTime = Long.max(dupCheckTime, mLastAirplaneModeTime);
+            dupCheckTime = Long.max(dupCheckTime,
+                    System.currentTimeMillis() - SystemClock.elapsedRealtime());
         }
 
         List<SmsCbMessage> cbMessages = new ArrayList<>();
diff --git a/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java b/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
index 6838497..333b5ba 100644
--- a/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
+++ b/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
@@ -21,9 +21,12 @@
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.Context;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Looper;
 import android.os.Message;
+import android.os.SystemClock;
 import android.provider.Telephony.CellBroadcasts;
 import android.telephony.CbGeoUtils.Geometry;
 import android.telephony.CellIdentity;
@@ -31,15 +34,16 @@
 import android.telephony.CellInfo;
 import android.telephony.SmsCbLocation;
 import android.telephony.SmsCbMessage;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
 import android.util.Pair;
 
 import com.android.cellbroadcastservice.GsmSmsCbMessage.GeoFencingTriggerMessage;
 import com.android.cellbroadcastservice.GsmSmsCbMessage.GeoFencingTriggerMessage.CellBroadcastIdentity;
+import com.android.internal.annotations.VisibleForTesting;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
+import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -55,12 +59,12 @@
     private static final String MESSAGE_NOT_BROADCASTED = "0";
 
     /** This map holds incomplete concatenated messages waiting for assembly. */
-    @UnsupportedAppUsage
     private final HashMap<SmsCbConcatInfo, byte[][]> mSmsCbPageMap =
             new HashMap<>(4);
 
-    protected GsmCellBroadcastHandler(Context context) {
-        super("GsmCellBroadcastHandler", context);
+    @VisibleForTesting
+    protected GsmCellBroadcastHandler(Context context, Looper looper) {
+        super("GsmCellBroadcastHandler", context, looper);
     }
 
     @Override
@@ -82,7 +86,7 @@
      * @return the new handler
      */
     public static GsmCellBroadcastHandler makeGsmCellBroadcastHandler(Context context) {
-        GsmCellBroadcastHandler handler = new GsmCellBroadcastHandler(context);
+        GsmCellBroadcastHandler handler = new GsmCellBroadcastHandler(context, Looper.myLooper());
         handler.start();
         return handler;
     }
@@ -99,9 +103,26 @@
         final List<SmsCbMessage> cbMessages = new ArrayList<>();
         final List<Uri> cbMessageUris = new ArrayList<>();
 
+        SubscriptionManager subMgr = (SubscriptionManager) mContext.getSystemService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        int[] subIds = subMgr.getSubscriptionIds(slotIndex);
+        Resources res;
+        if (subIds != null) {
+            res = getResources(subIds[0]);
+        } else {
+            res = getResources(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+        }
+
         // Only consider the cell broadcast received within 24 hours.
         long lastReceivedTime = System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS;
 
+        // Some carriers require reset duplication detection after airplane mode or reboot.
+        if (res.getBoolean(R.bool.reset_on_power_cycle_or_airplane_mode)) {
+            lastReceivedTime = Long.max(lastReceivedTime, mLastAirplaneModeTime);
+            lastReceivedTime = Long.max(lastReceivedTime,
+                    System.currentTimeMillis() - SystemClock.elapsedRealtime());
+        }
+
         // Find the cell broadcast message identify by the message identifier and serial number
         // and is not broadcasted.
         String where = CellBroadcasts.SERVICE_CATEGORY + "=? AND "
@@ -128,6 +149,9 @@
             }
         }
 
+        log("Found " + cbMessages.size() + " not broadcasted messages since "
+                + DateFormat.getDateTimeInstance().format(lastReceivedTime));
+
         List<Geometry> commonBroadcastArea = new ArrayList<>();
         if (geoFencingTriggerMessage.shouldShareBroadcastArea()) {
             for (SmsCbMessage msg : cbMessages) {
@@ -194,6 +218,7 @@
             SmsCbHeader header = createSmsCbHeader(pdu);
             if (header == null) return false;
 
+            log("header=" + header);
             if (header.getServiceCategory() == MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER) {
                 GeoFencingTriggerMessage triggerMessage =
                         GsmSmsCbMessage.createGeoFencingTriggerMessage(pdu);
@@ -365,7 +390,6 @@
         private final SmsCbHeader mHeader;
         private final SmsCbLocation mLocation;
 
-        @UnsupportedAppUsage
         SmsCbConcatInfo(SmsCbHeader header, SmsCbLocation location) {
             mHeader = header;
             mLocation = location;
@@ -401,7 +425,6 @@
          * @param cid the current Cell ID
          * @return true if this message is valid for the current location; false otherwise
          */
-        @UnsupportedAppUsage
         public boolean matchesLocation(String plmn, int lac, int cid) {
             return mLocation.isInLocationArea(plmn, lac, cid);
         }
diff --git a/src/com/android/cellbroadcastservice/WakeLockStateMachine.java b/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
index 789534d..1874cef 100644
--- a/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
+++ b/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
@@ -20,6 +20,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.SystemProperties;
@@ -67,8 +68,8 @@
     private final IdleState mIdleState = new IdleState();
     private final WaitingState mWaitingState = new WaitingState();
 
-    protected WakeLockStateMachine(String debugTag, Context context) {
-        super(debugTag);
+    protected WakeLockStateMachine(String debugTag, Context context, Looper looper) {
+        super(debugTag, looper);
 
         mContext = context;