diff options
| author | 2021-03-29 17:58:41 +0000 | |
|---|---|---|
| committer | 2021-03-29 17:58:41 +0000 | |
| commit | f3a83b6c9c33c266c86c76247c71b979045968c7 (patch) | |
| tree | 2ed2835beb553e0440961d7f25e47935b389fcba | |
| parent | 5fdf93fc9df27e20a0901c89cdbee7191a387cdd (diff) | |
| parent | 31c7d6162472077c20760025128271b8aa9f5a21 (diff) | |
Merge changes from topic "telephony-background-cb"
* changes:
Add a Compat Flag for Throwing For Null Telephony
Ensure Async APIs receive callbacks
| -rw-r--r-- | telephony/java/android/telephony/TelephonyManager.java | 182 |
1 files changed, 119 insertions, 63 deletions
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 7c39cf0b47a6..a2467f2067ac 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -99,6 +99,7 @@ import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; import com.android.internal.telephony.CellNetworkScanResult; import com.android.internal.telephony.IBooleanConsumer; import com.android.internal.telephony.ICallForwardingInfoCallback; @@ -128,6 +129,7 @@ import java.util.Map; import java.util.Objects; import java.util.UUID; import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -417,6 +419,27 @@ public class TelephonyManager { } /** + * Post a runnable to the BackgroundThread. + * + * Used to invoke user callbacks without calling into the caller's executor from the caller's + * calling thread context, for example to provide asynchronous error information that is + * generated locally (not over a binder thread). + * + * <p>This is not necessary unless you are invoking caller's code asynchronously from within + * the caller's thread context. + * + * @param r a runnable. + */ + private static void runOnBackgroundThread(@NonNull Runnable r) { + try { + BackgroundThread.getExecutor().execute(r); + } catch (RejectedExecutionException e) { + throw new IllegalStateException( + "Failed to post a callback from the caller's thread context.", e); + } + } + + /** * Returns the multi SIM variant * Returns DSDS for Dual SIM Dual Standby * Returns DSDA for Dual SIM Dual Active @@ -5875,7 +5898,7 @@ public class TelephonyManager { /** * Error response to - * {@link android.telephony.TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()}. + * {@link TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()}. * * Invoked when an error condition prevents updated {@link CellInfo} from being fetched * and returned from the modem. Callers of requestCellInfoUpdate() should override this @@ -5893,6 +5916,20 @@ public class TelephonyManager { }; /** + * Used for checking if the target SDK version for the current process is S or above. + * + * <p> Applies to the following methods: + * {@link #requestCellInfoUpdate}, + * {@link #setPreferredOpportunisticDataSubscription}, + * {@link #updateAvailableNetworks}, + * requestNumberVerification(), + * setSimPowerStateForSlot(), + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) + private static final long NULL_TELEPHONY_THROW_NO_CB = 182185642L; + + /** * Requests all available cell information from the current subscription for observed * camped/registered, serving, and neighboring cells. * @@ -5912,7 +5949,14 @@ public class TelephonyManager { @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) { try { ITelephony telephony = getITelephony(); - if (telephony == null) return; + if (telephony == null) { + if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) { + throw new IllegalStateException("Telephony is null"); + } else { + return; + } + } + telephony.requestCellInfoUpdate( getSubId(), new ICellInfoCallback.Stub() { @@ -5939,6 +5983,8 @@ public class TelephonyManager { } }, getOpPackageName(), getAttributionTag()); } catch (RemoteException ex) { + runOnBackgroundThread(() -> executor.execute( + () -> callback.onError(CellInfoCallback.ERROR_MODEM_ERROR, ex))); } } @@ -5966,7 +6012,14 @@ public class TelephonyManager { @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) { try { ITelephony telephony = getITelephony(); - if (telephony == null) return; + if (telephony == null) { + if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) { + throw new IllegalStateException("Telephony is null"); + } else { + return; + } + } + telephony.requestCellInfoUpdateWithWorkSource( getSubId(), new ICellInfoCallback.Stub() { @@ -5994,6 +6047,8 @@ public class TelephonyManager { } }, getOpPackageName(), getAttributionTag(), workSource); } catch (RemoteException ex) { + runOnBackgroundThread(() -> executor.execute( + () -> callback.onError(CellInfoCallback.ERROR_MODEM_ERROR, ex))); } } @@ -6960,14 +7015,21 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); - if (telephony != null) { - telephony.requestNumberVerification(range, timeoutMillis, internalCallback, - getOpPackageName()); + if (telephony == null) { + if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) { + throw new IllegalStateException("Telephony is null"); + } else { + return; + } } + + telephony.requestNumberVerification(range, timeoutMillis, internalCallback, + getOpPackageName()); } catch (RemoteException ex) { Rlog.e(TAG, "requestNumberVerification RemoteException", ex); - executor.execute(() -> - callback.onVerificationFailed(NumberVerificationCallback.REASON_UNSPECIFIED)); + runOnBackgroundThread(() -> executor.execute( + () -> callback.onVerificationFailed( + NumberVerificationCallback.REASON_UNSPECIFIED))); } } @@ -10333,6 +10395,8 @@ public class TelephonyManager { } try { ITelephony telephony = getITelephony(); + if (telephony == null) throw new IllegalStateException("Telephony is null."); + IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() { @Override public void accept(int result) { @@ -10340,11 +10404,18 @@ public class TelephonyManager { Binder.withCleanCallingIdentity(() -> callback.accept(result))); } }; - if (telephony != null) { - telephony.setSimPowerStateForSlotWithCallback(slotIndex, state, internalCallback); + if (telephony == null) { + if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) { + throw new IllegalStateException("Telephony is null"); + } else { + return; + } } + telephony.setSimPowerStateForSlotWithCallback(slotIndex, state, internalCallback); } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#setSimPowerStateForSlot", e); + runOnBackgroundThread(() -> executor.execute( + () -> callback.accept(SET_SIM_POWER_STATE_MODEM_ERROR))); } catch (SecurityException e) { Log.e(TAG, "Permission error calling ITelephony#setSimPowerStateForSlot", e); @@ -12774,22 +12845,12 @@ public class TelephonyManager { try { IOns iOpportunisticNetworkService = getIOns(); if (iOpportunisticNetworkService == null) { - if (executor == null || callback == null) { - return; - } - final long identity = Binder.clearCallingIdentity(); - try { - executor.execute(() -> { - if (Compatibility.isChangeEnabled(CALLBACK_ON_MORE_ERROR_CODE_CHANGE)) { - callback.accept(SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION); - } else { - callback.accept(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION); - } - }); - } finally { - Binder.restoreCallingIdentity(identity); + if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) { + throw new IllegalStateException("Opportunistic Network Service is null"); + } else { + // Let the general remote exception handling catch this. + throw new RemoteException("Null Opportunistic Network Service!"); } - return; } ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() { @Override @@ -12812,9 +12873,18 @@ public class TelephonyManager { .setPreferredDataSubscriptionId(subId, needValidation, callbackStub, pkgForDebug); } catch (RemoteException ex) { - Rlog.e(TAG, "setPreferredDataSubscriptionId RemoteException", ex); + Rlog.e(TAG, "setPreferredOpportunisticDataSubscription RemoteException", ex); + if (executor == null || callback == null) { + return; + } + runOnBackgroundThread(() -> executor.execute(() -> { + if (Compatibility.isChangeEnabled(CALLBACK_ON_MORE_ERROR_CODE_CHANGE)) { + callback.accept(SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION); + } else { + callback.accept(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION); + } + })); } - return; } /** @@ -12871,37 +12941,18 @@ public class TelephonyManager { @Nullable @CallbackExecutor Executor executor, @UpdateAvailableNetworksResult @Nullable Consumer<Integer> callback) { String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + Objects.requireNonNull(availableNetworks, "availableNetworks must not be null."); try { IOns iOpportunisticNetworkService = getIOns(); - if (iOpportunisticNetworkService == null || availableNetworks == null) { - if (executor == null || callback == null) { - return; - } - if (iOpportunisticNetworkService == null) { - final long identity = Binder.clearCallingIdentity(); - try { - executor.execute(() -> { - if (Compatibility.isChangeEnabled(CALLBACK_ON_MORE_ERROR_CODE_CHANGE)) { - callback.accept(UPDATE_AVAILABLE_NETWORKS_REMOTE_SERVICE_EXCEPTION); - } else { - callback.accept(UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE); - } - }); - } finally { - Binder.restoreCallingIdentity(identity); - } + if (iOpportunisticNetworkService == null) { + if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) { + throw new IllegalStateException("Opportunistic Network Service is null"); } else { - final long identity = Binder.clearCallingIdentity(); - try { - executor.execute(() -> { - callback.accept(UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS); - }); - } finally { - Binder.restoreCallingIdentity(identity); - } + // Let the general remote exception handling catch this. + throw new RemoteException("Null Opportunistic Network Service!"); } - return; } + IUpdateAvailableNetworksCallback callbackStub = new IUpdateAvailableNetworksCallback.Stub() { @Override @@ -12909,20 +12960,25 @@ public class TelephonyManager { if (executor == null || callback == null) { return; } - final long identity = Binder.clearCallingIdentity(); - try { - executor.execute(() -> { - callback.accept(result); - }); - } finally { - Binder.restoreCallingIdentity(identity); - } + Binder.withCleanCallingIdentity(() -> { + executor.execute(() -> callback.accept(result)); + }); } }; - iOpportunisticNetworkService.updateAvailableNetworks(availableNetworks, callbackStub, - pkgForDebug); + iOpportunisticNetworkService + .updateAvailableNetworks(availableNetworks, callbackStub, pkgForDebug); } catch (RemoteException ex) { Rlog.e(TAG, "updateAvailableNetworks RemoteException", ex); + if (executor == null || callback == null) { + return; + } + runOnBackgroundThread(() -> executor.execute(() -> { + if (Compatibility.isChangeEnabled(CALLBACK_ON_MORE_ERROR_CODE_CHANGE)) { + callback.accept(UPDATE_AVAILABLE_NETWORKS_REMOTE_SERVICE_EXCEPTION); + } else { + callback.accept(UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE); + } + })); } } |