diff options
| author | 2020-03-18 23:41:57 +0000 | |
|---|---|---|
| committer | 2020-03-18 23:41:57 +0000 | |
| commit | 2ea0b56cff0ec1c99a6f3a1660dd5b4d801eb5bf (patch) | |
| tree | aded5bafcc8d455506beaaa9b516ba6148b91911 | |
| parent | 055e616bd3e24a2943ac27396e60989883ab530c (diff) | |
| parent | 4ad89fb9554764a5920132341d75eab9a7e7f63d (diff) | |
Merge changes from topics "barring-cp", "nri-rplmn"
* changes:
Allow Nullable Registered PLMN
Return the RPLMN from NetworkRegistrationInfo
Expose PreciseDataConnectionstate#getApnSetting()
Skip sanitizing location info for Null Barring CID
Remove BarringInfo#isServiceBarred()
Introduce a new RIL request constant to support getBarringInfo.
Update BarringInfo as Barring HAL date stuctures updated
Add a BARRING_TYPE_UNKNOWN for Unreported Barring
Add Callback to notify changes of barring status
| -rw-r--r-- | api/current.txt | 36 | ||||
| -rwxr-xr-x | api/system-current.txt | 6 | ||||
| -rw-r--r-- | api/test-current.txt | 10 | ||||
| -rw-r--r-- | core/java/android/telephony/PhoneStateListener.java | 33 | ||||
| -rw-r--r-- | core/java/android/telephony/TelephonyRegistryManager.java | 17 | ||||
| -rw-r--r-- | core/java/com/android/internal/telephony/IPhoneStateListener.aidl | 2 | ||||
| -rw-r--r-- | core/java/com/android/internal/telephony/ITelephonyRegistry.aidl | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/TelephonyRegistry.java | 67 | ||||
| -rw-r--r-- | telephony/java/android/telephony/BarringInfo.aidl | 20 | ||||
| -rw-r--r-- | telephony/java/android/telephony/BarringInfo.java | 398 | ||||
| -rw-r--r-- | telephony/java/android/telephony/NetworkRegistrationInfo.java | 62 | ||||
| -rw-r--r-- | telephony/java/android/telephony/PreciseDataConnectionState.java | 4 | ||||
| -rw-r--r-- | telephony/java/com/android/internal/telephony/RILConstants.java | 2 |
13 files changed, 647 insertions, 12 deletions
diff --git a/api/current.txt b/api/current.txt index ce04fae07e3f..f17eae1eb077 100644 --- a/api/current.txt +++ b/api/current.txt @@ -44680,6 +44680,38 @@ package android.telephony { field public static final int PRIORITY_MED = 2; // 0x2 } + public final class BarringInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.telephony.BarringInfo.BarringServiceInfo getBarringServiceInfo(int); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int BARRING_SERVICE_TYPE_CS_FALLBACK = 5; // 0x5 + field public static final int BARRING_SERVICE_TYPE_CS_SERVICE = 0; // 0x0 + field public static final int BARRING_SERVICE_TYPE_CS_VOICE = 2; // 0x2 + field public static final int BARRING_SERVICE_TYPE_EMERGENCY = 8; // 0x8 + field public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO = 7; // 0x7 + field public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE = 6; // 0x6 + field public static final int BARRING_SERVICE_TYPE_MO_DATA = 4; // 0x4 + field public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING = 3; // 0x3 + field public static final int BARRING_SERVICE_TYPE_PS_SERVICE = 1; // 0x1 + field public static final int BARRING_SERVICE_TYPE_SMS = 9; // 0x9 + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.BarringInfo> CREATOR; + } + + public static final class BarringInfo.BarringServiceInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getBarringType(); + method public int getConditionalBarringFactor(); + method public int getConditionalBarringTimeSeconds(); + method public boolean isBarred(); + method public boolean isConditionallyBarred(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int BARRING_TYPE_CONDITIONAL = 1; // 0x1 + field public static final int BARRING_TYPE_NONE = 0; // 0x0 + field public static final int BARRING_TYPE_UNCONDITIONAL = 2; // 0x2 + field public static final int BARRING_TYPE_UNKNOWN = -1; // 0xffffffff + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.BarringInfo.BarringServiceInfo> CREATOR; + } + public class CarrierConfigManager { method @Nullable public android.os.PersistableBundle getConfig(); method @Nullable public android.os.PersistableBundle getConfigByComponentForSubId(@NonNull String, int); @@ -45316,6 +45348,7 @@ package android.telephony { method @Nullable public android.telephony.CellIdentity getCellIdentity(); method public int getDomain(); method public int getNrState(); + method @Nullable public String getRegisteredPlmn(); method public int getTransportType(); method public boolean isRegistered(); method public boolean isRoaming(); @@ -45442,6 +45475,7 @@ package android.telephony { ctor public PhoneStateListener(); ctor public PhoneStateListener(@NonNull java.util.concurrent.Executor); method public void onActiveDataSubscriptionIdChanged(int); + method public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo); method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onCallDisconnectCauseChanged(int, int); method public void onCallForwardingIndicatorChanged(boolean); method public void onCallStateChanged(int, String); @@ -45460,6 +45494,7 @@ package android.telephony { method public void onSignalStrengthsChanged(android.telephony.SignalStrength); method public void onUserMobileDataStateChanged(boolean); field public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000 + field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000 field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000 field public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8 field public static final int LISTEN_CALL_STATE = 32; // 0x20 @@ -45482,6 +45517,7 @@ package android.telephony { public final class PreciseDataConnectionState implements android.os.Parcelable { method public int describeContents(); + method @Nullable public android.telephony.data.ApnSetting getApnSetting(); method public int getLastCauseCode(); method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); diff --git a/api/system-current.txt b/api/system-current.txt index e466d4763d5d..94879facb90c 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -8169,6 +8169,11 @@ package android.telephony { field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0 } + public final class BarringInfo implements android.os.Parcelable { + ctor public BarringInfo(); + method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy(); + } + public final class CallAttributes implements android.os.Parcelable { ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality); method public int describeContents(); @@ -8844,6 +8849,7 @@ package android.telephony { method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int); diff --git a/api/test-current.txt b/api/test-current.txt index d46f36885c56..c9725710daf8 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -3098,6 +3098,15 @@ package android.telephony { field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0 } + public final class BarringInfo implements android.os.Parcelable { + ctor public BarringInfo(); + ctor public BarringInfo(@Nullable android.telephony.CellIdentity, @NonNull android.util.SparseArray<android.telephony.BarringInfo.BarringServiceInfo>); + } + + public static final class BarringInfo.BarringServiceInfo implements android.os.Parcelable { + ctor public BarringInfo.BarringServiceInfo(int, boolean, int, int); + } + public final class CallQuality implements android.os.Parcelable { ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int); ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean); @@ -3184,6 +3193,7 @@ package android.telephony { method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int); method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int); diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 1dca7fd0e444..ab31d247bb73 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -427,6 +427,17 @@ public class PhoneStateListener { @RequiresPermission(Manifest.permission.READ_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000; + /** + * Listen for Barring Information for the current registered / camped cell. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see #onBarringInfoChanged() + */ + @RequiresPermission(Manifest.permission.READ_PHONE_STATE) + public static final int LISTEN_BARRING_INFO = 0x80000000; + /* * Subscription used to listen to the phone state changes * @hide @@ -1036,6 +1047,20 @@ public class PhoneStateListener { } /** + * Report updated barring information for the current camped/registered cell. + * + * <p>Barring info is provided for all services applicable to the current camped/registered + * cell, for the registered PLMN and current access class/access category. + * + * @param barringInfo for all services on the current cell. + * + * @see android.telephony.BarringInfo + */ + public void onBarringInfoChanged(@NonNull BarringInfo barringInfo) { + // default implementation empty + } + + /** * The callback methods need to be called on the handler thread where * this object was created. If the binder did that for us it'd be nice. * @@ -1328,6 +1353,14 @@ public class PhoneStateListener { cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode))); // default implementation empty } + + public void onBarringInfoChanged(BarringInfo barringInfo) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onBarringInfoChanged(barringInfo))); + } } diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index c4b4c43056b1..73cd708f43f7 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -729,4 +729,21 @@ public class TelephonyRegistryManager { } catch (RemoteException ex) { } } + + /** + * Notify {@link BarringInfo} has changed for a specific subscription. + * + * @param slotIndex for the phone object that got updated barring info. + * @param subId for which the BarringInfo changed. + * @param barringInfo updated BarringInfo. + */ + public void notifyBarringInfoChanged( + int slotIndex, int subId, @NonNull BarringInfo barringInfo) { + try { + sRegistry.notifyBarringInfoChanged(slotIndex, subId, barringInfo); + } catch (RemoteException ex) { + // system server crash + } + } + } diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index d15f48054e9d..3d5dfbbb871a 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -16,6 +16,7 @@ package com.android.internal.telephony; +import android.telephony.BarringInfo; import android.telephony.CallAttributes; import android.telephony.CellIdentity; import android.telephony.CellInfo; @@ -66,4 +67,5 @@ oneway interface IPhoneStateListener { void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo); void onRegistrationFailed(in CellIdentity cellIdentity, String chosenPlmn, int domain, int causeCode, int additionalCauseCode); + void onBarringInfoChanged(in BarringInfo barringInfo); } diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 3176f96ef9ce..866715551a41 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -19,6 +19,7 @@ package com.android.internal.telephony; import android.content.Intent; import android.net.LinkProperties; import android.net.NetworkCapabilities; +import android.telephony.BarringInfo; import android.telephony.CallQuality; import android.telephony.CellIdentity; import android.telephony.CellInfo; @@ -102,4 +103,5 @@ interface ITelephonyRegistry { void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo); void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity, String chosenPlmn, int domain, int causeCode, int additionalCauseCode); + void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo); } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index f45d54dda620..45868932be2b 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -45,6 +45,7 @@ import android.telephony.Annotation; import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SrvccState; +import android.telephony.BarringInfo; import android.telephony.CallAttributes; import android.telephony.CallQuality; import android.telephony.CellIdentity; @@ -258,6 +259,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private int[] mCallPreciseDisconnectCause; + private List<BarringInfo> mBarringInfo = null; + private boolean mCarrierNetworkChangeState = false; private PhoneCapability mPhoneCapability = null; @@ -451,6 +454,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { cutListToSize(mCellInfo, mNumPhones); cutListToSize(mImsReasonInfo, mNumPhones); cutListToSize(mPreciseDataConnectionStates, mNumPhones); + cutListToSize(mBarringInfo, mNumPhones); return; } @@ -483,6 +487,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>()); mDisplayInfos[i] = null; + mBarringInfo.add(i, new BarringInfo()); } } @@ -541,6 +546,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mOutgoingCallEmergencyNumber = new EmergencyNumber[numPhones]; mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones]; mDisplayInfos = new DisplayInfo[numPhones]; + mBarringInfo = new ArrayList<>(); for (int i = 0; i < numPhones; i++) { mCallState[i] = TelephonyManager.CALL_STATE_IDLE; mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; @@ -569,6 +575,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>()); mDisplayInfos[i] = null; + mBarringInfo.add(i, new BarringInfo()); } mAppOps = mContext.getSystemService(AppOpsManager.class); @@ -1031,6 +1038,19 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } + if ((events & PhoneStateListener.LISTEN_BARRING_INFO) != 0) { + BarringInfo barringInfo = mBarringInfo.get(phoneId); + BarringInfo biNoLocation = barringInfo != null + ? barringInfo.createLocationInfoSanitizedCopy() : null; + if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo); + try { + r.callback.onBarringInfoChanged( + checkFineLocationAccess(r, Build.VERSION_CODES.R) + ? barringInfo : biNoLocation); + } catch (RemoteException ex) { + remove(r.binder); + } + } } } } else { @@ -2207,6 +2227,52 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + /** + * Send a notification of changes to barring status to PhoneStateListener registrants. + * + * @param phoneId the phoneId + * @param subId the subId + * @param barringInfo a structure containing the complete updated barring info. + */ + public void notifyBarringInfoChanged(int phoneId, int subId, @NonNull BarringInfo barringInfo) { + if (!checkNotifyPermission("notifyBarringInfo()")) { + return; + } + if (barringInfo == null) { + log("Received null BarringInfo for subId=" + subId + ", phoneId=" + phoneId); + mBarringInfo.set(phoneId, new BarringInfo()); + return; + } + + synchronized (mRecords) { + if (validatePhoneId(phoneId)) { + mBarringInfo.set(phoneId, barringInfo); + // Barring info is non-null + BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy(); + if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo); + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_BARRING_INFO) + && idMatch(r.subId, subId, phoneId)) { + try { + if (DBG_LOC) { + log("notifyBarringInfo: mBarringInfo=" + + barringInfo + " r=" + r); + } + r.callback.onBarringInfoChanged( + checkFineLocationAccess(r, Build.VERSION_CODES.R) + ? barringInfo : biNoLocation); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + } + handleRemoveListLocked(); + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); @@ -2247,6 +2313,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i)); pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]); pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]); + pw.println("mBarringInfo=" + mBarringInfo.get(i)); pw.decreaseIndent(); } pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState); diff --git a/telephony/java/android/telephony/BarringInfo.aidl b/telephony/java/android/telephony/BarringInfo.aidl new file mode 100644 index 000000000000..50ddf6b31919 --- /dev/null +++ b/telephony/java/android/telephony/BarringInfo.aidl @@ -0,0 +1,20 @@ +/* + * Copyright 2019 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. + */ + +/** @hide */ +package android.telephony; + +parcelable BarringInfo; diff --git a/telephony/java/android/telephony/BarringInfo.java b/telephony/java/android/telephony/BarringInfo.java new file mode 100644 index 000000000000..92423a2f2218 --- /dev/null +++ b/telephony/java/android/telephony/BarringInfo.java @@ -0,0 +1,398 @@ +/* + * Copyright 2019 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 android.telephony; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.SparseArray; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; +import java.util.Objects; + +/** + * Provides the barring configuration for a particular service type. + * + * Provides indication about the barring of a particular service for use. Certain barring types + * are only valid for certain technology families. Any service that does not have a barring + * configuration is unbarred by default. + */ +public final class BarringInfo implements Parcelable { + + /** + * Barring Service Type + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "BARRING_SERVICE_TYPE_", value = { + BARRING_SERVICE_TYPE_CS_SERVICE, + BARRING_SERVICE_TYPE_PS_SERVICE, + BARRING_SERVICE_TYPE_CS_VOICE, + BARRING_SERVICE_TYPE_MO_SIGNALLING, + BARRING_SERVICE_TYPE_MO_DATA, + BARRING_SERVICE_TYPE_CS_FALLBACK, + BARRING_SERVICE_TYPE_MMTEL_VOICE, + BARRING_SERVICE_TYPE_MMTEL_VIDEO, + BARRING_SERVICE_TYPE_EMERGENCY, + BARRING_SERVICE_TYPE_SMS}) + public @interface BarringServiceType {} + + /* Applicabe to UTRAN */ + /** Barring indicator for circuit-switched service; applicable to UTRAN */ + public static final int BARRING_SERVICE_TYPE_CS_SERVICE = + android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_SERVICE; + /** Barring indicator for packet-switched service; applicable to UTRAN */ + public static final int BARRING_SERVICE_TYPE_PS_SERVICE = + android.hardware.radio.V1_5.BarringInfo.ServiceType.PS_SERVICE; + /** Barring indicator for circuit-switched voice service; applicable to UTRAN */ + public static final int BARRING_SERVICE_TYPE_CS_VOICE = + android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_VOICE; + + /* Applicable to EUTRAN, NGRAN */ + /** Barring indicator for mobile-originated signalling; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING = + android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_SIGNALLING; + /** Barring indicator for mobile-originated data traffic; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_MO_DATA = + android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_DATA; + /** Barring indicator for circuit-switched fallback for voice; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_CS_FALLBACK = + android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_FALLBACK; + /** Barring indicator for MMTEL (IMS) voice; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE = + android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VOICE; + /** Barring indicator for MMTEL (IMS) video; applicable to EUTRAN and NGRAN */ + public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO = + android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VIDEO; + + /* Applicable to UTRAN, EUTRAN, NGRAN */ + /** Barring indicator for emergency services; applicable to UTRAN, EUTRAN, and NGRAN */ + public static final int BARRING_SERVICE_TYPE_EMERGENCY = + android.hardware.radio.V1_5.BarringInfo.ServiceType.EMERGENCY; + /** Barring indicator for SMS sending; applicable to UTRAN, EUTRAN, and NGRAN */ + public static final int BARRING_SERVICE_TYPE_SMS = + android.hardware.radio.V1_5.BarringInfo.ServiceType.SMS; + + //TODO: add barring constants for Operator-Specific barring codes + + /** Describe the current barring configuration of a cell */ + public static final class BarringServiceInfo implements Parcelable { + /** + * Barring Type + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "BARRING_TYPE_", value = + {BARRING_TYPE_NONE, + BARRING_TYPE_UNCONDITIONAL, + BARRING_TYPE_CONDITIONAL, + BARRING_TYPE_UNKNOWN}) + public @interface BarringType {} + + /** Barring is inactive */ + public static final int BARRING_TYPE_NONE = + android.hardware.radio.V1_5.BarringInfo.BarringType.NONE; + /** The service is barred */ + public static final int BARRING_TYPE_UNCONDITIONAL = + android.hardware.radio.V1_5.BarringInfo.BarringType.UNCONDITIONAL; + /** The service may be barred based on additional factors */ + public static final int BARRING_TYPE_CONDITIONAL = + android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL; + + /** If a modem does not report barring info, then the barring type will be UNKNOWN */ + public static final int BARRING_TYPE_UNKNOWN = -1; + + private final @BarringType int mBarringType; + + private final boolean mIsConditionallyBarred; + private final int mConditionalBarringFactor; + private final int mConditionalBarringTimeSeconds; + + /** @hide */ + public BarringServiceInfo(@BarringType int type) { + this(type, false, 0, 0); + } + + /** @hide */ + @TestApi + public BarringServiceInfo(@BarringType int barringType, boolean isConditionallyBarred, + int conditionalBarringFactor, int conditionalBarringTimeSeconds) { + mBarringType = barringType; + mIsConditionallyBarred = isConditionallyBarred; + mConditionalBarringFactor = conditionalBarringFactor; + mConditionalBarringTimeSeconds = conditionalBarringTimeSeconds; + } + + public @BarringType int getBarringType() { + return mBarringType; + } + + /** + * @return true if the conditional barring parameters have resulted in the service being + * barred; false if the service has either not been evaluated for conditional + * barring or has been evaluated and isn't barred. + */ + public boolean isConditionallyBarred() { + return mIsConditionallyBarred; + } + + /** + * @return the conditional barring factor as a percentage 0-100, which is the probability of + * a random device being barred for the service type. + */ + public int getConditionalBarringFactor() { + return mConditionalBarringFactor; + } + + /** + * @return the conditional barring time seconds, which is the interval between successive + * evaluations for conditional barring based on the barring factor. + */ + @SuppressLint("MethodNameUnits") + public int getConditionalBarringTimeSeconds() { + return mConditionalBarringTimeSeconds; + } + + /** + * Return whether a service is currently barred based on the BarringInfo + * + * @return true if the service is currently being barred, otherwise false + */ + public boolean isBarred() { + return mBarringType == BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL + || (mBarringType == BarringServiceInfo.BARRING_TYPE_CONDITIONAL + && mIsConditionallyBarred); + } + + @Override + public int hashCode() { + return Objects.hash(mBarringType, mIsConditionallyBarred, + mConditionalBarringFactor, mConditionalBarringTimeSeconds); + } + + @Override + public boolean equals(Object rhs) { + if (!(rhs instanceof BarringServiceInfo)) return false; + + BarringServiceInfo other = (BarringServiceInfo) rhs; + return mBarringType == other.mBarringType + && mIsConditionallyBarred == other.mIsConditionallyBarred + && mConditionalBarringFactor == other.mConditionalBarringFactor + && mConditionalBarringTimeSeconds == other.mConditionalBarringTimeSeconds; + } + + /** @hide */ + public BarringServiceInfo(Parcel p) { + mBarringType = p.readInt(); + mIsConditionallyBarred = p.readBoolean(); + mConditionalBarringFactor = p.readInt(); + mConditionalBarringTimeSeconds = p.readInt(); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mBarringType); + dest.writeBoolean(mIsConditionallyBarred); + dest.writeInt(mConditionalBarringFactor); + dest.writeInt(mConditionalBarringTimeSeconds); + } + + /* @inheritDoc */ + public static final @NonNull Parcelable.Creator<BarringServiceInfo> CREATOR = + new Parcelable.Creator<BarringServiceInfo>() { + @Override + public BarringServiceInfo createFromParcel(Parcel source) { + return new BarringServiceInfo(source); + } + + @Override + public BarringServiceInfo[] newArray(int size) { + return new BarringServiceInfo[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + } + + private static final BarringServiceInfo BARRING_SERVICE_INFO_UNKNOWN = + new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_UNKNOWN); + + private static final BarringServiceInfo BARRING_SERVICE_INFO_UNBARRED = + new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_NONE); + + private CellIdentity mCellIdentity; + + // A SparseArray potentially mapping each BarringService type to a BarringServiceInfo config + // that describes the current barring status of that particular service. + private SparseArray<BarringServiceInfo> mBarringServiceInfos; + + /** @hide */ + @TestApi + @SystemApi + public BarringInfo() { + mBarringServiceInfos = new SparseArray<>(); + } + + /** + * Constructor for new BarringInfo instances. + * + * @hide + */ + @TestApi + public BarringInfo(@Nullable CellIdentity barringCellId, + @NonNull SparseArray<BarringServiceInfo> barringServiceInfos) { + mCellIdentity = barringCellId; + mBarringServiceInfos = barringServiceInfos; + } + + /** @hide */ + public static BarringInfo create( + @NonNull android.hardware.radio.V1_5.CellIdentity halBarringCellId, + @NonNull List<android.hardware.radio.V1_5.BarringInfo> halBarringInfos) { + CellIdentity ci = CellIdentity.create(halBarringCellId); + SparseArray<BarringServiceInfo> serviceInfos = new SparseArray<>(); + + for (android.hardware.radio.V1_5.BarringInfo halBarringInfo : halBarringInfos) { + if (halBarringInfo.barringType + == android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL) { + if (halBarringInfo.barringTypeSpecificInfo.getDiscriminator() + != android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo + .hidl_discriminator.conditional) { + // this is an error case where the barring info is conditional but the + // conditional barring fields weren't included + continue; + } + android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo + .Conditional conditionalInfo = + halBarringInfo.barringTypeSpecificInfo.conditional(); + serviceInfos.put( + halBarringInfo.serviceType, new BarringServiceInfo( + halBarringInfo.barringType, // will always be CONDITIONAL here + conditionalInfo.isBarred, + conditionalInfo.factor, + conditionalInfo.timeSeconds)); + } else { + // Barring type is either NONE or UNCONDITIONAL + serviceInfos.put( + halBarringInfo.serviceType, new BarringServiceInfo( + halBarringInfo.barringType, false, 0, 0)); + } + } + return new BarringInfo(ci, serviceInfos); + } + + /** + * Get the BarringServiceInfo for a specified service. + * + * @return a BarringServiceInfo struct describing the current barring status for a service + */ + public @NonNull BarringServiceInfo getBarringServiceInfo(@BarringServiceType int service) { + BarringServiceInfo bsi = mBarringServiceInfos.get(service); + // If barring is reported but not for a particular service, then we report the barring + // type as UNKNOWN; if the modem reports barring info but doesn't report for a particular + // service then we can safely assume that the service isn't barred (for instance because + // that particular service isn't applicable to the current RAN). + return (bsi != null) ? bsi : mBarringServiceInfos.size() > 0 + ? BARRING_SERVICE_INFO_UNBARRED : BARRING_SERVICE_INFO_UNKNOWN; + } + + /** @hide */ + @SystemApi + public @NonNull BarringInfo createLocationInfoSanitizedCopy() { + // The only thing that would need sanitizing is the CellIdentity + if (mCellIdentity == null) return this; + + return new BarringInfo(mCellIdentity.sanitizeLocationInfo(), mBarringServiceInfos); + } + + /** @hide */ + public BarringInfo(Parcel p) { + mCellIdentity = p.readParcelable(CellIdentity.class.getClassLoader()); + mBarringServiceInfos = p.readSparseArray(BarringServiceInfo.class.getClassLoader()); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeParcelable(mCellIdentity, flags); + dest.writeSparseArray(mBarringServiceInfos); + } + + public static final @NonNull Parcelable.Creator<BarringInfo> CREATOR = + new Parcelable.Creator<BarringInfo>() { + @Override + public BarringInfo createFromParcel(Parcel source) { + return new BarringInfo(source); + } + + @Override + public BarringInfo[] newArray(int size) { + return new BarringInfo[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public int hashCode() { + int hash = mCellIdentity != null ? mCellIdentity.hashCode() : 7; + for (int i = 0; i < mBarringServiceInfos.size(); i++) { + hash = hash + 15 * mBarringServiceInfos.keyAt(i); + hash = hash + 31 * mBarringServiceInfos.valueAt(i).hashCode(); + } + return hash; + } + + @Override + public boolean equals(Object rhs) { + if (!(rhs instanceof BarringInfo)) return false; + + BarringInfo bi = (BarringInfo) rhs; + + if (hashCode() != bi.hashCode()) return false; + + if (mBarringServiceInfos.size() != bi.mBarringServiceInfos.size()) return false; + + for (int i = 0; i < mBarringServiceInfos.size(); i++) { + if (mBarringServiceInfos.keyAt(i) != bi.mBarringServiceInfos.keyAt(i)) return false; + if (!Objects.equals(mBarringServiceInfos.valueAt(i), + bi.mBarringServiceInfos.valueAt(i))) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "BarringInfo {mCellIdentity=" + mCellIdentity + + ", mBarringServiceInfos=" + mBarringServiceInfos + "}"; + } +} diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index d8a65517c90f..3e901e241e01 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -25,6 +25,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Annotation.NetworkType; +import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -214,6 +215,9 @@ public final class NetworkRegistrationInfo implements Parcelable { @Nullable private DataSpecificRegistrationInfo mDataSpecificInfo; + @NonNull + private String mRplmn; + /** * @param domain Network domain. Must be a {@link Domain}. For transport type * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}. @@ -234,13 +238,14 @@ public final class NetworkRegistrationInfo implements Parcelable { * @param availableServices The list of the supported services. * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the * information is not available. + * @param rplmn the registered plmn or the last plmn for attempted registration if reg failed. */ private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType, @RegistrationState int registrationState, @NetworkType int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable @ServiceType List<Integer> availableServices, - @Nullable CellIdentity cellIdentity) { + @Nullable CellIdentity cellIdentity, @Nullable String rplmn) { mDomain = domain; mTransportType = transportType; mRegistrationState = registrationState; @@ -253,6 +258,7 @@ public final class NetworkRegistrationInfo implements Parcelable { mCellIdentity = cellIdentity; mEmergencyOnly = emergencyOnly; mNrState = NR_STATE_NONE; + mRplmn = rplmn; } /** @@ -263,11 +269,11 @@ public final class NetworkRegistrationInfo implements Parcelable { int registrationState, int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable List<Integer> availableServices, - @Nullable CellIdentity cellIdentity, boolean cssSupported, - int roamingIndicator, int systemIsInPrl, + @Nullable CellIdentity cellIdentity, @Nullable String rplmn, + boolean cssSupported, int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, - emergencyOnly, availableServices, cellIdentity); + emergencyOnly, availableServices, cellIdentity, rplmn); mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator, systemIsInPrl, defaultRoamingIndicator); @@ -281,13 +287,13 @@ public final class NetworkRegistrationInfo implements Parcelable { int registrationState, int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, @Nullable List<Integer> availableServices, - @Nullable CellIdentity cellIdentity, int maxDataCalls, - boolean isDcNrRestricted, boolean isNrAvailable, - boolean isEndcAvailable, + @Nullable CellIdentity cellIdentity, @Nullable String rplmn, + int maxDataCalls, boolean isDcNrRestricted, + boolean isNrAvailable, boolean isEndcAvailable, LteVopsSupportInfo lteVopsSupportInfo, boolean isUsingCarrierAggregation) { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, - emergencyOnly, availableServices, cellIdentity); + emergencyOnly, availableServices, cellIdentity, rplmn); mDataSpecificInfo = new DataSpecificRegistrationInfo( maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo, isUsingCarrierAggregation); @@ -310,6 +316,7 @@ public final class NetworkRegistrationInfo implements Parcelable { mDataSpecificInfo = source.readParcelable( DataSpecificRegistrationInfo.class.getClassLoader()); mNrState = source.readInt(); + mRplmn = source.readString(); } /** @@ -343,6 +350,7 @@ public final class NetworkRegistrationInfo implements Parcelable { mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo); } mNrState = nri.mNrState; + mRplmn = nri.mRplmn; } /** @@ -395,6 +403,22 @@ public final class NetworkRegistrationInfo implements Parcelable { } /** + * Get the PLMN-ID for this Network Registration, also known as the RPLMN. + * + * <p>If the device is registered, this will return the registered PLMN-ID. If registration + * has failed, then this will return the PLMN ID of the last attempted registration. If the + * device is not registered, or if is registered to a non-3GPP radio technology, then this + * will return null. + * + * <p>See 3GPP TS 23.122 for further information about the Registered PLMN. + * + * @return the registered PLMN-ID or null. + */ + @Nullable public String getRegisteredPlmn() { + return mRplmn; + } + + /** * @return {@code true} if registered on roaming network, {@code false} otherwise. */ public boolean isRoaming() { @@ -590,6 +614,7 @@ public final class NetworkRegistrationInfo implements Parcelable { .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo) .append(" dataSpecificInfo=").append(mDataSpecificInfo) .append(" nrState=").append(nrStateToString(mNrState)) + .append(" rRplmn=").append(mRplmn) .append("}").toString(); } @@ -597,7 +622,7 @@ public final class NetworkRegistrationInfo implements Parcelable { public int hashCode() { return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, - mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState); + mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn); } @Override @@ -620,6 +645,7 @@ public final class NetworkRegistrationInfo implements Parcelable { && Objects.equals(mCellIdentity, other.mCellIdentity) && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo) && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo) + && TextUtils.equals(mRplmn, other.mRplmn) && mNrState == other.mNrState; } @@ -641,6 +667,7 @@ public final class NetworkRegistrationInfo implements Parcelable { dest.writeParcelable(mVoiceSpecificInfo, 0); dest.writeParcelable(mDataSpecificInfo, 0); dest.writeInt(mNrState); + dest.writeString(mRplmn); } /** @@ -741,6 +768,9 @@ public final class NetworkRegistrationInfo implements Parcelable { @Nullable private CellIdentity mCellIdentity; + @NonNull + private String mRplmn = ""; + /** * Default constructor for Builder. */ @@ -855,6 +885,18 @@ public final class NetworkRegistrationInfo implements Parcelable { } /** + * Set the registered PLMN. + * + * @param rplmn the registered plmn. + * + * @return The same instance of the builder. + */ + public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) { + mRplmn = rplmn; + return this; + } + + /** * Build the NetworkRegistrationInfo. * @return the NetworkRegistrationInfo object. * @hide @@ -863,7 +905,7 @@ public final class NetworkRegistrationInfo implements Parcelable { public @NonNull NetworkRegistrationInfo build() { return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, - mCellIdentity); + mCellIdentity, mRplmn); } } } diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index 54c22ae282fb..708adebb6db3 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -265,10 +265,10 @@ public final class PreciseDataConnectionState implements Parcelable { /** * Return the APN Settings for this data connection. * - * Returns the ApnSetting that was used to configure this data connection. + * @return the ApnSetting that was used to configure this data connection. */ // FIXME: This shouldn't be nullable; update once the ApnSetting is supplied correctly - @Nullable ApnSetting getApnSetting() { + public @Nullable ApnSetting getApnSetting() { return mApnSetting; } diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 53ad70a07563..6fdc13e6a31b 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -492,6 +492,7 @@ public interface RILConstants { int RIL_REQUEST_ENABLE_UICC_APPLICATIONS = 208; int RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT = 209; int RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS = 210; + int RIL_REQUEST_GET_BARRING_INFO = 211; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800; @@ -557,4 +558,5 @@ public interface RILConstants { int RIL_UNSOL_EMERGENCY_NUMBER_LIST = 1102; int RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED = 1103; int RIL_UNSOL_REGISTRATION_FAILED = 1104; + int RIL_UNSOL_BARRING_INFO_CHANGED = 1105; } |