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

Commit 17aa72ff authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8837442 from 1a9168d8 to tm-qpr1-release

Change-Id: Iaa0912589b2ab7474bb65cbfb553ee9c72986554
parents cb471334 1a9168d8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -295,6 +295,7 @@ message DataCallSession {
    optional bool ongoing = 18;
    optional int32 band_at_end = 19;
    repeated int32 handover_failure_causes = 20;
    repeated int32 handover_failure_rat = 21;
}

message CellularServiceState {
+81 −15
Original line number Diff line number Diff line
@@ -193,9 +193,6 @@ public class DataNetwork extends StateMachine {
    /** Event for display info changed. This is for getting 5G NSA or mmwave information. */
    private static final int EVENT_DISPLAY_INFO_CHANGED = 13;

    /** Event for initiating an handover between cellular and IWLAN. */
    private static final int EVENT_START_HANDOVER = 14;

    /** Event for setup data call (for handover) response from the data service. */
    private static final int EVENT_HANDOVER_RESPONSE = 15;

@@ -235,6 +232,24 @@ public class DataNetwork extends StateMachine {
    /** Event for CSS indicator changed. */
    private static final int EVENT_CSS_INDICATOR_CHANGED = 24;

    /**
     * Event for notifying source transport that handover is about to be initiated on target
     * transport.
     */
    private static final int EVENT_NOTIFY_HANDOVER_STARTED = 25;

    /**
     * Event for the response of notifying source transport that handover is about to be initiated
     * on target transport.
     */
    private static final int EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE = 26;

    /**
     * Event for the response of notifying source transport that handover is cancelled/failed on the
     * target transport.
     */
    private static final int EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE = 27;

    /** Invalid context id. */
    private static final int INVALID_CID = -1;

@@ -1096,6 +1111,9 @@ public class DataNetwork extends StateMachine {
                    updateNetworkCapabilities();
                    break;
                }
                case EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE:
                    log("Notified handover cancelled.");
                    break;
                case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
                case EVENT_TEAR_DOWN_NETWORK:
                case EVENT_PCO_DATA_RECEIVED:
@@ -1108,15 +1126,16 @@ public class DataNetwork extends StateMachine {
                    // Ignore the events when not in the correct state.
                    log("Ignored " + eventToString(msg.what));
                    break;
                case EVENT_START_HANDOVER:
                    // We reach here if network is not in the connected/connecting state.
                case EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE:
                case EVENT_NOTIFY_HANDOVER_STARTED:
                    // We reach here if network is not in the right state.
                    if (msg.obj != null) {
                        // Cancel it because it's either HO in progress or will soon disconnect.
                        // Either case we want to clean up obsolete retry attempts.
                        DataHandoverRetryEntry retryEntry = (DataHandoverRetryEntry) msg.obj;
                        retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
                    }
                    log("Ignore retry for the handover to " + AccessNetworkConstants
                    log("Ignore handover to " + AccessNetworkConstants
                            .transportTypeToString(msg.arg1) + " request.");
                    break;
                case EVENT_RADIO_NOT_AVAILABLE:
@@ -1187,7 +1206,7 @@ public class DataNetwork extends StateMachine {
                            msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
                    onSetupResponse(resultCode, dataCallResponse);
                    break;
                case EVENT_START_HANDOVER:
                case EVENT_NOTIFY_HANDOVER_STARTED:
                case EVENT_TEAR_DOWN_NETWORK:
                case EVENT_PCO_DATA_RECEIVED:
                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
@@ -1300,8 +1319,21 @@ public class DataNetwork extends StateMachine {
                case EVENT_DISPLAY_INFO_CHANGED:
                    onDisplayInfoChanged();
                    break;
                case EVENT_START_HANDOVER:
                    onStartHandover(msg.arg1, (DataHandoverRetryEntry) msg.obj);
                case EVENT_NOTIFY_HANDOVER_STARTED:
                    // Notify source transport that handover is about to start. Note this will not
                    // initiate the handover process on target transport, but more for notifying
                    // the source transport so that PDU session id can be preserved if network
                    // notifies PDN lost during handover. The real handover process will kick off
                    // after receiving EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE.
                    log("Notifying source transport "
                            + AccessNetworkConstants.transportTypeToString(mTransport)
                            + " that handover is about to start.");
                    mDataServiceManagers.get(mTransport).startHandover(mCid.get(mTransport),
                            obtainMessage(EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE, 0, msg.arg2,
                                    msg.obj));
                    // We enter handover state here because this is the first action we do for
                    // handover.
                    transitionTo(mHandoverState);
                    break;
                case EVENT_SUBSCRIPTION_PLAN_OVERRIDE:
                    updateMeteredAndCongested();
@@ -1373,6 +1405,9 @@ public class DataNetwork extends StateMachine {
                    log("Defer message " + eventToString(msg.what));
                    deferMessage(msg);
                    break;
                case EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE:
                    onStartHandover(msg.arg2, (DataHandoverRetryEntry) msg.obj);
                    break;
                case EVENT_HANDOVER_RESPONSE:
                    int resultCode = msg.arg1;
                    DataCallResponse dataCallResponse =
@@ -3038,6 +3073,12 @@ public class DataNetwork extends StateMachine {
    /**
     * Request the data network to handover to the target transport.
     *
     * This is the starting point of initiating IWLAN/cellular handover. It will first call
     * {@link DataServiceManager#startHandover(int, Message)} to notify source transport that
     * handover is about to start, and then call {@link DataServiceManager#setupDataCall(int,
     * DataProfile, boolean, boolean, int, LinkProperties, int, NetworkSliceInfo, TrafficDescriptor,
     * boolean, Message)} on target transport to initiate the handover process.
     *
     * @param targetTransport The target transport.
     * @param retryEntry Data handover retry entry. This would be {@code null} for first time
     * handover attempt.
@@ -3050,12 +3091,16 @@ public class DataNetwork extends StateMachine {
            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
            return false;
        }
        sendMessage(obtainMessage(EVENT_START_HANDOVER, targetTransport, 0, retryEntry));

        // Before we really initiate the handover process on target transport, we need to notify
        // source transport that handover is about to start. Handover will be eventually initiated
        // in onStartHandover().
        sendMessage(obtainMessage(EVENT_NOTIFY_HANDOVER_STARTED, 0, targetTransport, retryEntry));
        return true;
    }

    /**
     * Called when handover between IWLAN and cellular is needed.
     * Called when starting IWLAN/cellular handover process on the target transport.
     *
     * @param targetTransport The target transport.
     * @param retryEntry Data handover retry entry. This would be {@code null} for first time
@@ -3110,7 +3155,6 @@ public class DataNetwork extends StateMachine {
                DataService.REQUEST_REASON_HANDOVER, mLinkProperties, mPduSessionId,
                mNetworkSliceInfo, mHandoverDataProfile.getTrafficDescriptor(), true,
                obtainMessage(EVENT_HANDOVER_RESPONSE, retryEntry));
        transitionTo(mHandoverState);
    }

    /**
@@ -3155,6 +3199,12 @@ public class DataNetwork extends StateMachine {
                    () -> mDataNetworkCallback.onHandoverSucceeded(DataNetwork.this));
        } else {
            // Handover failed.

            // Notify source transport that handover failed on target transport so that PDU session
            // id can be released if it is preserved for handover.
            mDataServiceManagers.get(mTransport).cancelHandover(mCid.get(mTransport),
                    obtainMessage(EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE));

            long retry = response != null ? response.getRetryDurationMillis()
                    : DataCallResponse.RETRY_DURATION_UNDEFINED;
            // If the handover mode is unspecified, default to HANDOVER_FAILURE_MODE_UNKNOWN,
@@ -3165,13 +3215,25 @@ public class DataNetwork extends StateMachine {
            mDataNetworkCallback.invokeFromExecutor(
                    () -> mDataNetworkCallback.onHandoverFailed(DataNetwork.this,
                            mFailCause, retry, handoverFailureMode));
            mDataCallSessionStats.onHandoverFailure(mFailCause);
            trackHandoverFailure();
        }

        // No matter handover succeeded or not, transit back to connected state.
        transitionTo(mConnectedState);
    }

    /**
     * Called when handover failed. Record the source and target RAT{@link NetworkType} and the
     * failure cause {@link android.telephony.DataFailCause}.
     */
    private void trackHandoverFailure() {
        int sourceRat = getDataNetworkType();
        int targetTransport = DataUtils.getTargetTransport(mTransport);
        int targetRat = getDataNetworkType(targetTransport);

        mDataCallSessionStats.onHandoverFailure(mFailCause, sourceRat, targetRat);
    }

    /**
     * Called when receiving PCO (Protocol Configuration Options) data from the cellular network.
     *
@@ -3322,8 +3384,6 @@ public class DataNetwork extends StateMachine {
                return "EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED";
            case EVENT_DISPLAY_INFO_CHANGED:
                return "EVENT_DISPLAY_INFO_CHANGED";
            case EVENT_START_HANDOVER:
                return "EVENT_START_HANDOVER";
            case EVENT_HANDOVER_RESPONSE:
                return "EVENT_HANDOVER_RESPONSE";
            case EVENT_SUBSCRIPTION_PLAN_OVERRIDE:
@@ -3344,6 +3404,12 @@ public class DataNetwork extends StateMachine {
                return "EVENT_VOICE_CALL_ENDED";
            case EVENT_CSS_INDICATOR_CHANGED:
                return "EVENT_CSS_INDICATOR_CHANGED";
            case EVENT_NOTIFY_HANDOVER_STARTED:
                return "EVENT_NOTIFY_HANDOVER_STARTED";
            case EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE:
                return "EVENT_NOTIFY_HANDOVER_STARTED_RESPONSE";
            case EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE:
                return "EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE";
            default:
                return "Unknown(" + event + ")";
        }
+24 −5
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@ import java.util.Random;
/** Collects data call change events per DataConnection for the pulled atom. */
public class DataCallSessionStats {
    private static final String TAG = DataCallSessionStats.class.getSimpleName();
    private static final int SIZE_LIMIT_HANDOVER_FAILURE_CAUSES = 15;

    private final Phone mPhone;
    private long mStartTime;
@@ -60,6 +59,8 @@ public class DataCallSessionStats {

    private static final Random RANDOM = new Random();

    public static final int SIZE_LIMIT_HANDOVER_FAILURES = 15;

    public DataCallSessionStats(Phone phone) {
        mPhone = phone;
    }
@@ -175,17 +176,30 @@ public class DataCallSessionStats {
     *
     * @param failureCause failure cause as per android.telephony.DataFailCause
     */
    public synchronized void onHandoverFailure(@DataFailureCause int failureCause) {
    public synchronized void onHandoverFailure(@DataFailureCause int failureCause,
            @NetworkType int sourceRat, @NetworkType int targetRat) {
        if (mDataCallSession != null
                && mDataCallSession.handoverFailureCauses.length
                < SIZE_LIMIT_HANDOVER_FAILURE_CAUSES) {
                < SIZE_LIMIT_HANDOVER_FAILURES) {

            int[] failureCauses = mDataCallSession.handoverFailureCauses;
            for (int cause : failureCauses) {
                if (failureCause == cause) return;
            int[] handoverFailureRats = mDataCallSession.handoverFailureRat;
            int failureDirection = sourceRat | (targetRat << 16);

            for (int i = 0; i < failureCauses.length; i++) {
                if (failureCauses[i] == failureCause
                        && handoverFailureRats[i] == failureDirection) {
                    return;
                }
            }

            mDataCallSession.handoverFailureCauses = Arrays.copyOf(
                    failureCauses, failureCauses.length + 1);
            mDataCallSession.handoverFailureCauses[failureCauses.length] = failureCause;

            mDataCallSession.handoverFailureRat = Arrays.copyOf(handoverFailureRats,
                    handoverFailureRats.length + 1);
            mDataCallSession.handoverFailureRat[handoverFailureRats.length] = failureDirection;
        }
    }

@@ -224,6 +238,7 @@ public class DataCallSessionStats {
     * Note the following fields are reset after the snapshot:
     * - rat switch count
     * - handover failure causes
     * - handover failure rats
     */
    public synchronized void conclude() {
        if (mDataCallSession != null) {
@@ -233,6 +248,7 @@ public class DataCallSessionStats {
            mStartTime = nowMillis;
            mDataCallSession.ratSwitchCount = 0L;
            mDataCallSession.handoverFailureCauses = new int[0];
            mDataCallSession.handoverFailureRat = new int[0];
            mAtomsStorage.addDataCallSession(call);
        }
    }
@@ -274,6 +290,8 @@ public class DataCallSessionStats {
        copy.bandAtEnd = call.bandAtEnd;
        copy.handoverFailureCauses = Arrays.copyOf(call.handoverFailureCauses,
                call.handoverFailureCauses.length);
        copy.handoverFailureRat = Arrays.copyOf(call.handoverFailureRat,
                call.handoverFailureRat.length);
        return copy;
    }

@@ -297,6 +315,7 @@ public class DataCallSessionStats {
        proto.durationMinutes = 0;
        proto.ongoing = true;
        proto.handoverFailureCauses = new int[0];
        proto.handoverFailureRat = new int[0];
        return proto;
    }

+2 −1
Original line number Diff line number Diff line
@@ -831,7 +831,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                round(dataCallSession.durationMinutes, DURATION_BUCKET_MILLIS / MINUTE_IN_MILLIS),
                dataCallSession.ongoing,
                dataCallSession.bandAtEnd,
                dataCallSession.handoverFailureCauses);
                dataCallSession.handoverFailureCauses,
                dataCallSession.handoverFailureRat);
    }

    private static StatsEvent buildStatsEvent(ImsRegistrationStats stats) {
+34 −1
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;

/**
@@ -320,6 +321,16 @@ public class PersistAtomsStorage {
            DataCallSession existingCall = mAtoms.dataCallSession[index];
            dataCall.ratSwitchCount += existingCall.ratSwitchCount;
            dataCall.durationMinutes += existingCall.durationMinutes;

            dataCall.handoverFailureCauses = IntStream.concat(Arrays.stream(
                            dataCall.handoverFailureCauses),
                    Arrays.stream(existingCall.handoverFailureCauses))
                    .limit(DataCallSessionStats.SIZE_LIMIT_HANDOVER_FAILURES).toArray();
            dataCall.handoverFailureRat = IntStream.concat(Arrays.stream(
                            dataCall.handoverFailureRat),
                    Arrays.stream(existingCall.handoverFailureRat))
                    .limit(DataCallSessionStats.SIZE_LIMIT_HANDOVER_FAILURES).toArray();

            mAtoms.dataCallSession[index] = dataCall;
        } else {
            mAtoms.dataCallSession =
@@ -723,7 +734,8 @@ public class PersistAtomsStorage {
            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
            for (DataCallSession dataCallSession : previousDataCallSession) {
                // sort to de-correlate any potential pattern for UII concern
                Arrays.sort(dataCallSession.handoverFailureCauses);
                sortBaseOnArray(dataCallSession.handoverFailureCauses,
                        dataCallSession.handoverFailureRat);
            }
            return previousDataCallSession;
        } else {
@@ -731,6 +743,27 @@ public class PersistAtomsStorage {
        }
    }

    /**
     * Sort the other array base on the natural order of the primary array. Both arrays will be
     * sorted in-place.
     * @param primary The primary array to be sorted.
     * @param other The other array to be sorted in the order of primary array.
     */
    private void sortBaseOnArray(int[] primary, int[] other) {
        if (other.length != primary.length) return;
        int[] index = IntStream.range(0, primary.length).boxed()
                .sorted(Comparator.comparingInt(i -> primary[i]))
                .mapToInt(Integer::intValue)
                .toArray();
        int[] primaryCopy = Arrays.copyOf(primary,  primary.length);
        int[] otherCopy = Arrays.copyOf(other,  other.length);
        for (int i = 0; i < index.length; i++) {
            primary[i] = primaryCopy[index[i]];
            other[i] = otherCopy[index[i]];
        }
    }


    /**
     * Returns and clears the service state durations if last pulled longer than {@code
     * minIntervalMillis} ago, otherwise returns {@code null}.
Loading