Added area info support in cell broadcast service am: 87db6b74ba am: bd8106d00d
Change-Id: I0fcde329f3b06bf245ae41a3b7bac2e4ce8857b7
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e075727..7b71d76 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -30,6 +30,8 @@
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <protected-broadcast android:name="android.telephony.action.AREA_INFO_UPDATED" />
+
<uses-sdk android:minSdkVersion="29"/>
<application android:label="Module used to handle cell broadcasts."
diff --git a/res/values/config.xml b/res/values/config.xml
index 23c8177..7f02d4a 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -37,4 +37,13 @@
<!-- 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">
+ </string-array>
</resources>
diff --git a/src/com/android/cellbroadcastservice/DefaultCellBroadcastService.java b/src/com/android/cellbroadcastservice/DefaultCellBroadcastService.java
index 70d23ae..6b99801 100644
--- a/src/com/android/cellbroadcastservice/DefaultCellBroadcastService.java
+++ b/src/com/android/cellbroadcastservice/DefaultCellBroadcastService.java
@@ -16,6 +16,7 @@
package com.android.cellbroadcastservice;
+import android.annotation.NonNull;
import android.content.Context;
import android.os.Bundle;
import android.telephony.CellBroadcastService;
@@ -100,6 +101,12 @@
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
*
diff --git a/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java b/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
index fb04fa0..a61cc6d 100644
--- a/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
+++ b/src/com/android/cellbroadcastservice/GsmCellBroadcastHandler.java
@@ -16,17 +16,21 @@
package com.android.cellbroadcastservice;
+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;
@@ -36,6 +40,7 @@
import android.telephony.TelephonyManager;
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 +51,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 +62,8 @@
/** Indicates that a message is not being broadcasted. */
private static final String MESSAGE_NOT_BROADCASTED = "0";
+ private 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 +87,18 @@
}
/**
+ * Get the area information
+ *
+ * @param slotIndex SIM slot index
+ * @return The area information
+ */
+ @NonNull
+ public String getCellBroadcastAreaInfo(int slotIndex) {
+ String 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 +222,47 @@
}
/**
+ * 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())) {
+ 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,6 +290,12 @@
if (isDuplicate(cbMessage)) {
return false;
}
+
+ if (handleAreaInfoMessage(slotIndex, cbMessage)) {
+ log("Channel " + cbMessage.getServiceCategory() + " message processed");
+ return false;
+ }
+
handleBroadcastSms(cbMessage);
return true;
}
diff --git a/tests/src/com/android/cellbroadcastservice/tests/CellBroadcastServiceTestBase.java b/tests/src/com/android/cellbroadcastservice/tests/CellBroadcastServiceTestBase.java
index 009986e..9ec3489 100644
--- a/tests/src/com/android/cellbroadcastservice/tests/CellBroadcastServiceTestBase.java
+++ b/tests/src/com/android/cellbroadcastservice/tests/CellBroadcastServiceTestBase.java
@@ -158,6 +158,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..4e9e62e 100644
--- a/tests/src/com/android/cellbroadcastservice/tests/GsmCellBroadcastHandlerTest.java
+++ b/tests/src/com/android/cellbroadcastservice/tests/GsmCellBroadcastHandlerTest.java
@@ -157,7 +157,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