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

Commit dd5e924d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Update constant thresholds for trigger anomaly report" into tm-dev

parents 95ca4246 af00ca28
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -81,7 +81,28 @@ public class SlidingWindowEventCounter {
    }

    @VisibleForTesting
    int getNumOccurrences() {
    int getQueuedNumOccurrences() {
        return mTimestampQueueMillis.size();
    }

    /**
     * @return the time span in ms of the sliding window.
     */
    public synchronized long getWindowSizeMillis() {
        return mWindowSizeMillis;
    }

    /**
     * @return the least number of occurrences for {@link #isInWindow} to be true.
     */
    public synchronized int getNumOccurrences() {
        return mNumOccurrences;
    }

    @Override
    public String toString() {
        return String.format("SlidingWindowEventCounter=[windowSizeMillis=" + mWindowSizeMillis
                + ", numOccurrences=" + mNumOccurrences
                + ", timestampQueueMillis=" + mTimestampQueueMillis + "]");
    }
}
+214 −17
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.telephony.data.ApnSetting;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataNetworkController.HandoverRule;
import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryRule;
@@ -72,6 +73,9 @@ public class DataConfigManager extends Handler {
    /** Event for carrier config changed. */
    private static final int EVENT_CARRIER_CONFIG_CHANGED = 1;

    /** Event for device config changed. */
    private static final int EVENT_DEVICE_CONFIG_CHANGED = 2;

    /** Indicates the bandwidth estimation source is from the modem. */
    private static final String BANDWIDTH_SOURCE_MODEM_STRING_VALUE = "modem";

@@ -185,13 +189,52 @@ public class DataConfigManager extends Handler {
    @Retention(RetentionPolicy.SOURCE)
    private @interface DataConfigNetworkType {}

    /** DeviceConfig key of anomaly report threshold for back to back ims release-request. */
    private static final String KEY_ANOMALY_IMS_RELEASE_REQUEST = "anomaly_ims_release_request";
    /** DeviceConfig key of anomaly report threshold for frequent setup data failure. */
    private static final String KEY_ANOMALY_SETUP_DATA_CALL_FAILURE =
            "anomaly_setup_data_call_failure";
    /** DeviceConfig key of anomaly report threshold for frequent network-unwanted call. */
    private static final String KEY_ANOMALY_NETWORK_UNWANTED = "anomaly_network_unwanted";
    /** DeviceConfig key of anomaly report threshold for DataNetwork stuck in connecting state. */
    private static final String KEY_ANOMALY_NETWORK_CONNECTING_TIMEOUT =
            "anomaly_network_connecting_timeout";
    /** DeviceConfig key of anomaly report threshold for DataNetwork stuck in disconnecting state.*/
    private static final String KEY_ANOMALY_NETWORK_DISCONNECTING_TIMEOUT =
            "anomaly_network_disconnecting_timeout";
    /** DeviceConfig key of anomaly report threshold for DataNetwork stuck in handover state. */
    private static final String KEY_ANOMALY_NETWORK_HANDOVER_TIMEOUT =
            "anomaly_network_handover_timeout";

    /** Anomaly report thresholds for frequent setup data call failure. */
    private EventFrequency mSetupDataCallAnomalyReportThreshold;

    /** Anomaly report thresholds for back to back release-request of IMS. */
    private EventFrequency mImsReleaseRequestAnomalyReportThreshold;

    /**
     * Anomaly report thresholds for frequent network unwanted call
     * at {@link TelephonyNetworkAgent#onNetworkUnwanted}
     */
    private EventFrequency mNetworkUnwantedAnomalyReportThreshold;

    /**
     * The minimal time window for duplicate release-request for IMS, the violation of which
     * triggers anomaly report in {@link DataNetworkController}.
     * Timeout in ms before creating an anomaly report for a DataNetwork stuck in
     * {@link DataNetwork#ConnectingState}.
     */
    private final long mImsRequestReleaseThrottleAnomalyWindowMs =
            DeviceConfig.getInt(DeviceConfig.NAMESPACE_TELEPHONY,
                    "ims_release_request_window", 0);
    private int mNetworkConnectingTimeout;

    /**
     * Timeout in ms before creating an anomaly report for a DataNetwork stuck in
     * {@link DataNetwork#DisconnectingState}.
     */
    private int mNetworkDisconnectingTimeout;

    /**
     * Timeout in ms before creating an anomaly report for a DataNetwork stuck in
     * {@link DataNetwork#HandoverState}.
     */
    private int mNetworkHandoverTimeout;

    private @NonNull final Phone mPhone;
    private @NonNull final String mLogTag;
@@ -247,6 +290,7 @@ public class DataConfigManager extends Handler {

        mCarrierConfigManager = mPhone.getContext().getSystemService(CarrierConfigManager.class);

        // Register for carrier configs update
        IntentFilter filter = new IntentFilter();
        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        mPhone.getContext().registerReceiver(new BroadcastReceiver() {
@@ -262,8 +306,20 @@ public class DataConfigManager extends Handler {
            }
        }, filter, null, mPhone);

        // Register for device config update
        DeviceConfig.addOnPropertiesChangedListener(
                DeviceConfig.NAMESPACE_TELEPHONY, this::post,
                properties -> {
                    if (TextUtils.equals(DeviceConfig.NAMESPACE_TELEPHONY,
                            properties.getNamespace())) {
                        sendEmptyMessage(EVENT_DEVICE_CONFIG_CHANGED);
                    }
                });

        // Must be called to set mCarrierConfig and mResources to non-null values
        updateConfig();
        updateCarrierConfig();
        updateDeviceConfig();
        mConfigUpdateRegistrants.notifyRegistrants();
    }

    @Override
@@ -271,13 +327,44 @@ public class DataConfigManager extends Handler {
        switch (msg.what) {
            case EVENT_CARRIER_CONFIG_CHANGED:
                log("EVENT_CARRIER_CONFIG_CHANGED");
                updateConfig();
                updateCarrierConfig();
                mConfigUpdateRegistrants.notifyRegistrants();
                break;
            case EVENT_DEVICE_CONFIG_CHANGED:
                log("EVENT_DEVICE_CONFIG_CHANGED");
                updateDeviceConfig();
                mConfigUpdateRegistrants.notifyRegistrants();
                break;
            default:
                loge("Unexpected message " + msg.what);
        }
    }

    /** Update local properties from {@link DeviceConfig} */
    private void updateDeviceConfig() {
        DeviceConfig.Properties properties = //read all telephony properties
                DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TELEPHONY);

        mImsReleaseRequestAnomalyReportThreshold = parseSlidingWindowCounterThreshold(
                properties.getString(KEY_ANOMALY_IMS_RELEASE_REQUEST, null),
                300000,
                12);
        mNetworkUnwantedAnomalyReportThreshold = parseSlidingWindowCounterThreshold(
                properties.getString(KEY_ANOMALY_NETWORK_UNWANTED, null),
                300000,
                12);
        mSetupDataCallAnomalyReportThreshold = parseSlidingWindowCounterThreshold(
                properties.getString(KEY_ANOMALY_SETUP_DATA_CALL_FAILURE, null),
                0,
                2);
        mNetworkConnectingTimeout = properties.getInt(
                KEY_ANOMALY_NETWORK_CONNECTING_TIMEOUT, 86400000);
        mNetworkDisconnectingTimeout = properties.getInt(
                KEY_ANOMALY_NETWORK_DISCONNECTING_TIMEOUT, 86400000);
        mNetworkHandoverTimeout = properties.getInt(
                KEY_ANOMALY_NETWORK_HANDOVER_TIMEOUT, 86400000);
    }

    /**
     * @return {@code true} if the configuration is carrier specific. {@code false} if the
     * configuration is the default (i.e. SIM not inserted).
@@ -287,9 +374,9 @@ public class DataConfigManager extends Handler {
    }

    /**
     * Update the configuration.
     * Update the configuration from carrier configs and resources.
     */
    private void updateConfig() {
    private void updateCarrierConfig() {
        if (mCarrierConfigManager != null) {
            mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
        }
@@ -310,8 +397,6 @@ public class DataConfigManager extends Handler {

        log("Data config updated. Config is " + (isConfigCarrierSpecific() ? "" : "not ")
                + "carrier specific.");

        mConfigUpdateRegistrants.notifyRegistrants();
    }

    /**
@@ -666,10 +751,52 @@ public class DataConfigManager extends Handler {
    }

    /**
     * @return The IMS back to back request/release minimal interval.
     * Anomaly report thresholds for frequent setup data call failure.
     * @return EventFrequency to trigger the anomaly report
     */
    public @NonNull EventFrequency getAnomalySetupDataCallThreshold() {
        return mSetupDataCallAnomalyReportThreshold;
    }

    /**
     * Anomaly report thresholds for frequent network unwanted call
     * at {@link TelephonyNetworkAgent#onNetworkUnwanted}
     * @return EventFrequency to trigger the anomaly report
     */
    public @NonNull EventFrequency getAnomalyNetworkUnwantedThreshold() {
        return mNetworkUnwantedAnomalyReportThreshold;
    }

    /**
     * Anomaly report thresholds for back to back release-request of IMS.
     * @return EventFrequency to trigger the anomaly report
     */
    public @NonNull EventFrequency getAnomalyImsReleaseRequestThreshold() {
        return mImsReleaseRequestAnomalyReportThreshold;
    }

    /**
     * @return Timeout in ms before creating an anomaly report for a DataNetwork stuck in
     * {@link DataNetwork#ConnectingState}.
     */
    public long getImsRequestReleaseThrottleAnomalyWindowMs() {
        return mImsRequestReleaseThrottleAnomalyWindowMs;
    public int getAnomalyNetworkConnectingTimeoutMs() {
        return mNetworkConnectingTimeout;
    }

    /**
     * @return Timeout in ms before creating an anomaly report for a DataNetwork stuck in
     * {@link DataNetwork#DisconnectingState}.
     */
    public int getAnomalyNetworkDisconnectingTimeoutMs() {
        return mNetworkDisconnectingTimeout;
    }

    /**
     * @return Timeout in ms before creating an anomaly report for a DataNetwork stuck in
     * {@link DataNetwork#HandoverState}.
     */
    public int getNetworkHandoverTimeoutMs() {
        return mNetworkHandoverTimeout;
    }

    /**
@@ -794,6 +921,72 @@ public class DataConfigManager extends Handler {
        }
    }

    /**
     * Describe an event occurs eventNumOccurrence within a time span timeWindow
     */
    public static class EventFrequency {
        /** The time window in ms within which event occurs. */
        public final long timeWindow;

        /** The number of time the event occurs. */
        public final int eventNumOccurrence;

        /**
         * Constructor
         *
         * @param timeWindow The time window in ms within which event occurs.
         * @param eventNumOccurrence The number of time the event occurs.
         */
        public EventFrequency(long timeWindow, int eventNumOccurrence) {
            this.timeWindow = timeWindow;
            this.eventNumOccurrence = eventNumOccurrence;
        }

        @Override
        public String toString() {
            return String.format("EventFrequency=[timeWindow=%d, eventNumOccurrence=%d]",
                    timeWindow, eventNumOccurrence);
        }
    }

    /**
     * Parse a pair of event throttle thresholds of the form "time window in ms,occurrences"
     * into {@link EventFrequency}
     * @param s String to be parsed in the form of "time window in ms,occurrences"
     * @param defaultTimeWindow The time window to return if parsing failed.
     * @param defaultOccurrences The occurrence to return if parsing failed.
     * @return timeWindow and occurrence wrapped in EventFrequency
     */
    @VisibleForTesting
    public EventFrequency parseSlidingWindowCounterThreshold(String s,
            long defaultTimeWindow, int defaultOccurrences) {
        EventFrequency defaultValue = new EventFrequency(defaultTimeWindow, defaultOccurrences);
        if (TextUtils.isEmpty(s)) return defaultValue;

        final String[] pair = s.split(",");
        if (pair.length != 2) {
            loge("Invalid format: " + s
                    + "Format should be in \"time window in ms,occurrences\". "
                    + "Using default instead.");
            return defaultValue;
        }
        long windowSpan;
        int occurrence;
        try {
            windowSpan = Long.parseLong(pair[0].trim());
        } catch (NumberFormatException e) {
            loge("Exception parsing SlidingWindow window span " + pair[0] + ": " + e);
            return defaultValue;
        }
        try {
            occurrence = Integer.parseInt(pair[1].trim());
        } catch (NumberFormatException e) {
            loge("Exception parsing SlidingWindow occurrence as integer " + pair[1] + ": " + e);
            return defaultValue;
        }
        return new EventFrequency(windowSpan, occurrence);
    }

    /**
     * @return Get rules for handover between IWLAN and cellular networks.
     *
@@ -981,8 +1174,12 @@ public class DataConfigManager extends Handler {
        pw.increaseIndent();
        mDataHandoverRetryRules.forEach(pw::println);
        pw.decreaseIndent();
        pw.println("IMS request release throttle anomaly window in ms="
                + mImsRequestReleaseThrottleAnomalyWindowMs);
        pw.println("mSetupDataCallAnomalyReport=" + mSetupDataCallAnomalyReportThreshold);
        pw.println("mNetworkUnwantedAnomalyReport=" + mNetworkUnwantedAnomalyReportThreshold);
        pw.println("mImsReleaseRequestAnomalyReport=" + mImsReleaseRequestAnomalyReportThreshold);
        pw.println("mNetworkConnectingTimeout=" + mNetworkConnectingTimeout);
        pw.println("mNetworkDisconnectingTimeout=" + mNetworkDisconnectingTimeout);
        pw.println("mNetworkHandoverTimeout=" + mNetworkHandoverTimeout);
        pw.println("Metered APN types=" + mMeteredApnTypes.stream()
                .map(ApnSetting::getApnTypeString).collect(Collectors.joining(",")));
        pw.println("Roaming metered APN types=" + mRoamingMeteredApnTypes.stream()
+31 −22
Original line number Diff line number Diff line
@@ -207,8 +207,10 @@ public class DataNetwork extends StateMachine {

    /**
     * Event for data network stuck in transient (i.e. connecting/disconnecting/handover) state for
     * too long time. Timeout value specified in {@link #MAXIMUM_CONNECTING_DURATION_MILLIS},
     * {@link #MAXIMUM_DISCONNECTING_DURATION_MILLIS}, {@link #MAXIMUM_HANDOVER_DURATION_MILLIS}.
     * too long time. Timeout value specified in
     * {@link DataConfigManager#getAnomalyNetworkConnectingTimeoutMs()},
     * {@link DataConfigManager#getAnomalyNetworkDisconnectingTimeoutMs()},
     * {@link DataConfigManager#getNetworkHandoverTimeoutMs()}.
     */
    private static final int EVENT_STUCK_IN_TRANSIENT_STATE = 20;

@@ -227,18 +229,6 @@ public class DataNetwork extends StateMachine {
    /** Invalid context id. */
    private static final int INVALID_CID = -1;

    /** The maximum time the data network can stay in {@link ConnectingState}. */
    private static final long MAXIMUM_CONNECTING_DURATION_MILLIS =
            TimeUnit.SECONDS.toMillis(60);

    /** The maximum time the data network can stay in {@link DisconnectingState}. */
    private static final long MAXIMUM_DISCONNECTING_DURATION_MILLIS =
            TimeUnit.SECONDS.toMillis(60);

    /** The maximum time the data network can stay in {@link HandoverState}. */
    private static final long MAXIMUM_HANDOVER_DURATION_MILLIS =
            TimeUnit.SECONDS.toMillis(60);

    /**
     * The data network providing default internet will have a higher score of 50. Other network
     * will have a slightly lower score of 45. The intention is other connections will not cause
@@ -781,6 +771,13 @@ public class DataNetwork extends StateMachine {
         * @param dataNetwork The data network.
         */
        public abstract void onNetworkCapabilitiesChanged(@NonNull DataNetwork dataNetwork);

        /**
         * Called when attempt to tear down a data network
         *
         * @param dataNetwork The data network.
         */
        public abstract void onTrackNetworkUnwanted(@NonNull DataNetwork dataNetwork);
    }

    /**
@@ -1046,7 +1043,7 @@ public class DataNetwork extends StateMachine {
        @Override
        public void enter() {
            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
                    MAXIMUM_CONNECTING_DURATION_MILLIS);
                    mDataConfigManager.getAnomalyNetworkConnectingTimeoutMs());
            // Need to calculate the initial capabilities before creating the network agent.
            updateNetworkCapabilities();
            mNetworkAgent = createNetworkAgent();
@@ -1103,7 +1100,8 @@ public class DataNetwork extends StateMachine {
                case EVENT_STUCK_IN_TRANSIENT_STATE:
                    String message = "Data network stuck in connecting state for "
                            + TimeUnit.MILLISECONDS.toSeconds(
                                    MAXIMUM_CONNECTING_DURATION_MILLIS) + " seconds.";
                            mDataConfigManager.getAnomalyNetworkConnectingTimeoutMs())
                            + " seconds.";
                    logl(message);
                    AnomalyReporter.reportAnomaly(
                            UUID.fromString("58c56403-7ea7-4e56-a0c7-e467114d09b8"), message);
@@ -1235,7 +1233,8 @@ public class DataNetwork extends StateMachine {
    private final class HandoverState extends State {
        @Override
        public void enter() {
            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE, MAXIMUM_HANDOVER_DURATION_MILLIS);
            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
                    mDataConfigManager.getNetworkHandoverTimeoutMs());
            notifyPreciseDataConnectionState();
        }

@@ -1277,10 +1276,10 @@ public class DataNetwork extends StateMachine {
                case EVENT_STUCK_IN_TRANSIENT_STATE:
                    String message = "Data service did not respond the handover request within "
                            + TimeUnit.MILLISECONDS.toSeconds(
                            MAXIMUM_HANDOVER_DURATION_MILLIS) + " seconds.";
                            mDataConfigManager.getNetworkHandoverTimeoutMs()) + " seconds.";
                    logl(message);
                    AnomalyReporter.reportAnomaly(
                            UUID.fromString("15f60e1d-c985-48a9-abc4-be76e343864f"), message);
                            UUID.fromString("1afe68cb-8b41-4964-a737-4f34372429ea"), message);

                    // Handover failed. Use the retry logic defined in
                    // CarrierConfigManager.KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY.
@@ -1346,7 +1345,7 @@ public class DataNetwork extends StateMachine {
        @Override
        public void enter() {
            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
                    MAXIMUM_DISCONNECTING_DURATION_MILLIS);
                    mDataConfigManager.getAnomalyNetworkDisconnectingTimeoutMs());
            notifyPreciseDataConnectionState();
        }

@@ -1378,7 +1377,8 @@ public class DataNetwork extends StateMachine {
                    String message = "RIL did not send data call list changed event after "
                            + "deactivate data call request within "
                            + TimeUnit.MILLISECONDS.toSeconds(
                                    MAXIMUM_DISCONNECTING_DURATION_MILLIS) + " seconds.";
                            mDataConfigManager.getAnomalyNetworkDisconnectingTimeoutMs())
                            + " seconds.";
                    logl(message);
                    AnomalyReporter.reportAnomaly(
                            UUID.fromString("d0e4fa1c-c57b-4ba5-b4b6-8955487012cc"), message);
@@ -2253,6 +2253,14 @@ public class DataNetwork extends StateMachine {
            return;
        }

        //track frequent networkUnwanted call of IMS and INTERNET
        if ((isConnected())
                && (mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                || mNetworkCapabilities.hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_INTERNET))) {
            mDataNetworkCallback.onTrackNetworkUnwanted(this);
        }

        // TODO: Need to support DataService.REQUEST_REASON_SHUTDOWN
        mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
                DataService.REQUEST_REASON_NORMAL,
@@ -2268,7 +2276,8 @@ public class DataNetwork extends StateMachine {
        return mDataConfigManager.isImsDelayTearDownEnabled()
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone().getCallTracker().getState() != PhoneConstants.State.IDLE;
                && mPhone.getImsPhone().getCallTracker().getState()
                != PhoneConstants.State.IDLE;
    }

    /**
+62 −7

File changed.

Preview size limit exceeded, changes collapsed.

+0 −39
Original line number Diff line number Diff line
@@ -22,29 +22,24 @@ import android.annotation.Nullable;
import android.net.KeepalivePacketData;
import android.net.NetworkAgent;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkProvider;
import android.net.NetworkScore;
import android.net.QosFilter;
import android.net.QosSessionAttributes;
import android.net.Uri;
import android.os.Looper;
import android.telephony.AnomalyReporter;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;

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

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
 * TelephonyNetworkAgent class represents a single PDN (Packet Data Network). It is an agent
@@ -56,13 +51,6 @@ public class TelephonyNetworkAgent extends NetworkAgent implements NotifyQosSess
    private final Phone mPhone;
    private final LocalLog mLocalLog = new LocalLog(128);

    /** Event counter for unwanted network within time window, is used to trigger anomaly report. */
    private static final long NETWORK_UNWANTED_ANOMALY_WINDOW_MS = TimeUnit.MINUTES.toMillis(5);
    private static final int NETWORK_UNWANTED_ANOMALY_NUM_OCCURRENCES =  12;
    private static final SlidingWindowEventCounter sNetworkUnwantedCounter =
            new SlidingWindowEventCounter(NETWORK_UNWANTED_ANOMALY_WINDOW_MS,
                    NETWORK_UNWANTED_ANOMALY_NUM_OCCURRENCES);

    /** The parent data network. */
    private final @NonNull DataNetwork mDataNetwork;

@@ -189,36 +177,9 @@ public class TelephonyNetworkAgent extends NetworkAgent implements NotifyQosSess
            return;
        }

        NetworkCapabilities capabilities = mDataNetwork.getNetworkCapabilities();
        if ((mDataNetwork.isConnected() || mDataNetwork.isHandoverInProgress())
                && (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                || capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET))) {
            trackNetworkUnwanted();
        }

        mDataNetwork.tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
    }

    /**
     * There have been several bugs where a RECONNECT loop kicks off where a DataConnection
     * connects to the Network, ConnectivityService indicates that the Network is unwanted,
     * and then the DataConnection reconnects. By the time we get the bug report it's too late
     * because there have already been hundreds of RECONNECTS.  This is meant to capture the issue
     * when it first starts.
     *
     * The unwanted counter is configured to only take an anomaly report in extreme cases.
     * This is to avoid having the anomaly message show up on several devices.
     *
     */
    private void trackNetworkUnwanted() {
        if (sNetworkUnwantedCounter.addOccurrence()) {
            AnomalyReporter.reportAnomaly(
                    UUID.fromString("9f3bc55b-bfa6-4e26-afaa-5031426a66d2"),
                    "Network Unwanted called 12 times in 5 minutes.");
        }
    }


    /**
     * @return The unique id of the agent.
     */
Loading