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

Commit 4298f0a0 authored by Jack Yu's avatar Jack Yu Committed by Gerrit Code Review
Browse files

Merge changes from topics "unthrottle_apm", "unthrottle_on_tac_changes"

* changes:
  Unthrottle data retry in some conditions
  Unthrottle all APNs on APM
parents 43af3564 2142bc29
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
@@ -239,6 +239,8 @@ public class ServiceStateTracker extends Handler {
    private RegistrantList mNrStateChangedRegistrants = new RegistrantList();
    private RegistrantList mNrFrequencyChangedRegistrants = new RegistrantList();
    private RegistrantList mCssIndicatorChangedRegistrants = new RegistrantList();
    private final RegistrantList mAirplaneModeChangedRegistrants = new RegistrantList();
    private final RegistrantList mAreaCodeChangedRegistrants = new RegistrantList();

    /* Radio power off pending flag and tag counter */
    private boolean mPendingRadioPowerOffAfterDataOff = false;
@@ -648,6 +650,9 @@ public class ServiceStateTracker extends Handler {

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

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

    public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) {
        mNitzState = TelephonyComponentFactory.getInstance()
                .inject(NitzStateMachine.class.getName())
@@ -2010,6 +2015,7 @@ public class ServiceStateTracker extends Handler {
    public void onAirplaneModeChanged(boolean isAirplaneModeOn) {
        mLastNitzData = null;
        mNitzState.handleAirplaneModeChanged(isAirplaneModeOn);
        mAirplaneModeChangedRegistrants.notifyResult(isAirplaneModeOn);
    }

    protected Phone getPhone() {
@@ -2551,6 +2557,19 @@ public class ServiceStateTracker extends Handler {
        return cid;
    }

    //TODO: Move this and getCidFromCellIdentity to CellIdentityUtils.
    private static int getAreaCodeFromCellIdentity(CellIdentity id) {
        if (id == null) return CellInfo.UNAVAILABLE;
        switch(id.getType()) {
            case CellInfo.TYPE_GSM: return ((CellIdentityGsm) id).getLac();
            case CellInfo.TYPE_WCDMA: return ((CellIdentityWcdma) id).getLac();
            case CellInfo.TYPE_TDSCDMA: return ((CellIdentityTdscdma) id).getLac();
            case CellInfo.TYPE_LTE: return ((CellIdentityLte) id).getTac();
            case CellInfo.TYPE_NR: return ((CellIdentityNr) id).getTac();
            default: return CellInfo.UNAVAILABLE;
        }
    }

    private void setPhyCellInfoFromCellIdentity(ServiceState ss, CellIdentity cellIdentity) {
        if (cellIdentity == null) {
            if (DBG) {
@@ -3587,6 +3606,12 @@ public class ServiceStateTracker extends Handler {

        mCellIdentity = primaryCellIdentity;

        int areaCode = getAreaCodeFromCellIdentity(mCellIdentity);
        if (areaCode != mLastKnownAreaCode && areaCode != CellInfo.UNAVAILABLE) {
            mLastKnownAreaCode = areaCode;
            mAreaCodeChangedRegistrants.notifyRegistrants();
        }

        if (hasRilVoiceRadioTechnologyChanged) {
            updatePhoneObject();
        }
@@ -4758,6 +4783,27 @@ public class ServiceStateTracker extends Handler {
        }
    }

    /**
     * Registration for Airplane Mode changing.  The state of Airplane Mode will be returned
     * {@link AsyncResult#result} as a {@link Boolean} Object.
     * The {@link AsyncResult} will be in the notification {@link Message#obj}.
     * @param h handler to notify
     * @param what what code of message when delivered
     * @param obj placed in {@link AsyncResult#userObj}
     */
    public void registerForAirplaneModeChanged(Handler h, int what, Object obj) {
        mAirplaneModeChangedRegistrants.add(h, what, obj);
    }

    /**
     * Unregister for Airplane Mode changed event.
     *
     * @param h The handler
     */
    public void unregisterForAirplaneModeChanged(Handler h) {
        mAirplaneModeChangedRegistrants.remove(h);
    }

    /**
     * Registration point for transition into network attached.
     * @param h handler to notify
@@ -6162,4 +6208,22 @@ public class ServiceStateTracker extends Handler {
        // worry about unset flag which was set by other client.
        mPhone.setAlwaysReportSignalStrength(alwaysReport);
    }

    /**
     * Registers for TAC/LAC changed event.
     * @param h handler to notify
     * @param what what code of message when delivered
     * @param obj placed in Message.obj
     */
    public void registerForAreaCodeChanged(Handler h, int what, Object obj) {
        mAreaCodeChangedRegistrants.addUnique(h, what, obj);
    }

    /**
     * Unregisters for TAC/LAC changed event.
     * @param h handler to notify
     */
    public void unregisterForAreaCodeChanged(Handler h) {
        mAreaCodeChangedRegistrants.remove(h);
    }
}
+148 −4
Original line number Diff line number Diff line
@@ -17,12 +17,24 @@
package com.android.internal.telephony.dataconnection;

import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.PersistableBundle;
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation;
import android.telephony.Annotation.ApnType;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.ThrottleStatus;

import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RetryManager;
import com.android.telephony.Rlog;

@@ -35,11 +47,19 @@ import java.util.concurrent.ConcurrentHashMap;
 * Data throttler tracks the throttling status of the data network and notifies registrants when
 * there are changes.  The throttler is per phone and per transport type.
 */
public class DataThrottler {
public class DataThrottler extends Handler {
    private static final String TAG = DataThrottler.class.getSimpleName();

    private static final int EVENT_SET_RETRY_TIME = 1;
    private static final int EVENT_CARRIER_CONFIG_CHANGED = 2;
    private static final int EVENT_RESET = 3;
    private static final int EVENT_AIRPLANE_MODE_CHANGED = 4;
    private static final int EVENT_TRACING_AREA_CODE_CHANGED = 5;

    private final Phone mPhone;
    private final int mSlotIndex;
    private final @AccessNetworkConstants.TransportType int mTransportType;
    private boolean mResetWhenAreaCodeChanged = false;

    /**
     * Callbacks that report the apn throttle status.
@@ -52,9 +72,93 @@ public class DataThrottler {
     */
    private final Map<Integer, ThrottleStatus> mThrottleStatus = new ConcurrentHashMap<>();

    public DataThrottler(int slotIndex, int transportType) {
        mSlotIndex = slotIndex;
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
                if (mPhone.getPhoneId() == intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX,
                        SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
                    if (intent.getBooleanExtra(
                            CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
                        // Ignore the rebroadcast one to prevent multiple carrier config changed
                        // event during boot up.
                        return;
                    }
                    int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
                    if (SubscriptionManager.isValidSubscriptionId(subId)) {
                        sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED);
                    }
                }
            }
        }
    };

    public DataThrottler(Phone phone, int transportType) {
        super(null, false);
        mPhone = phone;
        mSlotIndex = phone.getPhoneId();
        mTransportType = transportType;

        IntentFilter filter = new IntentFilter();
        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone);

        mPhone.getServiceStateTracker().registerForAirplaneModeChanged(this,
                EVENT_AIRPLANE_MODE_CHANGED, null);
        mPhone.getServiceStateTracker().registerForAreaCodeChanged(this,
                EVENT_TRACING_AREA_CODE_CHANGED, null);
    }

    @Override
    public void handleMessage(Message msg) {
        AsyncResult ar;
        switch (msg.what) {
            case EVENT_SET_RETRY_TIME:
                int apnTypes = msg.arg1;
                int newRequestType = msg.arg2;
                long retryElapsedTime = (long) msg.obj;
                setRetryTimeInternal(apnTypes, retryElapsedTime, newRequestType);
                break;
            case EVENT_CARRIER_CONFIG_CHANGED:
                onCarrierConfigChanged();
                break;
            case EVENT_RESET:
                resetInternal();
                break;
            case EVENT_AIRPLANE_MODE_CHANGED:
                ar = (AsyncResult) msg.obj;
                if (!(Boolean) ar.result) {
                    resetInternal();
                }
                break;
            case EVENT_TRACING_AREA_CODE_CHANGED:
                if (mResetWhenAreaCodeChanged) {
                    resetInternal();
                }
                break;
        }
    }

    @NonNull
    private PersistableBundle getCarrierConfig() {
        CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (configManager != null) {
            // If an invalid subId is used, this bundle will contain default values.
            PersistableBundle config = configManager.getConfigForSubId(mPhone.getSubId());
            if (config != null) {
                return config;
            }
        }
        // Return static default defined in CarrierConfigManager.
        return CarrierConfigManager.getDefaultConfig();
    }

    private void onCarrierConfigChanged() {
        PersistableBundle config = getCarrierConfig();
        mResetWhenAreaCodeChanged = config.getBoolean(
                CarrierConfigManager.KEY_UNTHROTTLE_DATA_RETRY_WHEN_TAC_CHANGES_BOOL, false);
    }

    /**
@@ -65,8 +169,23 @@ public class DataThrottler {
     * retried. {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} indicates throttling does not exist.
     * {@link RetryManager#NO_RETRY} indicates retry should never happen.
     */
    public void setRetryTime(@ApnType int apnTypes, long retryElapsedTime,
    public void setRetryTime(@ApnType int apnTypes, @ElapsedRealtimeLong long retryElapsedTime,
            @DcTracker.RequestNetworkType int newRequestType) {
        sendMessage(obtainMessage(EVENT_SET_RETRY_TIME, apnTypes, newRequestType,
                retryElapsedTime));
    }

    /**
     * Set the retry time and handover failure mode for the give APN types. This is running on the
     * handler thread.
     *
     * @param apnTypes APN types
     * @param retryElapsedTime The elapsed time that data connection for APN types should not be
     * retried. {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} indicates throttling does not exist.
     * {@link RetryManager#NO_RETRY} indicates retry should never happen.
     */
    private void setRetryTimeInternal(@ApnType int apnTypes, @ElapsedRealtimeLong
            long retryElapsedTime, @DcTracker.RequestNetworkType int newRequestType) {
        if (retryElapsedTime < 0) {
            retryElapsedTime = RetryManager.NO_SUGGESTED_RETRY_DELAY;
        }
@@ -103,6 +222,9 @@ public class DataThrottler {
    /**
     * Get the earliest retry time for the given APN type. The time is the system's elapse time.
     *
     * Note the DataThrottler is running phone process's main thread, which is most of the telephony
     * components running on. Calling this method from other threads might run into race conditions.
     *
     * @param apnType APN type
     * @return The earliest retry time for APN type. The time is the system's elapse time.
     * {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} indicates there is no throttling for given APN
@@ -127,6 +249,28 @@ public class DataThrottler {
        return RetryManager.NO_SUGGESTED_RETRY_DELAY;
    }

    /**
     * Resets retry times for all APNs to {@link RetryManager.NO_SUGGESTED_RETRY_DELAY}.
     */
    public void reset() {
        sendEmptyMessage(EVENT_RESET);
    }

    /**
     * Resets retry times for all APNs to {@link RetryManager.NO_SUGGESTED_RETRY_DELAY}.
     */
    private void resetInternal() {
        final List<Integer> apnTypes = new ArrayList<>();
        for (ThrottleStatus throttleStatus : mThrottleStatus.values()) {
            apnTypes.add(throttleStatus.getApnType());
        }

        for (int apnType : apnTypes) {
            setRetryTime(apnType, RetryManager.NO_SUGGESTED_RETRY_DELAY,
                    DcTracker.REQUEST_TYPE_NORMAL);
        }
    }

    private ThrottleStatus createStatus(@Annotation.ApnType int apnType, long retryElapsedTime,
            @DcTracker.RequestNetworkType int newRequestType) {
        ThrottleStatus.Builder builder = new ThrottleStatus.Builder();
+2 −1
Original line number Diff line number Diff line
@@ -739,7 +739,7 @@ public class DcTracker extends Handler {

        mTransportType = transportType;
        mDataServiceManager = new DataServiceManager(phone, transportType, tagSuffix);
        mDataThrottler = new DataThrottler(mPhone.getPhoneId(), transportType);
        mDataThrottler = new DataThrottler(mPhone, transportType);

        mResolver = mPhone.getContext().getContentResolver();
        mAlarmManager =
@@ -832,6 +832,7 @@ public class DcTracker extends Handler {
        mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
        mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
        mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(mTransportType, this);
        mPhone.getServiceStateTracker().unregisterForAirplaneModeChanged(this);
    }

    private void registerForAllEvents() {
+29 −10
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ public class DataThrottlerTest extends TelephonyTest {
    @Before
    public void setUp() throws Exception {
        super.setUp(getClass().getSimpleName());
        mDataThrottler = new DataThrottler(1, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        mDataThrottler = new DataThrottler(mPhone, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        mDataThrottler.registerForThrottleStatusChanges(mMockChangedCallback1);
    }

@@ -87,9 +87,9 @@ public class DataThrottlerTest extends TelephonyTest {
        processAllMessages();
        expectedStatuses.add(List.of());


        mDataThrottler.setRetryTime(ApnSetting.TYPE_DEFAULT, 1234567890L,
                REQUEST_TYPE_NORMAL);
        processAllMessages();
        assertEquals(1234567890L, mDataThrottler.getRetryTime(ApnSetting.TYPE_DEFAULT));
        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY,
                mDataThrottler.getRetryTime(ApnSetting.TYPE_MMS));
@@ -97,14 +97,14 @@ public class DataThrottlerTest extends TelephonyTest {
        processAllMessages();
        expectedStatuses.add(List.of(
                new ThrottleStatus.Builder()
                        .setSlotIndex(1)
                        .setSlotIndex(0)
                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                        .setApnType(ApnSetting.TYPE_HIPRI)
                        .setThrottleExpiryTimeMillis(1234567890L)
                        .setRetryType(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION)
                        .build(),
                new ThrottleStatus.Builder()
                    .setSlotIndex(1)
                    .setSlotIndex(0)
                    .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                    .setApnType(DEFAULT_APN_TYPE)
                    .setThrottleExpiryTimeMillis(1234567890L)
@@ -115,27 +115,28 @@ public class DataThrottlerTest extends TelephonyTest {

        mDataThrottler.setRetryTime(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN, 13579L,
                REQUEST_TYPE_HANDOVER);
        processAllMessages();
        assertEquals(13579L, mDataThrottler.getRetryTime(ApnSetting.TYPE_DEFAULT));
        assertEquals(13579L, mDataThrottler.getRetryTime(ApnSetting.TYPE_DUN));

        processAllMessages();
        expectedStatuses.add(List.of(
                new ThrottleStatus.Builder()
                        .setSlotIndex(1)
                        .setSlotIndex(0)
                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                        .setApnType(ApnSetting.TYPE_HIPRI)
                        .setThrottleExpiryTimeMillis(13579L)
                        .setRetryType(ThrottleStatus.RETRY_TYPE_HANDOVER)
                        .build(),
                new ThrottleStatus.Builder()
                        .setSlotIndex(1)
                        .setSlotIndex(0)
                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                        .setApnType(ApnSetting.TYPE_DUN)
                        .setThrottleExpiryTimeMillis(13579L)
                        .setRetryType(ThrottleStatus.RETRY_TYPE_HANDOVER)
                        .build(),
                new ThrottleStatus.Builder()
                        .setSlotIndex(1)
                        .setSlotIndex(0)
                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                        .setApnType(DEFAULT_APN_TYPE)
                        .setThrottleExpiryTimeMillis(13579L)
@@ -146,12 +147,13 @@ public class DataThrottlerTest extends TelephonyTest {

        mDataThrottler.setRetryTime(ApnSetting.TYPE_MMS, -10,
                REQUEST_TYPE_NORMAL);
        processAllMessages();
        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY,
                mDataThrottler.getRetryTime(ApnSetting.TYPE_MMS));
        processAllMessages();
        expectedStatuses.add(List.of(
                new ThrottleStatus.Builder()
                        .setSlotIndex(1)
                        .setSlotIndex(0)
                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                        .setNoThrottle()
                        .setApnType(ApnSetting.TYPE_MMS)
@@ -165,14 +167,14 @@ public class DataThrottlerTest extends TelephonyTest {
        processAllMessages();
        expectedStatuses.add(List.of(
                new ThrottleStatus.Builder()
                        .setSlotIndex(1)
                        .setSlotIndex(0)
                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                        .setApnType(ApnSetting.TYPE_EMERGENCY)
                        .setThrottleExpiryTimeMillis(RetryManager.NO_RETRY)
                        .setRetryType(ThrottleStatus.RETRY_TYPE_NONE)
                        .build(),
                new ThrottleStatus.Builder()
                        .setSlotIndex(1)
                        .setSlotIndex(0)
                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                        .setApnType(ApnSetting.TYPE_FOTA)
                        .setThrottleExpiryTimeMillis(RetryManager.NO_RETRY)
@@ -213,4 +215,21 @@ public class DataThrottlerTest extends TelephonyTest {

        this.mDataThrottler.registerForThrottleStatusChanges(mMockChangedCallback2);
    }

    /**
     * Test the behavior of a retry manager with no waiting APNs set.
     */
    @Test
    @SmallTest
    public void testUnthrottle() throws Exception {
        mDataThrottler.setRetryTime(ApnSetting.TYPE_DEFAULT, 1234567890L,
                REQUEST_TYPE_NORMAL);
        processAllMessages();
        assertEquals(1234567890L, mDataThrottler.getRetryTime(ApnSetting.TYPE_DEFAULT));

        mDataThrottler.reset();
        processAllMessages();
        assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY,
                mDataThrottler.getRetryTime(ApnSetting.TYPE_DEFAULT));
    }
}