Merge "Do not use sendOrderedBroadcastAsUser"
diff --git a/Android.bp b/Android.bp
index 49e0d97..6253385 100644
--- a/Android.bp
+++ b/Android.bp
@@ -33,9 +33,19 @@
manifest: "AndroidManifest_Platform.xml",
}
+// used to share common constants between cellbroadcastservice and cellbroadcastreceier
filegroup {
name: "cellbroadcast-constants-shared-srcs",
srcs: [
"src/com/android/cellbroadcastservice/SmsCbConstants.java",
],
+}
+
+// used to share src with unit test app
+filegroup {
+ name: "cellbroadcast-shared-srcs",
+ srcs: [
+ "src/**/*.java",
+ ":framework-cellbroadcast-shared-srcs",
+ ],
}
\ No newline at end of file
diff --git a/src/com/android/cellbroadcastservice/CellBroadcastHandler.java b/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
index 2efbe47..466ae94 100644
--- a/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
+++ b/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
@@ -423,6 +423,8 @@
logd("Device location is outside the broadcast area "
+ CbGeoUtils.encodeGeometriesToString(broadcastArea));
}
+
+ sendMessage(EVENT_BROADCAST_NOT_REQUIRED);
}
/**
diff --git a/src/com/android/cellbroadcastservice/GsmSmsCbMessage.java b/src/com/android/cellbroadcastservice/GsmSmsCbMessage.java
index 3361c16..b8b6f5a 100644
--- a/src/com/android/cellbroadcastservice/GsmSmsCbMessage.java
+++ b/src/com/android/cellbroadcastservice/GsmSmsCbMessage.java
@@ -212,7 +212,7 @@
private static Pair<Integer, List<Geometry>> parseWarningAreaCoordinates(
byte[] pdu, int wacOffset) {
// little-endian
- int wacDataLength = (pdu[wacOffset + 1] << 8) | pdu[wacOffset];
+ int wacDataLength = ((pdu[wacOffset + 1] & 0xff) << 8) | (pdu[wacOffset] & 0xff);
int offset = wacOffset + 2;
if (offset + wacDataLength > pdu.length) {
diff --git a/src/com/android/cellbroadcastservice/WakeLockStateMachine.java b/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
index edb392e..789534d 100644
--- a/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
+++ b/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
@@ -51,6 +51,9 @@
/** Release wakelock after a short timeout when returning to idle state. */
static final int EVENT_RELEASE_WAKE_LOCK = 3;
+ /** Broadcast not required due to geo-fencing check */
+ static final int EVENT_BROADCAST_NOT_REQUIRED = 4;
+
@UnsupportedAppUsage
protected Context mContext;
@@ -148,13 +151,14 @@
@Override
public void exit() {
mWakeLock.acquire();
- if (DBG) log("acquired wakelock, leaving Idle state");
+ if (DBG) log("Idle: acquired wakelock, leaving Idle state");
}
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case EVENT_NEW_SMS_MESSAGE:
+ log("Idle: new cell broadcast message");
// transition to waiting state if we sent a broadcast
if (handleSmsMessage(msg)) {
transitionTo(mWaitingState);
@@ -162,9 +166,12 @@
return HANDLED;
case EVENT_RELEASE_WAKE_LOCK:
+ log("Idle: release wakelock");
releaseWakeLock();
return HANDLED;
-
+ case EVENT_BROADCAST_NOT_REQUIRED:
+ log("Idle: broadcast not required");
+ return HANDLED;
default:
return NOT_HANDLED;
}
@@ -180,19 +187,25 @@
public boolean processMessage(Message msg) {
switch (msg.what) {
case EVENT_NEW_SMS_MESSAGE:
- log("deferring message until return to idle");
+ log("Waiting: deferring message until return to idle");
deferMessage(msg);
return HANDLED;
case EVENT_BROADCAST_COMPLETE:
- log("broadcast complete, returning to idle");
+ log("Waiting: broadcast complete, returning to idle");
transitionTo(mIdleState);
return HANDLED;
case EVENT_RELEASE_WAKE_LOCK:
+ log("Waiting: release wakelock");
releaseWakeLock();
return HANDLED;
-
+ case EVENT_BROADCAST_NOT_REQUIRED:
+ log("Waiting: broadcast not required");
+ if (mReceiverCount.get() == 0) {
+ transitionTo(mIdleState);
+ }
+ return HANDLED;
default:
return NOT_HANDLED;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 1097217..f59dde6 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -13,7 +13,7 @@
"android.test.base",
"android.test.mock",
],
- srcs: ["src/**/*.java"],
+ srcs: ["src/**/*.java", ":cellbroadcast-shared-srcs"],
platform_apis: true,
test_suites: ["device-tests"],
certificate: "platform",
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 445a960..7403d26 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -22,7 +22,7 @@
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.cellbroadcastservice"
+ android:targetPackage="com.android.cellbroadcastservice.tests"
android:label="Tests for CellBroadcastService">
</instrumentation>
</manifest>
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index 8b61a43..022ff36 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -20,7 +20,7 @@
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="CellBroadcastServiceTests" />
- <test class="com.android.tradefed.testtype.InstrumentationTest" >
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.cellbroadcastservice.tests" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
diff --git a/tests/src/com/android/cellbroadcastservice/CellBroadcastServiceTestBase.java b/tests/src/com/android/cellbroadcastservice/CellBroadcastServiceTestBase.java
index 9246f35..04eda63 100644
--- a/tests/src/com/android/cellbroadcastservice/CellBroadcastServiceTestBase.java
+++ b/tests/src/com/android/cellbroadcastservice/CellBroadcastServiceTestBase.java
@@ -147,4 +147,50 @@
mInstanceKeys.clear();
mOldInstances.clear();
}
+
+ /**
+ * Converts a hex String to a byte array.
+ *
+ * @param s A string of hexadecimal characters, must be an even number of
+ * chars long
+ *
+ * @return byte array representation
+ *
+ * @throws RuntimeException on invalid format
+ */
+ public static byte[] hexStringToBytes(String s) {
+ byte[] ret;
+
+ if (s == null) return null;
+
+ int sz = s.length();
+
+ ret = new byte[sz / 2];
+
+ for (int i = 0; i < sz; i += 2) {
+ ret[i / 2] = (byte) ((hexCharToInt(s.charAt(i)) << 4) | hexCharToInt(s.charAt(i + 1)));
+ }
+
+ return ret;
+ }
+
+ /**
+ * Converts a hex char to its integer value
+ *
+ * @param c A single hexadecimal character. Must be in one of these ranges:
+ * - '0' to '9', or
+ * - 'a' to 'f', or
+ * - 'A' to 'F'
+ *
+ * @return the integer representation of {@code c}
+ *
+ * @throws RuntimeException on invalid character
+ */
+ private static int hexCharToInt(char c) {
+ if (c >= '0' && c <= '9') return (c - '0');
+ if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
+ if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
+
+ throw new RuntimeException("invalid hex char '" + c + "'");
+ }
}
diff --git a/tests/src/com/android/cellbroadcastservice/GsmSmsCbMessageTest.java b/tests/src/com/android/cellbroadcastservice/GsmSmsCbMessageTest.java
new file mode 100644
index 0000000..1c9f4e2
--- /dev/null
+++ b/tests/src/com/android/cellbroadcastservice/GsmSmsCbMessageTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 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.cellbroadcastservice;
+
+import android.telephony.CbGeoUtils;
+import android.telephony.SmsCbCmasInfo;
+import android.telephony.SmsCbMessage;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.util.Log;
+
+import com.android.cellbroadcastservice.CbGeoUtils.Circle;
+import com.android.cellbroadcastservice.CbGeoUtils.Polygon;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidTestingRunner.class)
+public class GsmSmsCbMessageTest extends CellBroadcastServiceTestBase {
+
+ @Test
+ @SmallTest
+ public void testCreateMessageFromBinary() throws Exception {
+ final byte[] pdu = hexStringToBytes("0111130F6A0101C8329BFD06559BD429E8FE96B3C92C101D9D9"
+ + "E83D27350B22E1C7EAFF234BDFCADB962AE9A6BCE06A1DCE57B0AD40241C3E73208147B81622E000"
+ + "0000000000000000000000000000000000000000000000039EA013028B53640A4BF600063204C8FC"
+ + "D063F341AF67167E683CF01215F1E40100C053028B53640A4BF600063204C8FCD063F341AF67167E"
+ + "683CF01215F1E40100C053028B53640A4BF600063204C8FCD063F341AF67167E683CF01215F1E401"
+ + "00C053028B53640A4BF600063204C8FCD063F341AF67167E683CF01215F1E40100C053028B53640A"
+ + "4BF600063204C8FCD063F341AF67167E683CF01215F1E40100C053028B53640A4BF600063204C8FC"
+ + "D063F341AF67167E683CF01215F1E40100C053028B53640A4BF600063204C8FCD063F341AF67167E"
+ + "683CF01215F1E40100C053028B53640A4BF600063204C8FCD063F341AF67167E683CF01215F1E401"
+ + "00C053028B53640A4BF600063204C8FCD063F341AF67167E683CF01215F1E40100C053028B53640A"
+ + "4BF600063204C8FCD063F341AF67167E683CF01215F1E40100C053028B53640A4BF600063204C8FC"
+ + "D063F341AF67167E683CF01215F1E40100C053028B53640A4BF600063204C8FCD063F341AF67167E"
+ + "683CF01215F1E40100C053028B53640A4BF600063204C8FCD063F341AF67167E683CF01215F1E401"
+ + "00C053028B53640A4BF600063204C8FCD063F341AF67167E683CF01215F1E40100C053028B53640A"
+ + "4BF600063204C8FCD063F341AF67167E683CF01215F1E40100C053028B53640A4BF600063");
+ SmsCbHeader header = new SmsCbHeader(pdu);
+
+ byte[][] pdus = new byte[1][];
+ pdus[0] = pdu;
+
+ SmsCbMessage msg = GsmSmsCbMessage.createSmsCbMessage(mMockedContext, header, null, pdus,
+ 0);
+
+ Log.d("GsmSmsCbMessageTest", "msg=" + msg);
+
+ assertEquals(SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE,
+ msg.getGeographicalScope());
+ assertEquals(3946, msg.getSerialNumber());
+ assertEquals(SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED,
+ msg.getServiceCategory());
+ assertEquals("en", msg.getLanguageCode());
+ assertEquals("Hello UMTS world, this is IuBC§Write§5.1.5.sl (new) - Page 1/ 1.",
+ msg.getMessageBody());
+ assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, msg.getMessagePriority());
+
+ SmsCbCmasInfo cmasInfo = msg.getCmasWarningInfo();
+ assertEquals(SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, cmasInfo.getMessageClass());
+ assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
+ assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
+ assertEquals(SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE, cmasInfo.getUrgency());
+ assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED, cmasInfo.getCertainty());
+
+ List<CbGeoUtils.Geometry> geometries = msg.getGeometries();
+ for (int i = 0; i < 15; i++) {
+ assertEquals(1546.875, ((Circle) geometries.get(i * 2)).getRadius());
+ assertEquals(37.41462707519531, ((Circle) geometries.get(i * 2)).getCenter().lat);
+ assertEquals(-122.08093643188477, ((Circle) geometries.get(i * 2)).getCenter().lng);
+ assertEquals(11.109967231750488,
+ ((Polygon) geometries.get(i * 2 + 1)).getVertices().get(0).lat);
+ assertEquals(22.219934463500977,
+ ((Polygon) geometries.get(i * 2 + 1)).getVertices().get(0).lng);
+ assertEquals(33.32998752593994, 44,
+ ((Polygon) geometries.get(i * 2 + 1)).getVertices().get(1).lat);
+ assertEquals(44.43995475769043,
+ ((Polygon) geometries.get(i * 2 + 1)).getVertices().get(1).lng);
+ assertEquals(55.549964904785156,
+ ((Polygon) geometries.get(i * 2 + 1)).getVertices().get(2).lat);
+ assertEquals(-56.560020446777344,
+ ((Polygon) geometries.get(i * 2 + 1)).getVertices().get(2).lng);
+ }
+ }
+}