diff options
9 files changed, 745 insertions, 3 deletions
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto index 4b70d2941f..48e7b0ddc1 100644 --- a/proto/src/persist_atoms.proto +++ b/proto/src/persist_atoms.proto @@ -23,7 +23,7 @@ option java_outer_classname = "PersistAtomsProto"; // Holds atoms to store on persist storage in case of power cycle or process crash. // NOTE: using int64 rather than google.protobuf.Timestamp for timestamps simplifies implementation. -// Next id: 80 +// Next id: 82 message PersistAtoms { /* Aggregated RAT usage during the call. */ repeated VoiceCallRatUsage voice_call_rat_usage = 1; @@ -261,6 +261,12 @@ message PersistAtoms { /* Timestamp of last satellite_config_updater pull. */ optional int64 satellite_config_updater_pull_timestamp_millis = 79; + + /** Snapshot of satellite access controller. */ + repeated SatelliteAccessController satellite_access_controller = 80; + + /* Timestamp of last satellite access controller pull. */ + optional int64 satellite_access_controller_pull_timestamp_millis = 81; } // The canonical versions of the following enums live in: @@ -708,6 +714,9 @@ message SatelliteController { optional int32 count_of_demo_mode_incoming_datagram_fail = 23; optional int32 count_of_datagram_type_keep_alive_success = 24; optional int32 count_of_datagram_type_keep_alive_fail = 25; + optional int32 count_of_allowed_satellite_access = 26; + optional int32 count_of_disallowed_satellite_access = 27; + optional int32 count_of_satellite_access_check_fail = 28; } message SatelliteSession { @@ -812,3 +821,15 @@ message SatelliteConfigUpdater { optional int32 carrier_config_result = 3; optional int32 count = 4; } + +message SatelliteAccessController { + optional int32 access_control_type = 1; + optional int64 location_query_time_millis = 2; + optional int64 on_device_lookup_time_millis = 3; + optional int64 total_checking_time_millis = 4; + optional bool is_allowed = 5; + optional bool is_emergency = 6; + optional int32 result_code = 7; + repeated string country_codes = 8; + optional int32 config_data_source = 9; +} diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java index e6f25bb853..a83cd06892 100644 --- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java +++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java @@ -39,6 +39,7 @@ import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS; import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT; import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS; import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS; +import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_ACCESS_CONTROLLER; import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_CONFIG_UPDATER; import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_CONTROLLER; import static com.android.internal.telephony.TelephonyStatsLog.SATELLITE_ENTITLEMENT; @@ -95,6 +96,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms; import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent; import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats; import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats; +import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteAccessController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteConfigUpdater; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteEntitlement; @@ -242,6 +244,7 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { registerAtom(CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS); registerAtom(SATELLITE_ENTITLEMENT); registerAtom(SATELLITE_CONFIG_UPDATER); + registerAtom(SATELLITE_ACCESS_CONTROLLER); Rlog.d(TAG, "registered"); } else { Rlog.e(TAG, "could not get StatsManager, atoms not registered"); @@ -346,6 +349,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { return pullSatelliteEntitlement(data); case SATELLITE_CONFIG_UPDATER: return pullSatelliteConfigUpdater(data); + case SATELLITE_ACCESS_CONTROLLER: + return pullSatelliteAccessController(data); default: Rlog.e(TAG, String.format("unexpected atom ID %d", atomTag)); return StatsManager.PULL_SKIP; @@ -1032,6 +1037,19 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { } } + private int pullSatelliteAccessController(List<StatsEvent> data) { + SatelliteAccessController[] satelliteAccessControllerAtoms = + mStorage.getSatelliteAccessControllerStats(MIN_COOLDOWN_MILLIS); + if (satelliteAccessControllerAtoms != null) { + Arrays.stream(satelliteAccessControllerAtoms) + .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom))); + return StatsManager.PULL_SUCCESS; + } else { + Rlog.w(TAG, "SATELLITE_ACCESS_CONTROLLER pull too frequent, skipping"); + return StatsManager.PULL_SKIP; + } + } + /** Registers a pulled atom ID {@code atomId}. */ private void registerAtom(int atomId) { mStatsManager.setPullAtomCallback(atomId, /* metadata= */ null, @@ -1453,7 +1471,10 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { satelliteController.countOfDemoModeIncomingDatagramSuccess, satelliteController.countOfDemoModeIncomingDatagramFail, satelliteController.countOfDatagramTypeKeepAliveSuccess, - satelliteController.countOfDatagramTypeKeepAliveFail); + satelliteController.countOfDatagramTypeKeepAliveFail, + satelliteController.countOfAllowedSatelliteAccess, + satelliteController.countOfDisallowedSatelliteAccess, + satelliteController.countOfSatelliteAccessCheckFail); } private static StatsEvent buildStatsEvent(SatelliteSession satelliteSession) { @@ -1578,6 +1599,20 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { stats.count); } + private static StatsEvent buildStatsEvent(SatelliteAccessController stats) { + return TelephonyStatsLog.buildStatsEvent( + SATELLITE_ACCESS_CONTROLLER, + stats.accessControlType, + stats.locationQueryTimeMillis, + stats.onDeviceLookupTimeMillis, + stats.totalCheckingTimeMillis, + stats.isAllowed, + stats.isEmergency, + stats.resultCode, + stats.countryCodes, + stats.configDataSource); + } + /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */ static Phone[] getPhonesIfAny() { try { diff --git a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java index 975750ed4f..12dab7a4ce 100644 --- a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java +++ b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java @@ -51,6 +51,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.PersistAtoms; import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent; import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats; import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats; +import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteAccessController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteConfigUpdater; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteEntitlement; @@ -766,6 +767,9 @@ public class PersistAtomsStorage { += stats.countOfDatagramTypeKeepAliveSuccess; atom.countOfDatagramTypeKeepAliveFail += stats.countOfDatagramTypeKeepAliveFail; + atom.countOfAllowedSatelliteAccess += stats.countOfAllowedSatelliteAccess; + atom.countOfDisallowedSatelliteAccess += stats.countOfDisallowedSatelliteAccess; + atom.countOfSatelliteAccessCheckFail += stats.countOfSatelliteAccessCheckFail; mAtoms.satelliteController = atomArray; saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS); @@ -894,6 +898,14 @@ public class PersistAtomsStorage { saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS); } + /** Adds a new {@link SatelliteAccessController} to the storage. */ + public synchronized void addSatelliteAccessControllerStats(SatelliteAccessController stats) { + mAtoms.satelliteAccessController = + insertAtRandomPlace(mAtoms.satelliteAccessController, stats, + mMaxNumSatelliteStats); + 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}. @@ -1542,7 +1554,7 @@ public class PersistAtomsStorage { long minIntervalMillis) { if (getWallTimeMillis() - mAtoms.satelliteSosMessageRecommenderPullTimestampMillis > minIntervalMillis) { - mAtoms.satelliteProvisionPullTimestampMillis = getWallTimeMillis(); + mAtoms.satelliteSosMessageRecommenderPullTimestampMillis = getWallTimeMillis(); SatelliteSosMessageRecommender[] statsArray = mAtoms.satelliteSosMessageRecommender; mAtoms.satelliteSosMessageRecommender = new SatelliteSosMessageRecommender[0]; saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS); @@ -1648,6 +1660,25 @@ public class PersistAtomsStorage { } } + /** + * Returns and clears the {@link SatelliteAccessController} stats if last pulled longer + * than {@code minIntervalMillis} ago, otherwise returns {@code null}. + */ + @Nullable + public synchronized SatelliteAccessController[] getSatelliteAccessControllerStats( + long minIntervalMillis) { + if (getWallTimeMillis() - mAtoms.satelliteAccessControllerPullTimestampMillis + > minIntervalMillis) { + mAtoms.satelliteAccessControllerPullTimestampMillis = getWallTimeMillis(); + SatelliteAccessController[] statsArray = mAtoms.satelliteAccessController; + mAtoms.satelliteAccessController = new SatelliteAccessController[0]; + saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS); + return statsArray; + } else { + return null; + } + } + /** Saves {@link PersistAtoms} to a file in private storage immediately. */ public synchronized void flushAtoms() { saveAtomsToFile(0); @@ -1814,6 +1845,9 @@ public class PersistAtomsStorage { SatelliteEntitlement.class, mMaxNumSatelliteStats); atoms.satelliteConfigUpdater = sanitizeAtoms(atoms.satelliteConfigUpdater, SatelliteConfigUpdater.class, mMaxNumSatelliteStats); + atoms.satelliteAccessController = sanitizeAtoms( + atoms.satelliteAccessController, SatelliteAccessController.class, + mMaxNumSatelliteStats); // out of caution, sanitize also the timestamps atoms.voiceCallRatUsagePullTimestampMillis = @@ -1886,6 +1920,8 @@ public class PersistAtomsStorage { sanitizeTimestamp(atoms.satelliteEntitlementPullTimestampMillis); atoms.satelliteConfigUpdaterPullTimestampMillis = sanitizeTimestamp(atoms.satelliteConfigUpdaterPullTimestampMillis); + atoms.satelliteAccessControllerPullTimestampMillis = + sanitizeTimestamp(atoms.satelliteAccessControllerPullTimestampMillis); return atoms; } catch (NoSuchFileException e) { Rlog.d(TAG, "PersistAtoms file not found"); @@ -2629,6 +2665,7 @@ public class PersistAtomsStorage { atoms.carrierRoamingSatelliteControllerStatsPullTimestampMillis = currentTime; atoms.satelliteEntitlementPullTimestampMillis = currentTime; atoms.satelliteConfigUpdaterPullTimestampMillis = currentTime; + atoms.satelliteAccessControllerPullTimestampMillis = currentTime; Rlog.d(TAG, "created new PersistAtoms"); return atoms; diff --git a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java index 978e9d3df6..c2b275386d 100644 --- a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java +++ b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java @@ -24,6 +24,7 @@ import android.telephony.satellite.SatelliteManager; import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteControllerStats; import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteSession; +import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteAccessController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteConfigUpdater; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteEntitlement; @@ -35,6 +36,8 @@ import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteSosMessage import com.android.internal.telephony.satellite.SatelliteConstants; import com.android.telephony.Rlog; +import java.util.Arrays; + /** Tracks Satellite metrics for each phone */ public class SatelliteStats { private static final String TAG = SatelliteStats.class.getSimpleName(); @@ -85,6 +88,9 @@ public class SatelliteStats { private final int mCountOfDemoModeIncomingDatagramFail; private final int mCountOfDatagramTypeKeepAliveSuccess; private final int mCountOfDatagramTypeKeepAliveFail; + private final int mCountOfAllowedSatelliteAccess; + private final int mCountOfDisallowedSatelliteAccess; + private final int mCountOfSatelliteAccessCheckFail; private SatelliteControllerParams(Builder builder) { this.mCountOfSatelliteServiceEnablementsSuccess = @@ -124,6 +130,12 @@ public class SatelliteStats { builder.mCountOfDatagramTypeKeepAliveSuccess; this.mCountOfDatagramTypeKeepAliveFail = builder.mCountOfDatagramTypeKeepAliveFail; + this.mCountOfAllowedSatelliteAccess = + builder.mCountOfAllowedSatelliteAccess; + this.mCountOfDisallowedSatelliteAccess = + builder.mCountOfDisallowedSatelliteAccess; + this.mCountOfSatelliteAccessCheckFail = + builder.mCountOfSatelliteAccessCheckFail; } public int getCountOfSatelliteServiceEnablementsSuccess() { @@ -226,6 +238,18 @@ public class SatelliteStats { return mCountOfDatagramTypeKeepAliveFail; } + public int getCountOfAllowedSatelliteAccess() { + return mCountOfAllowedSatelliteAccess; + } + + public int getCountOfDisallowedSatelliteAccess() { + return mCountOfDisallowedSatelliteAccess; + } + + public int getCountOfSatelliteAccessCheckFail() { + return mCountOfSatelliteAccessCheckFail; + } + /** * A builder class to create {@link SatelliteControllerParams} data structure class */ @@ -255,6 +279,9 @@ public class SatelliteStats { private int mCountOfDemoModeIncomingDatagramFail = 0; private int mCountOfDatagramTypeKeepAliveSuccess = 0; private int mCountOfDatagramTypeKeepAliveFail = 0; + private int mCountOfAllowedSatelliteAccess = 0; + private int mCountOfDisallowedSatelliteAccess = 0; + private int mCountOfSatelliteAccessCheckFail = 0; /** * Sets countOfSatelliteServiceEnablementsSuccess value of {@link SatelliteController} @@ -503,6 +530,37 @@ public class SatelliteStats { } /** + * Sets countOfAllowedSatelliteAccess value of {@link SatelliteController} atom + * then returns Builder class + */ + public Builder setCountOfAllowedSatelliteAccess( + int countOfAllowedSatelliteAccess) { + this.mCountOfAllowedSatelliteAccess = + countOfAllowedSatelliteAccess; + return this; + } + + /** + * Sets countOfDisallowedSatelliteAccess value of {@link SatelliteController} atom + * then returns Builder class + */ + public Builder setCountOfDisallowedSatelliteAccess( + int countOfDisallowedSatelliteAccess) { + this.mCountOfDisallowedSatelliteAccess = countOfDisallowedSatelliteAccess; + return this; + } + + /** + * Sets countOfSatelliteAccessCheckFail value of {@link SatelliteController} atom + * then returns Builder class + */ + public Builder setCountOfSatelliteAccessCheckFail( + int countOfSatelliteAccessCheckFail) { + this.mCountOfSatelliteAccessCheckFail = countOfSatelliteAccessCheckFail; + return this; + } + + /** * Returns ControllerParams, which contains whole component of * {@link SatelliteController} atom */ @@ -548,6 +606,9 @@ public class SatelliteStats { + mCountOfDatagramTypeKeepAliveSuccess + ", countOfDatagramTypeKeepAliveFail=" + mCountOfDatagramTypeKeepAliveFail + + ", countOfAllowedSatelliteAccess=" + mCountOfAllowedSatelliteAccess + + ", countOfDisallowedSatelliteAccess=" + mCountOfDisallowedSatelliteAccess + + ", countOfSatelliteAccessCheckFail=" + mCountOfSatelliteAccessCheckFail + ")"; } } @@ -1915,6 +1976,169 @@ public class SatelliteStats { } } + /** + * A data class to contain whole component of {@link SatelliteAccessControllerParams} atom. + * Refer to {@link #onSatelliteAccessControllerMetrics(SatelliteAccessControllerParams)}. + */ + public class SatelliteAccessControllerParams { + private final @SatelliteConstants.AccessControlType int mAccessControlType; + private final long mLocationQueryTimeMillis; + private final long mOnDeviceLookupTimeMillis; + private final long mTotalCheckingTimeMillis; + private final boolean mIsAllowed; + private final boolean mIsEmergency; + private final @SatelliteManager.SatelliteResult int mResultCode; + private final String[] mCountryCodes; + private final @SatelliteConstants.ConfigDataSource int mConfigDataSource; + + private SatelliteAccessControllerParams(Builder builder) { + this.mAccessControlType = builder.mAccessControlType; + this.mLocationQueryTimeMillis = builder.mLocationQueryTimeMillis; + this.mOnDeviceLookupTimeMillis = builder.mOnDeviceLookupTimeMillis; + this.mTotalCheckingTimeMillis = builder.mTotalCheckingTimeMillis; + this.mIsAllowed = builder.mIsAllowed; + this.mIsEmergency = builder.mIsEmergency; + this.mResultCode = builder.mResultCode; + this.mCountryCodes = builder.mCountryCodes; + this.mConfigDataSource = builder.mConfigDataSource; + } + + public @SatelliteConstants.AccessControlType int getAccessControlType() { + return mAccessControlType; + } + + public long getLocationQueryTime() { + return mLocationQueryTimeMillis; + } + + public long getOnDeviceLookupTime() { + return mOnDeviceLookupTimeMillis; + } + + public long getTotalCheckingTime() { + return mTotalCheckingTimeMillis; + } + + public boolean getIsAllowed() { + return mIsAllowed; + } + + public boolean getIsEmergency() { + return mIsEmergency; + } + + public @SatelliteManager.SatelliteResult int getResultCode() { + return mResultCode; + } + + public String[] getCountryCodes() { + return mCountryCodes; + } + + public @SatelliteConstants.ConfigDataSource int getConfigDataSource() { + return mConfigDataSource; + } + + /** + * A builder class to create {@link SatelliteAccessControllerParams} data structure class + */ + public static class Builder { + private @SatelliteConstants.AccessControlType int mAccessControlType; + private long mLocationQueryTimeMillis; + private long mOnDeviceLookupTimeMillis; + private long mTotalCheckingTimeMillis; + private boolean mIsAllowed; + private boolean mIsEmergency; + private @SatelliteManager.SatelliteResult int mResultCode; + private String[] mCountryCodes; + private @SatelliteConstants.ConfigDataSource int mConfigDataSource; + + /** + * Sets AccessControlType value of {@link #SatelliteAccessController} + * atom then returns Builder class + */ + public Builder setAccessControlType( + @SatelliteConstants.AccessControlType int accessControlType) { + this.mAccessControlType = accessControlType; + return this; + } + + /** Sets the location query time for current satellite enablement. */ + public Builder setLocationQueryTime(long locationQueryTimeMillis) { + this.mLocationQueryTimeMillis = locationQueryTimeMillis; + return this; + } + + /** Sets the on device lookup time for current satellite enablement. */ + public Builder setOnDeviceLookupTime(long onDeviceLookupTimeMillis) { + this.mOnDeviceLookupTimeMillis = onDeviceLookupTimeMillis; + return this; + } + + /** Sets the total checking time for current satellite enablement. */ + public Builder setTotalCheckingTime(long totalCheckingTimeMillis) { + this.mTotalCheckingTimeMillis = totalCheckingTimeMillis; + return this; + } + + /** Sets whether the satellite communication is allowed from current location. */ + public Builder setIsAllowed(boolean isAllowed) { + this.mIsAllowed = isAllowed; + return this; + } + + /** Sets whether the current satellite enablement is for emergency or not. */ + public Builder setIsEmergency(boolean isEmergency) { + this.mIsEmergency = isEmergency; + return this; + } + + /** Sets the result code for checking whether satellite service is allowed from current + location. */ + public Builder setResult(int result) { + this.mResultCode = result; + return this; + } + + /** Sets the country code for current location while attempting satellite enablement. */ + public Builder setCountryCodes(String[] countryCodes) { + this.mCountryCodes = Arrays.stream(countryCodes).toArray(String[]::new); + return this; + } + + /** Sets the config data source for checking whether satellite service is allowed from + current location. */ + public Builder setConfigDatasource(int configDatasource) { + this.mConfigDataSource = configDatasource; + return this; + } + + /** + * Returns AccessControllerParams, which contains whole component of + * {@link #SatelliteAccessController} atom + */ + public SatelliteAccessControllerParams build() { + return new SatelliteStats() + .new SatelliteAccessControllerParams(this); + } + } + + @Override + public String toString() { + return "AccessControllerParams(" + + ", AccessControlType=" + mAccessControlType + + ", LocationQueryTime=" + mLocationQueryTimeMillis + + ", OnDeviceLookupTime=" + mOnDeviceLookupTimeMillis + + ", TotalCheckingTime=" + mTotalCheckingTimeMillis + + ", IsAllowed=" + mIsAllowed + + ", IsEmergency=" + mIsEmergency + + ", ResultCode=" + mResultCode + + ", CountryCodes=" + Arrays.toString(mCountryCodes) + + ", ConfigDataSource=" + mConfigDataSource + + ")"; + } + } + /** Create a new atom or update an existing atom for SatelliteController metrics */ public synchronized void onSatelliteControllerMetrics(SatelliteControllerParams param) { SatelliteController proto = new SatelliteController(); @@ -2079,4 +2303,20 @@ public class SatelliteStats { proto.count = param.getCount(); mAtomsStorage.addSatelliteConfigUpdaterStats(proto); } + + /** Create a new atom or update an existing atom for SatelliteAccessController metrics */ + public synchronized void onSatelliteAccessControllerMetrics( + SatelliteAccessControllerParams param) { + SatelliteAccessController proto = new SatelliteAccessController(); + proto.accessControlType = param.getAccessControlType(); + proto.locationQueryTimeMillis = param.getLocationQueryTime(); + proto.onDeviceLookupTimeMillis = param.getOnDeviceLookupTime(); + proto.totalCheckingTimeMillis = param.getTotalCheckingTime(); + proto.isAllowed = param.getIsAllowed(); + proto.isEmergency = param.getIsEmergency(); + proto.resultCode = param.getResultCode(); + proto.countryCodes = param.getCountryCodes(); + proto.configDataSource = param.getConfigDataSource(); + mAtomsStorage.addSatelliteAccessControllerStats(proto); + } } diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteConstants.java b/src/java/com/android/internal/telephony/satellite/SatelliteConstants.java index f88069f868..384dfa5d96 100644 --- a/src/java/com/android/internal/telephony/satellite/SatelliteConstants.java +++ b/src/java/com/android/internal/telephony/satellite/SatelliteConstants.java @@ -83,4 +83,25 @@ public class SatelliteConstants { }) @Retention(RetentionPolicy.SOURCE) public @interface ConfigUpdateResult {} + + // Access control type is unknown + public static final int ACCESS_CONTROL_TYPE_UNKNOWN = 0; + // Network country code is used for satellite access decision + public static final int ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE = 1; + // Device's current location is used for satellite access decision + public static final int ACCESS_CONTROL_TYPE_CURRENT_LOCATION = 2; + // Device's last known location is used for satellite access decision + public static final int ACCESS_CONTROL_TYPE_LAST_KNOWN_LOCATION = 3; + // Cached country codes are used for satellite access decision + public static final int ACCESS_CONTROL_TYPE_CACHED_COUNTRY_CODE = 4; + + @IntDef(prefix = {"ACCESS_CONTROL_TYPE_"}, value = { + ACCESS_CONTROL_TYPE_UNKNOWN, + ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE, + ACCESS_CONTROL_TYPE_CURRENT_LOCATION, + ACCESS_CONTROL_TYPE_LAST_KNOWN_LOCATION, + ACCESS_CONTROL_TYPE_CACHED_COUNTRY_CODE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AccessControlType {} } diff --git a/src/java/com/android/internal/telephony/satellite/metrics/AccessControllerMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/AccessControllerMetricsStats.java new file mode 100644 index 0000000000..13ba7093de --- /dev/null +++ b/src/java/com/android/internal/telephony/satellite/metrics/AccessControllerMetricsStats.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2024 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.satellite.metrics; + +import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS; + +import static com.android.internal.telephony.satellite.SatelliteConstants.CONFIG_DATA_SOURCE_UNKNOWN; + +import android.annotation.NonNull; +import android.telephony.satellite.SatelliteManager; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.telephony.metrics.SatelliteStats; +import com.android.internal.telephony.satellite.SatelliteConstants; + +import java.util.Arrays; +import java.util.List; +public class AccessControllerMetricsStats { + private static final String TAG = AccessControllerMetricsStats.class.getSimpleName(); + private static AccessControllerMetricsStats sInstance = null; + + private @SatelliteConstants.AccessControlType int mAccessControlType; + private long mLocationQueryTimeMillis; + private long mOnDeviceLookupTimeMillis; + private long mTotalCheckingTimeMillis; + private Boolean mIsAllowed; + private Boolean mIsEmergency; + private @SatelliteManager.SatelliteResult int mResultCode; + private String[] mCountryCodes; + private @SatelliteConstants.ConfigDataSource int mConfigDataSource; + private AccessControllerMetricsStats() { + initializeAccessControllerMetricsParam(); + } + + /** + * Returns the Singleton instance of AccessControllerMetricsStats class. + * If an instance of the Singleton class has not been created, + * it creates a new instance and returns it. Otherwise, it returns + * the existing instance. + * @return the Singleton instance of AccessControllerMetricsStats. + */ + public static AccessControllerMetricsStats getInstance() { + if (sInstance == null) { + loge("create new AccessControllerMetricsStats."); + sInstance = new AccessControllerMetricsStats(); + } + return sInstance; + } + private void initializeAccessControllerMetricsParam() { + mAccessControlType = SatelliteConstants.ACCESS_CONTROL_TYPE_UNKNOWN; + mLocationQueryTimeMillis = 0; + mOnDeviceLookupTimeMillis = 0; + mTotalCheckingTimeMillis = 0; + mIsAllowed = null; + mIsEmergency = null; + mResultCode = SATELLITE_RESULT_SUCCESS; + mCountryCodes = new String[0]; + mConfigDataSource = CONFIG_DATA_SOURCE_UNKNOWN; + } + /** + * Sets the Access Control Type for current satellite enablement. + * @param accessControlType access control type of location query is attempted. + */ + public AccessControllerMetricsStats setAccessControlType( + @SatelliteConstants.AccessControlType int accessControlType) { + mAccessControlType = accessControlType; + logd("setAccessControlType: access control type = " + mAccessControlType); + return this; + } + /** + * Sets the location query time for current satellite enablement. + * @param queryStartTime the time location query is attempted. + */ + public AccessControllerMetricsStats setLocationQueryTime(long queryStartTime) { + mLocationQueryTimeMillis = + (queryStartTime > 0) ? (getCurrentTime() - queryStartTime) : 0; + logd("setLocationQueryTimeMillis: location query time = " + mLocationQueryTimeMillis); + return this; + } + /** + * Sets the on device lookup time for current satellite enablement. + * @param onDeviceLookupStartTime the time on device lookup is attempted. + */ + public AccessControllerMetricsStats setOnDeviceLookupTime(long onDeviceLookupStartTime) { + mOnDeviceLookupTimeMillis = + (onDeviceLookupStartTime > 0) ? (getCurrentTime() - onDeviceLookupStartTime) : 0; + logd("setLocationQueryTime: on device lookup time = " + mOnDeviceLookupTimeMillis); + return this; + } + /** + * Sets the total checking time for current satellite enablement. + * @param queryStartTime the time location query is attempted. + */ + public AccessControllerMetricsStats setTotalCheckingTime(long queryStartTime) { + mTotalCheckingTimeMillis = + (queryStartTime > 0) ? (getCurrentTime() - queryStartTime) : 0; + logd("setTotalCheckingTime: location query time = " + mTotalCheckingTimeMillis); + return this; + } + /** + * Sets whether the satellite communication is allowed from current location. + * @param isAllowed {@code true} if satellite communication is allowed from current location + * {@code false} otherwise. + */ + public AccessControllerMetricsStats setIsAllowed(boolean isAllowed) { + mIsAllowed = isAllowed; + logd("setIsAllowed: allowed=" + mIsAllowed); + return this; + } + /** + * Sets whether the current satellite enablement is for emergency or not. + * @param isEmergency {@code true} if current satellite enablement is for emergency SOS message + * {@code false} otherwise. + */ + public AccessControllerMetricsStats setIsEmergency(boolean isEmergency) { + mIsEmergency = isEmergency; + logd("setIsEmergency: emergency =" + mIsEmergency); + return this; + } + /** + * Sets the result code for checking whether satellite service is allowed from current + * location. + * @param result result code for checking process. + */ + public AccessControllerMetricsStats setResult(@SatelliteManager.SatelliteResult int result) { + mResultCode = result; + logd("setResult: result = " + mResultCode); + return this; + } + /** + * Sets the country code for current location while attempting satellite enablement. + * @param countryCodes Country code the user is located in + */ + public AccessControllerMetricsStats setCountryCodes(List<String> countryCodes) { + mCountryCodes = countryCodes.stream().toArray(String[]::new); + logd("setCountryCodes: country code is " + Arrays.toString(mCountryCodes)); + return this; + } + /** + * Sets the config data source for checking whether satellite service is allowed from current + * location. + * @param configDatasource configuration data source. + */ + public AccessControllerMetricsStats setConfigDataSource( + @SatelliteConstants.ConfigDataSource int configDatasource) { + mConfigDataSource = configDatasource; + logd("setConfigDataSource: config data source = " + mConfigDataSource); + return this; + } + /** Report the access controller metrics atoms to PersistAtomsStorage in telephony. */ + public void reportAccessControllerMetrics() { + SatelliteStats.SatelliteAccessControllerParams accessControllerParams = + new SatelliteStats.SatelliteAccessControllerParams.Builder() + .setAccessControlType(mAccessControlType) + .setLocationQueryTime(mLocationQueryTimeMillis) + .setOnDeviceLookupTime(mOnDeviceLookupTimeMillis) + .setTotalCheckingTime(mTotalCheckingTimeMillis) + .setIsAllowed(mIsAllowed) + .setIsEmergency(mIsEmergency) + .setResult(mResultCode) + .setCountryCodes(mCountryCodes) + .setConfigDatasource(mConfigDataSource) + .build(); + logd("reportAccessControllerMetrics: " + accessControllerParams.toString()); + SatelliteStats.getInstance().onSatelliteAccessControllerMetrics(accessControllerParams); + initializeAccessControllerMetricsParam(); + } + @VisibleForTesting + public long getCurrentTime() { + return System.currentTimeMillis(); + } + private static void logd(@NonNull String log) { + Log.d(TAG, log); + } + private static void loge(@NonNull String log) { + Log.e(TAG, log); + } +} diff --git a/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java index fdc7c5ca79..7dff2e6d1c 100644 --- a/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java +++ b/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java @@ -236,6 +236,36 @@ public class ControllerMetricsStats { mSatelliteStats.onSatelliteControllerMetrics(controllerParam); } + /** + * Report a counter when checking result whether satellite communication is allowed or not for + * current location. + */ + public void reportAllowedSatelliteAccessCount(boolean isAllowed) { + SatelliteStats.SatelliteControllerParams.Builder builder; + if (isAllowed) { + builder = new SatelliteStats.SatelliteControllerParams.Builder() + .setCountOfAllowedSatelliteAccess(ADD_COUNT); + } else { + builder = new SatelliteStats.SatelliteControllerParams.Builder() + .setCountOfDisallowedSatelliteAccess(ADD_COUNT); + } + SatelliteStats.SatelliteControllerParams controllerParam = builder.build(); + logd("reportAllowedSatelliteAccessCount:" + controllerParam); + mSatelliteStats.onSatelliteControllerMetrics(controllerParam); + } + + /** + * Report a counter when checking whether satellite communication for current location is + * allowed has failed. + */ + public void reportFailedSatelliteAccessCheckCount() { + SatelliteStats.SatelliteControllerParams controllerParam = + new SatelliteStats.SatelliteControllerParams.Builder() + .setCountOfSatelliteAccessCheckFail(ADD_COUNT).build(); + logd("reportFailedSatelliteAccessCheckCount:" + controllerParam); + mSatelliteStats.onSatelliteControllerMetrics(controllerParam); + } + /** Return the total service up time for satellite service */ @VisibleForTesting public int captureTotalServiceUpTimeSec() { diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java index 0f37a5776f..8ee3a371b6 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java @@ -20,6 +20,7 @@ import static android.telephony.SmsManager.RESULT_ERROR_NONE; import static android.telephony.SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY; import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_GPRS; import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_GSM; +import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; @@ -44,6 +45,10 @@ import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSIO import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS; import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO; import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT; +import static com.android.internal.telephony.satellite.SatelliteConstants.ACCESS_CONTROL_TYPE_CURRENT_LOCATION; +import static com.android.internal.telephony.satellite.SatelliteConstants.ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE; +import static com.android.internal.telephony.satellite.SatelliteConstants.CONFIG_DATA_SOURCE_CONFIG_UPDATER; +import static com.android.internal.telephony.satellite.SatelliteConstants.CONFIG_DATA_SOURCE_DEVICE_CONFIG; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -96,6 +101,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.PersistAtoms; import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent; import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats; import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats; +import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteAccessController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteConfigUpdater; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteEntitlement; @@ -129,6 +135,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.LinkedList; import java.util.Queue; +import java.util.concurrent.TimeUnit; public class PersistAtomsStorageTest extends TelephonyTest { private static final String TEST_FILE = "PersistAtomsStorageTest.pb"; @@ -316,6 +323,10 @@ public class PersistAtomsStorageTest extends TelephonyTest { private SatelliteConfigUpdater mSatelliteConfigUpdater2; private SatelliteConfigUpdater[] mSatelliteConfigUpdaters; + private SatelliteAccessController mSatelliteAccessController1; + private SatelliteAccessController mSatelliteAccessController2; + private SatelliteAccessController[] mSatelliteAccessControllers; + private void makeTestData() { // MO call with SRVCC (LTE to UMTS) mCall1Proto = new VoiceCallSession(); @@ -1392,6 +1403,32 @@ public class PersistAtomsStorageTest extends TelephonyTest { mSatelliteConfigUpdaters = new SatelliteConfigUpdater[] {mSatelliteConfigUpdater1, mSatelliteConfigUpdater2}; + + mSatelliteAccessController1 = new SatelliteAccessController(); + mSatelliteAccessController1.accessControlType = ACCESS_CONTROL_TYPE_NETWORK_COUNTRY_CODE; + mSatelliteAccessController1.locationQueryTimeMillis = TimeUnit.SECONDS.toMillis(1); + mSatelliteAccessController1.onDeviceLookupTimeMillis = TimeUnit.SECONDS.toMillis(2); + mSatelliteAccessController1.totalCheckingTimeMillis = TimeUnit.SECONDS.toMillis(3); + mSatelliteAccessController1.isAllowed = true; + mSatelliteAccessController1.isEmergency = false; + mSatelliteAccessController1.resultCode = SATELLITE_RESULT_SUCCESS; + mSatelliteAccessController1.countryCodes = new String[]{"AB", "CD"}; + mSatelliteAccessController1.configDataSource = CONFIG_DATA_SOURCE_DEVICE_CONFIG; + + mSatelliteAccessController2 = new SatelliteAccessController(); + mSatelliteAccessController1.accessControlType = ACCESS_CONTROL_TYPE_CURRENT_LOCATION; + mSatelliteAccessController1.locationQueryTimeMillis = TimeUnit.SECONDS.toMillis(4); + mSatelliteAccessController2.onDeviceLookupTimeMillis = TimeUnit.SECONDS.toMillis(5); + mSatelliteAccessController2.totalCheckingTimeMillis = TimeUnit.SECONDS.toMillis(6); + mSatelliteAccessController2.isAllowed = false; + mSatelliteAccessController2.isEmergency = true; + mSatelliteAccessController2.resultCode = SATELLITE_RESULT_SUCCESS; + mSatelliteAccessController2.countryCodes = new String[]{"EF", "GH"}; + mSatelliteAccessController2.configDataSource = CONFIG_DATA_SOURCE_CONFIG_UPDATER; + + mSatelliteAccessControllers = new SatelliteAccessController[]{ + mSatelliteAccessController1, mSatelliteAccessController2 + }; } private void generateTestDataNetworkValidationsData() { @@ -1630,6 +1667,9 @@ public class PersistAtomsStorageTest extends TelephonyTest { mSatelliteConfigUpdater1 = null; mSatelliteConfigUpdater2 = null; mSatelliteConfigUpdaters = null; + mSatelliteAccessController1 = null; + mSatelliteAccessController2 = null; + mSatelliteAccessControllers = null; super.tearDown(); } @@ -5184,6 +5224,63 @@ public class PersistAtomsStorageTest extends TelephonyTest { } @Test + public void addSatelliteAccessControllerStats_emptyProto() throws Exception { + createEmptyTestFile(); + mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext); + mPersistAtomsStorage.addSatelliteAccessControllerStats( + mSatelliteAccessController1); + mPersistAtomsStorage.incTimeMillis(100L); + + // Service state and service switch should be added successfully + verifyCurrentStateSavedToFileOnce(); + SatelliteAccessController[] output = + mPersistAtomsStorage.getSatelliteAccessControllerStats(0L); + assertProtoArrayEquals( + new SatelliteAccessController[] {mSatelliteAccessController1}, output); + } + + @Test + public void addSatelliteAccessControllerStats_tooManyEntries() throws Exception { + createEmptyTestFile(); + mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext); + + // Store atoms up to maximum number + 1 + int maxCount = 15 + 1; + for (int i = 0; i < maxCount; i++) { + mPersistAtomsStorage + .addSatelliteAccessControllerStats(//mSatelliteAccessController1); + copyOf(mSatelliteAccessController1)); + mPersistAtomsStorage.incTimeMillis(100L); + } + + // Store 1 different atom + mPersistAtomsStorage + .addSatelliteAccessControllerStats(mSatelliteAccessController2); + mPersistAtomsStorage.incTimeMillis(100L); + + verifyCurrentStateSavedToFileOnce(); + + SatelliteAccessController[] result = + mPersistAtomsStorage.getSatelliteAccessControllerStats(0L); + // First atom should have count 14, the other should have 1 + assertHasStatsAndCount(result, mSatelliteAccessController1, 14); + assertHasStatsAndCount(result, mSatelliteAccessController2, 1); + } + + @Test + public void getSatelliteAccessControllerStats_tooFrequent() throws Exception { + createTestFile(START_TIME_MILLIS); + + mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext); + mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum + SatelliteAccessController[] output = + mPersistAtomsStorage.getSatelliteAccessControllerStats(100L); + + // Should be denied + assertNull(output); + } + + @Test @SmallTest public void addDataNetworkValidation_newEntry() throws Exception { createEmptyTestFile(); @@ -5349,6 +5446,7 @@ public class PersistAtomsStorageTest extends TelephonyTest { atoms.satelliteEntitlementPullTimestampMillis = lastPullTimeMillis; atoms.satelliteConfigUpdater = mSatelliteConfigUpdaters; atoms.satelliteConfigUpdaterPullTimestampMillis = lastPullTimeMillis; + atoms.satelliteAccessControllerPullTimestampMillis = lastPullTimeMillis; FileOutputStream stream = new FileOutputStream(mTestFile); stream.write(PersistAtoms.toByteArray(atoms)); stream.close(); @@ -5535,6 +5633,11 @@ public class PersistAtomsStorageTest extends TelephonyTest { return SatelliteConfigUpdater.parseFrom(MessageNano.toByteArray(source)); } + private static SatelliteAccessController copyOf(SatelliteAccessController source) + throws Exception { + return SatelliteAccessController.parseFrom(MessageNano.toByteArray(source)); + } + private void assertAllPullTimestampEquals(long timestamp) { assertEquals( timestamp, @@ -5827,6 +5930,28 @@ public class PersistAtomsStorageTest extends TelephonyTest { assertEquals(expectedCount, actualCount); } + private static void assertHasStatsAndCount( + SatelliteAccessController[] tested, + @Nullable SatelliteAccessController expectedStats, int expectedCount) { + assertNotNull(tested); + int actualCount = 0; + for (SatelliteAccessController stats : tested) { + if (stats.accessControlType + == expectedStats.accessControlType + && stats.locationQueryTimeMillis == expectedStats.locationQueryTimeMillis + && stats.onDeviceLookupTimeMillis == expectedStats.onDeviceLookupTimeMillis + && stats.totalCheckingTimeMillis == expectedStats.totalCheckingTimeMillis + && stats.isAllowed == expectedStats.isAllowed + && stats.isEmergency == expectedStats.isEmergency + && stats.resultCode == expectedStats.resultCode + && Arrays.equals(stats.countryCodes, expectedStats.countryCodes) + && stats.configDataSource == expectedStats.configDataSource) { + actualCount++; + } + } + assertEquals(expectedCount, actualCount); + } + private static void assertHasStatsAndCountDuration( RcsAcsProvisioningStats[] statses, @Nullable RcsAcsProvisioningStats expectedStats, int count, long duration) { diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java index daa47c1908..cda96effc9 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java @@ -17,6 +17,10 @@ package com.android.internal.telephony.metrics; import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_GOOD; +import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS; + +import static com.android.internal.telephony.satellite.SatelliteConstants.CONFIG_DATA_SOURCE_DEVICE_CONFIG; +import static com.android.internal.telephony.satellite.SatelliteConstants.ACCESS_CONTROL_TYPE_CACHED_COUNTRY_CODE; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.verify; @@ -28,6 +32,7 @@ import android.telephony.TelephonyProtoEnums; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteControllerStats; import com.android.internal.telephony.nano.PersistAtomsProto.CarrierRoamingSatelliteSession; +import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteAccessController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteConfigUpdater; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteController; import com.android.internal.telephony.nano.PersistAtomsProto.SatelliteEntitlement; @@ -42,6 +47,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.util.concurrent.TimeUnit; + public class SatelliteStatsTest extends TelephonyTest { private static final String TAG = SatelliteStatsTest.class.getSimpleName(); @@ -436,4 +443,38 @@ public class SatelliteStatsTest extends TelephonyTest { verifyNoMoreInteractions(mPersistAtomsStorage); } + + + @Test + public void onSatelliteAccessControllerMetrics_withAtoms() { + SatelliteStats.SatelliteAccessControllerParams param = + new SatelliteStats.SatelliteAccessControllerParams.Builder() + .setAccessControlType(ACCESS_CONTROL_TYPE_CACHED_COUNTRY_CODE) + .setLocationQueryTime(TimeUnit.SECONDS.toMillis(1)) + .setOnDeviceLookupTime(TimeUnit.SECONDS.toMillis(2)) + .setTotalCheckingTime(TimeUnit.SECONDS.toMillis(3)) + .setIsAllowed(true) + .setIsEmergency(false) + .setResult(SATELLITE_RESULT_SUCCESS) + .setCountryCodes(new String[]{"AB", "CD"}) + .setConfigDatasource(CONFIG_DATA_SOURCE_DEVICE_CONFIG) + .build(); + + mSatelliteStats.onSatelliteAccessControllerMetrics(param); + + ArgumentCaptor<SatelliteAccessController> captor = ArgumentCaptor.forClass( + SatelliteAccessController.class); + verify(mPersistAtomsStorage).addSatelliteAccessControllerStats(captor.capture()); + SatelliteAccessController stats = captor.getValue(); + assertEquals(param.getAccessControlType(), stats.accessControlType); + assertEquals(param.getLocationQueryTime(), stats.locationQueryTimeMillis); + assertEquals(param.getOnDeviceLookupTime(), stats.onDeviceLookupTimeMillis); + assertEquals(param.getTotalCheckingTime(), stats.totalCheckingTimeMillis); + assertEquals(param.getIsAllowed(), stats.isAllowed); + assertEquals(param.getIsEmergency(), stats.isEmergency); + assertEquals(param.getResultCode(), stats.resultCode); + assertEquals(param.getCountryCodes(), stats.countryCodes); + assertEquals(param.getConfigDataSource(), stats.configDataSource); + verifyNoMoreInteractions(mPersistAtomsStorage); + } } |