Loading src/java/com/android/internal/telephony/CellBroadcastHandler.java +28 −13 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.provider.Telephony; import android.provider.Telephony.CellBroadcasts; import android.telephony.SmsCbMessage; import android.telephony.SubscriptionManager; import android.text.format.DateUtils; import android.util.LocalLog; import android.util.Log; Loading Loading @@ -98,7 +99,7 @@ public class CellBroadcastHandler extends WakeLockStateMachine { * 3GPP-format Cell Broadcast messages sent from radio are handled in the subclass. * * @param message the message to process * @return true if an ordered broadcast was sent; false on failure * @return true if need to wait for geo-fencing or an ordered broadcast was sent. */ @Override protected boolean handleSmsMessage(Message message) { Loading Loading @@ -141,7 +142,7 @@ public class CellBroadcastHandler extends WakeLockStateMachine { } else { performGeoFencing(message, uri, message.getGeometries(), location); } }); }, message.getMaximumWaitingTime()); } else { if (DBG) { log("Broadcast the message directly because no geo-fencing required, " Loading Loading @@ -185,9 +186,11 @@ public class CellBroadcastHandler extends WakeLockStateMachine { /** * Request a single location update. * @param callback a callback will be called when the location is available. * @param maximumWaitTimeSec the maximum wait time of this request. If location is not updated * within the maximum wait time, {@code callback#onLocationUpadte(null)} will be called. */ protected void requestLocationUpdate(LocationUpdateCallback callback) { mLocationRequester.requestLocationUpdate(callback); protected void requestLocationUpdate(LocationUpdateCallback callback, int maximumWaitTimeSec) { mLocationRequester.requestLocationUpdate(callback, maximumWaitTimeSec); } /** Loading Loading @@ -294,6 +297,12 @@ public class CellBroadcastHandler extends WakeLockStateMachine { private static final class LocationRequester { private static final String TAG = LocationRequester.class.getSimpleName(); /** * Use as the default maximum wait time if the cell broadcast doesn't specify the value. * Most of the location request should be responded within 20 seconds. */ private static final int DEFAULT_MAXIMUM_WAIT_TIME_SEC = 20; /** * Trigger this event when the {@link LocationManager} is not responded within the given * time. Loading @@ -303,9 +312,6 @@ public class CellBroadcastHandler extends WakeLockStateMachine { /** Request a single location update. */ private static final int EVENT_REQUEST_LOCATION_UPDATE = 2; /** Default expired time of the location request. */ private static final int LOCATION_REQUEST_TIMEOUT_MILLIS = 30 * 1000; /** * Request location update from network or gps location provider. Network provider will be * used if available, otherwise use the gps provider. Loading @@ -330,10 +336,16 @@ public class CellBroadcastHandler extends WakeLockStateMachine { /** * Request a single location update. If the location is not available, a callback with * {@code null} location will be called immediately. * * @param callback a callback to the the response when the location is available * @param maximumWaitTimeSec the maximum wait time of this request. If location is not * updated within the maximum wait time, {@code callback#onLocationUpadte(null)} will be * called. */ void requestLocationUpdate(@NonNull LocationUpdateCallback callback) { mLocationHandler.obtainMessage(EVENT_REQUEST_LOCATION_UPDATE, callback).sendToTarget(); void requestLocationUpdate(@NonNull LocationUpdateCallback callback, int maximumWaitTimeSec) { mLocationHandler.obtainMessage(EVENT_REQUEST_LOCATION_UPDATE, maximumWaitTimeSec, 0 /* arg2 */, callback).sendToTarget(); } private void onLocationUpdate(@Nullable LatLng location) { Loading @@ -343,7 +355,8 @@ public class CellBroadcastHandler extends WakeLockStateMachine { mCallbacks.clear(); } private void requestLocationUpdateInternal(@NonNull LocationUpdateCallback callback) { private void requestLocationUpdateInternal(@NonNull LocationUpdateCallback callback, int maximumWaitTimeSec) { if (DBG) Log.d(TAG, "requestLocationUpdate"); if (!isLocationServiceAvailable()) { if (DBG) { Loading @@ -353,11 +366,13 @@ public class CellBroadcastHandler extends WakeLockStateMachine { return; } // TODO: handle the "Geo-fencing Maximum Wait" defined in ATIS-0700041 Section 5.2.3 if (!mLocationHandler.hasMessages(EVENT_LOCATION_REQUEST_TIMEOUT)) { if (maximumWaitTimeSec == SmsCbMessage.MAXIMUM_WAIT_TIME_NOT_SET) { maximumWaitTimeSec = DEFAULT_MAXIMUM_WAIT_TIME_SEC; } mLocationHandler.sendMessageDelayed( mLocationHandler.obtainMessage(EVENT_LOCATION_REQUEST_TIMEOUT), LOCATION_REQUEST_TIMEOUT_MILLIS); maximumWaitTimeSec * DateUtils.SECOND_IN_MILLIS); } mCallbacks.add(callback); Loading Loading @@ -414,7 +429,7 @@ public class CellBroadcastHandler extends WakeLockStateMachine { onLocationUpdate(null); break; case EVENT_REQUEST_LOCATION_UPDATE: requestLocationUpdateInternal((LocationUpdateCallback) msg.obj); requestLocationUpdateInternal((LocationUpdateCallback) msg.obj, msg.arg1); break; default: Log.e(TAG, "Unsupported message type " + msg.what); Loading src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java +25 −11 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.telephony.SmsCbLocation; import android.telephony.SmsCbMessage; import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; import android.text.format.DateUtils; import com.android.internal.telephony.CbGeoUtils.Geometry; import com.android.internal.telephony.CellBroadcastHandler; Loading Loading @@ -83,16 +84,23 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { * Find the cell broadcast messages specify by the geo-fencing trigger message and perform a * geo-fencing check for these messages. * @param geoFencingTriggerMessage the trigger message * * @return {@code True} if geo-fencing is need for some cell broadcast message. */ private void handleGeoFencingTriggerMessage(GeoFencingTriggerMessage geoFencingTriggerMessage) { private boolean handleGeoFencingTriggerMessage( GeoFencingTriggerMessage geoFencingTriggerMessage) { final List<SmsCbMessage> cbMessages = new ArrayList<>(); final List<Uri> cbMessageUris = new ArrayList<>(); // Only consider the cell broadcast received within 24 hours. long lastReceivedTime = System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS; // Find the cell broadcast message identify by the message identifier and serial number // and is not broadcasted. String where = CellBroadcasts.SERVICE_CATEGORY + "=? AND " + CellBroadcasts.SERIAL_NUMBER + "=? AND " + CellBroadcasts.MESSAGE_BROADCASTED + "=?"; + CellBroadcasts.MESSAGE_BROADCASTED + "=? AND " + CellBroadcasts.RECEIVED_TIME + ">?"; ContentResolver resolver = mContext.getContentResolver(); for (CellBroadcastIdentity identity : geoFencingTriggerMessage.cbIdentifiers) { Loading @@ -100,7 +108,8 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { CellBroadcasts.QUERY_COLUMNS_FWK, where, new String[] { Integer.toString(identity.messageIdentifier), Integer.toString(identity.serialNumber), MESSAGE_NOT_BROADCASTED}, Integer.toString(identity.serialNumber), MESSAGE_NOT_BROADCASTED, Long.toString(lastReceivedTime) }, null /* sortOrder */)) { if (cursor != null) { while (cursor.moveToNext()) { Loading @@ -121,6 +130,14 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { } } // ATIS doesn't specify the geo fencing maximum wait time for the cell broadcasts specified // in geo fencing trigger message. We will pick the largest maximum wait time among these // cell broadcasts. int maximumWaitTimeSec = 0; for (SmsCbMessage msg : cbMessages) { maximumWaitTimeSec = Math.max(maximumWaitTimeSec, msg.getMaximumWaitingTime()); } if (DBG) { logd("Geo-fencing trigger message = " + geoFencingTriggerMessage); for (SmsCbMessage msg : cbMessages) { Loading @@ -130,10 +147,7 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { if (cbMessages.isEmpty()) { if (DBG) logd("No CellBroadcast message need to be broadcasted"); // Need to send this event to make the state machine back to Idle. if (mReceiverCount.get() == 0) sendMessage(EVENT_BROADCAST_COMPLETE); return; return false; } requestLocationUpdate(location -> { Loading @@ -152,14 +166,15 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { } } } }); }, maximumWaitTimeSec); return true; } /** * Handle 3GPP-format Cell Broadcast messages sent from radio. * * @param message the message to process * @return true if an ordered broadcast was sent; false on failure * @return true if need to wait for geo-fencing or an ordered broadcast was sent. */ @Override protected boolean handleSmsMessage(Message message) { Loading @@ -173,8 +188,7 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { GeoFencingTriggerMessage triggerMessage = GsmSmsCbMessage.createGeoFencingTriggerMessage(pdu); if (triggerMessage != null) { handleGeoFencingTriggerMessage(triggerMessage); return true; return handleGeoFencingTriggerMessage(triggerMessage); } } else { SmsCbMessage cbMessage = handleGsmBroadcastSms(header, ar); Loading Loading
src/java/com/android/internal/telephony/CellBroadcastHandler.java +28 −13 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.provider.Telephony; import android.provider.Telephony.CellBroadcasts; import android.telephony.SmsCbMessage; import android.telephony.SubscriptionManager; import android.text.format.DateUtils; import android.util.LocalLog; import android.util.Log; Loading Loading @@ -98,7 +99,7 @@ public class CellBroadcastHandler extends WakeLockStateMachine { * 3GPP-format Cell Broadcast messages sent from radio are handled in the subclass. * * @param message the message to process * @return true if an ordered broadcast was sent; false on failure * @return true if need to wait for geo-fencing or an ordered broadcast was sent. */ @Override protected boolean handleSmsMessage(Message message) { Loading Loading @@ -141,7 +142,7 @@ public class CellBroadcastHandler extends WakeLockStateMachine { } else { performGeoFencing(message, uri, message.getGeometries(), location); } }); }, message.getMaximumWaitingTime()); } else { if (DBG) { log("Broadcast the message directly because no geo-fencing required, " Loading Loading @@ -185,9 +186,11 @@ public class CellBroadcastHandler extends WakeLockStateMachine { /** * Request a single location update. * @param callback a callback will be called when the location is available. * @param maximumWaitTimeSec the maximum wait time of this request. If location is not updated * within the maximum wait time, {@code callback#onLocationUpadte(null)} will be called. */ protected void requestLocationUpdate(LocationUpdateCallback callback) { mLocationRequester.requestLocationUpdate(callback); protected void requestLocationUpdate(LocationUpdateCallback callback, int maximumWaitTimeSec) { mLocationRequester.requestLocationUpdate(callback, maximumWaitTimeSec); } /** Loading Loading @@ -294,6 +297,12 @@ public class CellBroadcastHandler extends WakeLockStateMachine { private static final class LocationRequester { private static final String TAG = LocationRequester.class.getSimpleName(); /** * Use as the default maximum wait time if the cell broadcast doesn't specify the value. * Most of the location request should be responded within 20 seconds. */ private static final int DEFAULT_MAXIMUM_WAIT_TIME_SEC = 20; /** * Trigger this event when the {@link LocationManager} is not responded within the given * time. Loading @@ -303,9 +312,6 @@ public class CellBroadcastHandler extends WakeLockStateMachine { /** Request a single location update. */ private static final int EVENT_REQUEST_LOCATION_UPDATE = 2; /** Default expired time of the location request. */ private static final int LOCATION_REQUEST_TIMEOUT_MILLIS = 30 * 1000; /** * Request location update from network or gps location provider. Network provider will be * used if available, otherwise use the gps provider. Loading @@ -330,10 +336,16 @@ public class CellBroadcastHandler extends WakeLockStateMachine { /** * Request a single location update. If the location is not available, a callback with * {@code null} location will be called immediately. * * @param callback a callback to the the response when the location is available * @param maximumWaitTimeSec the maximum wait time of this request. If location is not * updated within the maximum wait time, {@code callback#onLocationUpadte(null)} will be * called. */ void requestLocationUpdate(@NonNull LocationUpdateCallback callback) { mLocationHandler.obtainMessage(EVENT_REQUEST_LOCATION_UPDATE, callback).sendToTarget(); void requestLocationUpdate(@NonNull LocationUpdateCallback callback, int maximumWaitTimeSec) { mLocationHandler.obtainMessage(EVENT_REQUEST_LOCATION_UPDATE, maximumWaitTimeSec, 0 /* arg2 */, callback).sendToTarget(); } private void onLocationUpdate(@Nullable LatLng location) { Loading @@ -343,7 +355,8 @@ public class CellBroadcastHandler extends WakeLockStateMachine { mCallbacks.clear(); } private void requestLocationUpdateInternal(@NonNull LocationUpdateCallback callback) { private void requestLocationUpdateInternal(@NonNull LocationUpdateCallback callback, int maximumWaitTimeSec) { if (DBG) Log.d(TAG, "requestLocationUpdate"); if (!isLocationServiceAvailable()) { if (DBG) { Loading @@ -353,11 +366,13 @@ public class CellBroadcastHandler extends WakeLockStateMachine { return; } // TODO: handle the "Geo-fencing Maximum Wait" defined in ATIS-0700041 Section 5.2.3 if (!mLocationHandler.hasMessages(EVENT_LOCATION_REQUEST_TIMEOUT)) { if (maximumWaitTimeSec == SmsCbMessage.MAXIMUM_WAIT_TIME_NOT_SET) { maximumWaitTimeSec = DEFAULT_MAXIMUM_WAIT_TIME_SEC; } mLocationHandler.sendMessageDelayed( mLocationHandler.obtainMessage(EVENT_LOCATION_REQUEST_TIMEOUT), LOCATION_REQUEST_TIMEOUT_MILLIS); maximumWaitTimeSec * DateUtils.SECOND_IN_MILLIS); } mCallbacks.add(callback); Loading Loading @@ -414,7 +429,7 @@ public class CellBroadcastHandler extends WakeLockStateMachine { onLocationUpdate(null); break; case EVENT_REQUEST_LOCATION_UPDATE: requestLocationUpdateInternal((LocationUpdateCallback) msg.obj); requestLocationUpdateInternal((LocationUpdateCallback) msg.obj, msg.arg1); break; default: Log.e(TAG, "Unsupported message type " + msg.what); Loading
src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java +25 −11 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.telephony.SmsCbLocation; import android.telephony.SmsCbMessage; import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; import android.text.format.DateUtils; import com.android.internal.telephony.CbGeoUtils.Geometry; import com.android.internal.telephony.CellBroadcastHandler; Loading Loading @@ -83,16 +84,23 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { * Find the cell broadcast messages specify by the geo-fencing trigger message and perform a * geo-fencing check for these messages. * @param geoFencingTriggerMessage the trigger message * * @return {@code True} if geo-fencing is need for some cell broadcast message. */ private void handleGeoFencingTriggerMessage(GeoFencingTriggerMessage geoFencingTriggerMessage) { private boolean handleGeoFencingTriggerMessage( GeoFencingTriggerMessage geoFencingTriggerMessage) { final List<SmsCbMessage> cbMessages = new ArrayList<>(); final List<Uri> cbMessageUris = new ArrayList<>(); // Only consider the cell broadcast received within 24 hours. long lastReceivedTime = System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS; // Find the cell broadcast message identify by the message identifier and serial number // and is not broadcasted. String where = CellBroadcasts.SERVICE_CATEGORY + "=? AND " + CellBroadcasts.SERIAL_NUMBER + "=? AND " + CellBroadcasts.MESSAGE_BROADCASTED + "=?"; + CellBroadcasts.MESSAGE_BROADCASTED + "=? AND " + CellBroadcasts.RECEIVED_TIME + ">?"; ContentResolver resolver = mContext.getContentResolver(); for (CellBroadcastIdentity identity : geoFencingTriggerMessage.cbIdentifiers) { Loading @@ -100,7 +108,8 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { CellBroadcasts.QUERY_COLUMNS_FWK, where, new String[] { Integer.toString(identity.messageIdentifier), Integer.toString(identity.serialNumber), MESSAGE_NOT_BROADCASTED}, Integer.toString(identity.serialNumber), MESSAGE_NOT_BROADCASTED, Long.toString(lastReceivedTime) }, null /* sortOrder */)) { if (cursor != null) { while (cursor.moveToNext()) { Loading @@ -121,6 +130,14 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { } } // ATIS doesn't specify the geo fencing maximum wait time for the cell broadcasts specified // in geo fencing trigger message. We will pick the largest maximum wait time among these // cell broadcasts. int maximumWaitTimeSec = 0; for (SmsCbMessage msg : cbMessages) { maximumWaitTimeSec = Math.max(maximumWaitTimeSec, msg.getMaximumWaitingTime()); } if (DBG) { logd("Geo-fencing trigger message = " + geoFencingTriggerMessage); for (SmsCbMessage msg : cbMessages) { Loading @@ -130,10 +147,7 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { if (cbMessages.isEmpty()) { if (DBG) logd("No CellBroadcast message need to be broadcasted"); // Need to send this event to make the state machine back to Idle. if (mReceiverCount.get() == 0) sendMessage(EVENT_BROADCAST_COMPLETE); return; return false; } requestLocationUpdate(location -> { Loading @@ -152,14 +166,15 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { } } } }); }, maximumWaitTimeSec); return true; } /** * Handle 3GPP-format Cell Broadcast messages sent from radio. * * @param message the message to process * @return true if an ordered broadcast was sent; false on failure * @return true if need to wait for geo-fencing or an ordered broadcast was sent. */ @Override protected boolean handleSmsMessage(Message message) { Loading @@ -173,8 +188,7 @@ public class GsmCellBroadcastHandler extends CellBroadcastHandler { GeoFencingTriggerMessage triggerMessage = GsmSmsCbMessage.createGeoFencingTriggerMessage(pdu); if (triggerMessage != null) { handleGeoFencingTriggerMessage(triggerMessage); return true; return handleGeoFencingTriggerMessage(triggerMessage); } } else { SmsCbMessage cbMessage = handleGsmBroadcastSms(header, ar); Loading