diff --git a/core/api/current.txt b/core/api/current.txt index c3b5b943477f..6aeed38e0adb 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -38281,7 +38281,8 @@ package android.service.carrier { public abstract class CarrierService extends android.app.Service { ctor public CarrierService(); - method public final void notifyCarrierNetworkChange(boolean); + method @Deprecated public final void notifyCarrierNetworkChange(boolean); + method public final void notifyCarrierNetworkChange(int, boolean); method @CallSuper public android.os.IBinder onBind(android.content.Intent); method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier); field public static final String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService"; diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 859fd804dea5..e7f89204c1ec 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -285,6 +285,8 @@ public class TelephonyRegistryManager { * UI. There is no timeout associated with showing this UX, so a carrier app must be sure to * call with active set to false sometime after calling with it set to {@code true}. *

+ * This will apply to all subscriptions the carrier app has carrier privileges on. + *

* Requires Permission: calling app has carrier privileges. * * @param active Whether the carrier network change is or shortly will be @@ -299,6 +301,31 @@ public class TelephonyRegistryManager { } } + /** + * Informs the system of an intentional upcoming carrier network change by a carrier app on the + * given {@code subscriptionId}. This call only used to allow the system to provide alternative + * UI while telephony is performing an action that may result in intentional, temporary network + * lack of connectivity. + *

+ * Based on the active parameter passed in, this method will either show or hide the + * alternative UI. There is no timeout associated with showing this UX, so a carrier app must be + * sure to call with active set to false sometime after calling with it set to {@code true}. + *

+ * Requires Permission: calling app has carrier privileges. + * + * @param subscriptionId the subscription of the carrier network. + * @param active whether the carrier network change is or shortly will be active. Set this value + * to true to begin showing alternative UI and false to stop. + * @see TelephonyManager#hasCarrierPrivileges + */ + public void notifyCarrierNetworkChange(int subscriptionId, boolean active) { + try { + sRegistry.notifyCarrierNetworkChangeWithSubId(subscriptionId, active); + } catch (RemoteException ex) { + // system server crash + } + } + /** * Notify call state changed on certain subscription. * diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 6ba0279313b1..15d4246e302a 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -77,6 +77,7 @@ interface ITelephonyRegistry { void notifySubscriptionInfoChanged(); void notifyOpportunisticSubscriptionInfoChanged(); void notifyCarrierNetworkChange(in boolean active); + void notifyCarrierNetworkChangeWithSubId(in int subId, in boolean active); void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state); void notifyDisplayInfoChanged(int slotIndex, int subId, in TelephonyDisplayInfo telephonyDisplayInfo); void notifyPhoneCapabilityChanged(in PhoneCapability capability); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 91cd2f6ad676..d7c1cfb7d1ed 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -366,7 +366,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private List mBarringInfo = null; - private boolean mCarrierNetworkChangeState = false; + private boolean[] mCarrierNetworkChangeState = null; private PhoneCapability mPhoneCapability = null; @@ -675,6 +675,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones); mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones); mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones); + mCarrierNetworkChangeState = copyOf(mCarrierNetworkChangeState, mNumPhones); mIsDataEnabled= copyOf(mIsDataEnabled, mNumPhones); mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones); mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones); @@ -720,6 +721,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); + mCarrierNetworkChangeState[i] = false; mTelephonyDisplayInfos[i] = null; mIsDataEnabled[i] = false; mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER; @@ -784,6 +786,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mOutgoingCallEmergencyNumber = new EmergencyNumber[numPhones]; mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones]; mBarringInfo = new ArrayList<>(); + mCarrierNetworkChangeState = new boolean[numPhones]; mTelephonyDisplayInfos = new TelephonyDisplayInfo[numPhones]; mPhysicalChannelConfigs = new ArrayList<>(); mAllowedNetworkTypeReason = new int[numPhones]; @@ -820,6 +823,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); + mCarrierNetworkChangeState[i] = false; mTelephonyDisplayInfos[i] = null; mIsDataEnabled[i] = false; mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER; @@ -1230,7 +1234,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if (events.contains(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)) { try { - r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState); + r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState[r.phoneId]); } catch (RemoteException ex) { remove(r.binder); } @@ -1724,23 +1728,37 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { throw new SecurityException("notifyCarrierNetworkChange without carrier privilege"); } - synchronized (mRecords) { - mCarrierNetworkChangeState = active; - for (int subId : subIds) { - int phoneId = getPhoneIdFromSubId(subId); + for (int subId : subIds) { + notifyCarrierNetworkChangeWithPermission(subId, active); + } + } - if (VDBG) { - log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId); - } - for (Record r : mRecords) { - if (r.matchTelephonyCallbackEvent( - TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED) - && idMatch(r, subId, phoneId)) { - try { - r.callback.onCarrierNetworkChange(active); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); - } + @Override + public void notifyCarrierNetworkChangeWithSubId(int subId, boolean active) { + if (!TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, subId)) { + throw new SecurityException( + "notifyCarrierNetworkChange without carrier privilege on subId " + subId); + } + + notifyCarrierNetworkChangeWithPermission(subId, active); + } + + private void notifyCarrierNetworkChangeWithPermission(int subId, boolean active) { + synchronized (mRecords) { + int phoneId = getPhoneIdFromSubId(subId); + mCarrierNetworkChangeState[phoneId] = active; + + if (VDBG) { + log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId); + } + for (Record r : mRecords) { + if (r.matchTelephonyCallbackEvent( + TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED) + && idMatch(r, subId, phoneId)) { + try { + r.callback.onCarrierNetworkChange(active); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); } } } @@ -2788,6 +2806,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]); pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]); pw.println("mBarringInfo=" + mBarringInfo.get(i)); + pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState[i]); pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfos[i]); pw.println("mIsDataEnabled=" + mIsDataEnabled); pw.println("mDataEnabledReason=" + mDataEnabledReason); @@ -2797,7 +2816,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mLinkCapacityEstimateList=" + mLinkCapacityEstimateLists.get(i)); pw.decreaseIndent(); } - pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState); + pw.println("mPhoneCapability=" + mPhoneCapability); pw.println("mActiveDataSubId=" + mActiveDataSubId); pw.println("mRadioPowerState=" + mRadioPowerState); diff --git a/telephony/java/android/service/carrier/CarrierService.java b/telephony/java/android/service/carrier/CarrierService.java index d06ec11f3e61..ca27998ec8a8 100644 --- a/telephony/java/android/service/carrier/CarrierService.java +++ b/telephony/java/android/service/carrier/CarrierService.java @@ -115,7 +115,12 @@ public abstract class CarrierService extends Service { * active. Set this value to true to begin showing * alternative UI and false to stop. * @see android.telephony.TelephonyManager#hasCarrierPrivileges + * @deprecated use {@link #notifyCarrierNetworkChange(int, boolean)} instead. + * With no parameter to specify the subscription, this API will + * apply to all subscriptions that the carrier app has carrier + * privileges on. */ + @Deprecated public final void notifyCarrierNetworkChange(boolean active) { TelephonyRegistryManager telephonyRegistryMgr = (TelephonyRegistryManager) this.getSystemService( @@ -125,6 +130,31 @@ public abstract class CarrierService extends Service { } } + /** + * Informs the system of an intentional upcoming carrier network change by a carrier app on the + * given {@code subscriptionId}. This call is optional and is only used to allow the system to + * provide alternative UI while telephony is performing an action that may result in + * intentional, temporary network lack of connectivity. + * + *

Based on the active parameter passed in, this method will either show or hide the + * alternative UI. There is no timeout associated with showing 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: calling app has carrier privileges. + * + * @param subscriptionId the subscription of the carrier network that trigger the change. + * @param active whether the carrier network change is or shortly will be active. Set this + * value to true to begin showing alternative UI and false to stop. + * @see android.telephony.TelephonyManager#hasCarrierPrivileges + */ + public final void notifyCarrierNetworkChange(int subscriptionId, boolean active) { + TelephonyRegistryManager telephonyRegistryMgr = this.getSystemService( + TelephonyRegistryManager.class); + if (telephonyRegistryMgr != null) { + telephonyRegistryMgr.notifyCarrierNetworkChange(subscriptionId, active); + } + } + /** * If overriding this method, call through to the super method for any unknown actions. * {@inheritDoc}