diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java index c351d891bc618..aeb186b006863 100644 --- a/core/java/android/service/carrier/CarrierService.java +++ b/core/java/android/service/carrier/CarrierService.java @@ -114,9 +114,7 @@ public abstract class CarrierService extends Service { * this UX, so a carrier app must be sure to call with active set to false * sometime after calling with it set to true. *
- * Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
- * or the calling app has carrier privileges.
+ * Requires Permission: calling app has carrier privileges.
*
* @param active Whether the carrier network change is or shortly will be
* active. Set this value to true to begin showing
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 05b7e0c2ca5fa..8b10267f32ff8 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -73,10 +73,12 @@ import com.android.server.am.BatteryStatsService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.OptionalInt;
/**
* Since phone process can be restarted, this class provides a centralized place
@@ -1159,17 +1161,28 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
@Override
public void notifyCarrierNetworkChange(boolean active) {
- enforceNotifyPermissionOrCarrierPrivilege("notifyCarrierNetworkChange()");
+ // only CarrierService with carrier privilege rule should have the permission.
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ try {
+ subId = Arrays.stream(SubscriptionManager.from(mContext)
+ .getActiveSubscriptionIdList())
+ .filter(i -> TelephonyPermissions.checkCarrierPrivilegeForSubId(i))
+ .findFirst().getAsInt();
+ } catch (NoSuchElementException ex) {
+ log("notifyCarrierNetworkChange without carrier privilege");
+ }
+ int phoneId = SubscriptionManager.getPhoneId(subId);
if (VDBG) {
- log("notifyCarrierNetworkChange: active=" + active);
+ log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId);
}
synchronized (mRecords) {
mCarrierNetworkChangeState = active;
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE)) {
+ PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) &&
+ idMatch(r.subId, subId, phoneId)) {
try {
r.callback.onCarrierNetworkChange(active);
} catch (RemoteException ex) {
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 4886a3f8f1418..d93e58254b95c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -123,6 +123,19 @@ public final class TelephonyPermissions {
context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage, message);
}
+ /**
+ * Check whether the calling packages has carrier privileges for the passing subscription.
+ * @return {@code true} if the caller has carrier privileges, {@false} otherwise.
+ */
+ public static boolean checkCarrierPrivilegeForSubId(int subId) {
+ if (SubscriptionManager.isValidSubscriptionId(subId)
+ && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, Binder.getCallingUid())
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ return true;
+ }
+ return false;
+ }
+
@VisibleForTesting
public static boolean checkReadPhoneState(
Context context, Supplier