Loading proto/src/persist_atoms.proto +7 −0 Original line number Diff line number Diff line Loading @@ -305,6 +305,7 @@ message DataCallSession { optional int32 band_at_end = 19; repeated int32 handover_failure_causes = 20; repeated int32 handover_failure_rat = 21; optional bool is_non_dds = 22; } message CellularServiceState { Loading Loading @@ -517,3 +518,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; } src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java +32 −16 Original line number Diff line number Diff line Loading @@ -106,6 +106,10 @@ public class CarrierPrivilegesTracker extends Handler { private static final String SHA_1 = "SHA-1"; private static final String SHA_256 = "SHA-256"; private static final int PACKAGE_NOT_PRIVILEGED = 0; private static final int PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG = 1; private static final int PACKAGE_PRIVILEGED_FROM_SIM = 2; // TODO(b/232273884): Turn feature on when find solution to handle the inter-carriers switching /** * Time delay to clear UICC rules after UICC is gone. Loading Loading @@ -755,23 +759,35 @@ public class CarrierPrivilegesTracker extends Handler { @NonNull private PrivilegedPackageInfo getCurrentPrivilegedPackagesForAllUsers() { Set<String> carrierServiceEligiblePackages = new ArraySet<>(); Set<String> privilegedPackageNames = new ArraySet<>(); Set<Integer> privilegedUids = new ArraySet<>(); for (Map.Entry<String, Set<String>> e : mInstalledPackageCerts.entrySet()) { if (isPackagePrivileged(e.getKey(), e.getValue())) { final int priv = getPackagePrivilegedStatus(e.getKey(), e.getValue()); switch (priv) { case PACKAGE_PRIVILEGED_FROM_SIM: carrierServiceEligiblePackages.add(e.getKey()); // fallthrough case PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG: privilegedPackageNames.add(e.getKey()); privilegedUids.addAll(getUidsForPackage(e.getKey(), /* invalidateCache= */ false)); privilegedUids.addAll( getUidsForPackage(e.getKey(), /* invalidateCache= */ false)); } } return new PrivilegedPackageInfo(privilegedPackageNames, privilegedUids, getCarrierService(privilegedPackageNames)); return new PrivilegedPackageInfo( privilegedPackageNames, privilegedUids, getCarrierService(carrierServiceEligiblePackages)); } /** * Returns true iff there is an overlap between the provided certificate hashes and the * certificate hashes stored in mTestOverrideRules, mCarrierConfigRules and mUiccRules. * Returns the privilege status of the provided package. * * <p>Returned privilege status depends on whether a package matches the certificates from * carrier config, from test overrides or from certificates stored on the SIM. */ private boolean isPackagePrivileged(@NonNull String pkgName, @NonNull Set<String> certs) { private int getPackagePrivilegedStatus(@NonNull String pkgName, @NonNull Set<String> certs) { // Double-nested for loops, but each collection should contain at most 2 elements in nearly // every case. // TODO(b/184382310) find a way to speed this up Loading @@ -780,23 +796,23 @@ public class CarrierPrivilegesTracker extends Handler { if (mTestOverrideRules != null) { for (UiccAccessRule rule : mTestOverrideRules) { if (rule.matches(cert, pkgName)) { return true; return PACKAGE_PRIVILEGED_FROM_SIM; } } } else { for (UiccAccessRule rule : mCarrierConfigRules) { for (UiccAccessRule rule : mUiccRules) { if (rule.matches(cert, pkgName)) { return true; return PACKAGE_PRIVILEGED_FROM_SIM; } } for (UiccAccessRule rule : mUiccRules) { for (UiccAccessRule rule : mCarrierConfigRules) { if (rule.matches(cert, pkgName)) { return true; return PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG; } } } } return false; return PACKAGE_NOT_PRIVILEGED; } @NonNull Loading Loading @@ -1065,13 +1081,13 @@ public class CarrierPrivilegesTracker extends Handler { } @NonNull private Pair<String, Integer> getCarrierService(@NonNull Set<String> privilegedPackageNames) { private Pair<String, Integer> getCarrierService(@NonNull Set<String> simPrivilegedPackages) { List<ResolveInfo> carrierServiceResolveInfos = mPackageManager.queryIntentServices( new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), /* flags= */ 0); String carrierServicePackageName = null; for (ResolveInfo resolveInfo : carrierServiceResolveInfos) { String packageName = getPackageName(resolveInfo); if (privilegedPackageNames.contains(packageName)) { if (simPrivilegedPackages.contains(packageName)) { carrierServicePackageName = packageName; break; } Loading src/java/com/android/internal/telephony/PhoneSubInfoController.java +1 −25 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.os.Binder; import android.os.Build; import android.os.RemoteException; import android.os.TelephonyServiceManager.ServiceRegisterer; import android.os.UserHandle; import android.telephony.ImsiEncryptionInfo; import android.telephony.PhoneNumberUtils; import android.telephony.SubscriptionManager; Loading Loading @@ -150,8 +149,7 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getSubscriberIdForSubscriber(int subId, String callingPackage, String callingFeatureId) { String message = "getSubscriberIdForSubscriber"; enforceCallingPackage(callingPackage, Binder.getCallingUid(), message); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); long identity = Binder.clearCallingIdentity(); boolean isActive; Loading Loading @@ -332,28 +330,6 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { "Requires MODIFY_PHONE_STATE"); } /** * Make sure the caller is the calling package itself * * @throws SecurityException if the caller is not the calling package */ private void enforceCallingPackage(String callingPackage, int callingUid, String message) { int packageUid = -1; PackageManager pm = mContext.createContextAsUser( UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager(); if (pm != null) { try { packageUid = pm.getPackageUid(callingPackage, 0); } catch (PackageManager.NameNotFoundException e) { // packageUid is -1 } } if (packageUid != callingUid) { throw new SecurityException(message + ": Package " + callingPackage + " does not belong to " + callingUid); } } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int getDefaultSubscription() { return PhoneFactory.getDefaultSubscription(); Loading src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +54 −18 Original line number Diff line number Diff line Loading @@ -158,7 +158,8 @@ public class DataStallRecoveryManager extends Handler { /** Whether the result of last action(RADIO_RESTART) reported. */ private boolean mLastActionReported; /** The real time for data stall start. */ private @ElapsedRealtimeLong long mDataStallStartMs; @VisibleForTesting public @ElapsedRealtimeLong long mDataStallStartMs; /** Last data stall recovery action. */ private @RecoveryAction int mLastAction; /** Last radio power state. */ Loading @@ -175,6 +176,8 @@ public class DataStallRecoveryManager extends Handler { private boolean mIsAttemptedAllSteps; /** Whether internet network connected. */ private boolean mIsInternetNetworkConnected; /** The durations for current recovery action */ private @ElapsedRealtimeLong long mTimeElapsedOfCurrentAction; /** The array for the timers between recovery actions. */ private @NonNull long[] mDataStallRecoveryDelayMillisArray; Loading Loading @@ -467,6 +470,15 @@ public class DataStallRecoveryManager extends Handler { return (SystemClock.elapsedRealtime() - mTimeLastRecoveryStartMs); } /** * Get duration time for current recovery action. * * @return the time duration for current recovery action. */ private long getDurationOfCurrentRecoveryMs() { return (SystemClock.elapsedRealtime() - mTimeElapsedOfCurrentAction); } /** * Broadcast intent when data stall occurred. * Loading Loading @@ -592,38 +604,61 @@ public class DataStallRecoveryManager extends Handler { * @param isValid true for validation passed & false for validation failed */ private void setNetworkValidationState(boolean isValid) { boolean isLogNeeded = false; int timeDuration = 0; int timeDurationOfCurrentAction = 0; boolean isFirstDataStall = false; boolean isFirstValidationAfterDoRecovery = false; @RecoveredReason int reason = getRecoveredReason(isValid); // Validation status is true and was not data stall. if (isValid && !mDataStalled) { return; } if (!mDataStalled) { // First data stall isLogNeeded = true; mDataStalled = true; isFirstDataStall = true; mDataStallStartMs = SystemClock.elapsedRealtime(); logl("data stall: start time = " + DataUtils.elapsedTimeToString(mDataStallStartMs)); return; } else if (!mLastActionReported) { // When the first validation status appears, enter this block. isLogNeeded = true; timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); mLastActionReported = true; isFirstValidationAfterDoRecovery = true; } if (!mLastActionReported) { @RecoveredReason int reason = getRecoveredReason(isValid); int timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); if (isValid) { // When the validation passed(mobile data resume), enter this block. isLogNeeded = true; timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); mLastActionReported = false; mDataStalled = false; } if (isLogNeeded) { timeDurationOfCurrentAction = (isFirstDataStall == true ? 0 : (int) getDurationOfCurrentRecoveryMs()); DataStallRecoveryStats.onDataStallEvent( mLastAction, mPhone, isValid, timeDuration, reason, isFirstValidationAfterDoRecovery, timeDurationOfCurrentAction); logl( "data stall: lastaction = " "data stall: " + (isFirstDataStall == true ? "start" : isValid == false ? "in process" : "end") + ", lastaction=" + recoveryActionToString(mLastAction) + ", isRecovered=" + isValid + ", reason=" + recoveredReasonToString(reason) + ", isFirstValidationAfterDoRecovery=" + isFirstValidationAfterDoRecovery + ", TimeDuration=" + timeDuration); DataStallRecoveryStats.onDataStallEvent( mLastAction, mPhone, isValid, timeDuration, reason); mLastActionReported = true; } if (isValid) { mLastActionReported = false; mDataStalled = false; + timeDuration + ", TimeDurationForCurrentRecoveryAction=" + timeDurationOfCurrentAction); } } Loading Loading @@ -674,6 +709,7 @@ public class DataStallRecoveryManager extends Handler { mLastActionReported = false; broadcastDataStallDetected(recoveryAction); mNetworkCheckTimerStarted = false; mTimeElapsedOfCurrentAction = SystemClock.elapsedRealtime(); switch (recoveryAction) { case RECOVERY_ACTION_GET_DATA_CALL_LIST: Loading src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java +14 −0 Original line number Diff line number Diff line Loading @@ -29,7 +29,9 @@ import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.NetworkType; import android.telephony.DataFailCause; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting.ProtocolType; import android.telephony.data.DataCallResponse; import android.telephony.data.DataService; Loading Loading @@ -259,6 +261,16 @@ public class DataCallSessionStats { private void endDataCallSession() { mDataCallSession.oosAtEnd = getIsOos(); mDataCallSession.ongoing = false; // set if this data call is established for internet on the non-Dds SubscriptionInfo subInfo = SubscriptionController.getInstance() .getSubscriptionInfo(mPhone.getSubId()); if (mPhone.getSubId() != SubscriptionController.getInstance().getDefaultDataSubId() && ((mDataCallSession.apnTypeBitmask & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) && subInfo != null && !subInfo.isOpportunistic()) { mDataCallSession.isNonDds = true; } // store for the data call list event, after DataCall is disconnected and entered into // inactive mode PhoneFactory.getMetricsCollector().unregisterOngoingDataCallStat(this); Loading Loading @@ -294,6 +306,7 @@ public class DataCallSessionStats { call.handoverFailureCauses.length); copy.handoverFailureRat = Arrays.copyOf(call.handoverFailureRat, call.handoverFailureRat.length); copy.isNonDds = call.isNonDds; return copy; } Loading @@ -318,6 +331,7 @@ public class DataCallSessionStats { proto.ongoing = true; proto.handoverFailureCauses = new int[0]; proto.handoverFailureRat = new int[0]; proto.isNonDds = false; return proto; } Loading Loading
proto/src/persist_atoms.proto +7 −0 Original line number Diff line number Diff line Loading @@ -305,6 +305,7 @@ message DataCallSession { optional int32 band_at_end = 19; repeated int32 handover_failure_causes = 20; repeated int32 handover_failure_rat = 21; optional bool is_non_dds = 22; } message CellularServiceState { Loading Loading @@ -517,3 +518,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; }
src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java +32 −16 Original line number Diff line number Diff line Loading @@ -106,6 +106,10 @@ public class CarrierPrivilegesTracker extends Handler { private static final String SHA_1 = "SHA-1"; private static final String SHA_256 = "SHA-256"; private static final int PACKAGE_NOT_PRIVILEGED = 0; private static final int PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG = 1; private static final int PACKAGE_PRIVILEGED_FROM_SIM = 2; // TODO(b/232273884): Turn feature on when find solution to handle the inter-carriers switching /** * Time delay to clear UICC rules after UICC is gone. Loading Loading @@ -755,23 +759,35 @@ public class CarrierPrivilegesTracker extends Handler { @NonNull private PrivilegedPackageInfo getCurrentPrivilegedPackagesForAllUsers() { Set<String> carrierServiceEligiblePackages = new ArraySet<>(); Set<String> privilegedPackageNames = new ArraySet<>(); Set<Integer> privilegedUids = new ArraySet<>(); for (Map.Entry<String, Set<String>> e : mInstalledPackageCerts.entrySet()) { if (isPackagePrivileged(e.getKey(), e.getValue())) { final int priv = getPackagePrivilegedStatus(e.getKey(), e.getValue()); switch (priv) { case PACKAGE_PRIVILEGED_FROM_SIM: carrierServiceEligiblePackages.add(e.getKey()); // fallthrough case PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG: privilegedPackageNames.add(e.getKey()); privilegedUids.addAll(getUidsForPackage(e.getKey(), /* invalidateCache= */ false)); privilegedUids.addAll( getUidsForPackage(e.getKey(), /* invalidateCache= */ false)); } } return new PrivilegedPackageInfo(privilegedPackageNames, privilegedUids, getCarrierService(privilegedPackageNames)); return new PrivilegedPackageInfo( privilegedPackageNames, privilegedUids, getCarrierService(carrierServiceEligiblePackages)); } /** * Returns true iff there is an overlap between the provided certificate hashes and the * certificate hashes stored in mTestOverrideRules, mCarrierConfigRules and mUiccRules. * Returns the privilege status of the provided package. * * <p>Returned privilege status depends on whether a package matches the certificates from * carrier config, from test overrides or from certificates stored on the SIM. */ private boolean isPackagePrivileged(@NonNull String pkgName, @NonNull Set<String> certs) { private int getPackagePrivilegedStatus(@NonNull String pkgName, @NonNull Set<String> certs) { // Double-nested for loops, but each collection should contain at most 2 elements in nearly // every case. // TODO(b/184382310) find a way to speed this up Loading @@ -780,23 +796,23 @@ public class CarrierPrivilegesTracker extends Handler { if (mTestOverrideRules != null) { for (UiccAccessRule rule : mTestOverrideRules) { if (rule.matches(cert, pkgName)) { return true; return PACKAGE_PRIVILEGED_FROM_SIM; } } } else { for (UiccAccessRule rule : mCarrierConfigRules) { for (UiccAccessRule rule : mUiccRules) { if (rule.matches(cert, pkgName)) { return true; return PACKAGE_PRIVILEGED_FROM_SIM; } } for (UiccAccessRule rule : mUiccRules) { for (UiccAccessRule rule : mCarrierConfigRules) { if (rule.matches(cert, pkgName)) { return true; return PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG; } } } } return false; return PACKAGE_NOT_PRIVILEGED; } @NonNull Loading Loading @@ -1065,13 +1081,13 @@ public class CarrierPrivilegesTracker extends Handler { } @NonNull private Pair<String, Integer> getCarrierService(@NonNull Set<String> privilegedPackageNames) { private Pair<String, Integer> getCarrierService(@NonNull Set<String> simPrivilegedPackages) { List<ResolveInfo> carrierServiceResolveInfos = mPackageManager.queryIntentServices( new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), /* flags= */ 0); String carrierServicePackageName = null; for (ResolveInfo resolveInfo : carrierServiceResolveInfos) { String packageName = getPackageName(resolveInfo); if (privilegedPackageNames.contains(packageName)) { if (simPrivilegedPackages.contains(packageName)) { carrierServicePackageName = packageName; break; } Loading
src/java/com/android/internal/telephony/PhoneSubInfoController.java +1 −25 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.os.Binder; import android.os.Build; import android.os.RemoteException; import android.os.TelephonyServiceManager.ServiceRegisterer; import android.os.UserHandle; import android.telephony.ImsiEncryptionInfo; import android.telephony.PhoneNumberUtils; import android.telephony.SubscriptionManager; Loading Loading @@ -150,8 +149,7 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getSubscriberIdForSubscriber(int subId, String callingPackage, String callingFeatureId) { String message = "getSubscriberIdForSubscriber"; enforceCallingPackage(callingPackage, Binder.getCallingUid(), message); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); long identity = Binder.clearCallingIdentity(); boolean isActive; Loading Loading @@ -332,28 +330,6 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { "Requires MODIFY_PHONE_STATE"); } /** * Make sure the caller is the calling package itself * * @throws SecurityException if the caller is not the calling package */ private void enforceCallingPackage(String callingPackage, int callingUid, String message) { int packageUid = -1; PackageManager pm = mContext.createContextAsUser( UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager(); if (pm != null) { try { packageUid = pm.getPackageUid(callingPackage, 0); } catch (PackageManager.NameNotFoundException e) { // packageUid is -1 } } if (packageUid != callingUid) { throw new SecurityException(message + ": Package " + callingPackage + " does not belong to " + callingUid); } } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int getDefaultSubscription() { return PhoneFactory.getDefaultSubscription(); Loading
src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +54 −18 Original line number Diff line number Diff line Loading @@ -158,7 +158,8 @@ public class DataStallRecoveryManager extends Handler { /** Whether the result of last action(RADIO_RESTART) reported. */ private boolean mLastActionReported; /** The real time for data stall start. */ private @ElapsedRealtimeLong long mDataStallStartMs; @VisibleForTesting public @ElapsedRealtimeLong long mDataStallStartMs; /** Last data stall recovery action. */ private @RecoveryAction int mLastAction; /** Last radio power state. */ Loading @@ -175,6 +176,8 @@ public class DataStallRecoveryManager extends Handler { private boolean mIsAttemptedAllSteps; /** Whether internet network connected. */ private boolean mIsInternetNetworkConnected; /** The durations for current recovery action */ private @ElapsedRealtimeLong long mTimeElapsedOfCurrentAction; /** The array for the timers between recovery actions. */ private @NonNull long[] mDataStallRecoveryDelayMillisArray; Loading Loading @@ -467,6 +470,15 @@ public class DataStallRecoveryManager extends Handler { return (SystemClock.elapsedRealtime() - mTimeLastRecoveryStartMs); } /** * Get duration time for current recovery action. * * @return the time duration for current recovery action. */ private long getDurationOfCurrentRecoveryMs() { return (SystemClock.elapsedRealtime() - mTimeElapsedOfCurrentAction); } /** * Broadcast intent when data stall occurred. * Loading Loading @@ -592,38 +604,61 @@ public class DataStallRecoveryManager extends Handler { * @param isValid true for validation passed & false for validation failed */ private void setNetworkValidationState(boolean isValid) { boolean isLogNeeded = false; int timeDuration = 0; int timeDurationOfCurrentAction = 0; boolean isFirstDataStall = false; boolean isFirstValidationAfterDoRecovery = false; @RecoveredReason int reason = getRecoveredReason(isValid); // Validation status is true and was not data stall. if (isValid && !mDataStalled) { return; } if (!mDataStalled) { // First data stall isLogNeeded = true; mDataStalled = true; isFirstDataStall = true; mDataStallStartMs = SystemClock.elapsedRealtime(); logl("data stall: start time = " + DataUtils.elapsedTimeToString(mDataStallStartMs)); return; } else if (!mLastActionReported) { // When the first validation status appears, enter this block. isLogNeeded = true; timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); mLastActionReported = true; isFirstValidationAfterDoRecovery = true; } if (!mLastActionReported) { @RecoveredReason int reason = getRecoveredReason(isValid); int timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); if (isValid) { // When the validation passed(mobile data resume), enter this block. isLogNeeded = true; timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); mLastActionReported = false; mDataStalled = false; } if (isLogNeeded) { timeDurationOfCurrentAction = (isFirstDataStall == true ? 0 : (int) getDurationOfCurrentRecoveryMs()); DataStallRecoveryStats.onDataStallEvent( mLastAction, mPhone, isValid, timeDuration, reason, isFirstValidationAfterDoRecovery, timeDurationOfCurrentAction); logl( "data stall: lastaction = " "data stall: " + (isFirstDataStall == true ? "start" : isValid == false ? "in process" : "end") + ", lastaction=" + recoveryActionToString(mLastAction) + ", isRecovered=" + isValid + ", reason=" + recoveredReasonToString(reason) + ", isFirstValidationAfterDoRecovery=" + isFirstValidationAfterDoRecovery + ", TimeDuration=" + timeDuration); DataStallRecoveryStats.onDataStallEvent( mLastAction, mPhone, isValid, timeDuration, reason); mLastActionReported = true; } if (isValid) { mLastActionReported = false; mDataStalled = false; + timeDuration + ", TimeDurationForCurrentRecoveryAction=" + timeDurationOfCurrentAction); } } Loading Loading @@ -674,6 +709,7 @@ public class DataStallRecoveryManager extends Handler { mLastActionReported = false; broadcastDataStallDetected(recoveryAction); mNetworkCheckTimerStarted = false; mTimeElapsedOfCurrentAction = SystemClock.elapsedRealtime(); switch (recoveryAction) { case RECOVERY_ACTION_GET_DATA_CALL_LIST: Loading
src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java +14 −0 Original line number Diff line number Diff line Loading @@ -29,7 +29,9 @@ import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.NetworkType; import android.telephony.DataFailCause; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting.ProtocolType; import android.telephony.data.DataCallResponse; import android.telephony.data.DataService; Loading Loading @@ -259,6 +261,16 @@ public class DataCallSessionStats { private void endDataCallSession() { mDataCallSession.oosAtEnd = getIsOos(); mDataCallSession.ongoing = false; // set if this data call is established for internet on the non-Dds SubscriptionInfo subInfo = SubscriptionController.getInstance() .getSubscriptionInfo(mPhone.getSubId()); if (mPhone.getSubId() != SubscriptionController.getInstance().getDefaultDataSubId() && ((mDataCallSession.apnTypeBitmask & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) && subInfo != null && !subInfo.isOpportunistic()) { mDataCallSession.isNonDds = true; } // store for the data call list event, after DataCall is disconnected and entered into // inactive mode PhoneFactory.getMetricsCollector().unregisterOngoingDataCallStat(this); Loading Loading @@ -294,6 +306,7 @@ public class DataCallSessionStats { call.handoverFailureCauses.length); copy.handoverFailureRat = Arrays.copyOf(call.handoverFailureRat, call.handoverFailureRat.length); copy.isNonDds = call.isNonDds; return copy; } Loading @@ -318,6 +331,7 @@ public class DataCallSessionStats { proto.ongoing = true; proto.handoverFailureCauses = new int[0]; proto.handoverFailureRat = new int[0]; proto.isNonDds = false; return proto; } Loading