Loading proto/src/persist_atoms.proto +12 −0 Original line number Diff line number Diff line Loading @@ -180,6 +180,12 @@ message PersistAtoms { /* Unmetered networks information. */ repeated UnmeteredNetworks unmetered_networks = 52; /* Outgoing Short Code SMS statistics and information. */ repeated OutgoingShortCodeSms outgoing_short_code_sms = 53; /* Timestamp of last outgoing_short_code_sms pull. */ optional int64 outgoing_short_code_sms_pull_timestamp_millis = 54; } // The canonical versions of the following enums live in: Loading Loading @@ -516,3 +522,9 @@ message UnmeteredNetworks { optional int32 carrier_id = 2; optional int64 unmetered_networks_bitmask = 3; } message OutgoingShortCodeSms { optional int32 category = 1; optional int32 xml_version = 2; optional int32 short_code_sms_count = 3; } No newline at end of file src/java/com/android/internal/telephony/SMSDispatcher.java +6 −0 Original line number Diff line number Diff line Loading @@ -1861,6 +1861,12 @@ public abstract class SMSDispatcher extends Handler { trackers[0].mDestAddress, networkCountryIso)); } if (smsCategory != SmsManager.SMS_CATEGORY_NOT_SHORT_CODE) { int xmlVersion = mSmsDispatchersController.getUsageMonitor() .getShortCodeXmlFileVersion(); mPhone.getSmsStats().onOutgoingShortCodeSms(smsCategory, xmlVersion); } if (smsCategory == SmsManager.SMS_CATEGORY_NOT_SHORT_CODE || smsCategory == SmsManager.SMS_CATEGORY_FREE_SHORT_CODE || smsCategory == SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE) { Loading src/java/com/android/internal/telephony/SmsUsageMonitor.java +38 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; Loading Loading @@ -73,6 +74,8 @@ public class SmsUsageMonitor { private static final String SHORT_CODE_PATH = "/data/misc/sms/codes"; private static final String SHORT_CODE_VERSION_PATH = "/data/misc/sms/metadata/version"; /** Default checking period for SMS sent without user permission. */ private static final int DEFAULT_SMS_CHECK_PERIOD = 60000; // 1 minute Loading Loading @@ -128,6 +131,8 @@ public class SmsUsageMonitor { /** Last modified time for pattern file */ private long mPatternFileLastModified = 0; private int mPatternFileVersion = -1; private RoleManager mRoleManager; /** Directory for per-app SMS permission XML file. */ Loading Loading @@ -415,9 +420,11 @@ public class SmsUsageMonitor { if (mPatternFile.exists()) { if (DBG) Rlog.d(TAG, "Loading SMS Short Code patterns from file"); mCurrentPatternMatcher = getPatternMatcherFromFile(countryIso); mPatternFileVersion = getPatternFileVersionFromFile(); } else { if (DBG) Rlog.d(TAG, "Loading SMS Short Code patterns from resource"); mCurrentPatternMatcher = getPatternMatcherFromResource(countryIso); mPatternFileVersion = -1; } mCurrentCountry = countryIso; } Loading Loading @@ -655,6 +662,37 @@ public class SmsUsageMonitor { return false; } private int getPatternFileVersionFromFile() { File versionFile = new File(SHORT_CODE_VERSION_PATH); if (versionFile.exists()) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(versionFile)); String version = reader.readLine(); if (version != null) { return Integer.parseInt(version); } } catch (IOException e) { Rlog.e(TAG, "File reader exception reading short code " + "pattern file version", e); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { Rlog.e(TAG, "File reader exception closing short code " + "pattern file version reader", e); } } } return -1; } public int getShortCodeXmlFileVersion() { return mPatternFileVersion; } private static void log(String msg) { Rlog.d(TAG, msg); } Loading src/java/com/android/internal/telephony/metrics/MetricsCollector.java +26 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_ import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_TERMINATION; 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.OUTGOING_SHORT_CODE_SMS; 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; Loading Loading @@ -69,6 +70,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTerm import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms; import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequestsV2; import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms; import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms; import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent; import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats; import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats; Loading Loading @@ -176,6 +178,7 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { registerAtom(PRESENCE_NOTIFY_EVENT, POLICY_PULL_DAILY); registerAtom(GBA_EVENT, POLICY_PULL_DAILY); registerAtom(PER_SIM_STATUS, null); registerAtom(OUTGOING_SHORT_CODE_SMS, POLICY_PULL_DAILY); Rlog.d(TAG, "registered"); } else { Loading Loading @@ -251,6 +254,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { return pullGbaEvent(data); case PER_SIM_STATUS: return pullPerSimStatus(data); case OUTGOING_SHORT_CODE_SMS: return pullOutgoingShortCodeSms(data); default: Rlog.e(TAG, String.format("unexpected atom ID %d", atomTag)); return StatsManager.PULL_SKIP; Loading Loading @@ -692,6 +697,19 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { return result; } private int pullOutgoingShortCodeSms(List<StatsEvent> data) { OutgoingShortCodeSms[] outgoingShortCodeSmsList = mStorage .getOutgoingShortCodeSms(MIN_COOLDOWN_MILLIS); if (outgoingShortCodeSmsList != null) { // Outgoing short code SMS list is already shuffled when SMS were inserted Arrays.stream(outgoingShortCodeSmsList).forEach(sms -> data.add(buildStatsEvent(sms))); return StatsManager.PULL_SUCCESS; } else { Rlog.w(TAG, "OUTGOING_SHORT_CODE_SMS 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); Loading Loading @@ -1025,6 +1043,14 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { stats.count); } private static StatsEvent buildStatsEvent(OutgoingShortCodeSms shortCodeSms) { return TelephonyStatsLog.buildStatsEvent( OUTGOING_SHORT_CODE_SMS, shortCodeSms.category, shortCodeSms.xmlVersion, shortCodeSms.shortCodeSmsCount); } /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */ private static Phone[] getPhonesIfAny() { try { Loading src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java +57 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTerm import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms; import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequestsV2; import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms; import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms; import com.android.internal.telephony.nano.PersistAtomsProto.PersistAtoms; import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent; import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats; Loading Loading @@ -159,6 +160,10 @@ public class PersistAtomsStorage { /** Maximum number of GBA Event to store between pulls. */ private final int mMaxNumGbaEventStats; /** Maximum number of outgoing short code sms to store between pulls. */ private final int mMaxOutgoingShortCodeSms; /** Stores persist atoms and persist states of the puller. */ @VisibleForTesting protected PersistAtoms mAtoms; Loading Loading @@ -207,6 +212,7 @@ public class PersistAtomsStorage { mMaxNumUceEventStats = 5; mMaxNumPresenceNotifyEventStats = 10; mMaxNumGbaEventStats = 5; mMaxOutgoingShortCodeSms = 5; } else { mMaxNumVoiceCallSessions = 50; mMaxNumSms = 25; Loading @@ -229,6 +235,7 @@ public class PersistAtomsStorage { mMaxNumUceEventStats = 25; mMaxNumPresenceNotifyEventStats = 50; mMaxNumGbaEventStats = 10; mMaxOutgoingShortCodeSms = 10; } mAtoms = loadAtomsFromFile(); Loading Loading @@ -655,6 +662,18 @@ public class PersistAtomsStorage { } } /** Adds an outgoing short code sms to the storage. */ public synchronized void addOutgoingShortCodeSms(OutgoingShortCodeSms shortCodeSms) { OutgoingShortCodeSms existingOutgoingShortCodeSms = find(shortCodeSms); if (existingOutgoingShortCodeSms != null) { existingOutgoingShortCodeSms.shortCodeSmsCount += 1; } else { mAtoms.outgoingShortCodeSms = insertAtRandomPlace(mAtoms.outgoingShortCodeSms, shortCodeSms, mMaxOutgoingShortCodeSms); } 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}. Loading Loading @@ -1174,6 +1193,24 @@ public class PersistAtomsStorage { return bitmask; } /** * Returns and clears the OutgoingShortCodeSms if last pulled longer than {@code * minIntervalMillis} ago, otherwise returns {@code null}. */ @Nullable public synchronized OutgoingShortCodeSms[] getOutgoingShortCodeSms(long minIntervalMillis) { if ((getWallTimeMillis() - mAtoms.outgoingShortCodeSmsPullTimestampMillis) > minIntervalMillis) { mAtoms.outgoingShortCodeSmsPullTimestampMillis = getWallTimeMillis(); OutgoingShortCodeSms[] previousOutgoingShortCodeSms = mAtoms.outgoingShortCodeSms; mAtoms.outgoingShortCodeSms = new OutgoingShortCodeSms[0]; saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS); return previousOutgoingShortCodeSms; } else { return null; } } /** Saves {@link PersistAtoms} to a file in private storage immediately. */ public synchronized void flushAtoms() { saveAtomsToFile(0); Loading Loading @@ -1309,6 +1346,8 @@ public class PersistAtomsStorage { atoms.unmeteredNetworks, UnmeteredNetworks.class ); atoms.outgoingShortCodeSms = sanitizeAtoms(atoms.outgoingShortCodeSms, OutgoingShortCodeSms.class, mMaxOutgoingShortCodeSms); // out of caution, sanitize also the timestamps atoms.voiceCallRatUsagePullTimestampMillis = Loading Loading @@ -1357,6 +1396,8 @@ public class PersistAtomsStorage { sanitizeTimestamp(atoms.presenceNotifyEventPullTimestampMillis); atoms.gbaEventPullTimestampMillis = sanitizeTimestamp(atoms.gbaEventPullTimestampMillis); atoms.outgoingShortCodeSmsPullTimestampMillis = sanitizeTimestamp(atoms.outgoingShortCodeSmsPullTimestampMillis); return atoms; } catch (NoSuchFileException e) { Loading Loading @@ -1724,6 +1765,20 @@ public class PersistAtomsStorage { return null; } /** * Returns OutgoingShortCodeSms atom that has same category, xmlVersion as the given one, * or {@code null} if it does not exist. */ private @Nullable OutgoingShortCodeSms find(OutgoingShortCodeSms key) { for (OutgoingShortCodeSms shortCodeSms : mAtoms.outgoingShortCodeSms) { if (shortCodeSms.category == key.category && shortCodeSms.xmlVersion == key.xmlVersion) { return shortCodeSms; } } return null; } /** * Inserts a new element in a random position in an array with a maximum size. * Loading Loading @@ -1969,6 +2024,7 @@ public class PersistAtomsStorage { atoms.uceEventStatsPullTimestampMillis = currentTime; atoms.presenceNotifyEventPullTimestampMillis = currentTime; atoms.gbaEventPullTimestampMillis = currentTime; atoms.outgoingShortCodeSmsPullTimestampMillis = currentTime; Rlog.d(TAG, "created new PersistAtoms"); return atoms; Loading Loading
proto/src/persist_atoms.proto +12 −0 Original line number Diff line number Diff line Loading @@ -180,6 +180,12 @@ message PersistAtoms { /* Unmetered networks information. */ repeated UnmeteredNetworks unmetered_networks = 52; /* Outgoing Short Code SMS statistics and information. */ repeated OutgoingShortCodeSms outgoing_short_code_sms = 53; /* Timestamp of last outgoing_short_code_sms pull. */ optional int64 outgoing_short_code_sms_pull_timestamp_millis = 54; } // The canonical versions of the following enums live in: Loading Loading @@ -516,3 +522,9 @@ message UnmeteredNetworks { optional int32 carrier_id = 2; optional int64 unmetered_networks_bitmask = 3; } message OutgoingShortCodeSms { optional int32 category = 1; optional int32 xml_version = 2; optional int32 short_code_sms_count = 3; } No newline at end of file
src/java/com/android/internal/telephony/SMSDispatcher.java +6 −0 Original line number Diff line number Diff line Loading @@ -1861,6 +1861,12 @@ public abstract class SMSDispatcher extends Handler { trackers[0].mDestAddress, networkCountryIso)); } if (smsCategory != SmsManager.SMS_CATEGORY_NOT_SHORT_CODE) { int xmlVersion = mSmsDispatchersController.getUsageMonitor() .getShortCodeXmlFileVersion(); mPhone.getSmsStats().onOutgoingShortCodeSms(smsCategory, xmlVersion); } if (smsCategory == SmsManager.SMS_CATEGORY_NOT_SHORT_CODE || smsCategory == SmsManager.SMS_CATEGORY_FREE_SHORT_CODE || smsCategory == SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE) { Loading
src/java/com/android/internal/telephony/SmsUsageMonitor.java +38 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; Loading Loading @@ -73,6 +74,8 @@ public class SmsUsageMonitor { private static final String SHORT_CODE_PATH = "/data/misc/sms/codes"; private static final String SHORT_CODE_VERSION_PATH = "/data/misc/sms/metadata/version"; /** Default checking period for SMS sent without user permission. */ private static final int DEFAULT_SMS_CHECK_PERIOD = 60000; // 1 minute Loading Loading @@ -128,6 +131,8 @@ public class SmsUsageMonitor { /** Last modified time for pattern file */ private long mPatternFileLastModified = 0; private int mPatternFileVersion = -1; private RoleManager mRoleManager; /** Directory for per-app SMS permission XML file. */ Loading Loading @@ -415,9 +420,11 @@ public class SmsUsageMonitor { if (mPatternFile.exists()) { if (DBG) Rlog.d(TAG, "Loading SMS Short Code patterns from file"); mCurrentPatternMatcher = getPatternMatcherFromFile(countryIso); mPatternFileVersion = getPatternFileVersionFromFile(); } else { if (DBG) Rlog.d(TAG, "Loading SMS Short Code patterns from resource"); mCurrentPatternMatcher = getPatternMatcherFromResource(countryIso); mPatternFileVersion = -1; } mCurrentCountry = countryIso; } Loading Loading @@ -655,6 +662,37 @@ public class SmsUsageMonitor { return false; } private int getPatternFileVersionFromFile() { File versionFile = new File(SHORT_CODE_VERSION_PATH); if (versionFile.exists()) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(versionFile)); String version = reader.readLine(); if (version != null) { return Integer.parseInt(version); } } catch (IOException e) { Rlog.e(TAG, "File reader exception reading short code " + "pattern file version", e); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { Rlog.e(TAG, "File reader exception closing short code " + "pattern file version reader", e); } } } return -1; } public int getShortCodeXmlFileVersion() { return mPatternFileVersion; } private static void log(String msg) { Rlog.d(TAG, msg); } Loading
src/java/com/android/internal/telephony/metrics/MetricsCollector.java +26 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_ import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_TERMINATION; 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.OUTGOING_SHORT_CODE_SMS; 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; Loading Loading @@ -69,6 +70,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTerm import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms; import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequestsV2; import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms; import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms; import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent; import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats; import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats; Loading Loading @@ -176,6 +178,7 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { registerAtom(PRESENCE_NOTIFY_EVENT, POLICY_PULL_DAILY); registerAtom(GBA_EVENT, POLICY_PULL_DAILY); registerAtom(PER_SIM_STATUS, null); registerAtom(OUTGOING_SHORT_CODE_SMS, POLICY_PULL_DAILY); Rlog.d(TAG, "registered"); } else { Loading Loading @@ -251,6 +254,8 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { return pullGbaEvent(data); case PER_SIM_STATUS: return pullPerSimStatus(data); case OUTGOING_SHORT_CODE_SMS: return pullOutgoingShortCodeSms(data); default: Rlog.e(TAG, String.format("unexpected atom ID %d", atomTag)); return StatsManager.PULL_SKIP; Loading Loading @@ -692,6 +697,19 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { return result; } private int pullOutgoingShortCodeSms(List<StatsEvent> data) { OutgoingShortCodeSms[] outgoingShortCodeSmsList = mStorage .getOutgoingShortCodeSms(MIN_COOLDOWN_MILLIS); if (outgoingShortCodeSmsList != null) { // Outgoing short code SMS list is already shuffled when SMS were inserted Arrays.stream(outgoingShortCodeSmsList).forEach(sms -> data.add(buildStatsEvent(sms))); return StatsManager.PULL_SUCCESS; } else { Rlog.w(TAG, "OUTGOING_SHORT_CODE_SMS 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); Loading Loading @@ -1025,6 +1043,14 @@ public class MetricsCollector implements StatsManager.StatsPullAtomCallback { stats.count); } private static StatsEvent buildStatsEvent(OutgoingShortCodeSms shortCodeSms) { return TelephonyStatsLog.buildStatsEvent( OUTGOING_SHORT_CODE_SMS, shortCodeSms.category, shortCodeSms.xmlVersion, shortCodeSms.shortCodeSmsCount); } /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */ private static Phone[] getPhonesIfAny() { try { Loading
src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java +57 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTerm import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms; import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequestsV2; import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms; import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingShortCodeSms; import com.android.internal.telephony.nano.PersistAtomsProto.PersistAtoms; import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent; import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats; Loading Loading @@ -159,6 +160,10 @@ public class PersistAtomsStorage { /** Maximum number of GBA Event to store between pulls. */ private final int mMaxNumGbaEventStats; /** Maximum number of outgoing short code sms to store between pulls. */ private final int mMaxOutgoingShortCodeSms; /** Stores persist atoms and persist states of the puller. */ @VisibleForTesting protected PersistAtoms mAtoms; Loading Loading @@ -207,6 +212,7 @@ public class PersistAtomsStorage { mMaxNumUceEventStats = 5; mMaxNumPresenceNotifyEventStats = 10; mMaxNumGbaEventStats = 5; mMaxOutgoingShortCodeSms = 5; } else { mMaxNumVoiceCallSessions = 50; mMaxNumSms = 25; Loading @@ -229,6 +235,7 @@ public class PersistAtomsStorage { mMaxNumUceEventStats = 25; mMaxNumPresenceNotifyEventStats = 50; mMaxNumGbaEventStats = 10; mMaxOutgoingShortCodeSms = 10; } mAtoms = loadAtomsFromFile(); Loading Loading @@ -655,6 +662,18 @@ public class PersistAtomsStorage { } } /** Adds an outgoing short code sms to the storage. */ public synchronized void addOutgoingShortCodeSms(OutgoingShortCodeSms shortCodeSms) { OutgoingShortCodeSms existingOutgoingShortCodeSms = find(shortCodeSms); if (existingOutgoingShortCodeSms != null) { existingOutgoingShortCodeSms.shortCodeSmsCount += 1; } else { mAtoms.outgoingShortCodeSms = insertAtRandomPlace(mAtoms.outgoingShortCodeSms, shortCodeSms, mMaxOutgoingShortCodeSms); } 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}. Loading Loading @@ -1174,6 +1193,24 @@ public class PersistAtomsStorage { return bitmask; } /** * Returns and clears the OutgoingShortCodeSms if last pulled longer than {@code * minIntervalMillis} ago, otherwise returns {@code null}. */ @Nullable public synchronized OutgoingShortCodeSms[] getOutgoingShortCodeSms(long minIntervalMillis) { if ((getWallTimeMillis() - mAtoms.outgoingShortCodeSmsPullTimestampMillis) > minIntervalMillis) { mAtoms.outgoingShortCodeSmsPullTimestampMillis = getWallTimeMillis(); OutgoingShortCodeSms[] previousOutgoingShortCodeSms = mAtoms.outgoingShortCodeSms; mAtoms.outgoingShortCodeSms = new OutgoingShortCodeSms[0]; saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS); return previousOutgoingShortCodeSms; } else { return null; } } /** Saves {@link PersistAtoms} to a file in private storage immediately. */ public synchronized void flushAtoms() { saveAtomsToFile(0); Loading Loading @@ -1309,6 +1346,8 @@ public class PersistAtomsStorage { atoms.unmeteredNetworks, UnmeteredNetworks.class ); atoms.outgoingShortCodeSms = sanitizeAtoms(atoms.outgoingShortCodeSms, OutgoingShortCodeSms.class, mMaxOutgoingShortCodeSms); // out of caution, sanitize also the timestamps atoms.voiceCallRatUsagePullTimestampMillis = Loading Loading @@ -1357,6 +1396,8 @@ public class PersistAtomsStorage { sanitizeTimestamp(atoms.presenceNotifyEventPullTimestampMillis); atoms.gbaEventPullTimestampMillis = sanitizeTimestamp(atoms.gbaEventPullTimestampMillis); atoms.outgoingShortCodeSmsPullTimestampMillis = sanitizeTimestamp(atoms.outgoingShortCodeSmsPullTimestampMillis); return atoms; } catch (NoSuchFileException e) { Loading Loading @@ -1724,6 +1765,20 @@ public class PersistAtomsStorage { return null; } /** * Returns OutgoingShortCodeSms atom that has same category, xmlVersion as the given one, * or {@code null} if it does not exist. */ private @Nullable OutgoingShortCodeSms find(OutgoingShortCodeSms key) { for (OutgoingShortCodeSms shortCodeSms : mAtoms.outgoingShortCodeSms) { if (shortCodeSms.category == key.category && shortCodeSms.xmlVersion == key.xmlVersion) { return shortCodeSms; } } return null; } /** * Inserts a new element in a random position in an array with a maximum size. * Loading Loading @@ -1969,6 +2024,7 @@ public class PersistAtomsStorage { atoms.uceEventStatsPullTimestampMillis = currentTime; atoms.presenceNotifyEventPullTimestampMillis = currentTime; atoms.gbaEventPullTimestampMillis = currentTime; atoms.outgoingShortCodeSmsPullTimestampMillis = currentTime; Rlog.d(TAG, "created new PersistAtoms"); return atoms; Loading