[automerger skipped] Renamed SUB_ID to SUBSCRIPTION_ID am: 4711937bcf am: 9e98a00793 am: 339bc3629e -s ours
am skip reason: Change-Id I47cb8e2072d030a069ec3b95b3ddee739f291222 with SHA-1 fadeaa3708 is in history
Change-Id: I3cd964d4e3fb8cf24efb2432cde39f324789af4c
diff --git a/Android.bp b/Android.bp
index a5ad4a3..d423fa2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,30 +1,58 @@
// Copyright 2019 The Android Open Source Project
-
-android_app {
- name: "CellBroadcastServiceModule",
+java_defaults {
+ name: "CellBroadcastServiceCommon",
+ min_sdk_version: "29",
srcs: [
"src/**/*.java",
":framework-annotations",
":framework-cellbroadcast-shared-srcs",
+ ":statslog-cellbroadcast-java-gen",
],
libs: [
- "telephony-common",
"unsupportedappusage",
],
- platform_apis: true,
+ sdk_version: "system_current",
certificate: "platform",
privileged: true,
resource_dirs: ["res"],
optimize: {
proguard_flags_files: ["proguard.flags"],
},
+ jarjar_rules: "cellbroadcast-jarjar-rules.txt",
+ plugins: ["java_api_finder"],
}
+android_app {
+ name: "CellBroadcastServiceModule",
+ defaults: ["CellBroadcastServiceCommon"],
+ certificate: "networkstack",
+ manifest: "AndroidManifest.xml",
+}
+
+android_app {
+ name: "CellBroadcastServiceModulePlatform",
+ defaults: ["CellBroadcastServiceCommon"],
+ certificate: "platform",
+ // CellBroadcastServicePlatformModule is a replacement for com.android.cellbroadcast apex
+ // which consists of CellBroadcastServiceModule
+ overrides: ["com.android.cellbroadcast"],
+ manifest: "AndroidManifest_Platform.xml",
+}
+
+genrule {
+ name: "statslog-cellbroadcast-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module cellbroadcast --javaPackage com.android.cellbroadcastservice --javaClass CellBroadcastStatsLog",
+ out: ["com/android/cellbroadcastservice/CellBroadcastStatsLog.java"],
+}
+
+
// used to share common constants between cellbroadcastservice and cellbroadcastreceier
filegroup {
name: "cellbroadcast-constants-shared-srcs",
srcs: [
"src/com/android/cellbroadcastservice/SmsCbConstants.java",
+ ":statslog-cellbroadcast-java-gen",
],
}
@@ -44,5 +72,6 @@
srcs: [
"src/**/*.java",
":framework-cellbroadcast-shared-srcs",
+ ":statslog-cellbroadcast-java-gen",
],
}
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e075727..eff2cd6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -17,7 +17,9 @@
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- android:sharedUserId="android.uid.phone"
+ android:sharedUserId="android.uid.networkstack"
+ android:versionCode="300000000"
+ android:versionName="R-initial"
package="com.android.cellbroadcastservice">
<original-package android:name="com.android.cellbroadcastservice" />
@@ -29,15 +31,21 @@
<uses-permission android:name="android.permission.READ_CELL_BROADCASTS" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.BROADCAST_SMS" />
+ <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS" />
+
+ <protected-broadcast android:name="android.telephony.action.AREA_INFO_UPDATED" />
<uses-sdk android:minSdkVersion="29"/>
<application android:label="Module used to handle cell broadcasts."
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
- android:process="com.android.phone">
+ android:persistent="true"
+ android:process="com.android.networkstack.process">
<service android:name="DefaultCellBroadcastService"
+ android:process="com.android.networkstack.process"
android:exported="true"
android:permission="android.permission.BIND_CELL_BROADCAST_SERVICE">
<intent-filter>
diff --git a/AndroidManifest_Platform.xml b/AndroidManifest_Platform.xml
new file mode 100644
index 0000000..2c7314f
--- /dev/null
+++ b/AndroidManifest_Platform.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:sharedUserId="android.uid.phone"
+ package="com.android.cellbroadcastservice">
+
+ <original-package android:name="com.android.cellbroadcastservice" />
+
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.RECEIVE_SMS" />
+ <uses-permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST" />
+ <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+ <uses-permission android:name="android.permission.READ_CELL_BROADCASTS" />
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.BROADCAST_SMS" />
+ <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS" />
+
+ <protected-broadcast android:name="android.telephony.action.AREA_INFO_UPDATED" />
+
+ <uses-sdk android:minSdkVersion="29"/>
+
+ <application android:label="Module used to handle cell broadcasts."
+ android:defaultToDeviceProtectedStorage="true"
+ android:persistent="true"
+ android:directBootAware="true"
+ android:process="com.android.phone">
+
+ <service android:name="DefaultCellBroadcastService"
+ android:process="com.android.phone"
+ android:exported="true"
+ android:permission="android.permission.BIND_CELL_BROADCAST_SERVICE">
+ <intent-filter>
+ <action android:name="android.telephony.CellBroadcastService" />
+ </intent-filter>
+ </service>
+ </application>
+</manifest>
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..f69421d
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2007 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/CellBroadcastServiceModule)
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/OWNERS b/OWNERS
index 9a61858..3059d4d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,7 +1,15 @@
amitmahajan@google.com
+breadley@google.com
fionaxu@google.com
jackyu@google.com
+hallliu@google.com
rgreenwalt@google.com
-refuhoo@google.com
+tgunn@google.com
jminjie@google.com
shuoq@google.com
+refuhoo@google.com
+nazaninb@google.com
+sarahchin@google.com
+dbright@google.com
+xiaotonj@google.com
+
diff --git a/cellbroadcast-jarjar-rules.txt b/cellbroadcast-jarjar-rules.txt
index 32cfb51..3e4127a 100644
--- a/cellbroadcast-jarjar-rules.txt
+++ b/cellbroadcast-jarjar-rules.txt
@@ -1,6 +1,5 @@
rule android.os.HandlerExecutor* com.android.cellbroadcastservice.HandlerExecutor@1
rule android.util.LocalLog* com.android.cellbroadcastservice.LocalLog@1
-rule android.util.Slog* com.android.cellbroadcastservice.Slog@1
rule android.internal.util.IState* com.android.cellbroadcastservice.IState@1
rule android.internal.util.Preconditions* com.android.cellbroadcastservice.Preconditions@1
rule android.internal.util.State* com.android.cellbroadcastservice.State@1
diff --git a/res/values-mcc334-mnc03/config.xml b/res/values-mcc334-mnc03/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc334-mnc03/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc334-mnc030/config.xml b/res/values-mcc334-mnc030/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc334-mnc030/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc334/config.xml b/res/values-mcc334/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc334/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc404/config.xml b/res/values-mcc404/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc404/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc405/config.xml b/res/values-mcc405/config.xml
new file mode 100644
index 0000000..361d534
--- /dev/null
+++ b/res/values-mcc405/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>60</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc704-mnc03/config.xml b/res/values-mcc704-mnc03/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc704-mnc03/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc706-mnc04/config.xml b/res/values-mcc706-mnc04/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc706-mnc04/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc712-mnc04/config.xml b/res/values-mcc712-mnc04/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc712-mnc04/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc722-mnc07/config.xml b/res/values-mcc722-mnc07/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc722-mnc07/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc724/config.xml b/res/values-mcc724/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc724/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc732-mnc123/config.xml b/res/values-mcc732-mnc123/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc732-mnc123/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc732/config.xml b/res/values-mcc732/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc732/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc740-mnc00/config.xml b/res/values-mcc740-mnc00/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc740-mnc00/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values-mcc740/config.xml b/res/values-mcc740/config.xml
new file mode 100644
index 0000000..261ef67
--- /dev/null
+++ b/res/values-mcc740/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ <item>50</item>
+ </integer-array>
+</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 23c8177..97b0547 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -37,4 +37,14 @@
<!-- Whether to reset alert message duplicate detection and geo-fencing check after
reboot or toggling airplane mode -->
<bool name="reset_on_power_cycle_or_airplane_mode">false</bool>
+
+ <!-- Cell broadcast channels for area info update. Note the channel configuration for area info
+ is needed in CellBroadcastReceiver as well. -->
+ <integer-array name="area_info_channels">
+ </integer-array>
+
+ <!-- Package names of the area info receivers -->
+ <string-array name="config_area_info_receiver_packages" translatable="false">
+ <item>com.android.settings</item>
+ </string-array>
</resources>
diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml
index 85ba114..63f7ba3 100644
--- a/res/values/overlayable.xml
+++ b/res/values/overlayable.xml
@@ -21,6 +21,7 @@
<!-- Params from config.xml that can be overlayed -->
<item type="array" name="config_defaultCellBroadcastReceiverPkgs" />
<item type="array" name="config_testCellBroadcastReceiverPkgs" />
+ <item type="array" name="config_area_info_receiver_packages" />
<!-- Params from config.xml that can be overlayed -->
</policy>
<!-- END VENDOR CUSTOMIZATION -->
diff --git a/src/com/android/cellbroadcastservice/BearerData.java b/src/com/android/cellbroadcastservice/BearerData.java
index 032266a..c634527 100644
--- a/src/com/android/cellbroadcastservice/BearerData.java
+++ b/src/com/android/cellbroadcastservice/BearerData.java
@@ -576,65 +576,57 @@
* @param serviceCategory the envelope service category (for CMAS alert handling)
* @return an instance of BearerData.
*/
- public static BearerData decode(Context context, byte[] smsData, int serviceCategory) {
- try {
- BitwiseInputStream inStream = new BitwiseInputStream(smsData);
- BearerData bData = new BearerData();
- int foundSubparamMask = 0;
- while (inStream.available() > 0) {
- int subparamId = inStream.read(8);
- int subparamIdBit = 1 << subparamId;
- // int is 4 bytes. This duplicate check has a limit to Id number up to 32 (4*8)
- // as 32th bit is the max bit in int.
- // Per 3GPP2 C.S0015-B Table 4.5-1 Bearer Data Subparameter Identifiers:
- // last defined subparam ID is 23 (00010111 = 0x17 = 23).
- // Only do duplicate subparam ID check if subparam is within defined value as
- // reserved subparams are just skipped.
- if ((foundSubparamMask & subparamIdBit) != 0 &&
- (subparamId >= SUBPARAM_MESSAGE_IDENTIFIER &&
- subparamId <= SUBPARAM_ID_LAST_DEFINED)) {
- throw new CodingException("illegal duplicate subparameter (" +
- subparamId + ")");
- }
- boolean decodeSuccess;
- switch (subparamId) {
- case SUBPARAM_MESSAGE_IDENTIFIER:
- decodeSuccess = decodeMessageId(bData, inStream);
- break;
- case SUBPARAM_USER_DATA:
- decodeSuccess = decodeUserData(bData, inStream);
- break;
- case SUBPARAM_LANGUAGE_INDICATOR:
- decodeSuccess = decodeLanguageIndicator(bData, inStream);
- break;
- case SUBPARAM_PRIORITY_INDICATOR:
- decodeSuccess = decodePriorityIndicator(bData, inStream);
- break;
- default:
- decodeSuccess = decodeReserved(inStream, subparamId);
- }
- if (decodeSuccess &&
- (subparamId >= SUBPARAM_MESSAGE_IDENTIFIER &&
- subparamId <= SUBPARAM_ID_LAST_DEFINED)) {
- foundSubparamMask |= subparamIdBit;
- }
+ public static BearerData decode(Context context, byte[] smsData, int serviceCategory)
+ throws CodingException, BitwiseInputStream.AccessException {
+ BitwiseInputStream inStream = new BitwiseInputStream(smsData);
+ BearerData bData = new BearerData();
+ int foundSubparamMask = 0;
+ while (inStream.available() > 0) {
+ int subparamId = inStream.read(8);
+ int subparamIdBit = 1 << subparamId;
+ // int is 4 bytes. This duplicate check has a limit to Id number up to 32 (4*8)
+ // as 32th bit is the max bit in int.
+ // Per 3GPP2 C.S0015-B Table 4.5-1 Bearer Data Subparameter Identifiers:
+ // last defined subparam ID is 23 (00010111 = 0x17 = 23).
+ // Only do duplicate subparam ID check if subparam is within defined value as
+ // reserved subparams are just skipped.
+ if ((foundSubparamMask & subparamIdBit) != 0 && (
+ subparamId >= SUBPARAM_MESSAGE_IDENTIFIER
+ && subparamId <= SUBPARAM_ID_LAST_DEFINED)) {
+ throw new CodingException("illegal duplicate subparameter (" + subparamId + ")");
}
- if ((foundSubparamMask & (1 << SUBPARAM_MESSAGE_IDENTIFIER)) == 0) {
- throw new CodingException("missing MESSAGE_IDENTIFIER subparam");
+ boolean decodeSuccess;
+ switch (subparamId) {
+ case SUBPARAM_MESSAGE_IDENTIFIER:
+ decodeSuccess = decodeMessageId(bData, inStream);
+ break;
+ case SUBPARAM_USER_DATA:
+ decodeSuccess = decodeUserData(bData, inStream);
+ break;
+ case SUBPARAM_LANGUAGE_INDICATOR:
+ decodeSuccess = decodeLanguageIndicator(bData, inStream);
+ break;
+ case SUBPARAM_PRIORITY_INDICATOR:
+ decodeSuccess = decodePriorityIndicator(bData, inStream);
+ break;
+ default:
+ decodeSuccess = decodeReserved(inStream, subparamId);
}
- if (bData.userData != null) {
- if (isCmasAlertCategory(serviceCategory)) {
- decodeCmasUserData(context, bData, serviceCategory);
- } else {
- decodeUserDataPayload(context, bData.userData, bData.hasUserDataHeader);
- }
+ if (decodeSuccess && (subparamId >= SUBPARAM_MESSAGE_IDENTIFIER
+ && subparamId <= SUBPARAM_ID_LAST_DEFINED)) {
+ foundSubparamMask |= subparamIdBit;
}
- return bData;
- } catch (BitwiseInputStream.AccessException ex) {
- Log.e(LOG_TAG, "BearerData decode failed: " + ex);
- } catch (CodingException ex) {
- Log.e(LOG_TAG, "BearerData decode failed: " + ex);
}
- return null;
+ if ((foundSubparamMask & (1 << SUBPARAM_MESSAGE_IDENTIFIER)) == 0) {
+ throw new CodingException("missing MESSAGE_IDENTIFIER subparam");
+ }
+ if (bData.userData != null) {
+ if (isCmasAlertCategory(serviceCategory)) {
+ decodeCmasUserData(context, bData, serviceCategory);
+ } else {
+ decodeUserDataPayload(context, bData.userData, bData.hasUserDataHeader);
+ }
+ }
+ return bData;
}
}
diff --git a/src/com/android/cellbroadcastservice/CbGeoUtils.java b/src/com/android/cellbroadcastservice/CbGeoUtils.java
index 0a8fe48..044ecea 100644
--- a/src/com/android/cellbroadcastservice/CbGeoUtils.java
+++ b/src/com/android/cellbroadcastservice/CbGeoUtils.java
@@ -232,6 +232,9 @@
break;
default:
Log.e(TAG, "Invalid geometry format " + geometryStr);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__UNEXPECTED_GEOMETRY_FROM_FWK,
+ geometryStr);
}
}
return geometries;
diff --git a/src/com/android/cellbroadcastservice/CdmaServiceCategoryProgramHandler.java b/src/com/android/cellbroadcastservice/CdmaServiceCategoryProgramHandler.java
index 032edcc..2050960 100644
--- a/src/com/android/cellbroadcastservice/CdmaServiceCategoryProgramHandler.java
+++ b/src/com/android/cellbroadcastservice/CdmaServiceCategoryProgramHandler.java
@@ -16,6 +16,9 @@
package com.android.cellbroadcastservice;
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__CDMA_SCP_HANDLING_ERROR;
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__UNEXPECTED_CDMA_SCP_MESSAGE_TYPE_FROM_FWK;
+
import android.Manifest;
import android.app.Activity;
import android.app.AppOpsManager;
@@ -111,6 +114,9 @@
cdmaScpMessage.mCallback);
} else {
loge("handleMessage got object of type: " + message.obj.getClass().getName());
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__UNEXPECTED_CDMA_SCP_MESSAGE_TYPE_FROM_FWK,
+ message.obj.getClass().getName());
return false;
}
}
@@ -128,6 +134,8 @@
String originatingAddress, int phoneId, Consumer<Bundle> callback) {
if (programData == null) {
loge("handleServiceCategoryProgramData: program data list is null!");
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__CDMA_SCP_EMPTY);
return false;
}
@@ -143,7 +151,7 @@
for (String pkg : pkgs) {
intent.setPackage(pkg);
mContext.sendOrderedBroadcast(intent, Manifest.permission.RECEIVE_SMS,
- AppOpsManager.OP_RECEIVE_SMS, mScpResultsReceiver,
+ AppOpsManager.OPSTR_RECEIVE_SMS, mScpResultsReceiver,
getHandler(), Activity.RESULT_OK, null, null);
mScpCallback.add(callback);
}
@@ -160,6 +168,9 @@
int resultCode = getResultCode();
if ((resultCode != Activity.RESULT_OK) && (resultCode != Intents.RESULT_SMS_HANDLED)) {
loge("SCP results error: result code = " + resultCode);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__CDMA_SCP_HANDLING_ERROR,
+ "result code = " + resultCode);
return;
}
Bundle extras = getResultExtras(false);
diff --git a/src/com/android/cellbroadcastservice/CellBroadcastHandler.java b/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
index 8781c80..080d664 100644
--- a/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
+++ b/src/com/android/cellbroadcastservice/CellBroadcastHandler.java
@@ -16,6 +16,11 @@
package com.android.cellbroadcastservice;
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__UNEXPECTED_CDMA_MESSAGE_TYPE_FROM_FWK;
+
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -30,11 +35,12 @@
import android.content.res.Resources;
import android.database.Cursor;
import android.location.Location;
-import android.location.LocationListener;
import android.location.LocationManager;
+import android.location.LocationRequest;
import android.net.Uri;
-import android.os.Bundle;
+import android.os.CancellationSignal;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
@@ -50,7 +56,6 @@
import android.telephony.SubscriptionManager;
import android.telephony.cdma.CdmaSmsCbProgramData;
import android.text.TextUtils;
-import android.text.format.DateUtils;
import android.util.LocalLog;
import android.util.Log;
@@ -65,6 +70,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -97,7 +103,7 @@
private static final boolean IS_DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0) == 1;
/** Uses to request the location update. */
- public final LocationRequester mLocationRequester;
+ private final LocationRequester mLocationRequester;
/** Timestamp of last airplane mode on */
protected long mLastAirplaneModeTime = 0;
@@ -128,7 +134,11 @@
case ACTION_DUPLICATE_DETECTION:
mEnableDuplicateDetection = intent.getBooleanExtra(EXTRA_ENABLE,
true);
+ log("Duplicate detection " + (mEnableDuplicateDetection
+ ? "enabled" : "disabled"));
break;
+ default:
+ log("Unhandled broadcast " + intent.getAction());
}
}
};
@@ -143,7 +153,7 @@
mLocationRequester = new LocationRequester(
context,
(LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE),
- getHandler().getLooper());
+ getHandler());
// Adding GSM / CDMA service category mapping.
mServiceCategoryCrossRATMap = Stream.of(new Integer[][] {
@@ -243,7 +253,10 @@
}
return false;
} else {
- loge("handleMessage got object of type: " + message.obj.getClass().getName());
+ loge("handleSmsMessage got object of type: " + message.obj.getClass().getName());
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__UNEXPECTED_CDMA_MESSAGE_TYPE_FROM_FWK,
+ message.obj.getClass().getName());
return false;
}
}
@@ -407,6 +420,13 @@
+ " serialNumber = " + message.getSerialNumber());
}
+ if (uri != null) {
+ ContentValues cv = new ContentValues();
+ cv.put(CellBroadcasts.LOCATION_CHECK_TIME, System.currentTimeMillis());
+ mContext.getContentResolver().update(CellBroadcasts.CONTENT_URI, cv,
+ CellBroadcasts._ID + "=?", new String[] {uri.getLastPathSegment()});
+ }
+
for (Geometry geo : broadcastArea) {
if (geo.contains(location)) {
broadcastMessage(message, uri, slotIndex);
@@ -511,8 +531,8 @@
// Explicitly send the intent to all the configured cell broadcast receivers.
intent.setPackage(pkg);
mContext.createContextAsUser(UserHandle.ALL, 0).sendOrderedBroadcast(
- intent, receiverPermission, appOp, mReceiver, getHandler(),
- Activity.RESULT_OK, null, null);
+ intent, receiverPermission, appOp, mOrderedBroadcastReceiver,
+ getHandler(), Activity.RESULT_OK, null, null);
}
}
} else {
@@ -521,13 +541,11 @@
mLocalLog.log(msg);
// Send implicit intent since there are various 3rd party carrier apps listen to
// this intent.
- receiverPermission = Manifest.permission.RECEIVE_SMS;
- appOp = AppOpsManager.OPSTR_RECEIVE_SMS;
mReceiverCount.incrementAndGet();
CellBroadcastIntents.sendSmsCbReceivedBroadcast(
- mContext, UserHandle.ALL, message, mReceiver, getHandler(), Activity.RESULT_OK,
- slotIndex);
+ mContext, UserHandle.ALL, message, mOrderedBroadcastReceiver, getHandler(),
+ Activity.RESULT_OK, slotIndex);
}
if (messageUri != null) {
@@ -583,18 +601,9 @@
/**
* 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.
+ * Most of the location request should be responded within 30 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.
- */
- private static final int EVENT_LOCATION_REQUEST_TIMEOUT = 1;
-
- /** Request a single location update. */
- private static final int EVENT_REQUEST_LOCATION_UPDATE = 2;
+ private static final int DEFAULT_MAXIMUM_WAIT_TIME_SEC = 30;
/**
* Request location update from network or gps location provider. Network provider will be
@@ -604,17 +613,20 @@
LocationManager.NETWORK_PROVIDER, LocationManager.GPS_PROVIDER);
private final LocationManager mLocationManager;
- private final Looper mLooper;
private final List<LocationUpdateCallback> mCallbacks;
private final Context mContext;
- private Handler mLocationHandler;
+ private final Handler mLocationHandler;
- LocationRequester(Context context, LocationManager locationManager, Looper looper) {
+ private int mNumLocationUpdatesInProgress;
+
+ private final List<CancellationSignal> mCancellationSignals = new ArrayList<>();
+
+ LocationRequester(Context context, LocationManager locationManager, Handler handler) {
mLocationManager = locationManager;
- mLooper = looper;
mCallbacks = new ArrayList<>();
mContext = context;
- mLocationHandler = new LocationHandler(looper);
+ mLocationHandler = handler;
+ mNumLocationUpdatesInProgress = 0;
}
/**
@@ -622,103 +634,83 @@
* {@code null} location will be called immediately.
*
* @param callback a callback to the response when the location is available
- * @param maximumWaitTimeSec the maximum wait time of this request. If location is not
+ * @param maximumWaitTimeS 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,
- int maximumWaitTimeSec) {
- mLocationHandler.obtainMessage(EVENT_REQUEST_LOCATION_UPDATE, maximumWaitTimeSec,
- 0 /* arg2 */, callback).sendToTarget();
+ int maximumWaitTimeS) {
+ mLocationHandler.post(() -> requestLocationUpdateInternal(callback, maximumWaitTimeS));
}
- private void onLocationUpdate(@Nullable LatLng location) {
+ private void onLocationUpdate(@Nullable Location location) {
+ mNumLocationUpdatesInProgress--;
+
+ LatLng latLng = null;
+ if (location != null) {
+ Log.d(TAG, "Got location update");
+ latLng = new LatLng(location.getLatitude(), location.getLongitude());
+ } else if (mNumLocationUpdatesInProgress > 0) {
+ Log.d(TAG, "Still waiting for " + mNumLocationUpdatesInProgress
+ + " more location updates.");
+ return;
+ } else {
+ Log.d(TAG, "Location is not available.");
+ }
+
for (LocationUpdateCallback callback : mCallbacks) {
- callback.onLocationUpdate(location);
+ callback.onLocationUpdate(latLng);
}
mCallbacks.clear();
+
+ mCancellationSignals.forEach(CancellationSignal::cancel);
+ mCancellationSignals.clear();
+
+ mNumLocationUpdatesInProgress = 0;
}
private void requestLocationUpdateInternal(@NonNull LocationUpdateCallback callback,
- int maximumWaitTimeSec) {
+ int maximumWaitTimeS) {
if (DBG) Log.d(TAG, "requestLocationUpdate");
- if (!isLocationServiceAvailable()) {
+ if (!hasPermission(ACCESS_FINE_LOCATION) && !hasPermission(ACCESS_COARSE_LOCATION)) {
if (DBG) {
Log.d(TAG, "Can't request location update because of no location permission");
}
callback.onLocationUpdate(null);
return;
}
+ if (mNumLocationUpdatesInProgress == 0) {
+ for (String provider : LOCATION_PROVIDERS) {
+ if (!mLocationManager.isProviderEnabled(provider)) {
+ if (DBG) {
+ Log.d(TAG, "provider " + provider + " not available");
+ }
+ continue;
+ }
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(provider,
+ 0, 0, true);
+ if (maximumWaitTimeS == SmsCbMessage.MAXIMUM_WAIT_TIME_NOT_SET) {
+ maximumWaitTimeS = DEFAULT_MAXIMUM_WAIT_TIME_SEC;
+ }
+ request.setExpireIn(TimeUnit.SECONDS.toMillis(maximumWaitTimeS));
- 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),
- maximumWaitTimeSec * DateUtils.SECOND_IN_MILLIS);
- }
-
- mCallbacks.add(callback);
-
- for (String provider : LOCATION_PROVIDERS) {
- if (mLocationManager.isProviderEnabled(provider)) {
- mLocationManager.requestSingleUpdate(provider, mLocationListener, mLooper);
- break;
+ CancellationSignal signal = new CancellationSignal();
+ mCancellationSignals.add(signal);
+ mLocationManager.getCurrentLocation(request, signal,
+ new HandlerExecutor(mLocationHandler), this::onLocationUpdate);
+ mNumLocationUpdatesInProgress++;
}
}
- }
-
- private boolean isLocationServiceAvailable() {
- if (!hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)
- && !hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION)) return false;
- for (String provider : LOCATION_PROVIDERS) {
- if (mLocationManager.isProviderEnabled(provider)) return true;
+ if (mNumLocationUpdatesInProgress > 0) {
+ mCallbacks.add(callback);
+ } else {
+ callback.onLocationUpdate(null);
}
- return false;
}
private boolean hasPermission(String permission) {
return mContext.checkPermission(permission, Process.myPid(), Process.myUid())
== PackageManager.PERMISSION_GRANTED;
}
-
- private final LocationListener mLocationListener = new LocationListener() {
- @Override
- public void onLocationChanged(Location location) {
- mLocationHandler.removeMessages(EVENT_LOCATION_REQUEST_TIMEOUT);
- onLocationUpdate(new LatLng(location.getLatitude(), location.getLongitude()));
- }
-
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {}
-
- @Override
- public void onProviderEnabled(String provider) {}
-
- @Override
- public void onProviderDisabled(String provider) {}
- };
-
- private final class LocationHandler extends Handler {
- LocationHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_LOCATION_REQUEST_TIMEOUT:
- if (DBG) Log.d(TAG, "location request timeout");
- onLocationUpdate(null);
- break;
- case EVENT_REQUEST_LOCATION_UPDATE:
- requestLocationUpdateInternal((LocationUpdateCallback) msg.obj, msg.arg1);
- break;
- default:
- Log.e(TAG, "Unsupported message type " + msg.what);
- }
- }
- }
}
}
diff --git a/src/com/android/cellbroadcastservice/CellBroadcastProvider.java b/src/com/android/cellbroadcastservice/CellBroadcastProvider.java
index 46efa68..a1032f5 100644
--- a/src/com/android/cellbroadcastservice/CellBroadcastProvider.java
+++ b/src/com/android/cellbroadcastservice/CellBroadcastProvider.java
@@ -16,6 +16,8 @@
package com.android.cellbroadcastservice;
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__FAILED_TO_INSERT_TO_DB;
+
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -27,8 +29,6 @@
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
-import android.os.Binder;
-import android.os.Process;
import android.provider.Telephony.CellBroadcasts;
import android.text.TextUtils;
import android.util.Log;
@@ -112,6 +112,7 @@
CellBroadcasts.SERIAL_NUMBER,
CellBroadcasts.SERVICE_CATEGORY,
CellBroadcasts.LANGUAGE_CODE,
+ CellBroadcasts.DATA_CODING_SCHEME,
CellBroadcasts.MESSAGE_BODY,
CellBroadcasts.MESSAGE_FORMAT,
CellBroadcasts.MESSAGE_PRIORITY,
@@ -123,7 +124,9 @@
CellBroadcasts.CMAS_URGENCY,
CellBroadcasts.CMAS_CERTAINTY,
CellBroadcasts.RECEIVED_TIME,
+ CellBroadcasts.LOCATION_CHECK_TIME,
CellBroadcasts.MESSAGE_BROADCASTED,
+ CellBroadcasts.MESSAGE_DISPLAYED,
CellBroadcasts.GEOMETRIES,
CellBroadcasts.MAXIMUM_WAIT_TIME
};
@@ -232,12 +235,27 @@
.notifyChange(CONTENT_URI, null /* observer */);
return newUri;
} else {
- Log.e(TAG, "Insert record failed because of unknown reason, uri = " + uri);
+ String errorString = "uri=" + uri.toString() + " values=" + values;
+ // 1000 character limit for error logs
+ if (errorString.length() > 1000) {
+ errorString = errorString.substring(0, 1000);
+ }
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__FAILED_TO_INSERT_TO_DB,
+ errorString);
+ Log.e(TAG, "Insert record failed because of unknown reason. " + errorString);
return null;
}
default:
- throw new IllegalArgumentException(
- "Insert method doesn't support this uri = " + uri);
+ String errorString = "Insert method doesn't support this uri="
+ + uri.toString() + " values=" + values;
+ // 1000 character limit for error logs
+ if (errorString.length() > 1000) {
+ errorString = errorString.substring(0, 1000);
+ }
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__FAILED_TO_INSERT_TO_DB, errorString);
+ throw new IllegalArgumentException(errorString);
}
}
@@ -400,18 +418,26 @@
private class CellBroadcastPermissionChecker implements PermissionChecker {
@Override
public boolean hasWritePermission() {
- // Only the phone and network statck process has the write permission to modify this
- // provider.
- return Binder.getCallingUid() == Process.PHONE_UID
- || Binder.getCallingUid() == Process.NETWORK_STACK_UID;
+ // Only the telephony system compontents e.g, Cellbroadcast service has the write
+ // permission to modify this provider.
+ int status = getContext().checkCallingOrSelfPermission(
+ "android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS");
+ if (status == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ return false;
}
@Override
public boolean hasReadPermission() {
- // Only the phone and network stack process has the read permission to query data from
- // this provider.
- return Binder.getCallingUid() == Process.PHONE_UID
- || Binder.getCallingUid() == Process.NETWORK_STACK_UID;
+ // Only the telephony system compontents e.g, Cellbroadcast service has the read
+ // permission to access this provider.
+ int status = getContext().checkCallingOrSelfPermission(
+ "android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS");
+ if (status == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ return false;
}
@Override
diff --git a/src/com/android/cellbroadcastservice/DefaultCellBroadcastService.java b/src/com/android/cellbroadcastservice/DefaultCellBroadcastService.java
index 70d23ae..1eddde1 100644
--- a/src/com/android/cellbroadcastservice/DefaultCellBroadcastService.java
+++ b/src/com/android/cellbroadcastservice/DefaultCellBroadcastService.java
@@ -16,6 +16,9 @@
package com.android.cellbroadcastservice;
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__CDMA_DECODING_ERROR;
+
+import android.annotation.NonNull;
import android.content.Context;
import android.os.Bundle;
import android.telephony.CellBroadcastService;
@@ -33,8 +36,8 @@
import java.util.function.Consumer;
/**
- * The default implementation of CellBroadcastService, which is used for handling GSM and CDMA
- * cell broadcast messages.
+ * The default implementation of CellBroadcastService, which is used for handling GSM and CDMA cell
+ * broadcast messages.
*/
public class DefaultCellBroadcastService extends CellBroadcastService {
private GsmCellBroadcastHandler mGsmCellBroadcastHandler;
@@ -43,8 +46,8 @@
private static final String TAG = "DefaultCellBroadcastService";
- private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
@Override
public void onCreate() {
@@ -67,12 +70,16 @@
@Override
public void onGsmCellBroadcastSms(int slotIndex, byte[] message) {
Log.d(TAG, "onGsmCellBroadcastSms received message on slotId=" + slotIndex);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_REPORTED,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_REPORTED__TYPE__GSM);
mGsmCellBroadcastHandler.onGsmCellBroadcastSms(slotIndex, message);
}
@Override
public void onCdmaCellBroadcastSms(int slotIndex, byte[] bearerData, int serviceCategory) {
Log.d(TAG, "onCdmaCellBroadcastSms received message on slotId=" + slotIndex);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_REPORTED,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_REPORTED__TYPE__CDMA);
int[] subIds =
((SubscriptionManager) getSystemService(
Context.TELEPHONY_SUBSCRIPTION_SERVICE)).getSubscriptionIds(slotIndex);
@@ -80,12 +87,12 @@
if (subIds != null && subIds.length > 0) {
int subId = subIds[0];
plmn = ((TelephonyManager) getSystemService(
- Context.TELEPHONY_SERVICE)).createForSubscriptionId(
- subId).getNetworkOperator();
+ Context.TELEPHONY_SERVICE)).createForSubscriptionId(
+ subId).getNetworkOperator();
} else {
plmn = "";
}
- SmsCbMessage message = parseBroadcastSms(getApplicationContext(), slotIndex, plmn,
+ SmsCbMessage message = parseCdmaBroadcastSms(getApplicationContext(), slotIndex, plmn,
bearerData, serviceCategory);
if (message != null) {
mCdmaCellBroadcastHandler.onCdmaCellBroadcastSms(message);
@@ -96,25 +103,37 @@
public void onCdmaScpMessage(int slotIndex, List<CdmaSmsCbProgramData> programData,
String originatingAddress, Consumer<Bundle> callback) {
Log.d(TAG, "onCdmaScpMessage received message on slotId=" + slotIndex);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_REPORTED,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_REPORTED__TYPE__CDMA_SPC);
mCdmaScpHandler.onCdmaScpMessage(slotIndex, new ArrayList<>(programData),
originatingAddress, callback);
}
+ @Override
+ public @NonNull String getCellBroadcastAreaInfo(int slotIndex) {
+ Log.d(TAG, "getCellBroadcastAreaInfo on slotId=" + slotIndex);
+ return mGsmCellBroadcastHandler.getCellBroadcastAreaInfo(slotIndex);
+ }
+
/**
* Parses a CDMA broadcast SMS
*
- * @param slotIndex the slotIndex the SMS was received on
- * @param plmn the PLMN for a broadcast SMS or "" if unknown
- * @param bearerData the bearerData of the SMS
+ * @param slotIndex the slotIndex the SMS was received on
+ * @param plmn the PLMN for a broadcast SMS or "" if unknown
+ * @param bearerData the bearerData of the SMS
* @param serviceCategory the service category of the broadcast
*/
@VisibleForTesting
- public static SmsCbMessage parseBroadcastSms(Context context, int slotIndex, String plmn,
+ public static SmsCbMessage parseCdmaBroadcastSms(Context context, int slotIndex, String plmn,
byte[] bearerData,
int serviceCategory) {
- BearerData bData = BearerData.decode(context, bearerData, serviceCategory);
- if (bData == null) {
- Log.w(TAG, "BearerData.decode() returned null");
+ BearerData bData;
+ try {
+ bData = BearerData.decode(context, bearerData, serviceCategory);
+ } catch (Exception e) {
+ Log.e(TAG, "Error decoding bearer data e=" + e.toString());
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__CDMA_DECODING_ERROR, e.toString());
return null;
}
Log.d(TAG, "MT raw BearerData = " + toHexString(bearerData, 0, bearerData.length));
@@ -130,9 +149,9 @@
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2,
SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location,
- serviceCategory, bData.getLanguage(), 0, bData.userData.payloadStr,
- bData.priority, null, bData.cmasWarningInfo, 0, null, System.currentTimeMillis(),
- slotIndex, subId);
+ serviceCategory, bData.getLanguage(), bData.userData.msgEncoding,
+ bData.userData.payloadStr, bData.priority, null, bData.cmasWarningInfo, 0, null,
+ System.currentTimeMillis(), slotIndex, subId);
}
private static String toHexString(byte[] array, int offset, int length) {
diff --git a/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java b/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
index fb04fa0..6682a8b 100644
--- a/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
+++ b/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
@@ -16,17 +16,24 @@
package com.android.cellbroadcastservice;
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_INVALID_PDU;
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__UNEXPECTED_GSM_MESSAGE_TYPE_FROM_FWK;
+
+import android.annotation.NonNull;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
+import android.content.Intent;
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.os.UserHandle;
import android.provider.Telephony.CellBroadcasts;
import android.telephony.CbGeoUtils.Geometry;
+import android.telephony.CellBroadcastIntents;
import android.telephony.CellIdentity;
import android.telephony.CellIdentityGsm;
import android.telephony.CellInfo;
@@ -34,8 +41,10 @@
import android.telephony.SmsCbMessage;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Pair;
+import android.util.SparseArray;
import com.android.cellbroadcastservice.GsmSmsCbMessage.GeoFencingTriggerMessage;
import com.android.cellbroadcastservice.GsmSmsCbMessage.GeoFencingTriggerMessage.CellBroadcastIdentity;
@@ -46,6 +55,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.stream.IntStream;
/**
* Handler for 3GPP format Cell Broadcasts. Parent class can also handle CDMA Cell Broadcasts.
@@ -56,6 +66,8 @@
/** Indicates that a message is not being broadcasted. */
private static final String MESSAGE_NOT_BROADCASTED = "0";
+ private final SparseArray<String> mAreaInfos = new SparseArray<>();
+
/** This map holds incomplete concatenated messages waiting for assembly. */
private final HashMap<SmsCbConcatInfo, byte[][]> mSmsCbPageMap =
new HashMap<>(4);
@@ -79,6 +91,21 @@
}
/**
+ * Get the area information
+ *
+ * @param slotIndex SIM slot index
+ * @return The area information
+ */
+ @NonNull
+ public String getCellBroadcastAreaInfo(int slotIndex) {
+ String info;
+ synchronized (mAreaInfos) {
+ info = mAreaInfos.get(slotIndex);
+ }
+ return info == null ? "" : info;
+ }
+
+ /**
* Create a new CellBroadcastHandler.
* @param context the context to use for dispatching Intents
* @return the new handler
@@ -202,6 +229,54 @@
}
/**
+ * Process area info message.
+ *
+ * @param slotIndex SIM slot index
+ * @param message Cell broadcast message
+ * @return {@code true} if the mssage is an area info message and got processed correctly,
+ * otherwise {@code false}.
+ */
+ private boolean handleAreaInfoMessage(int slotIndex, SmsCbMessage message) {
+ SubscriptionManager subMgr = (SubscriptionManager) mContext.getSystemService(
+ Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+
+ // Check area info message
+ int[] subIds = subMgr.getSubscriptionIds(slotIndex);
+ Resources res;
+ if (subIds != null) {
+ res = getResources(subIds[0]);
+ } else {
+ res = getResources(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ }
+ int[] areaInfoChannels = res.getIntArray(R.array.area_info_channels);
+
+ if (IntStream.of(areaInfoChannels).anyMatch(
+ x -> x == message.getServiceCategory())) {
+ synchronized (mAreaInfos) {
+ String info = mAreaInfos.get(slotIndex);
+ if (TextUtils.equals(info, message.getMessageBody())) {
+ // Message is a duplicate
+ return true;
+ }
+ mAreaInfos.put(slotIndex, message.getMessageBody());
+ }
+
+ String[] pkgs = mContext.getResources().getStringArray(
+ R.array.config_area_info_receiver_packages);
+ for (String pkg : pkgs) {
+ Intent intent = new Intent(CellBroadcastIntents.ACTION_AREA_INFO_UPDATED);
+ intent.setPackage(pkg);
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+ }
+ return true;
+ }
+
+ // This is not an area info message.
+ return false;
+ }
+
+ /**
* Handle 3GPP-format Cell Broadcast messages sent from radio.
*
* @param message the message to process
@@ -229,13 +304,29 @@
if (isDuplicate(cbMessage)) {
return false;
}
+
+ if (handleAreaInfoMessage(slotIndex, cbMessage)) {
+ log("Channel " + cbMessage.getServiceCategory() + " message processed");
+ return false;
+ }
+
handleBroadcastSms(cbMessage);
return true;
}
if (VDBG) log("Not handled GSM broadcasts.");
}
+ } else {
+ loge("handleSmsMessage for GSM got object of type: "
+ + message.obj.getClass().getName());
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__UNEXPECTED_GSM_MESSAGE_TYPE_FROM_FWK,
+ message.obj.getClass().getName());
}
- return super.handleSmsMessage(message);
+ if (message.obj instanceof SmsCbMessage) {
+ return super.handleSmsMessage(message);
+ } else {
+ return false;
+ }
}
// return the GSM cell location from the first GSM cell info
@@ -367,6 +458,8 @@
} catch (RuntimeException e) {
loge("Error in decoding SMS CB pdu", e);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_INVALID_PDU, e.toString());
return null;
}
}
diff --git a/src/com/android/cellbroadcastservice/GsmSmsCbMessage.java b/src/com/android/cellbroadcastservice/GsmSmsCbMessage.java
index cb5c305..8657c6b 100644
--- a/src/com/android/cellbroadcastservice/GsmSmsCbMessage.java
+++ b/src/com/android/cellbroadcastservice/GsmSmsCbMessage.java
@@ -22,11 +22,16 @@
import static android.telephony.SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE;
import static android.telephony.SmsCbEtwsInfo.ETWS_WARNING_TYPE_TSUNAMI;
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_INVALID_GEO_FENCING_DATA;
+import static com.android.cellbroadcastservice.CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_UMTS_INVALID_WAC;
+
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
+import android.telephony.CbGeoUtils.Circle;
import android.telephony.CbGeoUtils.Geometry;
import android.telephony.CbGeoUtils.LatLng;
+import android.telephony.CbGeoUtils.Polygon;
import android.telephony.SmsCbLocation;
import android.telephony.SmsCbMessage;
import android.telephony.SmsMessage;
@@ -34,8 +39,6 @@
import android.util.Log;
import android.util.Pair;
-import com.android.cellbroadcastservice.CbGeoUtils.Circle;
-import com.android.cellbroadcastservice.CbGeoUtils.Polygon;
import com.android.cellbroadcastservice.GsmSmsCbMessage.GeoFencingTriggerMessage.CellBroadcastIdentity;
import com.android.cellbroadcastservice.SmsCbHeader.DataCodingScheme;
import com.android.internal.annotations.VisibleForTesting;
@@ -109,10 +112,11 @@
// message identifier, warning type, and warning security information.
// There is no field for the content/text so we get the text from the resources.
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP, header.getGeographicalScope(),
- header.getSerialNumber(), location, header.getServiceCategory(), null, 0,
- getEtwsPrimaryMessage(context, header.getEtwsInfo().getWarningType()),
- SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, header.getEtwsInfo(),
- header.getCmasInfo(), 0, null, receivedTimeMillis, slotIndex, subId);
+ header.getSerialNumber(), location, header.getServiceCategory(), null,
+ header.getDataCodingScheme(), getEtwsPrimaryMessage(context,
+ header.getEtwsInfo().getWarningType()), SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY,
+ header.getEtwsInfo(), header.getCmasInfo(), 0, null, receivedTimeMillis,
+ slotIndex, subId);
} else if (header.isUmtsFormat()) {
// UMTS format has only 1 PDU
byte[] pdu = pdus[0];
@@ -144,9 +148,9 @@
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
header.getGeographicalScope(), header.getSerialNumber(), location,
- header.getServiceCategory(), language, 0, body, priority,
- header.getEtwsInfo(), header.getCmasInfo(), maximumWaitingTimeSec, geometries,
- receivedTimeMillis, slotIndex, subId);
+ header.getServiceCategory(), language, header.getDataCodingScheme(), body,
+ priority, header.getEtwsInfo(), header.getCmasInfo(), maximumWaitingTimeSec,
+ geometries, receivedTimeMillis, slotIndex, subId);
} else {
String language = null;
StringBuilder sb = new StringBuilder();
@@ -160,9 +164,9 @@
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
header.getGeographicalScope(), header.getSerialNumber(), location,
- header.getServiceCategory(), language, 0, sb.toString(), priority,
- header.getEtwsInfo(), header.getCmasInfo(), 0, null, receivedTimeMillis,
- slotIndex, subId);
+ header.getServiceCategory(), language, header.getDataCodingScheme(),
+ sb.toString(), priority, header.getEtwsInfo(), header.getCmasInfo(), 0, null,
+ receivedTimeMillis, slotIndex, subId);
}
}
@@ -206,6 +210,9 @@
return new GeoFencingTriggerMessage(type, cbIdentifiers);
} catch (Exception ex) {
Log.e(TAG, "create geo-fencing trigger failed, ex = " + ex.toString());
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_INVALID_GEO_FENCING_DATA,
+ ex.toString());
return null;
}
}
@@ -226,8 +233,13 @@
int offset = wacOffset + 2;
if (offset + wacDataLength > pdu.length) {
- throw new IllegalArgumentException("Invalid wac data, expected the length of pdu at"
- + "least " + offset + wacDataLength + ", actual is " + pdu.length);
+ IllegalArgumentException ex = new IllegalArgumentException(
+ "Invalid wac data, expected the length of pdu at least " + offset
+ + wacDataLength + ", actual is " + pdu.length);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_UMTS_INVALID_WAC,
+ ex.toString());
+ throw ex;
}
BitStreamReader bitReader = new BitStreamReader(pdu, offset);
@@ -268,7 +280,12 @@
geo.add(new Circle(center, radius));
break;
default:
- throw new IllegalArgumentException("Unsupported geoType = " + type);
+ IllegalArgumentException ex = new IllegalArgumentException(
+ "Unsupported geoType = " + type);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_UMTS_INVALID_WAC,
+ ex.toString());
+ throw ex;
}
}
return new Pair(maximumWaitTimeSec, geo);
diff --git a/src/com/android/cellbroadcastservice/SmsCbHeader.java b/src/com/android/cellbroadcastservice/SmsCbHeader.java
index 61a07d2..186d9f1 100644
--- a/src/com/android/cellbroadcastservice/SmsCbHeader.java
+++ b/src/com/android/cellbroadcastservice/SmsCbHeader.java
@@ -131,6 +131,8 @@
public SmsCbHeader(byte[] pdu) throws IllegalArgumentException {
if (pdu == null || pdu.length < PDU_HEADER_LENGTH) {
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_INVALID_HEADER_LENGTH);
throw new IllegalArgumentException("Illegal PDU");
}
@@ -186,7 +188,12 @@
int messageType = pdu[0];
if (messageType != MESSAGE_TYPE_CBS_MESSAGE) {
- throw new IllegalArgumentException("Unsupported message type " + messageType);
+ IllegalArgumentException ex = new IllegalArgumentException(
+ "Unsupported message type " + messageType);
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_UNSUPPORTED_HEADER_MESSAGE_TYPE,
+ ex.toString());
+ throw ex;
}
mMessageIdentifier = ((pdu[1] & 0xff) << 8) | pdu[2] & 0xff;
@@ -562,6 +569,9 @@
// UDH structure not supported
case 0x0e:
// Defined by the WAP forum not supported
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_ERROR,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_ERROR__TYPE__GSM_UNSUPPORTED_HEADER_DATA_CODING_SCHEME,
+ "Unsupported GSM dataCodingScheme " + dataCodingScheme);
throw new IllegalArgumentException("Unsupported GSM dataCodingScheme "
+ dataCodingScheme);
diff --git a/src/com/android/cellbroadcastservice/WakeLockStateMachine.java b/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
index 0cb5352..5e8f56b 100644
--- a/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
+++ b/src/com/android/cellbroadcastservice/WakeLockStateMachine.java
@@ -220,7 +220,7 @@
/**
* BroadcastReceiver to send message to return to idle state.
*/
- protected final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ protected final BroadcastReceiver mOrderedBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (mReceiverCount.decrementAndGet() == 0) {
diff --git a/tests/Android.bp b/tests/Android.bp
index e04c259..58ca86a 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -16,7 +16,7 @@
],
srcs: ["src/**/*.java", ":cellbroadcast-shared-srcs"],
platform_apis: true,
- test_suites: ["device-tests"],
+ test_suites: ["device-tests", "mts"],
certificate: "platform",
instrumentation_for: "CellBroadcastServiceModule",
}
diff --git a/tests/src/com/android/cellbroadcastservice/tests/CdmaSmsMessageTest.java b/tests/src/com/android/cellbroadcastservice/tests/CdmaSmsMessageTest.java
index 171d437..277326b 100644
--- a/tests/src/com/android/cellbroadcastservice/tests/CdmaSmsMessageTest.java
+++ b/tests/src/com/android/cellbroadcastservice/tests/CdmaSmsMessageTest.java
@@ -43,7 +43,7 @@
import java.util.Random;
/**
- * Test cases to verify that our parseBroadcastSms function correctly works with the
+ * Test cases to verify that our parseCdmaBroadcastSms function correctly works with the
* CdmaSmsMessage class.
*/
@RunWith(AndroidTestingRunner.class)
@@ -448,9 +448,9 @@
BearerData.LANGUAGE_ENGLISH, encoding, TEST_TEXT);
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(context,
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(context,
0, "", msg.getEnvelopeBearerData(), msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
verifyCbValues(cbMessage);
assertEquals(123, cbMessage.getServiceCategory());
assertEquals(456, cbMessage.getSerialNumber());
@@ -483,9 +483,9 @@
ENCODING_7BIT_ASCII, body, -1, -1, -1, -1, -1);
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(context,
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(context,
0, "", msg.getEnvelopeBearerData(), msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
verifyCbValues(cbMessage);
assertEquals(serviceCategory, cbMessage.getServiceCategory());
assertEquals(1234, cbMessage.getSerialNumber());
@@ -544,9 +544,9 @@
SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(mMockedContext,
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(mMockedContext,
0, "", msg.getEnvelopeBearerData(), msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
verifyCbValues(cbMessage);
assertEquals(CdmaSmsCbProgramData.CATEGORY_CMAS_EXTREME_THREAT,
cbMessage.getServiceCategory());
@@ -575,9 +575,9 @@
0x1F, EXTREME_ALERT, -1, -1, -1, -1, -1);
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(mMockedContext,
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(mMockedContext,
0, "", msg.getEnvelopeBearerData(), msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
assertNull("expected null for unsupported charset", cbMessage);
}
@@ -590,9 +590,9 @@
ENCODING_KOREAN, EXTREME_ALERT, -1, -1, -1, -1, -1);
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(mMockedContext,
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(mMockedContext,
0, "", msg.getEnvelopeBearerData(), msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
assertNull("expected null for unsupported charset", cbMessage);
}
@@ -606,9 +606,9 @@
ENCODING_7BIT_ASCII, null, -1, -1, -1, -1, -1);
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(mMockedContext,
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(mMockedContext,
0, "", msg.getEnvelopeBearerData(), msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
verifyCbValues(cbMessage);
assertEquals(CdmaSmsCbProgramData.CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
cbMessage.getServiceCategory());
@@ -643,11 +643,11 @@
CdmaSmsMessage cdmaSmsMessage = createBroadcastParcel(category);
SmsMessage msg = createMessageFromParcel(cdmaSmsMessage, data);
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(
mMockedContext,
0, "", msg.getEnvelopeBearerData(),
msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
// with random input, cbMessage will almost always be null (log when it isn't)
if (cbMessage != null) {
Log.d(TAG, "success: " + cbMessage);
@@ -682,9 +682,9 @@
SmsMessage msg = createMessageFromParcel(cdmaSmsMessage, bos.toByteArray());
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(mMockedContext, 0, "",
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(mMockedContext, 0, "",
msg.getEnvelopeBearerData(), msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
} catch (Exception e) {
Log.d(TAG, "exception thrown", e);
fail("Exception in decoder at run " + run + " length " + len + ": " + e);
@@ -854,9 +854,9 @@
SmsMessage msg = createMessageFromParcel(cdmaSmsMessage, CMAS_TEST_BEARER_DATA);
SmsCbMessage cbMessage =
- DefaultCellBroadcastService.parseBroadcastSms(mMockedContext,
+ DefaultCellBroadcastService.parseCdmaBroadcastSms(mMockedContext,
0, "", msg.getEnvelopeBearerData(), msg.getEnvelopeServiceCategory());
- //SmsCbMessage cbMessage = msg.parseBroadcastSms("", 0);
+ //SmsCbMessage cbMessage = msg.parseCdmaBroadcastSms("", 0);
assertNotNull("expected non-null for bearer data", cbMessage);
assertEquals("geoScope", cbMessage.getGeographicalScope(), 1);
assertEquals("serialNumber", cbMessage.getSerialNumber(), 51072);
diff --git a/tests/src/com/android/cellbroadcastservice/tests/CellBroadcastServiceTestBase.java b/tests/src/com/android/cellbroadcastservice/tests/CellBroadcastServiceTestBase.java
index 009986e..fc96ed1 100644
--- a/tests/src/com/android/cellbroadcastservice/tests/CellBroadcastServiceTestBase.java
+++ b/tests/src/com/android/cellbroadcastservice/tests/CellBroadcastServiceTestBase.java
@@ -18,6 +18,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
@@ -135,6 +136,7 @@
return null;
}).when(mMockedContext).registerReceiver(
any(BroadcastReceiver.class), any(IntentFilter.class));
+ doReturn(true).when(mMockedLocationManager).isProviderEnabled(anyString());
}
protected void tearDown() throws Exception {
@@ -158,6 +160,8 @@
doReturn(value).when(mMockedResources).getInteger(eq(id));
} else if (value instanceof Integer[]) {
doReturn(value).when(mMockedResources).getIntArray(eq(id));
+ } else if (value instanceof int[]) {
+ doReturn(value).when(mMockedResources).getIntArray(eq(id));
} else if (value instanceof String) {
doReturn(value).when(mMockedResources).getString(eq(id));
}
diff --git a/tests/src/com/android/cellbroadcastservice/tests/GsmCellBroadcastHandlerTest.java b/tests/src/com/android/cellbroadcastservice/tests/GsmCellBroadcastHandlerTest.java
index 837fdcc..0ecaec1 100644
--- a/tests/src/com/android/cellbroadcastservice/tests/GsmCellBroadcastHandlerTest.java
+++ b/tests/src/com/android/cellbroadcastservice/tests/GsmCellBroadcastHandlerTest.java
@@ -21,6 +21,7 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.ContentValues;
@@ -28,6 +29,8 @@
import android.content.res.Resources;
import android.database.Cursor;
import android.database.MatrixCursor;
+import android.location.Location;
+import android.location.LocationRequest;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
@@ -52,8 +55,10 @@
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import java.util.Map;
+import java.util.function.Consumer;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -157,7 +162,11 @@
putResources(com.android.cellbroadcastservice.R.integer.message_expiration_time, 86400000);
putResources(
com.android.cellbroadcastservice.R.array.config_defaultCellBroadcastReceiverPkgs,
- new String[]{"fake.cellbroadcast.pkg"});
+ new String[]{"fake.cellcbroadcast.pkg"});
+ putResources(com.android.cellbroadcastservice.R.array.area_info_channels, new int[]{});
+ putResources(
+ com.android.cellbroadcastservice.R.array.config_area_info_receiver_packages,
+ new String[]{"fake.inforeceiver.pkg"});
}
@After
@@ -168,6 +177,7 @@
@Test
@SmallTest
public void testTriggerMessage() throws Exception {
+ doReturn(false).when(mMockedLocationManager).isProviderEnabled(anyString());
final byte[] pdu = hexStringToBytes("0001113001010010C0111204D2");
mGsmCellBroadcastHandler.onGsmCellBroadcastSms(0, pdu);
mTestableLooper.processAllMessages();
@@ -202,4 +212,27 @@
verify(mMockedContext, never()).sendOrderedBroadcast(any(), anyString(), anyString(),
any(), any(), anyInt(), any(), any());
}
+
+ @Test
+ @SmallTest
+ public void testGeofencingAlertOutOfPolygon() {
+ final byte[] pdu = hexStringToBytes("01111D7090010254747A0E4ACF416110B538A582DE6650906AA28"
+ + "2AE6979995D9ECF41C576597E2EBBC77950905D96D3D3EE33689A9FD3CB6D1708CA2E87E76550FAE"
+ + "C7ECBCB203ABA0C6A97E7F3F0B9EC02C15CB5769A5D0652A030FB1ECECF5D5076393C2F83C8E9B9B"
+ + "C7C0ECBC9203A3A3D07B5CBF379F85C06E16030580D660BB662B51A0D57CC3500000000000000000"
+ + "0000000000000000000000000000000000000000000000000003021002078B53B6CA4B84B53988A4"
+ + "B86B53958A4C2DB53B54A4C28B53B6CA4B840100CFF");
+ mGsmCellBroadcastHandler.onGsmCellBroadcastSms(0, pdu);
+ mTestableLooper.processAllMessages();
+
+ ArgumentCaptor<Consumer<Location>> captor = ArgumentCaptor.forClass(Consumer.class);
+ verify(mMockedLocationManager, times(2)).getCurrentLocation(
+ any(LocationRequest.class), any(), any(), captor.capture());
+
+ Consumer<Location> consumer = captor.getValue();
+ consumer.accept(Mockito.mock(Location.class));
+
+ verify(mMockedContext, never()).sendOrderedBroadcast(any(), anyString(), anyString(),
+ any(), any(), anyInt(), any(), any());
+ }
}
diff --git a/tests/src/com/android/cellbroadcastservice/tests/GsmSmsCbMessageTest.java b/tests/src/com/android/cellbroadcastservice/tests/GsmSmsCbMessageTest.java
index 73820b6..e1c9308 100644
--- a/tests/src/com/android/cellbroadcastservice/tests/GsmSmsCbMessageTest.java
+++ b/tests/src/com/android/cellbroadcastservice/tests/GsmSmsCbMessageTest.java
@@ -17,6 +17,8 @@
package com.android.cellbroadcastservice.tests;
import android.telephony.CbGeoUtils;
+import android.telephony.CbGeoUtils.Circle;
+import android.telephony.CbGeoUtils.Polygon;
import android.telephony.SmsCbCmasInfo;
import android.telephony.SmsCbEtwsInfo;
import android.telephony.SmsCbLocation;
@@ -27,8 +29,6 @@
import androidx.test.InstrumentationRegistry;
-import com.android.cellbroadcastservice.CbGeoUtils.Circle;
-import com.android.cellbroadcastservice.CbGeoUtils.Polygon;
import com.android.cellbroadcastservice.GsmSmsCbMessage;
import com.android.cellbroadcastservice.R;
import com.android.cellbroadcastservice.SmsCbConstants;