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

Commit bfff58e1 authored by Michele Berionne's avatar Michele Berionne Committed by Android (Google) Code Review
Browse files

Merge "Add metrics for 5G enterprise slicing." into sc-dev

parents a22ce262 de667dc2
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -87,6 +87,12 @@ message PersistAtoms {

    /* Last Android build fingerprint. This usually changes after system OTA. */
    optional string build_fingerprint = 21;

    /* Summary of received network requests. */
    repeated NetworkRequests network_requests = 22;

    /* Timestamp of last network_requests pull. */
    optional int64 network_requests_pull_timestamp_millis = 23;
}

// The canonical versions of the following enums live in:
@@ -261,3 +267,9 @@ message ImsRegistrationStats {
    // Internal use only
    optional int64 last_used_millis = 10001;
}

message NetworkRequests {
    optional int32 carrier_id = 1;
    optional int32 enterprise_request_count = 2;
    optional int32 enterprise_release_count = 3;
}
+2 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.telephony.metrics;

import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;

import static com.android.internal.telephony.TelephonyStatsLog.AIRPLANE_MODE;

@@ -113,6 +114,6 @@ public class AirplaneModeStats extends ContentObserver {
        int phoneId = dataSubId != INVALID_SUBSCRIPTION_ID
                ? SubscriptionManager.getPhoneId(dataSubId) : 0;
        Phone phone = PhoneFactory.getPhone(phoneId);
        return phone != null ? phone.getCarrierId() : INVALID_SUBSCRIPTION_ID;
        return phone != null ? phone.getCarrierId() : UNKNOWN_CARRIER_ID;
    }
}
+25 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS;
import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS;
import static com.android.internal.telephony.TelephonyStatsLog.SIM_SLOT_STATE;
import static com.android.internal.telephony.TelephonyStatsLog.SUPPORTED_RADIO_ACCESS_FAMILY;
import static com.android.internal.telephony.TelephonyStatsLog.TELEPHONY_NETWORK_REQUESTS;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION;

