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

Commit 995671e5 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8872621 from 138bc9a6 to tm-qpr1-release

Change-Id: Ic9ce30fce9eb9fe5b9c7aa89bf32de36af46f3cb
parents d0b23aec 138bc9a6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -248,6 +248,10 @@ message IncomingSms {
    optional bool is_esim = 12;
    optional int32 carrier_id = 13;
    optional int64 message_id = 14;
    optional int32 count = 15;

    // Internal use only
    optional int32 hashCode = 10001;
}

message OutgoingSms {
@@ -265,6 +269,10 @@ message OutgoingSms {
    optional int64 message_id = 12;
    optional int32 retry_id = 13;
    optional int64 interval_millis = 14;
    optional int32 count = 15;

    // Internal use only
    optional int32 hashCode = 10001;
}

message CarrierIdMismatch {
+1 −1
Original line number Diff line number Diff line
@@ -715,7 +715,7 @@ public class LinkBandwidthEstimator extends Handler {
            int filterInKbps = mBwSampleValid ? mBwSampleKbps : avgKbps;

            long currTimeMs = mTelephonyFacade.getElapsedSinceBootMillis();
            int timeDeltaSec = (int) (currTimeMs - mBwSampleValidTimeMs) / 1000;
            int timeDeltaSec = (int) ((currTimeMs - mBwSampleValidTimeMs) / 1000);

            // If the operation condition changes significantly since the last update
            // or the sample has higher BW, use a faster filter. Otherwise, use a slow filter
+4 −2
Original line number Diff line number Diff line
@@ -787,7 +787,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                sms.isMultiSim,
                sms.isEsim,
                sms.carrierId,
                sms.messageId);
                sms.messageId,
                sms.count);
    }

    private static StatsEvent buildStatsEvent(OutgoingSms sms) {
@@ -806,7 +807,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                sms.carrierId,
                sms.messageId,
                sms.retryId,
                sms.intervalMillis);
                sms.intervalMillis,
                sms.count);
    }

    private static StatsEvent buildStatsEvent(DataCallSession dataCallSession) {
+95 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager.NetworkTypeBitMask;
import android.util.SparseIntArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.nano.PersistAtomsProto.CarrierIdMismatch;
@@ -257,6 +258,7 @@ public class PersistAtomsStorage {

    /** Adds an incoming SMS to the storage. */
    public synchronized void addIncomingSms(IncomingSms sms) {
        sms.hashCode = SmsStats.getSmsHashCode(sms);
        mAtoms.incomingSms = insertAtRandomPlace(mAtoms.incomingSms, sms, mMaxNumSms);
        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);

@@ -266,6 +268,7 @@ public class PersistAtomsStorage {

    /** Adds an outgoing SMS to the storage. */
    public synchronized void addOutgoingSms(OutgoingSms sms) {
        sms.hashCode = SmsStats.getSmsHashCode(sms);
        // Update the retry id, if needed, so that it's unique and larger than all
        // previous ones. (this algorithm ignores the fact that some SMS atoms might
        // be dropped due to limit in size of the array).
@@ -1682,8 +1685,9 @@ public class PersistAtomsStorage {
    }

    /**
     * Inserts a new element in a random position in an array with a maximum size, replacing the
     * least recent item if possible.
     * Inserts a new element in a random position in an array with a maximum size.
     *
     * <p>If the array is full, merge with existing item if possible or replace one item randomly.
     */
    private static <T> T[] insertAtRandomPlace(T[] storage, T instance, int maxLength) {
        final int newLength = storage.length + 1;
@@ -1692,7 +1696,11 @@ public class PersistAtomsStorage {
        if (newLength == 1) {
            result[0] = instance;
        } else if (arrayFull) {
            if (instance instanceof OutgoingSms || instance instanceof IncomingSms) {
                mergeSmsOrEvictInFullStorage(result, instance);
            } else {
                result[findItemToEvict(storage)] = instance;
            }
        } else {
            // insert at random place (by moving the item at the random place to the end)
            int insertAt = sRandom.nextInt(newLength);
@@ -1702,6 +1710,90 @@ public class PersistAtomsStorage {
        return result;
    }

    /**
     * Merge new sms in a full storage.
     *
     * <p>If new sms is similar to old sms, merge them.
     * If not, merge 2 old similar sms and add the new sms.
     * If not, replace old sms with the lowest count.
     */
    private static <T> void mergeSmsOrEvictInFullStorage(T[] storage, T instance) {
        // key: hashCode, value: smsIndex
        SparseIntArray map = new SparseIntArray();
        int smsIndex1 = -1;
        int smsIndex2 = -1;
        int indexLowestCount = -1;
        int minCount = Integer.MAX_VALUE;

        for (int i = 0; i < storage.length; i++) {
            // If the new SMS can be merged to an existing item, merge it and return immediately.
            if (areSmsMergeable(storage[i], instance)) {
                storage[i] = mergeSms(storage[i], instance);
                return;
            }

            // Keep sms index with lowest count to evict, in case we cannot merge any 2 messages.
            int smsCount = getSmsCount(storage[i]);
            if (smsCount < minCount) {
                indexLowestCount = i;
                minCount = smsCount;
            }

            // Find any 2 messages in the storage that can be merged together.
            if (smsIndex1 != -1) {
                int smsHashCode = getSmsHashCode(storage[i]);
                if (map.indexOfKey(smsHashCode) < 0) {
                    map.append(smsHashCode, i);
                } else {
                    smsIndex1 = map.get(smsHashCode);
                    smsIndex2 = i;
                }
            }
        }

        // Merge 2 similar old sms and add the new sms
        if (smsIndex1 != -1) {
            storage[smsIndex1] = mergeSms(storage[smsIndex1], storage[smsIndex2]);
            storage[smsIndex2] = instance;
            return;
        }

        // Or replace old sms that has the lowest count
        storage[indexLowestCount] = instance;
        return;
    }

    private static <T> int getSmsHashCode(T sms) {
        return sms instanceof OutgoingSms
                ? ((OutgoingSms) sms).hashCode : ((IncomingSms) sms).hashCode;
    }

    private static <T> int getSmsCount(T sms) {
        return sms instanceof OutgoingSms
                ? ((OutgoingSms) sms).count : ((IncomingSms) sms).count;
    }

    /** Compares 2 SMS hash codes to check if they can be clubbed together in the metrics. */
    private static <T> boolean areSmsMergeable(T instance1, T instance2) {
        return getSmsHashCode(instance1) == getSmsHashCode(instance2);
    }

    /** Merges sms2 data on top of sms1 and returns the merged value. */
    private static <T> T mergeSms(T sms1, T sms2) {
        if (sms1 instanceof OutgoingSms) {
            OutgoingSms tSms1 = (OutgoingSms) sms1;
            OutgoingSms tSms2 = (OutgoingSms) sms2;
            tSms1.intervalMillis = (tSms1.intervalMillis * tSms1.count
                    + tSms2.intervalMillis * tSms2.count) / (tSms1.count + tSms2.count);
            tSms1.count += tSms2.count;
        } else if (sms1 instanceof IncomingSms) {
            IncomingSms tSms1 = (IncomingSms) sms1;
            IncomingSms tSms2 = (IncomingSms) sms2;
            tSms1.count += tSms2.count;
        }
        return sms1;
    }

    /** Returns index of the item suitable for eviction when the array is full. */
    private static <T> int findItemToEvict(T[] array) {
        if (array instanceof CellularServiceState[]) {
+23 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms;
import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms;
import com.android.telephony.Rlog;

import java.util.Objects;
import java.util.Random;

/** Collects sms events per phone ID for the pulled atom. */
@@ -214,6 +215,7 @@ public class SmsStats {
        // Message ID is initialized with random number, as it is not available for all incoming
        // SMS messages (e.g. those handled by OS or error cases).
        proto.messageId = RANDOM.nextLong();
        proto.count = 1;
        return proto;
    }

@@ -238,6 +240,7 @@ public class SmsStats {
        // in the persistent storage.
        proto.retryId = 0;
        proto.intervalMillis = intervalMillis;
        proto.count = 1;
        return proto;
    }

@@ -304,6 +307,26 @@ public class SmsStats {
        }
    }

    /**
     * Returns a hash value to identify messages that are identical for the purpose of merging them
     * together when storage is full.
     */
    static int getSmsHashCode(OutgoingSms sms) {
        return Objects.hash(sms.smsFormat, sms.smsTech, sms.rat, sms.sendResult, sms.errorCode,
                    sms.isRoaming, sms.isFromDefaultApp, sms.simSlotIndex, sms.isMultiSim,
                    sms.isEsim, sms.carrierId);
    }

    /**
     * Returns a hash value to identify messages that are identical for the purpose of merging them
     * together when storage is full.
     */
    static int getSmsHashCode(IncomingSms sms) {
        return Objects.hash(sms.smsFormat, sms.smsTech, sms.rat, sms.smsType,
            sms.totalParts, sms.receivedParts, sms.blocked, sms.error,
            sms.isRoaming, sms.simSlotIndex, sms.isMultiSim, sms.isEsim, sms.carrierId);
    }

    private int getPhoneId() {
        Phone phone = mPhone;
        if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
Loading