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

Commit ea0699c6 authored by Rambo Wang's avatar Rambo Wang Committed by Automerger Merge Worker
Browse files

Merge "Introduces class SignalStrengthController" am: a1fa6fc8 am: 82c6d0f1 am: 1974a311

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1545049

Change-Id: Iac7c43cf0bbb164d40c561f5e6aad794a6f57eb8
parents e20f41b7 1974a311
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -308,6 +308,9 @@ public class GsmCdmaPhone extends Phone {
                .makeCarrierSignalAgent(this);
        mTransportManager = mTelephonyComponentFactory.inject(TransportManager.class.getName())
                .makeTransportManager(this);
        // SST/DSM depends on SSC, so SSC is instanced before SST/DSM
        mSignalStrengthController = mTelephonyComponentFactory.inject(
                SignalStrengthController.class.getName()).makeSignalStrengthController(this);
        mSST = mTelephonyComponentFactory.inject(ServiceStateTracker.class.getName())
                .makeServiceStateTracker(this, this.mCi);
        mEmergencyNumberTracker = mTelephonyComponentFactory
@@ -656,6 +659,11 @@ public class GsmCdmaPhone extends Phone {
        return mDisplayInfoController;
    }

    @Override
    public SignalStrengthController getSignalStrengthController() {
        return mSignalStrengthController;
    }

    @Override
    public void updateVoiceMail() {
        if (isPhoneTypeGsm()) {
@@ -4109,13 +4117,15 @@ public class GsmCdmaPhone extends Phone {
    @Override
    public void setSignalStrengthReportingCriteria(int signalStrengthMeasure,
            int[] systemThresholds, int ran, boolean isEnabledForSystem) {
        int[] consolidatedThresholds = mSST.getConsolidatedSignalThresholds(
        int[] consolidatedThresholds = mSignalStrengthController.getConsolidatedSignalThresholds(
                ran,
                signalStrengthMeasure,
                isEnabledForSystem && mSST.shouldHonorSystemThresholds() ? systemThresholds
                isEnabledForSystem && mSignalStrengthController.shouldHonorSystemThresholds()
                        ? systemThresholds
                        : new int[]{},
                REPORTING_HYSTERESIS_DB);
        boolean isEnabledForAppRequest = mSST.shouldEnableSignalThresholdForAppRequest(
        boolean isEnabledForAppRequest =
                mSignalStrengthController.shouldEnableSignalThresholdForAppRequest(
                        ran,
                        signalStrengthMeasure,
                        getSubId(),
+20 −4
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import android.telephony.ims.RegistrationManager;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
import android.util.SparseArray;
import android.util.Xml;

@@ -342,6 +343,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    protected DataEnabledSettings mDataEnabledSettings;
    // Used for identify the carrier of current subscription
    protected CarrierResolver mCarrierResolver;
    protected SignalStrengthController mSignalStrengthController;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    protected int mPhoneId;
@@ -1898,6 +1900,14 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        return null;
    }

    /**
     * Retrieves the SignalStrengthController of the phone instance.
     */
    public SignalStrengthController getSignalStrengthController() {
        Log.wtf(LOG_TAG, "getSignalStrengthController return null.");
        return null;
    }

    /**
     * Update voice activation state
     */
@@ -4792,12 +4802,12 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
     * @param isIdle true if the new state is idle
     */
    public void notifyDeviceIdleStateChanged(boolean isIdle) {
        ServiceStateTracker sst = getServiceStateTracker();
        if (sst == null) {
            Rlog.e(LOG_TAG, "notifyDeviceIdleStateChanged: SST is null");
        SignalStrengthController ssc = getSignalStrengthController();
        if (ssc == null) {
            Rlog.e(LOG_TAG, "notifyDeviceIdleStateChanged: SignalStrengthController is null");
            return;
        }
        sst.onDeviceIdleStateChanged(isIdle);
        ssc.onDeviceIdleStateChanged(isIdle);
    }

    /**
@@ -4995,6 +5005,12 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
            pw.println("++++++++++++++++++++++++++++++++");
        }

        if (mSignalStrengthController != null) {
            pw.println("SignalStrengthController:");
            mSignalStrengthController.dump(fd, pw, args);
            pw.println("++++++++++++++++++++++++++++++++");
        }

        if (mTransportManager != null) {
            mTransportManager.dump(fd, pw, args);
        }
+1 −276
Original line number Diff line number Diff line
@@ -42,13 +42,11 @@ import android.os.AsyncResult;
import android.os.BaseBundle;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Parcel;
import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.TimestampedValue;
@@ -69,8 +67,6 @@ import android.telephony.CellIdentityNr;
import android.telephony.CellIdentityTdscdma;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellSignalStrengthLte;
import android.telephony.CellSignalStrengthNr;
import android.telephony.DataSpecificRegistrationInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhysicalChannelConfig;
@@ -78,8 +74,6 @@ import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState;
import android.telephony.ServiceState.RilRadioTechnology;
import android.telephony.SignalStrength;
import android.telephony.SignalStrengthUpdateRequest;
import android.telephony.SignalThresholdInfo;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
@@ -129,11 +123,9 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -303,9 +295,6 @@ public class ServiceStateTracker extends Handler {
    protected static final int EVENT_CELL_LOCATION_RESPONSE            = 56;
    protected static final int EVENT_CARRIER_CONFIG_CHANGED            = 57;
    private static final int EVENT_POLL_STATE_REQUEST                  = 58;
    private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST  = 59;
    private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 60;
    private static final int EVENT_ON_DEVICE_IDLE_STATE_CHANGED         = 61;
    // Timeout event used when delaying radio power off to wait for IMS deregistration to happen.
    private static final int EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT    = 62;

@@ -650,8 +639,6 @@ public class ServiceStateTracker extends Handler {
    private final Object mRsrpBoostLock = new Object();
    private static final int INVALID_ARFCN = -1;

    private final List<SignalRequestRecord> mSignalRequestRecords = new ArrayList<>();

    /* Last known TAC/LAC */
    private int mLastKnownAreaCode = CellInfo.UNAVAILABLE;

@@ -1769,75 +1756,6 @@ public class ServiceStateTracker extends Handler {
                pollStateInternal(false);
                break;

            case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
                Pair<SignalRequestRecord, Message> pair =
                        (Pair<SignalRequestRecord, Message>) msg.obj;
                SignalRequestRecord record = pair.first;
                Message onCompleted = pair.second;
                AsyncResult ret = AsyncResult.forMessage(onCompleted);

                // TODO(b/177956310): Check subId to filter out old request until a better solution
                boolean dupRequest = mSignalRequestRecords.stream().anyMatch(
                        srr -> srr.mCallingUid == record.mCallingUid
                                && srr.mSubId == record.mSubId);
                if (dupRequest) {
                    ret.exception = new IllegalStateException(
                            "setSignalStrengthUpdateRequest called again with same subId");
                    onCompleted.sendToTarget();
                    break;
                }

                try {
                    record.mRequest.getLiveToken().linkToDeath(record, 0);
                } catch (RemoteException | NullPointerException ex) {
                    ret.exception = new IllegalStateException(
                            "Signal request client is already dead.");
                    onCompleted.sendToTarget();
                    break;
                }

                mSignalRequestRecords.add(record);
                updateAlwaysReportSignalStrength();
                updateReportingCriteria(getCarrierConfig());

                onCompleted.sendToTarget();

                // Always poll signal strength after setting the update request which has waken up
                // modem if it was idle. An additional signal strength polling is almost cost free.
                obtainMessage(EVENT_POLL_SIGNAL_STRENGTH).sendToTarget();
                break;
            }

            case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
                Pair<SignalRequestRecord, Message> pair =
                        (Pair<SignalRequestRecord, Message>) msg.obj;
                SignalRequestRecord record = pair.first;
                Message onCompleted = pair.second;

                // for loop with removal may cause ConcurrentModificationException
                Iterator<SignalRequestRecord> it = mSignalRequestRecords.iterator();
                while (it.hasNext()) {
                    SignalRequestRecord srr = it.next();
                    if (srr.mRequest.getLiveToken().equals(record.mRequest.getLiveToken())) {
                        it.remove();
                    }
                }

                updateAlwaysReportSignalStrength();
                updateReportingCriteria(getCarrierConfig());

                if (onCompleted != null) {
                    AsyncResult ret = AsyncResult.forMessage(onCompleted);
                    onCompleted.sendToTarget();
                }
                break;
            }

            case EVENT_ON_DEVICE_IDLE_STATE_CHANGED: {
                updateReportingCriteria(getCarrierConfig());
                break;
            }

            case EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT: {
                if (DBG) log("EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT triggered");
                powerOffRadioSafely();
@@ -5205,7 +5123,7 @@ public class ServiceStateTracker extends Handler {
        }

        updateArfcnLists(config);
        updateReportingCriteria(config);
        mPhone.getSignalStrengthController().updateReportingCriteria(config);
        updateOperatorNamePattern(config);
        mCdnr.updateEfFromCarrierConfig(config);
        mPhone.notifyCallForwardingIndicator();
@@ -5242,52 +5160,6 @@ public class ServiceStateTracker extends Handler {
        }
    }

    private void updateReportingCriteria(PersistableBundle config) {
        int lteMeasurementEnabled = config.getInt(CarrierConfigManager
                .KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT, CellSignalStrengthLte.USE_RSRP);
        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
                config.getIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY),
                AccessNetworkType.EUTRAN,
                (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRP) != 0);
        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
                config.getIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY),
                AccessNetworkType.UTRAN, true);
        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
                config.getIntArray(CarrierConfigManager.KEY_GSM_RSSI_THRESHOLDS_INT_ARRAY),
                AccessNetworkType.GERAN, true);

        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
            mPhone.setSignalStrengthReportingCriteria(
                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
                    config.getIntArray(CarrierConfigManager.KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY),
                    AccessNetworkType.EUTRAN,
                    (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRQ) != 0);
            mPhone.setSignalStrengthReportingCriteria(
                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
                    config.getIntArray(CarrierConfigManager.KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY),
                    AccessNetworkType.EUTRAN,
                    (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSSNR) != 0);

            int measurementEnabled = config.getInt(CarrierConfigManager
                    .KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, CellSignalStrengthNr.USE_SSRSRP);
            mPhone.setSignalStrengthReportingCriteria(
                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
                    config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY),
                    AccessNetworkType.NGRAN,
                    (measurementEnabled & CellSignalStrengthNr.USE_SSRSRP) != 0);
            mPhone.setSignalStrengthReportingCriteria(
                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
                    config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY),
                    AccessNetworkType.NGRAN,
                    (measurementEnabled & CellSignalStrengthNr.USE_SSRSRQ) != 0);
            mPhone.setSignalStrengthReportingCriteria(
                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
                    config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY),
                    AccessNetworkType.NGRAN,
                    (measurementEnabled & CellSignalStrengthNr.USE_SSSINR) != 0);
        }
    }

    private void updateServiceStateArfcnRsrpBoost(ServiceState serviceState,
            CellIdentity cellIdentity) {
        int rsrpBoost = 0;
@@ -6283,153 +6155,6 @@ public class ServiceStateTracker extends Handler {
        return values;
    }

    /**
     * Set a new request to update the signal strength thresholds.
     */
    public void setSignalStrengthUpdateRequest(int subId, int callingUid,
            SignalStrengthUpdateRequest request, @NonNull Message onCompleted) {
        SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
        sendMessage(obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
                new Pair<SignalRequestRecord, Message>(record, onCompleted)));
    }

    /**
     * Clear the previously set request.
     */
    public void clearSignalStrengthUpdateRequest(int subId, int callingUid,
            SignalStrengthUpdateRequest request, @Nullable Message onCompleted) {
        SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
        sendMessage(obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
                new Pair<SignalRequestRecord, Message>(record, onCompleted)));
    }

    /**
     * Align all the qualified thresholds set from applications to the {@code systemThresholds}
     * and consolidate a new thresholds array, follow rules below:
     * 1. All threshold values (whose interval is guaranteed to be larger than hysteresis) in
     *    {@code systemThresholds} will keep as it.
     * 2. Any threshold from apps that has interval less than hysteresis from any threshold in
     *    {@code systemThresholds} will be removed.
     * 3. The target thresholds will be {@code systemThresholds} + all qualified thresholds from
     *    apps, sorted in ascending order.
     */
    int[] getConsolidatedSignalThresholds(int ran, int measurement,
            int[] systemThresholds, int hysteresis) {

        // TreeSet with comparator that will filter element with interval less than hysteresis
        // from any current element
        Set<Integer> target = new TreeSet<>((x, y) -> {
            if (y >= x - hysteresis && y <= x + hysteresis) {
                return 0;
            }
            return Integer.compare(x, y);
        });

        for (int systemThreshold : systemThresholds) {
            target.add(systemThreshold);
        }

        final boolean isDeviceIdle = mPhone.isDeviceIdle();
        final int curSubId = mPhone.getSubId();
        // The total number of record is small (10~15 tops). With each request has at most 5
        // SignalThresholdInfo which has at most 8 thresholds arrays. So the nested loop should
        // not be a concern here.
        for (SignalRequestRecord record : mSignalRequestRecords) {
            if (curSubId != record.mSubId
                    || (isDeviceIdle && !record.mRequest.isReportingRequestedWhileIdle())) {
                continue;
            }
            for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
                if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)) {
                    for (int appThreshold : info.getThresholds()) {
                        target.add(appThreshold);
                    }
                }
            }
        }

        int[] targetArray = new int[target.size()];
        int i = 0;
        for (int element : target) {
            targetArray[i++] = element;
        }
        return targetArray;
    }

    boolean shouldHonorSystemThresholds() {
        if (!mPhone.isDeviceIdle()) {
            return true;
        }

        final int curSubId = mPhone.getSubId();
        return mSignalRequestRecords.stream().anyMatch(
                srr -> curSubId == srr.mSubId
                        && srr.mRequest.isSystemThresholdReportingRequestedWhileIdle());
    }

    void onDeviceIdleStateChanged(boolean isDeviceIdle) {
        sendMessage(obtainMessage(EVENT_ON_DEVICE_IDLE_STATE_CHANGED, isDeviceIdle));
    }

    boolean shouldEnableSignalThresholdForAppRequest(
            @AccessNetworkConstants.RadioAccessNetworkType int ran,
            @SignalThresholdInfo.SignalMeasurementType int measurement,
            int subId,
            boolean isDeviceIdle) {
        for (SignalRequestRecord record : mSignalRequestRecords) {
            if (subId != record.mSubId) {
                continue;
            }
            for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
                if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)
                        && (!isDeviceIdle || isSignalReportRequestedWhileIdle(record.mRequest))) {
                    return true;
                }
            }
        }
        return false;
    }

    private static boolean isRanAndSignalMeasurementTypeMatch(
            @AccessNetworkConstants.RadioAccessNetworkType int ran,
            @SignalThresholdInfo.SignalMeasurementType int measurement,
            SignalThresholdInfo info) {
        return ran == info.getRadioAccessNetworkType()
                && measurement == info.getSignalMeasurementType();
    }

    private static boolean isSignalReportRequestedWhileIdle(SignalStrengthUpdateRequest request) {
        return request.isSystemThresholdReportingRequestedWhileIdle()
                || request.isReportingRequestedWhileIdle();
    }

    private class SignalRequestRecord implements IBinder.DeathRecipient {
        final int mSubId; // subId the request originally applied to
        final int mCallingUid;
        final SignalStrengthUpdateRequest mRequest;

        SignalRequestRecord(int subId, int uid, @NonNull SignalStrengthUpdateRequest request) {
            this.mCallingUid = uid;
            this.mSubId = subId;
            this.mRequest = request;
        }

        @Override
        public void binderDied() {
            clearSignalStrengthUpdateRequest(mSubId, mCallingUid, mRequest, null /*onCompleted*/);
        }
    }

    private void updateAlwaysReportSignalStrength() {
        final int curSubId = mPhone.getSubId();
        boolean alwaysReport = mSignalRequestRecords.stream().anyMatch(
                srr -> srr.mSubId == curSubId && isSignalReportRequestedWhileIdle(srr.mRequest));

        // TODO(b/177924721): TM#setAlwaysReportSignalStrength will be removed and we will not
        // worry about unset flag which was set by other client.
        mPhone.setAlwaysReportSignalStrength(alwaysReport);
    }

    /**
     * Registers for TAC/LAC changed event.
     * @param h handler to notify
+400 −0

File added.

Preview size limit exceeded, changes collapsed.

+7 −0
Original line number Diff line number Diff line
@@ -445,6 +445,13 @@ public class TelephonyComponentFactory {
        return MultiSimSettingController.init(c, sc);
    }

    /**
     * Create a new SignalStrengthController instance.
     */
    public SignalStrengthController makeSignalStrengthController(GsmCdmaPhone phone) {
        return new SignalStrengthController(phone);
    }

    public SubscriptionInfoUpdater makeSubscriptionInfoUpdater(Looper looper, Context context,
            SubscriptionController sc) {
        return new SubscriptionInfoUpdater(looper, context, sc);
Loading