From 4f2a849e254eea87d4796a6eea983d00e9f2f86c Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Sat, 1 Aug 2020 19:55:31 -0700 Subject: Refactored precise data connection state Instead of triggering the data connection state changed event from outside, now the event is triggering from DataConnection. Whenever detecting data connection state changes, the event will be triggered. This significantly reduced the unnecessary redundant events sent to telephony registry, even though it has a duplicate detection mechanism. This are also two behavioral changes. 1. Previously if a data connection supports multiple APN types, there will be multiple data connection state changed event for each APN type. Now there is only one. The listener should use PreciseDataConnectionState.getApnSetting().getApnTypeBitmask() to check which APN types this data connection supports. 2. If setup data call fails before a data connection instance can be created, there won't be any event with fail cause. Fix: 161572838 Test: FrameworksTelephonyTests and manual Merged-In: I9723d5284c2a8fbae9f63179dc30ddc42da1d0fc Change-Id: I9723d5284c2a8fbae9f63179dc30ddc42da1d0fc (cherry picked from commit 34a09a4cbd2fbb32d0dd7b8879483b879125bf52) --- .../telephony/TelephonyRegistryManager.java | 29 +--- .../internal/telephony/ITelephonyRegistry.aidl | 6 +- .../java/com/android/server/TelephonyRegistry.java | 174 ++++++--------------- .../telephony/PreciseDataConnectionState.java | 24 +-- 4 files changed, 62 insertions(+), 171 deletions(-) diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 2dbce7b0fc7b..3673ae7f7a37 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -26,10 +26,8 @@ import android.os.Binder; import android.os.Build; import android.os.RemoteException; import android.os.ServiceManager; -import android.telephony.Annotation.ApnType; import android.telephony.Annotation.CallState; import android.telephony.Annotation.DataActivityType; -import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.DisconnectCauses; import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.PreciseCallStates; @@ -37,7 +35,6 @@ import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; -import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; import android.util.Log; @@ -413,17 +410,16 @@ public class TelephonyRegistryManager { * @param subId for which data connection state changed. * @param slotIndex for which data connections state changed. Can be derived from subId except * when subId is invalid. - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. * @param preciseState the PreciseDataConnectionState * - * @see android.telephony.PreciseDataConnection + * @see PreciseDataConnectionState * @see TelephonyManager#DATA_DISCONNECTED */ public void notifyDataConnectionForSubscriber(int slotIndex, int subId, - @ApnType int apnType, @Nullable PreciseDataConnectionState preciseState) { + @NonNull PreciseDataConnectionState preciseState) { try { sRegistry.notifyDataConnectionForSubscriber( - slotIndex, subId, apnType, preciseState); + slotIndex, subId, preciseState); } catch (RemoteException ex) { // system process is dead } @@ -622,25 +618,6 @@ public class TelephonyRegistryManager { } } - /** - * Notify precise data connection failed cause on certain subscription. - * - * @param subId for which data connection failed. - * @param slotIndex for which data conenction failed. Can be derived from subId except when - * subId is invalid. - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. - * @param apn the APN {@link ApnSetting#getApnName()} of this data connection. - * @param failCause data fail cause. - */ - public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, @ApnType int apnType, - @Nullable String apn, @DataFailureCause int failCause) { - try { - sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause); - } catch (RemoteException ex) { - // system process is dead - } - } - /** * Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call * on certain subscription. diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 5a04992a35b4..ea09fc8cd34a 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -65,9 +65,7 @@ interface ITelephonyRegistry { void notifyDataActivity(int state); void notifyDataActivityForSubscriber(in int subId, int state); void notifyDataConnectionForSubscriber( - int phoneId, int subId, int apnType, in PreciseDataConnectionState preciseState); - @UnsupportedAppUsage - void notifyDataConnectionFailed(String apnType); + int phoneId, int subId, in PreciseDataConnectionState preciseState); // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. void notifyCellLocation(in CellIdentity cellLocation); void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation); @@ -77,8 +75,6 @@ interface ITelephonyRegistry { int foregroundCallState, int backgroundCallState); void notifyDisconnectCause(int phoneId, int subId, int disconnectCause, int preciseDisconnectCause); - void notifyPreciseDataConnectionFailed(int phoneId, int subId, int apnType, String apn, - int failCause); void notifyCellInfoForSubscriber(in int subId, in List cellInfo); void notifySrvccStateChanged(in int subId, in int lteState); void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 7fc502819cae..865392e8e0b9 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -34,7 +34,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.net.LinkProperties; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -46,8 +45,6 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.DeviceConfig; import android.telephony.Annotation; -import android.telephony.Annotation.ApnType; -import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SrvccState; import android.telephony.BarringInfo; @@ -80,7 +77,9 @@ import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; +import android.util.ArrayMap; import android.util.LocalLog; +import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; @@ -303,13 +302,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { @RadioPowerState private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE; - private final LocalLog mLocalLog = new LocalLog(100); + private final LocalLog mLocalLog = new LocalLog(200); - private final LocalLog mListenLog = new LocalLog(100); + private final LocalLog mListenLog = new LocalLog(00); - // Per-phoneMap of APN Type to DataConnectionState - private List> mPreciseDataConnectionStates = - new ArrayList>(); + /** + * Per-phone map of precise data connection state. The key of the map is the pair of transport + * type and APN setting. This is the cache to prevent redundant callbacks to the listeners. + * A precise data connection with state {@link TelephonyManager#DATA_DISCONNECTED} removes + * its entry from the map. + */ + private List, PreciseDataConnectionState>> + mPreciseDataConnectionStates; static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = PhoneStateListener.LISTEN_REGISTRATION_FAILURE @@ -522,7 +526,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; - mPreciseDataConnectionStates.add(new HashMap()); + mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; } @@ -611,7 +615,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; - mPreciseDataConnectionStates.add(new HashMap()); + mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; } @@ -1688,38 +1692,25 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { * * @param phoneId the phoneId carrying the data connection * @param subId the subscriptionId for the data connection - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. * @param preciseState a PreciseDataConnectionState that has info about the data connection */ @Override - public void notifyDataConnectionForSubscriber( - int phoneId, int subId, @ApnType int apnType, PreciseDataConnectionState preciseState) { + public void notifyDataConnectionForSubscriber(int phoneId, int subId, + @NonNull PreciseDataConnectionState preciseState) { if (!checkNotifyPermission("notifyDataConnection()" )) { return; } - String apn = ""; - int state = TelephonyManager.DATA_UNKNOWN; - int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; - LinkProperties linkProps = null; + ApnSetting apnSetting = preciseState.getApnSetting(); - if (preciseState != null) { - apn = preciseState.getDataConnectionApn(); - state = preciseState.getState(); - networkType = preciseState.getNetworkType(); - linkProps = preciseState.getLinkProperties(); - } - if (VDBG) { - log("notifyDataConnectionForSubscriber: subId=" + subId - + " state=" + state + "' apn='" + apn - + "' apnType=" + apnType + " networkType=" + networkType - + "' preciseState=" + preciseState); - } + int apnTypes = apnSetting.getApnTypeBitmask(); + int state = preciseState.getState(); + int networkType = preciseState.getNetworkType(); synchronized (mRecords) { if (validatePhoneId(phoneId)) { // We only call the callback when the change is for default APN type. - if ((ApnSetting.TYPE_DEFAULT & apnType) != 0 + if ((ApnSetting.TYPE_DEFAULT & apnTypes) != 0 && (mDataConnectionState[phoneId] != state || mDataConnectionNetworkType[phoneId] != networkType)) { String str = "onDataConnectionStateChanged(" @@ -1748,19 +1739,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataConnectionNetworkType[phoneId] = networkType; } - boolean needsNotify = false; - // State has been cleared for this APN Type - if (preciseState == null) { - // We try clear the state and check if the state was previously not cleared - needsNotify = mPreciseDataConnectionStates.get(phoneId).remove(apnType) != null; - } else { - // We need to check to see if the state actually changed - PreciseDataConnectionState oldPreciseState = - mPreciseDataConnectionStates.get(phoneId).put(apnType, preciseState); - needsNotify = !preciseState.equals(oldPreciseState); - } - - if (needsNotify) { + Pair key = Pair.create(preciseState.getTransportType(), + preciseState.getApnSetting()); + PreciseDataConnectionState oldState = mPreciseDataConnectionStates.get(phoneId) + .remove(key); + if (!Objects.equals(oldState, preciseState)) { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) @@ -1772,54 +1755,22 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } } - } - } - handleRemoveListLocked(); - } + handleRemoveListLocked(); - broadcastDataConnectionStateChanged(state, apn, apnType, subId); - } + broadcastDataConnectionStateChanged(phoneId, subId, preciseState); - /** - * Stub to satisfy the ITelephonyRegistry aidl interface; do not use this function. - * @see #notifyDataConnectionFailedForSubscriber - */ - public void notifyDataConnectionFailed(String apnType) { - loge("This function should not be invoked"); - } + String str = "notifyDataConnectionForSubscriber: phoneId=" + phoneId + " subId=" + + subId + " " + preciseState; + log(str); + mLocalLog.log(str); + } - private void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, int apnType) { - if (!checkNotifyPermission("notifyDataConnectionFailed()")) { - return; - } - if (VDBG) { - log("notifyDataConnectionFailedForSubscriber: subId=" + subId - + " apnType=" + apnType); - } - synchronized (mRecords) { - if (validatePhoneId(phoneId)) { - mPreciseDataConnectionStates.get(phoneId).put( - apnType, - new PreciseDataConnectionState.Builder() - .setApnSetting(new ApnSetting.Builder() - .setApnTypeBitmask(apnType) - .build()) - .build()); - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) - && idMatch(r.subId, subId, phoneId)) { - try { - r.callback.onPreciseDataConnectionStateChanged( - mPreciseDataConnectionStates.get(phoneId).get(apnType)); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); - } - } + // If the state is disconnected, it would be the end of life cycle of a data + // connection, so remove it from the cache. + if (preciseState.getState() != TelephonyManager.DATA_DISCONNECTED) { + mPreciseDataConnectionStates.get(phoneId).put(key, preciseState); } } - - handleRemoveListLocked(); } } @@ -1968,43 +1919,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - @Override - public void notifyPreciseDataConnectionFailed(int phoneId, int subId, @ApnType int apnType, - String apn, @DataFailureCause int failCause) { - if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { - return; - } - - // precise notify invokes imprecise notify - notifyDataConnectionFailedForSubscriber(phoneId, subId, apnType); - - synchronized (mRecords) { - if (validatePhoneId(phoneId)) { - mPreciseDataConnectionStates.get(phoneId).put( - apnType, - new PreciseDataConnectionState.Builder() - .setApnSetting(new ApnSetting.Builder() - .setApnTypeBitmask(apnType) - .build()) - .setFailCause(failCause) - .build()); - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) - && idMatch(r.subId, subId, phoneId)) { - try { - r.callback.onPreciseDataConnectionStateChanged( - mPreciseDataConnectionStates.get(phoneId).get(apnType)); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); - } - } - } - } - handleRemoveListLocked(); - } - } - @Override public void notifySrvccStateChanged(int subId, @SrvccState int state) { if (!checkNotifyPermission("notifySrvccStateChanged()")) { @@ -2575,16 +2489,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - private void broadcastDataConnectionStateChanged(int state, String apn, - int apnType, int subId) { + private void broadcastDataConnectionStateChanged(int slotIndex, int subId, + @NonNull PreciseDataConnectionState pdcs) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); - intent.putExtra(PHONE_CONSTANTS_STATE_KEY, TelephonyUtils.dataStateToString(state)); - intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, apn); + intent.putExtra(PHONE_CONSTANTS_STATE_KEY, + TelephonyUtils.dataStateToString(pdcs.getState())); + intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, pdcs.getApnSetting().getApnName()); intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, - ApnSetting.getApnTypesStringFromBitmask(apnType)); + ApnSetting.getApnTypesStringFromBitmask(pdcs.getApnSetting().getApnTypeBitmask())); + intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, slotIndex); intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE); } @@ -2941,7 +2857,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { /** * Returns a string representation of the radio technology (network type) * currently in use on the device. - * @param subId for which network type is returned + * @param type for which network type is returned * @return the name of the radio technology * */ diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index ecef747b871f..fd9f46011c7e 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -36,6 +36,8 @@ import android.telephony.Annotation.NetworkType; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; +import com.android.internal.telephony.util.TelephonyUtils; + import java.util.Objects; @@ -82,6 +84,7 @@ public final class PreciseDataConnectionState implements Parcelable { linkProperties, failCause, new ApnSetting.Builder() .setApnTypeBitmask(apnTypes) .setApnName(apn) + .setEntryName(apn) .build()); } @@ -254,7 +257,9 @@ public final class PreciseDataConnectionState implements Parcelable { /** * Return the APN Settings for this data connection. * - * @return the ApnSetting that was used to configure this data connection. + * @return the ApnSetting that was used to configure this data connection. Note that a data + * connection cannot be established without a valid {@link ApnSetting}. The return value would + * never be {@code null} even though it has {@link Nullable} annotation. */ public @Nullable ApnSetting getApnSetting() { return mApnSetting; @@ -314,17 +319,14 @@ public final class PreciseDataConnectionState implements Parcelable { public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("Data Connection state: " + mState); - sb.append(", Transport type: " + sb.append(" state: " + TelephonyUtils.dataStateToString(mState)); + sb.append(", transport: " + AccessNetworkConstants.transportTypeToString(mTransportType)); - sb.append(", Id: " + mId); - sb.append(", Network type: " + mNetworkType); - sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask( - getDataConnectionApnTypeBitMask())); - sb.append(", APN: " + getDataConnectionApn()); - sb.append(", Link properties: " + mLinkProperties); - sb.append(", Fail cause: " + DataFailCause.toString(mFailCause)); - sb.append(", Apn Setting: " + mApnSetting); + sb.append(", id: " + mId); + sb.append(", network type: " + TelephonyManager.getNetworkTypeName(mNetworkType)); + sb.append(", APN Setting: " + mApnSetting); + sb.append(", link properties: " + mLinkProperties); + sb.append(", fail cause: " + DataFailCause.toString(mFailCause)); return sb.toString(); } -- cgit v1.2.3-59-g8ed1b