Update Telephony APIs for Cell Broadcast
Bug: 256043136
Test: atest CtsTelephonyTestCases
Test: manual
Change-Id: Ib1b149c5902c1615b6f1aa118c6f809c0486ff33
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index b3cbba2..bdf20f1 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -13080,6 +13080,17 @@
method @NonNull public java.util.List<android.telephony.CbGeoUtils.LatLng> getVertices();
}
+ public final class CellBroadcastIdRange implements android.os.Parcelable {
+ ctor public CellBroadcastIdRange(int, int, int, boolean) throws java.lang.IllegalArgumentException;
+ method public int describeContents();
+ method public int getEndId();
+ method public int getStartId();
+ method public int getType();
+ method public boolean isEnabled();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellBroadcastIdRange> CREATOR;
+ }
+
public class CellBroadcastIntents {
method public static void sendSmsCbReceivedBroadcast(@NonNull android.content.Context, @Nullable android.os.UserHandle, @NonNull android.telephony.SmsCbMessage, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, int);
field public static final String ACTION_AREA_INFO_UPDATED = "android.telephony.action.AREA_INFO_UPDATED";
@@ -13639,10 +13650,10 @@
}
public final class SmsManager {
- method public boolean disableCellBroadcastRange(int, int, int);
- method public boolean enableCellBroadcastRange(int, int, int);
+ method @Deprecated public boolean disableCellBroadcastRange(int, int, int);
+ method @Deprecated public boolean enableCellBroadcastRange(int, int, int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public void resetAllCellBroadcastRanges();
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public void resetAllCellBroadcastRanges();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int);
field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3
@@ -13847,6 +13858,7 @@
method public String getCdmaPrlVersion();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaSubscriptionMode();
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public java.util.List<android.telephony.CellBroadcastIdRange> getCellBroadcastIdRanges();
method public int getCurrentPhoneType();
method public int getCurrentPhoneType(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState();
@@ -13935,6 +13947,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaRoamingMode(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaSubscriptionMode(int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public void setCellBroadcastIdRanges(@NonNull java.util.List<android.telephony.CellBroadcastIdRange>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
@@ -13998,6 +14011,11 @@
field public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
field public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
field public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
+ field public static final int CELLBROADCAST_RESULT_FAIL_ACTIVATION = 3; // 0x3
+ field public static final int CELLBROADCAST_RESULT_FAIL_CONFIG = 2; // 0x2
+ field public static final int CELLBROADCAST_RESULT_SUCCESS = 0; // 0x0
+ field public static final int CELLBROADCAST_RESULT_UNKNOWN = -1; // 0xffffffff
+ field public static final int CELLBROADCAST_RESULT_UNSUPPORTED = 1; // 0x1
field public static final int ENABLE_NR_DUAL_CONNECTIVITY_INVALID_STATE = 4; // 0x4
field public static final int ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED = 1; // 0x1
field public static final int ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR = 3; // 0x3
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 4109425..1069445 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -501,6 +501,7 @@
<permission name="android.permission.CAPTURE_MEDIA_OUTPUT" />
<permission name="android.permission.CAPTURE_TUNER_AUDIO_INPUT" />
<permission name="android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT" />
+ <permission name="android.permission.MODIFY_CELL_BROADCASTS" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 47794b8..682774e 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -701,6 +701,7 @@
<!-- Permission required for CTS test - CtsTelephonyTestCases -->
<uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE" />
+ <uses-permission android:name="android.permission.MODIFY_CELL_BROADCASTS" />
<!-- Permission required for CTS test - CtsPersistentDataBlockManagerTestCases -->
<uses-permission android:name="android.permission.ACCESS_PDB_STATE" />
diff --git a/telephony/java/android/telephony/CellBroadcastIdRange.aidl b/telephony/java/android/telephony/CellBroadcastIdRange.aidl
new file mode 100644
index 0000000..ddaceff
--- /dev/null
+++ b/telephony/java/android/telephony/CellBroadcastIdRange.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022, 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 android.telephony;
+
+parcelable CellBroadcastIdRange;
diff --git a/telephony/java/android/telephony/CellBroadcastIdRange.java b/telephony/java/android/telephony/CellBroadcastIdRange.java
new file mode 100644
index 0000000..eaf4f1c
--- /dev/null
+++ b/telephony/java/android/telephony/CellBroadcastIdRange.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2022 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 android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Describes a particular cell broadcast message identifier range.
+ * @hide
+ */
+@SystemApi
+public final class CellBroadcastIdRange implements Parcelable {
+
+ private int mStartId;
+ private int mEndId;
+ private int mType;
+ private boolean mIsEnabled;
+
+ /**
+ * Create a new CellBroacastRange
+ *
+ * @param startId first message identifier as specified in TS 23.041 (3GPP)
+ * or C.R1001-G (3GPP2)
+ * @param endId last message identifier as specified in TS 23.041 (3GPP)
+ * or C.R1001-G (3GPP2)
+ * @param type the message format as defined in {@link SmsCbMessage}
+ * @param isEnabled whether the range is enabled
+ *
+ * @throws IllegalArgumentException if endId < startId or invalid value
+ */
+ public CellBroadcastIdRange(int startId, int endId,
+ @android.telephony.SmsCbMessage.MessageFormat int type, boolean isEnabled)
+ throws IllegalArgumentException {
+ if (startId < 0 || endId < 0) {
+ throw new IllegalArgumentException("invalid id");
+ }
+ if (endId < startId) {
+ throw new IllegalArgumentException("endId must be greater than or equal to startId");
+ }
+ mStartId = startId;
+ mEndId = endId;
+ mType = type;
+ mIsEnabled = isEnabled;
+ }
+
+ /**
+ * Return the first message identifier of this range as specified in TS 23.041 (3GPP)
+ * or C.R1001-G (3GPP2)
+ */
+ public int getStartId() {
+ return mStartId;
+ }
+
+ /**
+ * Return the last message identifier of this range as specified in TS 23.041 (3GPP)
+ * or C.R1001-G (3GPP2)
+ */
+ public int getEndId() {
+ return mEndId;
+ }
+
+ /**
+ * Return the message format of this range as defined in {@link SmsCbMessage}
+ */
+ public @android.telephony.SmsCbMessage.MessageFormat int getType() {
+ return mType;
+ }
+
+ /**
+ * Return whether the range is enabled
+ */
+ public boolean isEnabled() {
+ return mIsEnabled;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mStartId);
+ out.writeInt(mEndId);
+ out.writeInt(mType);
+ out.writeBoolean(mIsEnabled);
+ }
+
+ /**
+ * {@link Parcelable.Creator}
+ *
+ */
+ public static final @NonNull Parcelable.Creator<CellBroadcastIdRange> CREATOR =
+ new Creator<CellBroadcastIdRange>() {
+ @NonNull
+ @Override
+ public CellBroadcastIdRange createFromParcel(Parcel in) {
+ int startId = in.readInt();
+ int endId = in.readInt();
+ int type = in.readInt();
+ boolean isEnabled = in.readBoolean();
+
+ return new CellBroadcastIdRange(startId, endId, type, isEnabled);
+ }
+
+ @NonNull
+ @Override
+ public CellBroadcastIdRange[] newArray(int size) {
+ return new CellBroadcastIdRange[size];
+ }
+ };
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mStartId, mEndId, mType, mIsEnabled);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof CellBroadcastIdRange)) {
+ return false;
+ }
+
+ CellBroadcastIdRange other = (CellBroadcastIdRange) obj;
+
+ return mStartId == other.mStartId && mEndId == other.mEndId && mType == other.mType
+ && mIsEnabled == other.mIsEnabled;
+ }
+
+ @Override
+ public String toString() {
+ return "CellBroadcastIdRange[" + mStartId + ", " + mEndId + ", " + mType + ", "
+ + mIsEnabled + "]";
+ }
+}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index d1f19ee..8106819 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -1914,8 +1914,10 @@
* @see #disableCellBroadcastRange(int, int, int)
*
* @throws IllegalArgumentException if endMessageId < startMessageId
+ * @deprecated Use {@link TelephonyManager#setCellBroadcastRanges} instead.
* {@hide}
*/
+ @Deprecated
@SystemApi
public boolean enableCellBroadcastRange(int startMessageId, int endMessageId,
@android.telephony.SmsCbMessage.MessageFormat int ranType) {
@@ -1974,8 +1976,10 @@
* @see #enableCellBroadcastRange(int, int, int)
*
* @throws IllegalArgumentException if endMessageId < startMessageId
+ * @deprecated Use {@link TelephonyManager#setCellBroadcastRanges} instead.
* {@hide}
*/
+ @Deprecated
@SystemApi
public boolean disableCellBroadcastRange(int startMessageId, int endMessageId,
@android.telephony.SmsCbMessage.MessageFormat int ranType) {
@@ -3374,8 +3378,10 @@
/**
* Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this.
+ * @deprecated Use {@link TelephonyManager#resetAllCellBroadcastRanges} instead
* @hide
*/
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
public void resetAllCellBroadcastRanges() {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c926a23..950b26c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -17821,4 +17821,115 @@
ex.rethrowFromSystemServer();
}
}
+
+ /**
+ * Get current cell broadcast message identifier ranges.
+ *
+ * @throws SecurityException if the caller does not have the required permission
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
+ @NonNull
+ public List<CellBroadcastIdRange> getCellBroadcastIdRanges() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.getCellBroadcastIdRanges(getSubId());
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ return new ArrayList<>();
+ }
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"CELLBROADCAST_RESULT_"}, value = {
+ CELLBROADCAST_RESULT_UNKNOWN,
+ CELLBROADCAST_RESULT_SUCCESS,
+ CELLBROADCAST_RESULT_UNSUPPORTED,
+ CELLBROADCAST_RESULT_FAIL_CONFIG,
+ CELLBROADCAST_RESULT_FAIL_ACTIVATION})
+ public @interface CellBroadcastResult {}
+
+ /**
+ * The result of the cell broadcast request is unknown
+ * @hide
+ */
+ @SystemApi
+ public static final int CELLBROADCAST_RESULT_UNKNOWN = -1;
+
+ /**
+ * The cell broadcast request is successful.
+ * @hide
+ */
+ @SystemApi
+ public static final int CELLBROADCAST_RESULT_SUCCESS = 0;
+
+ /**
+ * The cell broadcast request is not supported.
+ * @hide
+ */
+ @SystemApi
+ public static final int CELLBROADCAST_RESULT_UNSUPPORTED = 1;
+
+ /**
+ * The cell broadcast request is failed due to the error to set config
+ * @hide
+ */
+ @SystemApi
+ public static final int CELLBROADCAST_RESULT_FAIL_CONFIG = 2;
+
+ /**
+ * The cell broadcast request is failed due to the error to set activation
+ * @hide
+ */
+ @SystemApi
+ public static final int CELLBROADCAST_RESULT_FAIL_ACTIVATION = 3;
+
+ /**
+ * Set reception of cell broadcast messages with the list of the given ranges
+ *
+ * <p>The ranges set previously will be overridden by the new one. Empty list
+ * can be used to clear the ranges.
+ *
+ * @param ranges the list of {@link CellBroadcastIdRange} to be set.
+ * @param executor The {@link Executor} that will be used to call the callback.
+ * @param callback A callback called on the supplied {@link Executor} to notify
+ * the result when the operation completes.
+ * @throws SecurityException if the caller does not have the required permission
+ * @throws IllegalArgumentException when the ranges are invalid.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
+ public void setCellBroadcastIdRanges(@NonNull List<CellBroadcastIdRange> ranges,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<Integer> callback) {
+ IIntegerConsumer consumer = callback == null ? null : new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> callback.accept(result));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ };
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ telephony.setCellBroadcastIdRanges(getSubId(), ranges, consumer);
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 9445d076..33da454 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -35,6 +35,7 @@
import android.telephony.CarrierRestrictionRules;
import android.telephony.CellIdentity;
import android.telephony.CellInfo;
+import android.telephony.CellBroadcastIdRange;
import android.telephony.ClientRequestStats;
import android.telephony.ThermalMitigationRequest;
import android.telephony.gba.UaSecurityProtocolIdentifier;
@@ -2658,4 +2659,15 @@
* @hide
*/
boolean isNullCipherAndIntegrityPreferenceEnabled();
+
+ /**
+ * Get current broadcast ranges.
+ */
+ List<CellBroadcastIdRange> getCellBroadcastIdRanges(int subId);
+
+ /**
+ * Set reception of cell broadcast messages with the list of the given ranges
+ */
+ void setCellBroadcastIdRanges(int subId, in List<CellBroadcastIdRange> ranges,
+ IIntegerConsumer callback);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
index f4f4036..b70d548 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.gsm;
+import java.util.Objects;
+
/**
* SmsBroadcastConfigInfo defines one configuration of Cell Broadcast
* Message (CBM) to be received by the ME
@@ -130,4 +132,24 @@
mFromCodeScheme + ',' + mToCodeScheme + "] " +
(mSelected ? "ENABLED" : "DISABLED");
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mFromServiceId, mToServiceId,
+ mFromCodeScheme, mToCodeScheme, mSelected);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof SmsBroadcastConfigInfo)) {
+ return false;
+ }
+
+ SmsBroadcastConfigInfo other = (SmsBroadcastConfigInfo) obj;
+
+ return mFromServiceId == other.mFromServiceId
+ && mToServiceId == other.mToServiceId
+ && mFromCodeScheme == other.mFromCodeScheme
+ && mToCodeScheme == other.mToCodeScheme && mSelected == other.mSelected;
+ }
}