diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 542de3fad8b0e..0d8b1f83b7fe1 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -27,6 +27,7 @@ import android.os.Binder; import android.os.Build; import android.os.RemoteException; import android.os.ServiceManager; +import android.service.carrier.CarrierService; import android.telephony.Annotation.CallState; import android.telephony.Annotation.DataActivityType; import android.telephony.Annotation.DisconnectCauses; @@ -36,6 +37,7 @@ import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; +import android.telephony.TelephonyManager.CarrierPrivilegesCallback; import android.telephony.TelephonyManager.CarrierPrivilegesListener; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; @@ -44,17 +46,19 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.listeners.ListenerExecutor; -import com.android.internal.telephony.ICarrierPrivilegesListener; +import com.android.internal.telephony.ICarrierPrivilegesCallback; import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ITelephonyRegistry; import java.lang.ref.WeakReference; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.Executor; +import java.util.stream.Collectors; /** * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update @@ -1258,34 +1262,78 @@ public class TelephonyRegistryManager { pkgName, attributionTag, callback, new int[0], notifyNow); } - private static class CarrierPrivilegesListenerWrapper extends ICarrierPrivilegesListener.Stub + // TODO(b/216549778): Remove listener logic once all clients switch to CarrierPrivilegesCallback + private static class CarrierPrivilegesCallbackWrapper extends ICarrierPrivilegesCallback.Stub implements ListenerExecutor { - private final WeakReference mListener; - private final Executor mExecutor; + // Either mListener or mCallback may be null, never both + @Nullable private final WeakReference mListener; + @Nullable private final WeakReference mCallback; + @NonNull private final Executor mExecutor; - CarrierPrivilegesListenerWrapper(CarrierPrivilegesListener listener, Executor executor) { + CarrierPrivilegesCallbackWrapper( + @NonNull CarrierPrivilegesCallback callback, @NonNull Executor executor) { + mListener = null; + mCallback = new WeakReference<>(callback); + mExecutor = executor; + } + + CarrierPrivilegesCallbackWrapper( + @NonNull CarrierPrivilegesListener listener, @NonNull Executor executor) { mListener = new WeakReference<>(listener); + mCallback = null; mExecutor = executor; } @Override public void onCarrierPrivilegesChanged( - List privilegedPackageNames, int[] privilegedUids) { - Binder.withCleanCallingIdentity( - () -> - executeSafely( - mExecutor, - mListener::get, - cpl -> - cpl.onCarrierPrivilegesChanged( - privilegedPackageNames, privilegedUids))); + @NonNull List privilegedPackageNames, @NonNull int[] privilegedUids) { + if (mListener != null) { + Binder.withCleanCallingIdentity( + () -> + executeSafely( + mExecutor, + mListener::get, + cpl -> + cpl.onCarrierPrivilegesChanged( + privilegedPackageNames, privilegedUids))); + } + + if (mCallback != null) { + // AIDL interface does not support Set, keep the List/Array and translate them here + Set privilegedPkgNamesSet = Set.copyOf(privilegedPackageNames); + Set privilegedUidsSet = Arrays.stream(privilegedUids).boxed().collect( + Collectors.toSet()); + Binder.withCleanCallingIdentity( + () -> + executeSafely( + mExecutor, + mCallback::get, + cpc -> + cpc.onCarrierPrivilegesChanged( + privilegedPkgNamesSet, privilegedUidsSet))); + } + } + + @Override + public void onCarrierServiceChanged(@Nullable String packageName, int uid) { + if (mCallback != null) { + Binder.withCleanCallingIdentity( + () -> + executeSafely( + mExecutor, + mCallback::get, + cpc -> cpc.onCarrierServiceChanged(packageName, uid))); + } } } - @GuardedBy("sCarrierPrivilegeListeners") - private static final WeakHashMap< - CarrierPrivilegesListener, WeakReference> - sCarrierPrivilegeListeners = new WeakHashMap<>(); + // TODO(b/216549778): Change the map key to CarrierPrivilegesCallback once all clients switch to + // CarrierPrivilegesCallback. Before that, the key is either CarrierPrivilegesCallback or + // CarrierPrivilegesListener, no logic actually depends on the type. + @NonNull + @GuardedBy("sCarrierPrivilegeCallbacks") + private static final WeakHashMap> + sCarrierPrivilegeCallbacks = new WeakHashMap<>(); /** * Registers a {@link CarrierPrivilegesListener} on the given {@code logicalSlotIndex} to @@ -1295,7 +1343,11 @@ public class TelephonyRegistryManager { * @param logicalSlotIndex The SIM slot to listen on * @param executor The executor where {@code listener} will be invoked * @param listener The callback to register + * + * @deprecated Use {@link #addCarrierPrivilegesCallback} instead. This API will be removed + * prior to API finalization. */ + @Deprecated public void addCarrierPrivilegesListener( int logicalSlotIndex, @NonNull @CallbackExecutor Executor executor, @@ -1303,18 +1355,18 @@ public class TelephonyRegistryManager { if (listener == null || executor == null) { throw new IllegalArgumentException("listener and executor must be non-null"); } - synchronized (sCarrierPrivilegeListeners) { - WeakReference existing = - sCarrierPrivilegeListeners.get(listener); + synchronized (sCarrierPrivilegeCallbacks) { + WeakReference existing = + sCarrierPrivilegeCallbacks.get(listener); if (existing != null && existing.get() != null) { Log.d(TAG, "addCarrierPrivilegesListener: listener already registered"); return; } - CarrierPrivilegesListenerWrapper wrapper = - new CarrierPrivilegesListenerWrapper(listener, executor); - sCarrierPrivilegeListeners.put(listener, new WeakReference<>(wrapper)); + CarrierPrivilegesCallbackWrapper wrapper = + new CarrierPrivilegesCallbackWrapper(listener, executor); + sCarrierPrivilegeCallbacks.put(listener, new WeakReference<>(wrapper)); try { - sRegistry.addCarrierPrivilegesListener( + sRegistry.addCarrierPrivilegesCallback( logicalSlotIndex, wrapper, mContext.getOpPackageName(), @@ -1329,19 +1381,84 @@ public class TelephonyRegistryManager { * Unregisters a {@link CarrierPrivilegesListener}. * * @param listener The callback to unregister + * + * @deprecated Use {@link #removeCarrierPrivilegesCallback} instead. The callback will prior + * to API finalization. */ + @Deprecated public void removeCarrierPrivilegesListener(@NonNull CarrierPrivilegesListener listener) { if (listener == null) { throw new IllegalArgumentException("listener must be non-null"); } - synchronized (sCarrierPrivilegeListeners) { - WeakReference ref = - sCarrierPrivilegeListeners.remove(listener); + synchronized (sCarrierPrivilegeCallbacks) { + WeakReference ref = + sCarrierPrivilegeCallbacks.remove(listener); if (ref == null) return; - CarrierPrivilegesListenerWrapper wrapper = ref.get(); + CarrierPrivilegesCallbackWrapper wrapper = ref.get(); if (wrapper == null) return; try { - sRegistry.removeCarrierPrivilegesListener(wrapper, mContext.getOpPackageName()); + sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to + * receive callbacks when the set of packages with carrier privileges changes. The callback will + * immediately be called with the latest state. + * + * @param logicalSlotIndex The SIM slot to listen on + * @param executor The executor where {@code listener} will be invoked + * @param callback The callback to register + */ + public void addCarrierPrivilegesCallback( + int logicalSlotIndex, + @NonNull @CallbackExecutor Executor executor, + @NonNull CarrierPrivilegesCallback callback) { + if (callback == null || executor == null) { + throw new IllegalArgumentException("callback and executor must be non-null"); + } + synchronized (sCarrierPrivilegeCallbacks) { + WeakReference existing = + sCarrierPrivilegeCallbacks.get(callback); + if (existing != null && existing.get() != null) { + Log.d(TAG, "addCarrierPrivilegesCallback: callback already registered"); + return; + } + CarrierPrivilegesCallbackWrapper wrapper = + new CarrierPrivilegesCallbackWrapper(callback, executor); + sCarrierPrivilegeCallbacks.put(callback, new WeakReference<>(wrapper)); + try { + sRegistry.addCarrierPrivilegesCallback( + logicalSlotIndex, + wrapper, + mContext.getOpPackageName(), + mContext.getAttributionTag()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Unregisters a {@link CarrierPrivilegesCallback}. + * + * @param callback The callback to unregister + */ + public void removeCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) { + if (callback == null) { + throw new IllegalArgumentException("listener must be non-null"); + } + synchronized (sCarrierPrivilegeCallbacks) { + WeakReference ref = + sCarrierPrivilegeCallbacks.remove(callback); + if (ref == null) return; + CarrierPrivilegesCallbackWrapper wrapper = ref.get(); + if (wrapper == null) return; + try { + sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1357,15 +1474,33 @@ public class TelephonyRegistryManager { */ public void notifyCarrierPrivilegesChanged( int logicalSlotIndex, - @NonNull List privilegedPackageNames, - @NonNull int[] privilegedUids) { + @NonNull Set privilegedPackageNames, + @NonNull Set privilegedUids) { if (privilegedPackageNames == null || privilegedUids == null) { throw new IllegalArgumentException( "privilegedPackageNames and privilegedUids must be non-null"); } try { - sRegistry.notifyCarrierPrivilegesChanged( - logicalSlotIndex, privilegedPackageNames, privilegedUids); + // AIDL doesn't support Set yet. Convert Set to List/Array + List pkgList = List.copyOf(privilegedPackageNames); + int[] uids = privilegedUids.stream().mapToInt(Number::intValue).toArray(); + sRegistry.notifyCarrierPrivilegesChanged(logicalSlotIndex, pkgList, uids); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Notify listeners that the {@link CarrierService} for current user has changed. + * + * @param logicalSlotIndex the SIM slot the change occurred on + * @param packageName the package name of the changed {@link CarrierService} + * @param uid the UID of the changed {@link CarrierService} + */ + public void notifyCarrierServiceChanged(int logicalSlotIndex, @Nullable String packageName, + int uid) { + try { + sRegistry.notifyCarrierServiceChanged(logicalSlotIndex, packageName, uid); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl b/core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl similarity index 84% rename from core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl rename to core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl index 6ca8cecba3c85..0c8e73fb2b677 100644 --- a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl +++ b/core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl @@ -16,7 +16,8 @@ package com.android.internal.telephony; -oneway interface ICarrierPrivilegesListener { +oneway interface ICarrierPrivilegesCallback { void onCarrierPrivilegesChanged( in List privilegedPackageNames, in int[] privilegedUids); + void onCarrierServiceChanged(in String carrierServicePackageName, in int carrierServiceUid); } diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 9712d7e38a4b6..c7fa757ac0b74 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -32,7 +32,7 @@ import android.telephony.PreciseDataConnectionState; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.emergency.EmergencyNumber; -import com.android.internal.telephony.ICarrierPrivilegesListener; +import com.android.internal.telephony.ICarrierPrivilegesCallback; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.IOnSubscriptionsChangedListener; @@ -102,9 +102,11 @@ interface ITelephonyRegistry { void notifyLinkCapacityEstimateChanged(in int phoneId, in int subId, in List linkCapacityEstimateList); - void addCarrierPrivilegesListener( - int phoneId, ICarrierPrivilegesListener callback, String pkg, String featureId); - void removeCarrierPrivilegesListener(ICarrierPrivilegesListener callback, String pkg); + void addCarrierPrivilegesCallback( + int phoneId, ICarrierPrivilegesCallback callback, String pkg, String featureId); + void removeCarrierPrivilegesCallback(ICarrierPrivilegesCallback callback, String pkg); void notifyCarrierPrivilegesChanged( int phoneId, in List privilegedPackageNames, in int[] privilegedUids); + void notifyCarrierServiceChanged(int phoneId, in String packageName, int uid); + } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 382359ab1da56..06b331164083d 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -91,7 +91,7 @@ import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; -import com.android.internal.telephony.ICarrierPrivilegesListener; +import com.android.internal.telephony.ICarrierPrivilegesCallback; import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.ITelephonyRegistry; @@ -151,7 +151,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { IPhoneStateListener callback; IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback; IOnSubscriptionsChangedListener onOpportunisticSubscriptionsChangedListenerCallback; - ICarrierPrivilegesListener carrierPrivilegesListener; + ICarrierPrivilegesCallback carrierPrivilegesCallback; int callerUid; int callerPid; @@ -176,8 +176,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { return (onOpportunisticSubscriptionsChangedListenerCallback != null); } - boolean matchCarrierPrivilegesListener() { - return carrierPrivilegesListener != null; + boolean matchCarrierPrivilegesCallback() { + return carrierPrivilegesCallback != null; } boolean canReadCallLog() { @@ -197,7 +197,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { + onSubscriptionsChangedListenerCallback + " onOpportunisticSubscriptionsChangedListenererCallback=" + onOpportunisticSubscriptionsChangedListenerCallback - + " carrierPrivilegesListener=" + carrierPrivilegesListener + + " carrierPrivilegesCallback=" + carrierPrivilegesCallback + " subId=" + subId + " phoneId=" + phoneId + " events=" + eventList + "}"; } } @@ -412,7 +412,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mPreciseDataConnectionStates; /** Per-phoneId snapshot of privileged packages (names + UIDs). */ - private List, int[]>> mCarrierPrivilegeStates; + @NonNull private List, int[]>> mCarrierPrivilegeStates; + /** Per-phoneId of CarrierService (PackageName, UID) pair. */ + @NonNull private List> mCarrierServiceStates; /** * Support backward compatibility for {@link android.telephony.TelephonyDisplayInfo}. @@ -702,22 +704,23 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { cutListToSize(mPhysicalChannelConfigs, mNumPhones); cutListToSize(mLinkCapacityEstimateLists, mNumPhones); cutListToSize(mCarrierPrivilegeStates, mNumPhones); + cutListToSize(mCarrierServiceStates, mNumPhones); return; } // mNumPhones > oldNumPhones: ss -> ds switch for (int i = oldNumPhones; i < mNumPhones; i++) { - mCallState[i] = TelephonyManager.CALL_STATE_IDLE; + mCallState[i] = TelephonyManager.CALL_STATE_IDLE; mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN; mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; - mCallIncomingNumber[i] = ""; - mServiceState[i] = new ServiceState(); - mSignalStrength[i] = null; + mCallIncomingNumber[i] = ""; + mServiceState[i] = new ServiceState(); + mSignalStrength[i] = null; mUserMobileDataState[i] = false; - mMessageWaiting[i] = false; - mCallForwarding[i] = false; + mMessageWaiting[i] = false; + mCallForwarding[i] = false; mCellIdentity[i] = null; mCellInfo.add(i, null); mImsReasonInfo.add(i, null); @@ -743,6 +746,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mAllowedNetworkTypeValue[i] = -1; mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST); mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0])); + mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID)); } } @@ -809,6 +813,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataEnabledReason = new int[numPhones]; mLinkCapacityEstimateLists = new ArrayList<>(); mCarrierPrivilegeStates = new ArrayList<>(); + mCarrierServiceStates = new ArrayList<>(); for (int i = 0; i < numPhones; i++) { mCallState[i] = TelephonyManager.CALL_STATE_IDLE; @@ -847,6 +852,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mAllowedNetworkTypeValue[i] = -1; mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST); mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0])); + mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID)); } mAppOps = mContext.getSystemService(AppOpsManager.class); @@ -2780,16 +2786,16 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void addCarrierPrivilegesListener( + public void addCarrierPrivilegesCallback( int phoneId, - ICarrierPrivilegesListener callback, - String callingPackage, - String callingFeatureId) { + @NonNull ICarrierPrivilegesCallback callback, + @NonNull String callingPackage, + @NonNull String callingFeatureId) { int callerUserId = UserHandle.getCallingUserId(); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, - "addCarrierPrivilegesListener"); + "addCarrierPrivilegesCallback"); if (VDBG) { log( "listen carrier privs: E pkg=" + pii(callingPackage) + " phoneId=" + phoneId @@ -2809,7 +2815,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (r == null) return; r.context = mContext; - r.carrierPrivilegesListener = callback; + r.carrierPrivilegesCallback = callback; r.callingPackage = callingPackage; r.callingFeatureId = callingFeatureId; r.callerUid = Binder.getCallingUid(); @@ -2821,10 +2827,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } Pair, int[]> state = mCarrierPrivilegeStates.get(phoneId); + Pair carrierServiceState = mCarrierServiceStates.get(phoneId); try { - r.carrierPrivilegesListener.onCarrierPrivilegesChanged( - Collections.unmodifiableList(state.first), - Arrays.copyOf(state.second, state.second.length)); + if (r.matchCarrierPrivilegesCallback()) { + // Here, two callbacks are triggered in quick succession on the same binder. + // In typical case, we expect the callers to care about only one or the other. + r.carrierPrivilegesCallback.onCarrierPrivilegesChanged( + Collections.unmodifiableList(state.first), + Arrays.copyOf(state.second, state.second.length)); + + r.carrierPrivilegesCallback.onCarrierServiceChanged(carrierServiceState.first, + carrierServiceState.second); + } } catch (RemoteException ex) { remove(r.binder); } @@ -2832,12 +2846,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void removeCarrierPrivilegesListener( - ICarrierPrivilegesListener callback, String callingPackage) { + public void removeCarrierPrivilegesCallback( + @NonNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage) { mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, - "removeCarrierPrivilegesListener"); + "removeCarrierPrivilegesCallback"); remove(callback.asBinder()); } @@ -2860,13 +2874,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { // Listeners are per-slot, not per-subscription. This is to provide a stable // view across SIM profile switches. - if (!r.matchCarrierPrivilegesListener() + if (!r.matchCarrierPrivilegesCallback() || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) { continue; } try { // Make sure even in-process listeners can't modify the values. - r.carrierPrivilegesListener.onCarrierPrivilegesChanged( + r.carrierPrivilegesCallback.onCarrierPrivilegesChanged( Collections.unmodifiableList(privilegedPackageNames), Arrays.copyOf(privilegedUids, privilegedUids.length)); } catch (RemoteException ex) { @@ -2877,6 +2891,34 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + @Override + public void notifyCarrierServiceChanged(int phoneId, @Nullable String packageName, int uid) { + if (!checkNotifyPermission("notifyCarrierServiceChanged")) return; + if (!validatePhoneId(phoneId)) return; + if (VDBG) { + log("notifyCarrierServiceChanged: phoneId=" + phoneId + + ", package=" + pii(packageName) + ", uid=" + uid); + } + + synchronized (mRecords) { + mCarrierServiceStates.set( + phoneId, new Pair<>(packageName, uid)); + for (Record r : mRecords) { + // Listeners are per-slot, not per-subscription. + if (!r.matchCarrierPrivilegesCallback() + || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) { + continue; + } + try { + r.carrierPrivilegesCallback.onCarrierServiceChanged(packageName, uid); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + handleRemoveListLocked(); + } + } + @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); @@ -2931,6 +2973,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println( "mCarrierPrivilegeState="); + Pair carrierServiceState = mCarrierServiceStates.get(i); + pw.println("mCarrierServiceState="); pw.decreaseIndent(); } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index c66229875ee23..47dfb42d538af 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -16252,6 +16252,7 @@ public class TelephonyManager { * @deprecated Use {@link CarrierPrivilegesCallback} instead. This API will be removed soon * prior to API finalization. */ + @Deprecated @SystemApi public interface CarrierPrivilegesListener { /** @@ -16389,8 +16390,17 @@ public class TelephonyManager { int logicalSlotIndex, @NonNull @CallbackExecutor Executor executor, @NonNull CarrierPrivilegesCallback callback) { - // TODO(b/216549778): cherry-pick implementation once merge conflict is resolved - throw new UnsupportedOperationException("Not implemented, yet"); + if (mContext == null) { + throw new IllegalStateException("Telephony service is null"); + } else if (executor == null || callback == null) { + throw new IllegalArgumentException( + "CarrierPrivilegesCallback and executor must be non-null"); + } + mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); + if (mTelephonyRegistryMgr == null) { + throw new IllegalStateException("Telephony registry service is null"); + } + mTelephonyRegistryMgr.addCarrierPrivilegesCallback(logicalSlotIndex, executor, callback); } /** @@ -16401,7 +16411,15 @@ public class TelephonyManager { @SystemApi @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) { - // TODO(b/216549778): cherry-pick implementation once merge conflict is resolved - throw new UnsupportedOperationException("Not implemented, yet"); + if (mContext == null) { + throw new IllegalStateException("Telephony service is null"); + } else if (callback == null) { + throw new IllegalArgumentException("CarrierPrivilegesCallback must be non-null"); + } + mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); + if (mTelephonyRegistryMgr == null) { + throw new IllegalStateException("Telephony registry service is null"); + } + mTelephonyRegistryMgr.removeCarrierPrivilegesCallback(callback); } }