Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3a83b6c authored by Nathan Harold's avatar Nathan Harold Committed by Gerrit Code Review
Browse files

Merge changes from topic "telephony-background-cb"

* changes:
  Add a Compat Flag for Throwing For Null Telephony
  Ensure Async APIs receive callbacks
parents 5fdf93fc 31c7d616
Loading
Loading
Loading
Loading
+119 −63
Original line number Diff line number Diff line
@@ -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;
@@ -416,6 +418,27 @@ public class TelephonyManager {
        return Process.myUid() == Process.SYSTEM_UID;
    }
    /**
     * 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
@@ -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
@@ -5892,6 +5915,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) {
            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);
                if (Compatibility.isChangeEnabled(NULL_TELEPHONY_THROW_NO_CB)) {
                    throw new IllegalStateException("Opportunistic Network Service is null");
                } else {
                            callback.accept(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
                    // Let the general remote exception handling catch this.
                    throw new RemoteException("Null Opportunistic Network Service!");
                }
                    });
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
                return;
            }
            ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
                @Override
@@ -12812,10 +12873,19 @@ 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);
                }
            }));
        }
    }
    /**
     * Get preferred opportunistic data subscription Id
@@ -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 (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);
                            Binder.withCleanCallingIdentity(() -> {
                                executor.execute(() -> callback.accept(result));
                            });
                            } finally {
                                Binder.restoreCallingIdentity(identity);
                            }
                        }
                    };
            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);
                }
            }));
        }
    }