@@ -49,6 +50,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationStats;
import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTermination;
import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms;
import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequests;
import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms;
import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
@@ -118,6 +120,7 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
            registerAtom(DATA_CALL_SESSION, POLICY_PULL_DAILY);
            registerAtom(IMS_REGISTRATION_STATS, POLICY_PULL_DAILY);
            registerAtom(IMS_REGISTRATION_TERMINATION, POLICY_PULL_DAILY);
            registerAtom(TELEPHONY_NETWORK_REQUESTS, POLICY_PULL_DAILY);

            Rlog.d(TAG, "registered");
        } else {
@@ -167,6 +170,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                return pullImsRegistrationStats(data);
            case IMS_REGISTRATION_TERMINATION:
                return pullImsRegistrationTermination(data);
            case TELEPHONY_NETWORK_REQUESTS:
                return pullTelephonyNetworkRequests(data);
            default:
                Rlog.e(TAG, String.format("unexpected atom ID %d", atomTag));
                return StatsManager.PULL_SKIP;
@@ -363,6 +368,18 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
        }
    }

    private int pullTelephonyNetworkRequests(List<StatsEvent> data) {
        NetworkRequests[] persistAtoms = mStorage.getNetworkRequests(MIN_COOLDOWN_MILLIS);
        if (persistAtoms != null) {
            Arrays.stream(persistAtoms)
                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
            return StatsManager.PULL_SUCCESS;
        } else {
            Rlog.w(TAG, "TELEPHONY_NETWORK_REQUESTS pull too frequent, skipping");
            return StatsManager.PULL_SKIP;
        }
    }

    /** Registers a pulled atom ID {@code atomId} with optional {@code policy} for pulling. */
    private void registerAtom(int atomId, @Nullable StatsManager.PullAtomMetadata policy) {
        mStatsManager.setPullAtomCallback(atomId, policy, ConcurrentUtils.DIRECT_EXECUTOR, this);
@@ -536,6 +553,14 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback {
                termination.count);
    }

    private static StatsEvent buildStatsEvent(NetworkRequests networkRequests) {
        return TelephonyStatsLog.buildStatsEvent(
                TELEPHONY_NETWORK_REQUESTS,
                networkRequests.carrierId,
                networkRequests.enterpriseRequestCount,
                networkRequests.enterpriseReleaseCount);
    }

    /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */
    private static Phone[] getPhonesIfAny() {
        try {
+57 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony.metrics;

import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;

import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequests;


/** Metrics for the network requests. */
public class NetworkRequestsStats {
    private NetworkRequestsStats() { }

    /** Generate metrics when enterprise network request occurs. */
    public static void addEnterpriseRequest(int subId) {
        NetworkRequests networkRequests = new NetworkRequests();
        networkRequests.carrierId = getCarrierId(subId);
        networkRequests.enterpriseRequestCount = 1;

        PersistAtomsStorage storage = PhoneFactory.getMetricsCollector().getAtomsStorage();
        storage.addNetworkRequests(networkRequests);
    }

    /** Generate metrics when enterprise network release occurs. */
    public static void addEnterpriseRelease(int subId) {
        NetworkRequests networkRequests = new NetworkRequests();
        networkRequests.carrierId = getCarrierId(subId);
        networkRequests.enterpriseReleaseCount = 1;

        PersistAtomsStorage storage = PhoneFactory.getMetricsCollector().getAtomsStorage();
        storage.addNetworkRequests(networkRequests);
    }

    /** Returns the carrier ID of the given subscription id. */
    private static int getCarrierId(int subId) {
        int phoneId = SubscriptionManager.getPhoneId(subId);
        Phone phone = PhoneFactory.getPhone(phoneId);
        return phone != null ? phone.getCarrierId() : TelephonyManager.UNKNOWN_CARRIER_ID;
    }
}
+49 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationStats;
import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTermination;
import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms;
import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequests;
import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms;
import com.android.internal.telephony.nano.PersistAtomsProto.PersistAtoms;
import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
@@ -299,6 +300,20 @@ public class PersistAtomsStorage {
        }
    }

    /** Adds a new {@link NetworkRequests} to the storage. */
    public synchronized void addNetworkRequests(NetworkRequests networkRequests) {
        NetworkRequests existingMetrics = find(networkRequests);
        if (existingMetrics != null) {
            existingMetrics.enterpriseRequestCount += networkRequests.enterpriseRequestCount;
            existingMetrics.enterpriseReleaseCount += networkRequests.enterpriseReleaseCount;
        } else {
            int newLength = mAtoms.networkRequests.length + 1;
            mAtoms.networkRequests = Arrays.copyOf(mAtoms.networkRequests, newLength);
            mAtoms.networkRequests[newLength - 1] = networkRequests;
        }
        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
    }

    /**
     * Returns and clears the voice call sessions if last pulled longer than {@code
     * minIntervalMillis} ago, otherwise returns {@code null}.
@@ -465,6 +480,23 @@ public class PersistAtomsStorage {
        }
    }

    /**
     * Returns and clears the network requests if last pulled longer than {@code
     * minIntervalMillis} ago, otherwise returns {@code null}.
     */
    @Nullable
    public synchronized NetworkRequests[] getNetworkRequests(long minIntervalMillis) {
        if (getWallTimeMillis() - mAtoms.networkRequestsPullTimestampMillis > minIntervalMillis) {
            mAtoms.networkRequestsPullTimestampMillis = getWallTimeMillis();
            NetworkRequests[] previousNetworkRequests = mAtoms.networkRequests;
            mAtoms.networkRequests = new NetworkRequests[0];
            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
            return previousNetworkRequests;
        } else {
            return null;
        }
    }

    /** Loads {@link PersistAtoms} from a file in private storage. */
    private PersistAtoms loadAtomsFromFile() {
        try {
@@ -515,6 +547,7 @@ public class PersistAtomsStorage {
                            atoms.imsRegistrationTermination,
                            ImsRegistrationTermination.class,
                            MAX_NUM_IMS_REGISTRATION_TERMINATIONS);
            atoms.networkRequests = sanitizeAtoms(atoms.networkRequests, NetworkRequests.class);
            // out of caution, sanitize also the timestamps
            atoms.voiceCallRatUsagePullTimestampMillis =
                    sanitizeTimestamp(atoms.voiceCallRatUsagePullTimestampMillis);
@@ -534,6 +567,8 @@ public class PersistAtomsStorage {
                    sanitizeTimestamp(atoms.imsRegistrationStatsPullTimestampMillis);
            atoms.imsRegistrationTerminationPullTimestampMillis =
                    sanitizeTimestamp(atoms.imsRegistrationTerminationPullTimestampMillis);
            atoms.networkRequestsPullTimestampMillis =
                    sanitizeTimestamp(atoms.networkRequestsPullTimestampMillis);
            return atoms;
        } catch (NoSuchFileException e) {
            Rlog.d(TAG, "PersistAtoms file not found");
@@ -656,6 +691,19 @@ public class PersistAtomsStorage {
        return null;
    }

    /**
     * Returns the network requests event that has the same carrier id as the given one,
     * or {@code null} if it does not exist.
     */
    private @Nullable NetworkRequests find(NetworkRequests key) {
        for (NetworkRequests item : mAtoms.networkRequests) {
            if (item.carrierId == key.carrierId) {
                return item;
            }
        }
        return null;
    }

    /**
     * Inserts a new element in a random position in an array with a maximum size, replacing the
     * least recent item if possible.
@@ -745,6 +793,7 @@ public class PersistAtomsStorage {
        atoms.cellularDataServiceSwitchPullTimestampMillis = currentTime;
        atoms.imsRegistrationStatsPullTimestampMillis = currentTime;
        atoms.imsRegistrationTerminationPullTimestampMillis = currentTime;
        atoms.networkRequestsPullTimestampMillis = currentTime;
        Rlog.d(TAG, "created new PersistAtoms");
        return atoms;
    }