diff options
58 files changed, 1009 insertions, 329 deletions
diff --git a/Android.bp b/Android.bp index 977954f45c73..45a3d605f9b0 100644 --- a/Android.bp +++ b/Android.bp @@ -704,7 +704,7 @@ java_defaults { "android.hardware.vibrator-V1.2-java", "android.hardware.wifi-V1.0-java-constants", "networkstack-aidl-interfaces-java", - "netd_aidl_interface-java", + "netd_aidl_parcelables-java", ], required: [ @@ -1109,12 +1109,21 @@ packages_to_document = [ "org/apache/http/params", ] +// Make the api/current.txt file available for use by modules in other +// directories. +filegroup { + name: "frameworks-base-api-current.txt", + srcs: [ + "api/current.txt", + ], +} + framework_docs_only_args = " -android -manifest $(location core/res/AndroidManifest.xml) " + "-werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " + "-overview $(location core/java/overview.html) " + // Federate Support Library references against local API file. "-federate SupportLib https://developer.android.com " + - "-federationapi SupportLib $(location current/support-api.txt) " + "-federationapi SupportLib $(location :current-support-api) " framework_docs_only_libs = [ "voip-common", diff --git a/Android.mk b/Android.mk index 9a91dd1c491a..c58f7af1d7d5 100644 --- a/Android.mk +++ b/Android.mk @@ -77,8 +77,6 @@ docs offline-sdk-docs: $(OUT_DOCS)/offline-sdk-timestamp # Run this for checkbuild checkbuild: doc-comment-check-docs -# Check comment when you are updating the API -update-api: doc-comment-check-docs # ==== hiddenapi lists ======================================= ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true) diff --git a/api/current.txt b/api/current.txt index bcac6ad0b58b..172140fd653f 100755 --- a/api/current.txt +++ b/api/current.txt @@ -42350,6 +42350,7 @@ package android.telephony { method public String getMccString(); method public String getMncString(); method @Nullable public String getMobileNetworkOperator(); + method public int getUarfcn(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityTdscdma> CREATOR; } @@ -43017,12 +43018,12 @@ package android.telephony { method public boolean canChangeDtmfToneLength(); method @Nullable public android.telephony.TelephonyManager createForPhoneAccountHandle(android.telecom.PhoneAccountHandle); method public android.telephony.TelephonyManager createForSubscriptionId(int); - method @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public java.util.List<android.telephony.CellInfo> getAllCellInfo(); + method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public java.util.List<android.telephony.CellInfo> getAllCellInfo(); method public int getCallState(); method public int getCardIdForDefaultEuicc(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @WorkerThread public android.os.PersistableBundle getCarrierConfig(); method public int getCarrierIdFromSimMccMnc(); - method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.CellLocation getCellLocation(); + method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.telephony.CellLocation getCellLocation(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @Nullable public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getCurrentEmergencyNumberList(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @Nullable public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getCurrentEmergencyNumberList(int); method public int getDataActivity(); @@ -43052,7 +43053,7 @@ package android.telephony { method public int getPhoneCount(); method public int getPhoneType(); method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription(); - method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.ServiceState getServiceState(); + method @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState(); method @Nullable public android.telephony.SignalStrength getSignalStrength(); method public int getSimCarrierId(); method @Nullable public CharSequence getSimCarrierIdName(); @@ -43094,8 +43095,8 @@ package android.telephony { method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle); method public boolean isWorldPhone(); method public void listen(android.telephony.PhoneStateListener, int); - method @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback); + method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); + method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback); method public void sendDialerSpecialCode(String); method public String sendEnvelopeWithStatus(String); method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler); @@ -43163,7 +43164,6 @@ package android.telephony { field public static final String EXTRA_STATE_RINGING; field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.extra.SUBSCRIPTION_ID"; field public static final String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER"; - field public static final int INVALID_CARD_ID = -1; // 0xffffffff field public static final String METADATA_HIDE_VOICEMAIL_SETTINGS_MENU = "android.telephony.HIDE_VOICEMAIL_SETTINGS_MENU"; field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7 field public static final int NETWORK_TYPE_CDMA = 4; // 0x4 @@ -43199,7 +43199,9 @@ package android.telephony { field public static final int SIM_STATE_PUK_REQUIRED = 3; // 0x3 field public static final int SIM_STATE_READY = 5; // 0x5 field public static final int SIM_STATE_UNKNOWN = 0; // 0x0 + field public static final int UNINITIALIZED_CARD_ID = -2; // 0xfffffffe field public static final int UNKNOWN_CARRIER_ID = -1; // 0xffffffff + field public static final int UNSUPPORTED_CARD_ID = -1; // 0xffffffff field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe field public static final int USSD_RETURN_FAILURE = -1; // 0xffffffff field public static final String VVM_TYPE_CVVM = "vvm_type_cvvm"; diff --git a/api/removed.txt b/api/removed.txt index 05d52d4e40c0..72202ad9712a 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -540,7 +540,7 @@ package android.telephony { public class TelephonyManager { method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo(); - method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, android.telephony.TelephonyScanManager.NetworkScanCallback); + method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, android.telephony.TelephonyScanManager.NetworkScanCallback); } } diff --git a/api/system-current.txt b/api/system-current.txt index bd19daab4570..33cc4162ca54 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6352,6 +6352,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.util.Pair<java.lang.Integer,java.lang.Integer>> getLogicalToPhysicalSlotMapping(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmap(); method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState(); method public int getSimApplicationState(); @@ -6376,7 +6377,7 @@ package android.telephony { method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle); method public boolean needsOtaServiceProvisioning(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); - method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); + method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig(); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>); diff --git a/api/test-current.txt b/api/test-current.txt index 01127249c1fc..83119750df41 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -668,6 +668,7 @@ package android.net { method public int[] getCapabilities(); method public int[] getTransportTypes(); method public boolean satisfiedByNetworkCapabilities(android.net.NetworkCapabilities); + field public static final int TRANSPORT_TEST = 7; // 0x7 } public class NetworkStack { diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc index 1b3c32b20503..469c9646a4aa 100644 --- a/cmds/bootanimation/bootanim.rc +++ b/cmds/bootanimation/bootanim.rc @@ -2,7 +2,6 @@ service bootanim /system/bin/bootanimation class core animation user graphics group graphics audio - updatable disabled oneshot writepid /dev/stune/top-app/tasks diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index 236919866be3..dd21674ba2b4 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -603,8 +603,6 @@ Landroid/net/IConnectivityManager;->getTetherableWifiRegexs()[Ljava/lang/String; Landroid/net/IConnectivityManager;->getTetheredIfaces()[Ljava/lang/String; Landroid/net/IConnectivityManager;->getTetheringErroredIfaces()[Ljava/lang/String; Landroid/net/IConnectivityManager;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V -Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd; -Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V Landroid/net/INetworkPolicyListener$Stub;-><init>()V Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager; diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index c42a2bce2c48..4bbc12fbe63b 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -83,7 +83,6 @@ import android.net.IConnectivityManager; import android.net.IEthernetManager; import android.net.IIpMemoryStore; import android.net.IIpSecService; -import android.net.INetd; import android.net.INetworkPolicyManager; import android.net.IpMemoryStore; import android.net.IpSecManager; @@ -290,11 +289,10 @@ final class SystemServiceRegistry { return new ConnectivityManager(context, service); }}); - registerService(Context.NETD_SERVICE, INetd.class, new StaticServiceFetcher<INetd>() { + registerService(Context.NETD_SERVICE, IBinder.class, new StaticServiceFetcher<IBinder>() { @Override - public INetd createService() throws ServiceNotFoundException { - return INetd.Stub.asInterface( - ServiceManager.getServiceOrThrow(Context.NETD_SERVICE)); + public IBinder createService() throws ServiceNotFoundException { + return ServiceManager.getServiceOrThrow(Context.NETD_SERVICE); } }); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 68ac46c874ff..48f611d52c07 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -678,11 +678,20 @@ public class ConnectivityManager { @Deprecated public static final int TYPE_VPN = 17; + /** + * A network that is exclusively meant to be used for testing + * + * @deprecated Use {@link NetworkCapabilities} instead. + * @hide + */ + @Deprecated + public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused. + /** {@hide} */ - public static final int MAX_RADIO_TYPE = TYPE_VPN; + public static final int MAX_RADIO_TYPE = TYPE_TEST; /** {@hide} */ - public static final int MAX_NETWORK_TYPE = TYPE_VPN; + public static final int MAX_NETWORK_TYPE = TYPE_TEST; private static final int MIN_NETWORK_TYPE = TYPE_MOBILE; diff --git a/core/java/android/net/InterfaceConfiguration.java b/core/java/android/net/InterfaceConfiguration.java index 62cf7d7ceb25..b9d49c14f6c6 100644 --- a/core/java/android/net/InterfaceConfiguration.java +++ b/core/java/android/net/InterfaceConfiguration.java @@ -36,8 +36,9 @@ public class InterfaceConfiguration implements Parcelable { private LinkAddress mAddr; private HashSet<String> mFlags = Sets.newHashSet(); - private static final String FLAG_UP = INetd.IF_STATE_UP; - private static final String FLAG_DOWN = INetd.IF_STATE_DOWN; + // Must be kept in sync with constant in INetd.aidl + private static final String FLAG_UP = "up"; + private static final String FLAG_DOWN = "down"; private static final String[] EMPTY_STRING_ARRAY = new String[0]; diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 7e9bda14b199..1d2d81dc4fbe 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -597,6 +597,7 @@ public final class NetworkCapabilities implements Parcelable { TRANSPORT_VPN, TRANSPORT_WIFI_AWARE, TRANSPORT_LOWPAN, + TRANSPORT_TEST, }) public @interface Transport { } @@ -635,10 +636,18 @@ public final class NetworkCapabilities implements Parcelable { */ public static final int TRANSPORT_LOWPAN = 6; + /** + * Indicates this network uses a Test-only virtual interface as a transport. + * + * @hide + */ + @TestApi + public static final int TRANSPORT_TEST = 7; + /** @hide */ public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR; /** @hide */ - public static final int MAX_TRANSPORT = TRANSPORT_LOWPAN; + public static final int MAX_TRANSPORT = TRANSPORT_TEST; /** @hide */ public static boolean isValidTransport(@Transport int transportType) { @@ -652,7 +661,8 @@ public final class NetworkCapabilities implements Parcelable { "ETHERNET", "VPN", "WIFI_AWARE", - "LOWPAN" + "LOWPAN", + "TEST" }; /** diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 5ab34e9aa6e8..bf272625e713 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -92,16 +92,6 @@ public class NetworkPolicyManager { public static final int MASK_ALL_NETWORKS = 0b11110000; public static final int FIREWALL_RULE_DEFAULT = 0; - public static final int FIREWALL_RULE_ALLOW = INetd.FIREWALL_RULE_ALLOW; - public static final int FIREWALL_RULE_DENY = INetd.FIREWALL_RULE_DENY; - - public static final int FIREWALL_TYPE_WHITELIST = INetd.FIREWALL_WHITELIST; - public static final int FIREWALL_TYPE_BLACKLIST = INetd.FIREWALL_BLACKLIST; - - public static final int FIREWALL_CHAIN_NONE = INetd.FIREWALL_CHAIN_NONE; - public static final int FIREWALL_CHAIN_DOZABLE = INetd.FIREWALL_CHAIN_DOZABLE; - public static final int FIREWALL_CHAIN_STANDBY = INetd.FIREWALL_CHAIN_STANDBY; - public static final int FIREWALL_CHAIN_POWERSAVE = INetd.FIREWALL_CHAIN_POWERSAVE; public static final String FIREWALL_CHAIN_NAME_NONE = "none"; public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable"; diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 1f3369376b10..a851e04e78ec 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -21,13 +21,14 @@ import android.annotation.Nullable; import android.annotation.WorkerThread; import java.util.ArrayDeque; -import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -190,13 +191,19 @@ import java.util.concurrent.atomic.AtomicInteger; public abstract class AsyncTask<Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; - private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); - // We want at least 2 threads and at most 4 threads in the core pool, - // preferring to have 1 less than the CPU count to avoid saturating - // the CPU with background work - private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); - private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; - private static final int KEEP_ALIVE_SECONDS = 30; + // We keep only a single pool thread around all the time. + // We let the pool grow to a fairly large number of threads if necessary, + // but let them time out quickly. In the unlikely case that we run out of threads, + // we fall back to a simple unbounded-queue executor. + // This combination ensures that: + // 1. We normally keep few threads (1) around. + // 2. We queue only after launching a significantly larger, but still bounded, set of threads. + // 3. We keep the total number of threads bounded, but still allow an unbounded set + // of tasks to be queued. + private static final int CORE_POOL_SIZE = 1; + private static final int MAXIMUM_POOL_SIZE = 20; + private static final int BACKUP_POOL_SIZE = 5; + private static final int KEEP_ALIVE_SECONDS = 3; private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); @@ -206,8 +213,29 @@ public abstract class AsyncTask<Params, Progress, Result> { } }; - private static final BlockingQueue<Runnable> sPoolWorkQueue = - new LinkedBlockingQueue<Runnable>(128); + // Used only for rejected executions. + // Initialization protected by sRunOnSerialPolicy lock. + private static ThreadPoolExecutor sBackupExecutor; + private static LinkedBlockingQueue<Runnable> sBackupExecutorQueue; + + private static final RejectedExecutionHandler sRunOnSerialPolicy = + new RejectedExecutionHandler() { + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { + android.util.Log.w(LOG_TAG, "Exceeded ThreadPoolExecutor pool size"); + // As a last ditch fallback, run it on an executor with an unbounded queue. + // Create this executor lazily, hopefully almost never. + synchronized (this) { + if (sBackupExecutor == null) { + sBackupExecutorQueue = new LinkedBlockingQueue<Runnable>(); + sBackupExecutor = new ThreadPoolExecutor( + BACKUP_POOL_SIZE, BACKUP_POOL_SIZE, KEEP_ALIVE_SECONDS, + TimeUnit.SECONDS, sBackupExecutorQueue, sThreadFactory); + sBackupExecutor.allowCoreThreadTimeOut(true); + } + } + sBackupExecutor.execute(r); + } + }; /** * An {@link Executor} that can be used to execute tasks in parallel. @@ -217,8 +245,8 @@ public abstract class AsyncTask<Params, Progress, Result> { static { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, - sPoolWorkQueue, sThreadFactory); - threadPoolExecutor.allowCoreThreadTimeOut(true); + new SynchronousQueue<Runnable>(), sThreadFactory); + threadPoolExecutor.setRejectedExecutionHandler(sRunOnSerialPolicy); THREAD_POOL_EXECUTOR = threadPoolExecutor; } diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 8492b0cf58e2..3ee54ceebaa9 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -32,6 +32,7 @@ import android.content.pm.PackageManager; import android.provider.Settings; import android.telephony.euicc.EuiccManager; import android.text.TextUtils; +import android.text.format.DateFormat; import android.util.Log; import android.view.Display; import android.view.WindowManager; @@ -762,7 +763,8 @@ public class RecoverySystem { String reasonArg = null; if (!TextUtils.isEmpty(reason)) { - reasonArg = "--reason=" + sanitizeArg(reason); + String timeStamp = DateFormat.format("yyyy-MM-ddTHH:mm:ssZ", System.currentTimeMillis()).toString(); + reasonArg = "--reason=" + sanitizeArg(reason + "," + timeStamp); } final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ; diff --git a/core/java/android/os/connectivity/CellularBatteryStats.java b/core/java/android/os/connectivity/CellularBatteryStats.java index 2593c85cff12..c99ecb32d418 100644 --- a/core/java/android/os/connectivity/CellularBatteryStats.java +++ b/core/java/android/os/connectivity/CellularBatteryStats.java @@ -44,6 +44,7 @@ public final class CellularBatteryStats implements Parcelable { private long[] mTimeInRatMs; private long[] mTimeInRxSignalStrengthLevelMs; private long[] mTxTimeMs; + private long mMonitoredRailChargeConsumedMaMs; public static final Parcelable.Creator<CellularBatteryStats> CREATOR = new Parcelable.Creator<CellularBatteryStats>() { @@ -74,6 +75,7 @@ public final class CellularBatteryStats implements Parcelable { out.writeLongArray(mTimeInRatMs); out.writeLongArray(mTimeInRxSignalStrengthLevelMs); out.writeLongArray(mTxTimeMs); + out.writeLong(mMonitoredRailChargeConsumedMaMs); } public void readFromParcel(Parcel in) { @@ -90,6 +92,7 @@ public final class CellularBatteryStats implements Parcelable { in.readLongArray(mTimeInRatMs); in.readLongArray(mTimeInRxSignalStrengthLevelMs); in.readLongArray(mTxTimeMs); + mMonitoredRailChargeConsumedMaMs = in.readLong(); } public long getLoggingDurationMs() { @@ -144,6 +147,10 @@ public final class CellularBatteryStats implements Parcelable { return mTxTimeMs; } + public long getMonitoredRailChargeConsumedMaMs() { + return mMonitoredRailChargeConsumedMaMs; + } + public void setLoggingDurationMs(long t) { mLoggingDurationMs = t; return; @@ -211,6 +218,11 @@ public final class CellularBatteryStats implements Parcelable { return; } + public void setMonitoredRailChargeConsumedMaMs(long monitoredRailEnergyConsumedMaMs) { + mMonitoredRailChargeConsumedMaMs = monitoredRailEnergyConsumedMaMs; + return; + } + public int describeContents() { return 0; } @@ -237,6 +249,7 @@ public final class CellularBatteryStats implements Parcelable { Arrays.fill(mTimeInRxSignalStrengthLevelMs, 0); mTxTimeMs = new long[ModemActivityInfo.TX_POWER_LEVELS]; Arrays.fill(mTxTimeMs, 0); + mMonitoredRailChargeConsumedMaMs = 0; return; } }
\ No newline at end of file diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java index b84e556cc552..53cc25b14285 100644 --- a/core/java/android/service/euicc/EuiccService.java +++ b/core/java/android/service/euicc/EuiccService.java @@ -76,6 +76,11 @@ import java.util.concurrent.atomic.AtomicInteger; * filter with the appropriate action, the {@link #CATEGORY_EUICC_UI} category, and a non-zero * priority. * + * <p>Old implementations of EuiccService may support passing in slot IDs equal to + * {@link android.telephony.SubscriptionManager#INVALID_SIM_SLOT_INDEX}, which allows the LPA to + * decide which eUICC to target when there are multiple eUICCs. This behavior is not supported in + * Android Q or later. + * * @hide */ @SystemApi @@ -520,7 +525,7 @@ public abstract class EuiccService extends Service { int resultCode = EuiccService.this.onDownloadSubscription( slotId, subscription, switchAfterDownload, forceDeactivateSim); result = new DownloadSubscriptionResult(resultCode, - 0 /* resolvableErrors */, TelephonyManager.INVALID_CARD_ID); + 0 /* resolvableErrors */, TelephonyManager.UNSUPPORTED_CARD_ID); } try { callback.onComplete(result); diff --git a/core/jni/Android.bp b/core/jni/Android.bp index c81a77d4c16e..08a5789743cc 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -278,8 +278,8 @@ cc_library_shared { "libsoundtrigger", "libminikin", "libprocessgroup", - "libnativebridge", - "libnativeloader", + "libnativebridge_lazy", + "libnativeloader_lazy", "libmemunreachable", "libhidlbase", "libhidltransport", diff --git a/core/jni/OWNERS b/core/jni/OWNERS index 774c2242e144..7ff15f2e182d 100644 --- a/core/jni/OWNERS +++ b/core/jni/OWNERS @@ -6,4 +6,4 @@ per-file *Camera*,*camera* = shuzhenwang@google.com, yinchiayeh@google.com, zhij per-file android_net_* = codewiz@google.com, jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com # Zygote -per-file com_android_inernal_os_Zygote.*,fd_utils.* = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com +per-file com_android_internal_os_Zygote.*,fd_utils.* = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp new file mode 100644 index 000000000000..c0ac2cb8f800 --- /dev/null +++ b/core/proto/android/server/connectivity/Android.bp @@ -0,0 +1,25 @@ +// Copyright (C) 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. + +java_library_static { + name: "datastallprotosnano", + proto: { + type: "nano", + }, + srcs: [ + "data_stall_event.proto", + ], + sdk_version: "system_current", + no_framework_libs: true, +}
\ No newline at end of file diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index 9b70ff368afb..2c9b6eb72b4d 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -174,6 +174,7 @@ public class CaptivePortalLoginActivity extends Activity { webSettings.setSupportZoom(true); webSettings.setBuiltInZoomControls(true); webSettings.setDisplayZoomControls(false); + webSettings.setDomStorageEnabled(true); mWebViewClient = new MyWebViewClient(); webview.setWebViewClient(mWebViewClient); webview.setWebChromeClient(new MyWebChromeClient()); diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java index 4f67350b5adc..31549fa0d1bb 100644 --- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java +++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java @@ -106,6 +106,7 @@ public class CaptivePortalLoginActivity extends Activity { webSettings.setLoadWithOverviewMode(true); webSettings.setSupportZoom(true); webSettings.setBuiltInZoomControls(true); + webSettings.setDomStorageEnabled(true); mWebViewClient = new MyWebViewClient(); mWebView.setWebViewClient(mWebViewClient); mWebView.setWebChromeClient(new MyWebChromeClient()); diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml index e4d35915c77c..860ebfbf6da7 100644 --- a/packages/NetworkStack/AndroidManifest.xml +++ b/packages/NetworkStack/AndroidManifest.xml @@ -31,6 +31,7 @@ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> <uses-permission android:name="android.permission.NETWORK_STACK" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> <application android:label="NetworkStack" android:defaultToDeviceProtectedStorage="true" diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java index 9e5991298834..b1f6d246563e 100644 --- a/packages/NetworkStack/src/android/net/ip/IpClient.java +++ b/packages/NetworkStack/src/android/net/ip/IpClient.java @@ -46,6 +46,7 @@ import android.net.shared.ProvisioningConfiguration; import android.net.util.InterfaceParams; import android.net.util.SharedLog; import android.os.ConditionVariable; +import android.os.IBinder; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; @@ -380,6 +381,13 @@ public class IpClient extends StateMachine { public InterfaceParams getInterfaceParams(String ifname) { return InterfaceParams.getByName(ifname); } + + /** + * Get a INetd connector. + */ + public INetd getNetd(Context context) { + return INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)); + } } public IpClient(Context context, String ifName, IIpClientCallbacks callback, @@ -413,7 +421,7 @@ public class IpClient extends StateMachine { // TODO: Consider creating, constructing, and passing in some kind of // InterfaceController.Dependencies class. - mNetd = mContext.getSystemService(INetd.class); + mNetd = deps.getNetd(mContext); mInterfaceCtrl = new InterfaceController(mInterfaceName, mNetd, mLog); mLinkObserver = new IpClientLinkObserver( diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java index cedcb84e9d08..c6a207f26577 100644 --- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java +++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java @@ -114,7 +114,8 @@ public class NetworkStackService extends Service { NetworkStackConnector(Context context) { mContext = context; - mNetd = (INetd) context.getSystemService(Context.NETD_SERVICE); + mNetd = INetd.Stub.asInterface( + (IBinder) context.getSystemService(Context.NETD_SERVICE)); mObserverRegistry = new NetworkObserverRegistry(); mCm = context.getSystemService(ConnectivityManager.class); diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java index 2e72d8296a37..b9e901b5c5e3 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java @@ -67,15 +67,9 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; -import android.telephony.CellIdentityCdma; -import android.telephony.CellIdentityGsm; -import android.telephony.CellIdentityLte; -import android.telephony.CellIdentityWcdma; -import android.telephony.CellInfo; -import android.telephony.CellInfoCdma; -import android.telephony.CellInfoGsm; -import android.telephony.CellInfoLte; -import android.telephony.CellInfoWcdma; +import android.telephony.AccessNetworkConstants; +import android.telephony.NetworkRegistrationState; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; @@ -1312,6 +1306,7 @@ public class NetworkMonitor extends StateMachine { urlConnection.setInstanceFollowRedirects(probeType == ValidationProbeEvent.PROBE_PAC); urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS); urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS); + urlConnection.setRequestProperty("Connection", "close"); urlConnection.setUseCaches(false); if (mCaptivePortalUserAgent != null) { urlConnection.setRequestProperty("User-Agent", mCaptivePortalUserAgent); @@ -1485,10 +1480,6 @@ public class NetworkMonitor extends StateMachine { */ private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal, long requestTimestampMs, long responseTimestampMs) { - if (!mWifiManager.isScanAlwaysAvailable()) { - return; - } - if (!mSystemReady) { return; } @@ -1496,6 +1487,10 @@ public class NetworkMonitor extends StateMachine { Intent latencyBroadcast = new Intent(NetworkMonitorUtils.ACTION_NETWORK_CONDITIONS_MEASURED); if (mNetworkCapabilities.hasTransport(TRANSPORT_WIFI)) { + if (!mWifiManager.isScanAlwaysAvailable()) { + return; + } + WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo(); if (currentWifiInfo != null) { // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not @@ -1515,39 +1510,21 @@ public class NetworkMonitor extends StateMachine { } latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_WIFI); } else if (mNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { + // TODO(b/123893112): Support multi-sim. latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_NETWORK_TYPE, mTelephonyManager.getNetworkType()); - List<CellInfo> info = mTelephonyManager.getAllCellInfo(); - if (info == null) return; - int numRegisteredCellInfo = 0; - for (CellInfo cellInfo : info) { - if (cellInfo.isRegistered()) { - numRegisteredCellInfo++; - if (numRegisteredCellInfo > 1) { - if (VDBG) { - logw("more than one registered CellInfo." - + " Can't tell which is active. Bailing."); - } - return; - } - if (cellInfo instanceof CellInfoCdma) { - CellIdentityCdma cellId = ((CellInfoCdma) cellInfo).getCellIdentity(); - latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CELL_ID, cellId); - } else if (cellInfo instanceof CellInfoGsm) { - CellIdentityGsm cellId = ((CellInfoGsm) cellInfo).getCellIdentity(); - latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CELL_ID, cellId); - } else if (cellInfo instanceof CellInfoLte) { - CellIdentityLte cellId = ((CellInfoLte) cellInfo).getCellIdentity(); - latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CELL_ID, cellId); - } else if (cellInfo instanceof CellInfoWcdma) { - CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity(); - latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CELL_ID, cellId); - } else { - if (VDBG) logw("Registered cellinfo is unrecognized"); - return; - } - } + final ServiceState dataSs = mTelephonyManager.getServiceState(); + if (dataSs == null) { + logw("failed to retrieve ServiceState"); + return; } + // See if the data sub is registered for PS services on cell. + final NetworkRegistrationState nrs = dataSs.getNetworkRegistrationState( + NetworkRegistrationState.DOMAIN_PS, + AccessNetworkConstants.TransportType.WWAN); + latencyBroadcast.putExtra( + NetworkMonitorUtils.EXTRA_CELL_ID, + nrs == null ? null : nrs.getCellIdentity()); latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_MOBILE); } else { return; diff --git a/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java index 7e57d1eb00b0..aaaff0279fed 100644 --- a/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java +++ b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java @@ -104,8 +104,8 @@ public class IpClientTest { when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm); when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm); - when(mContext.getSystemService(INetd.class)).thenReturn(mNetd); when(mContext.getResources()).thenReturn(mResources); + when(mDependencies.getNetd(any())).thenReturn(mNetd); when(mResources.getInteger(R.integer.config_networkAvoidBadWifi)) .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE); diff --git a/packages/SettingsLib/common.mk b/packages/SettingsLib/common.mk index 8d24eaba5cc4..8c309ff97370 100644 --- a/packages/SettingsLib/common.mk +++ b/packages/SettingsLib/common.mk @@ -31,4 +31,3 @@ LOCAL_STATIC_ANDROID_LIBRARIES += \ androidx.legacy_legacy-preference-v14 \ SettingsLib -LOCAL_RESOURCE_DIR += $(call my-dir)/res diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index af2bbfbb1dc3..9b4cd230427f 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2832,6 +2832,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) { log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests()); } + // Clear all notifications of this network. + mNotifier.clearNotification(nai.network.netId); // A network agent has disconnected. // TODO - if we move the logic to the network agent (have them disconnect // because they lost all their requests or because their score isn't good) diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index da4df22d7b02..a4fda8e9f57b 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -20,18 +20,18 @@ import static android.Manifest.permission.CONNECTIVITY_INTERNAL; import static android.Manifest.permission.NETWORK_SETTINGS; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.SHUTDOWN; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_BLACKLIST; +import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_NONE; +import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; +import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.INetd.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_RULE_DENY; +import static android.net.INetd.FIREWALL_WHITELIST; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; -import static android.net.NetworkPolicyManager.FIREWALL_TYPE_BLACKLIST; -import static android.net.NetworkPolicyManager.FIREWALL_TYPE_WHITELIST; import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.STATS_PER_UID; import static android.net.NetworkStats.TAG_ALL; @@ -1941,7 +1941,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub int numUids = 0; if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName); - if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { + if (getFirewallType(chain) == FIREWALL_WHITELIST) { // Close all sockets on all non-system UIDs... ranges = new UidRange[] { // TODO: is there a better way of finding all existing users? If so, we could @@ -1953,7 +1953,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub final SparseIntArray rules = getUidFirewallRulesLR(chain); exemptUids = new int[rules.size()]; for (int i = 0; i < exemptUids.length; i++) { - if (rules.valueAt(i) == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { + if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) { exemptUids[numUids] = rules.keyAt(i); numUids++; } @@ -1975,7 +1975,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub final SparseIntArray rules = getUidFirewallRulesLR(chain); ranges = new UidRange[rules.size()]; for (int i = 0; i < ranges.length; i++) { - if (rules.valueAt(i) == NetworkPolicyManager.FIREWALL_RULE_DENY) { + if (rules.valueAt(i) == FIREWALL_RULE_DENY) { int uid = rules.keyAt(i); ranges[numUids] = new UidRange(uid, uid); numUids++; @@ -2047,13 +2047,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub private int getFirewallType(int chain) { switch (chain) { case FIREWALL_CHAIN_STANDBY: - return FIREWALL_TYPE_BLACKLIST; + return FIREWALL_BLACKLIST; case FIREWALL_CHAIN_DOZABLE: - return FIREWALL_TYPE_WHITELIST; + return FIREWALL_WHITELIST; case FIREWALL_CHAIN_POWERSAVE: - return FIREWALL_TYPE_WHITELIST; + return FIREWALL_WHITELIST; default: - return isFirewallEnabled() ? FIREWALL_TYPE_WHITELIST : FIREWALL_TYPE_BLACKLIST; + return isFirewallEnabled() ? FIREWALL_WHITELIST : FIREWALL_BLACKLIST; } } @@ -2155,14 +2155,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub private @NonNull String getFirewallRuleName(int chain, int rule) { String ruleName; - if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { - if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { + if (getFirewallType(chain) == FIREWALL_WHITELIST) { + if (rule == FIREWALL_RULE_ALLOW) { ruleName = "allow"; } else { ruleName = "deny"; } } else { // Blacklist mode - if (rule == NetworkPolicyManager.FIREWALL_RULE_DENY) { + if (rule == FIREWALL_RULE_DENY) { ruleName = "deny"; } else { ruleName = "allow"; @@ -2188,7 +2188,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub private int getFirewallRuleType(int chain, int rule) { if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { - return getFirewallType(chain) == FIREWALL_TYPE_WHITELIST + return getFirewallType(chain) == FIREWALL_WHITELIST ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW; } return rule; diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 43af36f86f3d..3b5c9f53d9a1 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.net.LinkProperties; import android.net.NetworkCapabilities; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -246,7 +247,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private PreciseDataConnectionState mPreciseDataConnectionState = new PreciseDataConnectionState(); - static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = + // Nothing here yet, but putting it here in case we want to add more in the future. + static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = 0; + + static final int ENFORCE_FINE_LOCATION_PERMISSION_MASK = PhoneStateListener.LISTEN_CELL_LOCATION | PhoneStateListener.LISTEN_CELL_INFO; @@ -637,8 +641,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { try { if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]); - r.callback.onServiceStateChanged( - new ServiceState(mServiceState[phoneId])); + ServiceState rawSs = new ServiceState(mServiceState[phoneId]); + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { + r.callback.onServiceStateChanged(rawSs); + } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { + r.callback.onServiceStateChanged(rawSs.sanitizeLocationInfo(false)); + } else { + r.callback.onServiceStateChanged(rawSs.sanitizeLocationInfo(true)); + } } catch (RemoteException ex) { remove(r.binder); } @@ -673,7 +683,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("listen: mCellLocation = " + mCellLocation[phoneId]); - if (checkLocationAccess(r)) { + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onCellLocationChanged( new Bundle(mCellLocation[phoneId])); } @@ -722,7 +732,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = " + mCellInfo.get(phoneId)); - if (checkLocationAccess(r)) { + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); } } catch (RemoteException ex) { @@ -1009,13 +1019,22 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) && idMatch(r.subId, subId, phoneId)) { + try { + ServiceState stateToSend; + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { + stateToSend = new ServiceState(state); + } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { + stateToSend = state.sanitizeLocationInfo(false); + } else { + stateToSend = state.sanitizeLocationInfo(true); + } if (DBG) { log("notifyServiceStateForSubscriber: callback.onSSC r=" + r + " subId=" + subId + " phoneId=" + phoneId + " state=" + state); } - r.callback.onServiceStateChanged(new ServiceState(state)); + r.callback.onServiceStateChanged(stateToSend); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -1198,7 +1217,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) && idMatch(r.subId, subId, phoneId) && - checkLocationAccess(r)) { + checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { try { if (DBG_LOC) { log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r); @@ -1500,7 +1519,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && idMatch(r.subId, subId, phoneId) && - checkLocationAccess(r)) { + checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { try { if (DBG_LOC) { log("notifyCellLocation: cellLocation=" + cellLocation @@ -2109,12 +2128,35 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private boolean checkListenerPermission( int events, int subId, String callingPackage, String message) { + LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder = + new LocationAccessPolicy.LocationPermissionQuery.Builder() + .setCallingPackage(callingPackage) + .setMethod(message + " events: " + events) + .setCallingPid(Binder.getCallingPid()) + .setCallingUid(Binder.getCallingUid()); + + boolean shouldCheckLocationPermissions = false; if ((events & ENFORCE_COARSE_LOCATION_PERMISSION_MASK) != 0) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.ACCESS_COARSE_LOCATION, null); - if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), - callingPackage) != AppOpsManager.MODE_ALLOWED) { - return false; + locationQueryBuilder.setMinSdkVersionForCoarse(0); + shouldCheckLocationPermissions = true; + } + + if ((events & ENFORCE_FINE_LOCATION_PERMISSION_MASK) != 0) { + // Everything that requires fine location started in Q. So far... + locationQueryBuilder.setMinSdkVersionForFine(Build.VERSION_CODES.Q); + shouldCheckLocationPermissions = true; + } + + if (shouldCheckLocationPermissions) { + LocationAccessPolicy.LocationPermissionResult result = + LocationAccessPolicy.checkLocationPermission( + mContext, locationQueryBuilder.build()); + switch (result) { + case DENIED_HARD: + throw new SecurityException("Unable to listen for events " + events + " due to " + + "insufficient location permissions."); + case DENIED_SOFT: + return false; } } @@ -2229,15 +2271,38 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - private boolean checkLocationAccess(Record r) { - long token = Binder.clearCallingIdentity(); - try { - return LocationAccessPolicy.canAccessCellLocation(mContext, - r.callingPackage, r.callerUid, r.callerPid, - /*throwOnDeniedPermission*/ false); - } finally { - Binder.restoreCallingIdentity(token); - } + private boolean checkFineLocationAccess(Record r, int minSdk) { + LocationAccessPolicy.LocationPermissionQuery query = + new LocationAccessPolicy.LocationPermissionQuery.Builder() + .setCallingPackage(r.callingPackage) + .setCallingPid(r.callerPid) + .setCallingUid(r.callerUid) + .setMethod("TelephonyRegistry push") + .setMinSdkVersionForFine(minSdk) + .build(); + + return Binder.withCleanCallingIdentity(() -> { + LocationAccessPolicy.LocationPermissionResult locationResult = + LocationAccessPolicy.checkLocationPermission(mContext, query); + return locationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED; + }); + } + + private boolean checkCoarseLocationAccess(Record r, int minSdk) { + LocationAccessPolicy.LocationPermissionQuery query = + new LocationAccessPolicy.LocationPermissionQuery.Builder() + .setCallingPackage(r.callingPackage) + .setCallingPid(r.callerPid) + .setCallingUid(r.callerUid) + .setMethod("TelephonyRegistry push") + .setMinSdkVersionForCoarse(minSdk) + .build(); + + return Binder.withCleanCallingIdentity(() -> { + LocationAccessPolicy.LocationPermissionResult locationResult = + LocationAccessPolicy.checkLocationPermission(mContext, query); + return locationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED; + }); } private void checkPossibleMissNotify(Record r, int phoneId) { @@ -2287,7 +2352,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " + mCellInfo.get(phoneId)); } - if (checkLocationAccess(r)) { + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); } } catch (RemoteException ex) { @@ -2337,7 +2402,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " + mCellLocation[phoneId]); - if (checkLocationAccess(r)) { + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); } } catch (RemoteException ex) { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 455a3e302480..e698b841a2fd 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3260,6 +3260,21 @@ public class AudioService extends IAudioService.Stub if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) { return; } + + if (mContext.checkCallingOrSelfPermission( + android.Manifest.permission.MODIFY_PHONE_STATE) + != PackageManager.PERMISSION_GRANTED) { + synchronized (mSetModeDeathHandlers) { + for (SetModeDeathHandler h : mSetModeDeathHandlers) { + if (h.getMode() == AudioSystem.MODE_IN_CALL) { + Log.w(TAG, "getMode is call, Permission Denial: setSpeakerphoneOn from pid=" + + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); + return; + } + } + } + } + // for logging only final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on) .append(") from u/pid:").append(Binder.getCallingUid()).append("/") diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index a14fd17209e8..19bdc0969e6d 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -96,6 +96,7 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; @@ -180,6 +181,7 @@ public class Tethering extends BaseNetworkObserver { // into a single coherent structure. private final HashSet<IpServer> mForwardedDownstreams; private final VersionedBroadcastListener mCarrierConfigChange; + private final VersionedBroadcastListener mDefaultSubscriptionChange; private final TetheringDependencies mDeps; private final EntitlementManager mEntitlementMgr; @@ -232,6 +234,15 @@ public class Tethering extends BaseNetworkObserver { mEntitlementMgr.reevaluateSimCardProvisioning(); }); + filter = new IntentFilter(); + filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); + mDefaultSubscriptionChange = new VersionedBroadcastListener( + "DefaultSubscriptionChangeListener", mContext, smHandler, filter, + (Intent ignored) -> { + mLog.log("OBSERVED default data subscription change"); + updateConfiguration(); + mEntitlementMgr.reevaluateSimCardProvisioning(); + }); mStateReceiver = new StateReceiver(); // Load tethering configuration. @@ -242,6 +253,7 @@ public class Tethering extends BaseNetworkObserver { private void startStateMachineUpdaters() { mCarrierConfigChange.startListening(); + mDefaultSubscriptionChange.startListening(); final Handler handler = mTetherMasterSM.getHandler(); IntentFilter filter = new IntentFilter(); @@ -270,7 +282,8 @@ public class Tethering extends BaseNetworkObserver { // NOTE: This is always invoked on the mLooper thread. private void updateConfiguration() { - mConfig = new TetheringConfiguration(mContext, mLog); + final int subId = mDeps.getDefaultDataSubscriptionId(); + mConfig = new TetheringConfiguration(mContext, mLog, subId); mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); mEntitlementMgr.updateConfiguration(mConfig); } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java index 1e6bb04858a1..8a46ff18979f 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java @@ -26,8 +26,8 @@ import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; import static com.android.internal.R.array.config_mobile_hotspot_provision_app; import static com.android.internal.R.array.config_tether_bluetooth_regexs; import static com.android.internal.R.array.config_tether_dhcp_range; -import static com.android.internal.R.array.config_tether_usb_regexs; import static com.android.internal.R.array.config_tether_upstream_types; +import static com.android.internal.R.array.config_tether_usb_regexs; import static com.android.internal.R.array.config_tether_wifi_regexs; import static com.android.internal.R.bool.config_tether_upstream_automatic; import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui; @@ -38,6 +38,7 @@ import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.util.SharedLog; import android.provider.Settings; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -100,29 +101,34 @@ public class TetheringConfiguration { public final String[] provisioningApp; public final String provisioningAppNoUi; - public TetheringConfiguration(Context ctx, SharedLog log) { + public final int subId; + + public TetheringConfiguration(Context ctx, SharedLog log, int id) { final SharedLog configLog = log.forSubComponent("config"); - tetherableUsbRegexs = getResourceStringArray(ctx, config_tether_usb_regexs); + subId = id; + Resources res = getResources(ctx, subId); + + tetherableUsbRegexs = getResourceStringArray(res, config_tether_usb_regexs); // TODO: Evaluate deleting this altogether now that Wi-Fi always passes // us an interface name. Careful consideration needs to be given to // implications for Settings and for provisioning checks. - tetherableWifiRegexs = getResourceStringArray(ctx, config_tether_wifi_regexs); - tetherableBluetoothRegexs = getResourceStringArray(ctx, config_tether_bluetooth_regexs); + tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs); + tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs); dunCheck = checkDunRequired(ctx); configLog.log("DUN check returned: " + dunCheckString(dunCheck)); - chooseUpstreamAutomatically = getResourceBoolean(ctx, config_tether_upstream_automatic); - preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(ctx, dunCheck); + chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic); + preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, dunCheck); isDunRequired = preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN); - legacyDhcpRanges = getLegacyDhcpRanges(ctx); + legacyDhcpRanges = getLegacyDhcpRanges(res); defaultIPv4DNS = copy(DEFAULT_IPV4_DNS); enableLegacyDhcpServer = getEnableLegacyDhcpServer(ctx); - provisioningApp = getResourceStringArray(ctx, config_mobile_hotspot_provision_app); - provisioningAppNoUi = getProvisioningAppNoUi(ctx); + provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app); + provisioningAppNoUi = getProvisioningAppNoUi(res); configLog.log(toString()); } @@ -144,6 +150,9 @@ public class TetheringConfiguration { } public void dump(PrintWriter pw) { + pw.print("subId: "); + pw.println(subId); + dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs); dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs); dumpStringArray(pw, "tetherableBluetoothRegexs", tetherableBluetoothRegexs); @@ -169,6 +178,7 @@ public class TetheringConfiguration { public String toString() { final StringJoiner sj = new StringJoiner(" "); + sj.add(String.format("subId:%d", subId)); sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs))); sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs))); sj.add(String.format("tetherableBluetoothRegexs:%s", @@ -235,8 +245,8 @@ public class TetheringConfiguration { } } - private static Collection<Integer> getUpstreamIfaceTypes(Context ctx, int dunCheck) { - final int ifaceTypes[] = ctx.getResources().getIntArray(config_tether_upstream_types); + private static Collection<Integer> getUpstreamIfaceTypes(Resources res, int dunCheck) { + final int[] ifaceTypes = res.getIntArray(config_tether_upstream_types); final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length); for (int i : ifaceTypes) { switch (i) { @@ -286,33 +296,33 @@ public class TetheringConfiguration { return false; } - private static String[] getLegacyDhcpRanges(Context ctx) { - final String[] fromResource = getResourceStringArray(ctx, config_tether_dhcp_range); + private static String[] getLegacyDhcpRanges(Resources res) { + final String[] fromResource = getResourceStringArray(res, config_tether_dhcp_range); if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) { return fromResource; } return copy(LEGACY_DHCP_DEFAULT_RANGE); } - private static String getProvisioningAppNoUi(Context ctx) { + private static String getProvisioningAppNoUi(Resources res) { try { - return ctx.getResources().getString(config_mobile_hotspot_provision_app_no_ui); + return res.getString(config_mobile_hotspot_provision_app_no_ui); } catch (Resources.NotFoundException e) { return ""; } } - private static boolean getResourceBoolean(Context ctx, int resId) { + private static boolean getResourceBoolean(Resources res, int resId) { try { - return ctx.getResources().getBoolean(resId); + return res.getBoolean(resId); } catch (Resources.NotFoundException e404) { return false; } } - private static String[] getResourceStringArray(Context ctx, int resId) { + private static String[] getResourceStringArray(Resources res, int resId) { try { - final String[] strArray = ctx.getResources().getStringArray(resId); + final String[] strArray = res.getStringArray(resId); return (strArray != null) ? strArray : EMPTY_STRING_ARRAY; } catch (Resources.NotFoundException e404) { return EMPTY_STRING_ARRAY; @@ -325,6 +335,19 @@ public class TetheringConfiguration { return intVal != 0; } + private Resources getResources(Context ctx, int subId) { + if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + return getResourcesForSubIdWrapper(ctx, subId); + } else { + return ctx.getResources(); + } + } + + @VisibleForTesting + protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) { + return SubscriptionManager.getResourcesForSubId(ctx, subId); + } + private static String[] copy(String[] strarray) { return Arrays.copyOf(strarray, strarray.length); } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java index 6d6f81eb98e6..3fddac111ec5 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java @@ -21,6 +21,7 @@ import android.net.NetworkRequest; import android.net.ip.IpServer; import android.net.util.SharedLog; import android.os.Handler; +import android.telephony.SubscriptionManager; import com.android.internal.util.StateMachine; import com.android.server.connectivity.MockableSystemProperties; @@ -85,4 +86,11 @@ public class TetheringDependencies { SharedLog log, MockableSystemProperties systemProperties) { return new EntitlementManager(ctx, target, log, systemProperties); } + + /** + * Get default data subscription id to build TetheringConfiguration. + */ + public int getDefaultDataSubscriptionId() { + return SubscriptionManager.getDefaultDataSubscriptionId(); + } } diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java index 9e5b92a6b944..3f15b381c18b 100644 --- a/services/core/java/com/android/server/net/LockdownVpnTracker.java +++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java @@ -17,9 +17,6 @@ package com.android.server.net; import static android.Manifest.permission.CONNECTIVITY_INTERNAL; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; import static android.provider.Settings.ACTION_VPN_SETTINGS; import android.app.Notification; @@ -30,17 +27,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; -import android.net.LinkProperties; import android.net.LinkAddress; +import android.net.LinkProperties; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; -import android.net.NetworkPolicyManager; import android.os.INetworkManagementService; -import android.os.RemoteException; import android.security.Credentials; import android.security.KeyStore; -import android.system.Os; import android.text.TextUtils; import android.util.Slog; diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java index 31fdc01b8d4d..7cc357c3661c 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java +++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java @@ -15,15 +15,15 @@ */ package com.android.server.net; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; +import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.INetd.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; import android.app.ActivityManager; import android.net.NetworkPolicyManager; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index e539ffd5a85f..863ef67d4f0f 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -38,6 +38,11 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; +import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.INetd.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -45,12 +50,7 @@ import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS; import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; diff --git a/services/net/Android.bp b/services/net/Android.bp index 638ec95ec544..9946cc3db0e8 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -1,6 +1,9 @@ java_library_static { name: "services.net", srcs: ["java/**/*.java"], + static_libs: [ + "netd_aidl_interface-java", + ] } filegroup { diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java index c9180a99c98d..a5ac20e951ec 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java @@ -16,12 +16,12 @@ package com.android.server; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE; -import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; +import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; +import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.INetd.FIREWALL_RULE_ALLOW; +import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; import static android.util.DebugUtils.valueToString; import static org.junit.Assert.assertEquals; diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index 38143335dbf1..dba437a3a007 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -141,6 +141,14 @@ public final class CellIdentityTdscdma extends CellIdentity { return mCpid; } + /** + * @return 16-bit UMTS Absolute RF Channel Number, + * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable. + */ + public int getUarfcn() { + return mUarfcn; + } + /** @hide */ @Override public int getChannelNumber() { diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java index 53d69f447a56..24db438580c9 100644 --- a/telephony/java/android/telephony/LocationAccessPolicy.java +++ b/telephony/java/android/telephony/LocationAccessPolicy.java @@ -26,11 +26,12 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.location.LocationManager; import android.os.Binder; +import android.os.Build; import android.os.Process; -import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; +import android.widget.Toast; import java.util.List; @@ -41,61 +42,236 @@ import java.util.List; public final class LocationAccessPolicy { private static final String TAG = "LocationAccessPolicy"; private static final boolean DBG = false; + public static final int MAX_SDK_FOR_ANY_ENFORCEMENT = Build.VERSION_CODES.P; - /** - * API to determine if the caller has permissions to get cell location. - * - * @param pkgName Package name of the application requesting access - * @param uid The uid of the package - * @param pid The pid of the package - * @param throwOnDeniedPermission Whether to throw if the location permission is denied. - * @return boolean true or false if permissions is granted - */ - public static boolean canAccessCellLocation(@NonNull Context context, @NonNull String pkgName, - int uid, int pid, boolean throwOnDeniedPermission) throws SecurityException { - Trace.beginSection("TelephonyLocationCheck"); - try { - // Always allow the phone process and system server to access location. This avoid - // breaking legacy code that rely on public-facing APIs to access cell location, and - // it doesn't create an info leak risk because the cell location is stored in the phone - // process anyway, and the system server already has location access. - if (uid == Process.PHONE_UID || uid == Process.SYSTEM_UID || uid == Process.ROOT_UID) { - return true; + public enum LocationPermissionResult { + ALLOWED, + /** + * Indicates that the denial is due to a transient device state + * (e.g. app-ops, location master switch) + */ + DENIED_SOFT, + /** + * Indicates that the denial is due to a misconfigured app (e.g. missing entry in manifest) + */ + DENIED_HARD, + } + + public static class LocationPermissionQuery { + public final String callingPackage; + public final int callingUid; + public final int callingPid; + public final int minSdkVersionForCoarse; + public final int minSdkVersionForFine; + public final String method; + + private LocationPermissionQuery(String callingPackage, int callingUid, int callingPid, + int minSdkVersionForCoarse, int minSdkVersionForFine, String method) { + this.callingPackage = callingPackage; + this.callingUid = callingUid; + this.callingPid = callingPid; + this.minSdkVersionForCoarse = minSdkVersionForCoarse; + this.minSdkVersionForFine = minSdkVersionForFine; + this.method = method; + } + + public static class Builder { + private String mCallingPackage; + private int mCallingUid; + private int mCallingPid; + private int mMinSdkVersionForCoarse = Integer.MAX_VALUE; + private int mMinSdkVersionForFine = Integer.MAX_VALUE; + private String mMethod; + + /** + * Mandatory parameter, used for performing permission checks. + */ + public Builder setCallingPackage(String callingPackage) { + mCallingPackage = callingPackage; + return this; } - // We always require the location permission and also require the - // location mode to be on for non-legacy apps. Legacy apps are - // required to be in the foreground to at least mitigate the case - // where a legacy app the user is not using tracks their location. - // Granting ACCESS_FINE_LOCATION to an app automatically grants it - // ACCESS_COARSE_LOCATION. - if (throwOnDeniedPermission) { - context.enforcePermission(Manifest.permission.ACCESS_COARSE_LOCATION, - pid, uid, "canAccessCellLocation"); - } else if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, - pid, uid) == PackageManager.PERMISSION_DENIED) { - if (DBG) Log.w(TAG, "Permission checked failed (" + pid + "," + uid + ")"); - return false; + /** + * Mandatory parameter, used for performing permission checks. + */ + public Builder setCallingUid(int callingUid) { + mCallingUid = callingUid; + return this; } - final int opCode = AppOpsManager.permissionToOpCode( - Manifest.permission.ACCESS_COARSE_LOCATION); - if (opCode != AppOpsManager.OP_NONE && context.getSystemService(AppOpsManager.class) - .noteOpNoThrow(opCode, uid, pkgName) != AppOpsManager.MODE_ALLOWED) { - if (DBG) Log.w(TAG, "AppOp check failed (" + uid + "," + pkgName + ")"); - return false; + + /** + * Mandatory parameter, used for performing permission checks. + */ + public Builder setCallingPid(int callingPid) { + mCallingPid = callingPid; + return this; } - if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))) { - if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")"); - return false; + + /** + * Apps that target at least this sdk version will be checked for coarse location + * permission. Defaults to INT_MAX (which means don't check) + */ + public Builder setMinSdkVersionForCoarse( + int minSdkVersionForCoarse) { + mMinSdkVersionForCoarse = minSdkVersionForCoarse; + return this; } - // If the user or profile is current, permission is granted. - // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission. - return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context); - } finally { - Trace.endSection(); + + /** + * Apps that target at least this sdk version will be checked for fine location + * permission. Defaults to INT_MAX (which means don't check) + */ + public Builder setMinSdkVersionForFine( + int minSdkVersionForFine) { + mMinSdkVersionForFine = minSdkVersionForFine; + return this; + } + + /** + * Optional, for logging purposes only. + */ + public Builder setMethod(String method) { + mMethod = method; + return this; + } + + public LocationPermissionQuery build() { + return new LocationPermissionQuery(mCallingPackage, mCallingUid, + mCallingPid, mMinSdkVersionForCoarse, mMinSdkVersionForFine, mMethod); + } + } + } + + private static void logError(Context context, String errorMsg) { + Log.e(TAG, errorMsg); + try { + if (Build.IS_DEBUGGABLE) { + Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show(); + } + } catch (Throwable t) { + // whatever, not important + } + } + + private static LocationPermissionResult appOpsModeToPermissionResult(int appOpsMode) { + switch (appOpsMode) { + case AppOpsManager.MODE_ALLOWED: + return LocationPermissionResult.ALLOWED; + case AppOpsManager.MODE_ERRORED: + return LocationPermissionResult.DENIED_HARD; + default: + return LocationPermissionResult.DENIED_SOFT; } } + private static LocationPermissionResult checkAppLocationPermissionHelper(Context context, + LocationPermissionQuery query, String permissionToCheck) { + String locationTypeForLog = + Manifest.permission.ACCESS_FINE_LOCATION.equals(permissionToCheck) + ? "fine" : "coarse"; + + // Do the app-ops and the manifest check without any of the allow-overrides first. + boolean hasManifestPermission = checkManifestPermission(context, query.callingPid, + query.callingUid, permissionToCheck); + + int appOpMode = context.getSystemService(AppOpsManager.class) + .noteOpNoThrow(AppOpsManager.permissionToOpCode(permissionToCheck), + query.callingUid, query.callingPackage); + + if (hasManifestPermission && appOpMode == AppOpsManager.MODE_ALLOWED) { + // If the app did everything right, return without logging. + return LocationPermissionResult.ALLOWED; + } + + // If the app has the manifest permission but not the app-op permission, it means that + // it's aware of the requirement and the user denied permission explicitly. If we see + // this, don't let any of the overrides happen. + if (hasManifestPermission) { + Log.i(TAG, query.callingPackage + " is aware of " + locationTypeForLog + " but the" + + " app-ops permission is specifically denied."); + return appOpsModeToPermissionResult(appOpMode); + } + + int minSdkVersion = Manifest.permission.ACCESS_FINE_LOCATION.equals(permissionToCheck) + ? query.minSdkVersionForFine : query.minSdkVersionForCoarse; + + // If the app fails for some reason, see if it should be allowed to proceed. + if (minSdkVersion > MAX_SDK_FOR_ANY_ENFORCEMENT) { + String errorMsg = "Allowing " + query.callingPackage + " " + locationTypeForLog + + " because we're not enforcing API " + query.minSdkVersionForFine + " yet." + + " Please fix this app because it will break in the future. Called from " + + query.method; + logError(context, errorMsg); + return null; + } else if (!isAppAtLeastSdkVersion(context, query.callingPackage, minSdkVersion)) { + String errorMsg = "Allowing " + query.callingPackage + " " + locationTypeForLog + + " because it doesn't target API " + query.minSdkVersionForFine + " yet." + + " Please fix this app. Called from " + query.method; + logError(context, errorMsg); + return null; + } else { + // If we're not allowing it due to the above two conditions, this means that the app + // did not declare the permission in their manifest. + return LocationPermissionResult.DENIED_HARD; + } + } + + public static LocationPermissionResult checkLocationPermission( + Context context, LocationPermissionQuery query) { + // Always allow the phone process and system server to access location. This avoid + // breaking legacy code that rely on public-facing APIs to access cell location, and + // it doesn't create an info leak risk because the cell location is stored in the phone + // process anyway, and the system server already has location access. + if (query.callingUid == Process.PHONE_UID || query.callingUid == Process.SYSTEM_UID + || query.callingUid == Process.ROOT_UID) { + return LocationPermissionResult.ALLOWED; + } + + // Check the system-wide requirements. If the location master switch is off or + // the app's profile isn't in foreground, return a soft denial. + if (!checkSystemLocationAccess(context, query.callingUid, query.callingPid)) { + return LocationPermissionResult.DENIED_SOFT; + } + + // Do the check for fine, then for coarse. + if (query.minSdkVersionForFine < Integer.MAX_VALUE) { + LocationPermissionResult resultForFine = checkAppLocationPermissionHelper( + context, query, Manifest.permission.ACCESS_FINE_LOCATION); + if (resultForFine != null) { + return resultForFine; + } + } + + if (query.minSdkVersionForCoarse < Integer.MAX_VALUE) { + LocationPermissionResult resultForCoarse = checkAppLocationPermissionHelper( + context, query, Manifest.permission.ACCESS_COARSE_LOCATION); + if (resultForCoarse != null) { + return resultForCoarse; + } + } + + // At this point, we're out of location checks to do. If the app bypassed all the previous + // ones due to the SDK grandfathering schemes, allow it access. + return LocationPermissionResult.ALLOWED; + } + + + private static boolean checkManifestPermission(Context context, int pid, int uid, + String permissionToCheck) { + return context.checkPermission(permissionToCheck, pid, uid) + == PackageManager.PERMISSION_GRANTED; + } + + private static boolean checkSystemLocationAccess(@NonNull Context context, int uid, int pid) { + if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))) { + if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")"); + return false; + } + // If the user or profile is current, permission is granted. + // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission. + return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context, uid, pid); + } + private static boolean isLocationModeEnabled(@NonNull Context context, @UserIdInt int userId) { LocationManager locationManager = context.getSystemService(LocationManager.class); if (locationManager == null) { @@ -105,10 +281,10 @@ public final class LocationAccessPolicy { return locationManager.isLocationEnabledForUser(UserHandle.of(userId)); } - private static boolean checkInteractAcrossUsersFull(@NonNull Context context) { - return context.checkCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) - == PackageManager.PERMISSION_GRANTED; + private static boolean checkInteractAcrossUsersFull( + @NonNull Context context, int pid, int uid) { + return checkManifestPermission(context, pid, uid, + Manifest.permission.INTERACT_ACROSS_USERS_FULL); } private static boolean isCurrentProfile(@NonNull Context context, int uid) { @@ -132,4 +308,18 @@ public final class LocationAccessPolicy { Binder.restoreCallingIdentity(token); } } -} + + private static boolean isAppAtLeastSdkVersion(Context context, String pkgName, int sdkVersion) { + try { + if (context.getPackageManager().getApplicationInfo(pkgName, 0).targetSdkVersion + >= sdkVersion) { + return true; + } + } catch (PackageManager.NameNotFoundException e) { + // In case of exception, assume known app (more strict checking) + // Note: This case will never happen since checkPackage is + // called to verify validity before checking app's version. + } + return false; + } +}
\ No newline at end of file diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index ceb76b57ae0c..6e6d59e62148 100644 --- a/telephony/java/android/telephony/NetworkRegistrationState.java +++ b/telephony/java/android/telephony/NetworkRegistrationState.java @@ -27,6 +27,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.Objects; +import java.util.stream.Collectors; /** * Description of a mobile network registration state @@ -151,7 +152,7 @@ public class NetworkRegistrationState implements Parcelable { private final int[] mAvailableServices; @Nullable - private final CellIdentity mCellIdentity; + private CellIdentity mCellIdentity; @Nullable private VoiceSpecificRegistrationStates mVoiceSpecificStates; @@ -360,7 +361,34 @@ public class NetworkRegistrationState implements Parcelable { return 0; } - private static String regStateToString(int regState) { + /** + * Convert service type to string + * + * @hide + * + * @param serviceType The service type + * @return The service type in string format + */ + public static String serviceTypeToString(@ServiceType int serviceType) { + switch (serviceType) { + case SERVICE_TYPE_VOICE: return "VOICE"; + case SERVICE_TYPE_DATA: return "DATA"; + case SERVICE_TYPE_SMS: return "SMS"; + case SERVICE_TYPE_VIDEO: return "VIDEO"; + case SERVICE_TYPE_EMERGENCY: return "EMERGENCY"; + } + return "Unknown service type " + serviceType; + } + + /** + * Convert registration state to string + * + * @hide + * + * @param regState The registration state + * @return The reg state in string + */ + public static String regStateToString(@RegState int regState) { switch (regState) { case REG_STATE_NOT_REG_NOT_SEARCHING: return "NOT_REG_NOT_SEARCHING"; case REG_STATE_HOME: return "HOME"; @@ -389,14 +417,17 @@ public class NetworkRegistrationState implements Parcelable { public String toString() { return new StringBuilder("NetworkRegistrationState{") .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS") - .append("transportType=").append(mTransportType) + .append(" transportType=").append(TransportType.toString(mTransportType)) .append(" regState=").append(regStateToString(mRegState)) - .append(" roamingType=").append(mRoamingType) + .append(" roamingType=").append(ServiceState.roamingTypeToString(mRoamingType)) .append(" accessNetworkTechnology=") .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology)) .append(" rejectCause=").append(mRejectCause) .append(" emergencyEnabled=").append(mEmergencyOnly) - .append(" supportedServices=").append(mAvailableServices) + .append(" availableServices=").append("[" + (mAvailableServices != null + ? Arrays.stream(mAvailableServices) + .mapToObj(type -> serviceTypeToString(type)) + .collect(Collectors.joining(",")) : null) + "]") .append(" cellIdentity=").append(mCellIdentity) .append(" voiceSpecificStates=").append(mVoiceSpecificStates) .append(" dataSpecificStates=").append(mDataSpecificStates) @@ -490,4 +521,22 @@ public class NetworkRegistrationState implements Parcelable { return new NetworkRegistrationState[size]; } }; + + /** + * @hide + */ + public NetworkRegistrationState sanitizeLocationInfo() { + NetworkRegistrationState result = copy(); + result.mCellIdentity = null; + return result; + } + + private NetworkRegistrationState copy() { + Parcel p = Parcel.obtain(); + this.writeToParcel(p, 0); + p.setDataPosition(0); + NetworkRegistrationState result = new NetworkRegistrationState(p); + p.recycle(); + return result; + } } diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 2c9ba1dfff7b..3ce646cb400b 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -46,7 +46,7 @@ import java.util.concurrent.Executor; * Override the methods for the state that you wish to receive updates for, and * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_ * flags to {@link TelephonyManager#listen TelephonyManager.listen()}. Methods are - * called when the state changes, os well as once on initial registration. + * called when the state changes, as well as once on initial registration. * <p> * Note that access to some telephony information is * permission-protected. Your application won't receive updates for protected diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 33178766f3a3..a1aee6d8217f 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; /** * Contains phone state and service related information. @@ -887,6 +888,24 @@ public class ServiceState implements Parcelable { } /** + * Convert roaming type to string + * + * @param roamingType roaming type + * @return The roaming type in string format + * + * @hide + */ + public static String roamingTypeToString(@RoamingType int roamingType) { + switch (roamingType) { + case ROAMING_TYPE_NOT_ROAMING: return "NOT_ROAMING"; + case ROAMING_TYPE_UNKNOWN: return "UNKNOWN"; + case ROAMING_TYPE_DOMESTIC: return "DOMESTIC"; + case ROAMING_TYPE_INTERNATIONAL: return "INTERNATIONAL"; + } + return "Unknown roaming type " + roamingType; + } + + /** * Convert radio technology to String * * @param rt radioTechnology @@ -1867,4 +1886,29 @@ public class ServiceState implements Parcelable { ? range1 : range2; } + + /** + * Returns a copy of self with location-identifying information removed. + * Always clears the NetworkRegistrationState's CellIdentity fields, but if removeCoarseLocation + * is true, clears other info as well. + * @hide + */ + public ServiceState sanitizeLocationInfo(boolean removeCoarseLocation) { + ServiceState state = new ServiceState(this); + if (state.mNetworkRegistrationStates != null) { + state.mNetworkRegistrationStates = state.mNetworkRegistrationStates.stream() + .map(NetworkRegistrationState::sanitizeLocationInfo) + .collect(Collectors.toList()); + } + if (!removeCoarseLocation) return state; + + state.mDataOperatorAlphaLong = null; + state.mDataOperatorAlphaShort = null; + state.mDataOperatorNumeric = null; + state.mVoiceOperatorAlphaLong = null; + state.mVoiceOperatorAlphaShort = null; + state.mVoiceOperatorNumeric = null; + + return state; + } } diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java index 52a2085f03bd..2a73a5cdef54 100644 --- a/telephony/java/android/telephony/SmsMessage.java +++ b/telephony/java/android/telephony/SmsMessage.java @@ -981,4 +981,13 @@ public class SmsMessage { return false; } + + /** + * {@hide} + * Returns the recipient address(receiver) of this SMS message in String form or null if + * unavailable. + */ + public String getRecipientAddress() { + return mWrappedSmsMessage.getRecipientAddress(); + } } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 2629bd6a52ca..5b9e23228dcb 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -865,7 +865,8 @@ public class SubscriptionManager { } /** - * Callback invoked when there is any change to any SubscriptionInfo. Typically + * Callback invoked when there is any change to any SubscriptionInfo, as well as once on + * registering for changes with {@link #addOnSubscriptionsChangedListener}. Typically * this method would invoke {@link #getActiveSubscriptionInfoList} */ public void onSubscriptionsChanged() { @@ -917,7 +918,9 @@ public class SubscriptionManager { /** * Register for changes to the list of active {@link SubscriptionInfo} records or to the * individual records themselves. When a change occurs the onSubscriptionsChanged method of - * the listener will be invoked immediately if there has been a notification. + * the listener will be invoked immediately if there has been a notification. The + * onSubscriptionChanged method will also be triggered once initially when calling this + * function. * * @param listener an instance of {@link OnSubscriptionsChangedListener} with * onSubscriptionsChanged overridden. @@ -1860,7 +1863,7 @@ public class SubscriptionManager { iSub.setDefaultSmsSubId(subscriptionId); } } catch (RemoteException ex) { - // ignore it + ex.rethrowFromSystemServer(); } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index abcb7956af12..1433b2ac9280 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -72,6 +72,7 @@ import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.annotations.VisibleForTesting; @@ -228,10 +229,19 @@ public class TelephonyManager { public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; /** - * An invalid UICC card identifier. See {@link #getCardIdForDefaultEuicc()} and - * {@link UiccCardInfo#getCardId()}. + * A UICC card identifier used if the device does not support the operation. + * For example, {@link #getCardIdForDefaultEuicc()} returns this value if the device has no + * eUICC, or the eUICC cannot be read. */ - public static final int INVALID_CARD_ID = -1; + public static final int UNSUPPORTED_CARD_ID = -1; + + /** + * A UICC card identifier used before the UICC card is loaded. See + * {@link #getCardIdForDefaultEuicc()} and {@link UiccCardInfo#getCardId()}. + * <p> + * Note that once the UICC card is loaded, the card ID may become {@link #UNSUPPORTED_CARD_ID}. + */ + public static final int UNINITIALIZED_CARD_ID = -2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -1654,10 +1664,7 @@ public class TelephonyManager { * @deprecated use {@link #getAllCellInfo} instead, which returns a superset of this API. */ @Deprecated - @RequiresPermission(anyOf = { - android.Manifest.permission.ACCESS_COARSE_LOCATION, - android.Manifest.permission.ACCESS_FINE_LOCATION - }) + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public CellLocation getCellLocation() { try { ITelephony telephony = getITelephony(); @@ -3132,24 +3139,25 @@ public class TelephonyManager { } /** - * Get the card ID of the default eUICC card. If there is no eUICC, returns - * {@link #INVALID_CARD_ID}. + * Get the card ID of the default eUICC card. If the eUICCs have not yet been loaded, returns + * {@link #UNINITIALIZED_CARD_ID}. If there is no eUICC or the device does not support card IDs + * for eUICCs, returns {@link #UNSUPPORTED_CARD_ID}. * * <p>The card ID is a unique identifier associated with a UICC or eUICC card. Card IDs are * unique to a device, and always refer to the same UICC or eUICC card unless the device goes * through a factory reset. * - * @return card ID of the default eUICC card. + * @return card ID of the default eUICC card, if loaded. */ public int getCardIdForDefaultEuicc() { try { ITelephony telephony = getITelephony(); if (telephony == null) { - return INVALID_CARD_ID; + return UNINITIALIZED_CARD_ID; } return telephony.getCardIdForDefaultEuicc(mSubId, mContext.getOpPackageName()); } catch (RemoteException e) { - return INVALID_CARD_ID; + return UNINITIALIZED_CARD_ID; } } @@ -3252,6 +3260,35 @@ public class TelephonyManager { } } + /** + * Get the mapping from logical slots to physical slots. The mapping represent by a pair list. + * The key of the piar is the logical slot id and the value of the pair is the physical + * slots id mapped to this logical slot id. + * + * @return an pair list indicates the mapping from logical slots to physical slots. The size of + * the list should be {@link #getPhoneCount()} if success, otherwise return an empty list. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @NonNull + public List<Pair<Integer, Integer>> getLogicalToPhysicalSlotMapping() { + List<Pair<Integer, Integer>> slotMapping = new ArrayList<>(); + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + int[] slotMappingArray = telephony.getSlotsMapping(); + for (int i = 0; i < slotMappingArray.length; i++) { + slotMapping.add(new Pair(i, slotMappingArray[i])); + } + } + } catch (RemoteException e) { + Log.e(TAG, "getSlotsMapping RemoteException", e); + } + return slotMapping; + } + // // // Subscriber Info @@ -4888,7 +4925,7 @@ public class TelephonyManager { * @return List of {@link android.telephony.CellInfo}; null if cell * information is unavailable. */ - @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public List<CellInfo> getAllCellInfo() { try { ITelephony telephony = getITelephony(); @@ -4965,7 +5002,7 @@ public class TelephonyManager { * @param executor the executor on which callback will be invoked. * @param callback a callback to receive CellInfo. */ - @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate( @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) { try { @@ -5004,7 +5041,7 @@ public class TelephonyManager { * @hide */ @SystemApi - @RequiresPermission(allOf = {android.Manifest.permission.ACCESS_COARSE_LOCATION, + @RequiresPermission(allOf = {android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull WorkSource workSource, @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) { @@ -6594,9 +6631,10 @@ public class TelephonyManager { * * <p> Note that this scan can take a long time (sometimes minutes) to happen. * - * <p>Requires Permission: + * <p>Requires Permissions: * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier * privileges (see {@link #hasCarrierPrivileges}) + * and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. * * @return {@link CellNetworkScanResult} with the status * {@link CellNetworkScanResult#STATUS_SUCCESS} and a list of @@ -6605,12 +6643,15 @@ public class TelephonyManager { * * @hide */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(allOf = { + android.Manifest.permission.MODIFY_PHONE_STATE, + Manifest.permission.ACCESS_COARSE_LOCATION + }) public CellNetworkScanResult getAvailableNetworks() { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getCellNetworkScanResults(getSubId()); + return telephony.getCellNetworkScanResults(getSubId(), getOpPackageName()); } } catch (RemoteException ex) { Rlog.e(TAG, "getAvailableNetworks RemoteException", ex); @@ -6629,7 +6670,8 @@ public class TelephonyManager { * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling - * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * app has carrier privileges (see {@link #hasCarrierPrivileges}) + * and {@link android.Manifest.permission#ACCESS_FINE_LOCATION}. * * @param request Contains all the RAT with bands/channels that need to be scanned. * @param executor The executor through which the callback should be invoked. Since the scan @@ -6640,7 +6682,10 @@ public class TelephonyManager { * @return A NetworkScan obj which contains a callback which can be used to stop the scan. */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(allOf = { + android.Manifest.permission.MODIFY_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) public NetworkScan requestNetworkScan( NetworkScanRequest request, Executor executor, TelephonyScanManager.NetworkScanCallback callback) { @@ -6649,7 +6694,8 @@ public class TelephonyManager { mTelephonyScanManager = new TelephonyScanManager(); } } - return mTelephonyScanManager.requestNetworkScan(getSubId(), request, executor, callback); + return mTelephonyScanManager.requestNetworkScan(getSubId(), request, executor, callback, + getOpPackageName()); } /** @@ -6659,7 +6705,10 @@ public class TelephonyManager { * @removed */ @Deprecated - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresPermission(allOf = { + android.Manifest.permission.MODIFY_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) public NetworkScan requestNetworkScan( NetworkScanRequest request, TelephonyScanManager.NetworkScanCallback callback) { return requestNetworkScan(request, AsyncTask.SERIAL_EXECUTOR, callback); @@ -8659,10 +8708,14 @@ public class TelephonyManager { * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()} * * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} - * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}) + * and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + @RequiresPermission(allOf = { + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.ACCESS_COARSE_LOCATION + }) public ServiceState getServiceState() { return getServiceStateForSubscriber(getSubId()); } diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java index 96ff33255b53..91f74b867fa0 100644 --- a/telephony/java/android/telephony/TelephonyScanManager.java +++ b/telephony/java/android/telephony/TelephonyScanManager.java @@ -29,14 +29,14 @@ import android.os.Messenger; import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; -import android.util.Log; import android.util.SparseArray; + +import com.android.internal.telephony.ITelephony; + import java.util.Arrays; import java.util.List; import java.util.concurrent.Executor; -import com.android.internal.telephony.ITelephony; - /** * Manages the radio access network scan requests and callbacks. */ @@ -183,6 +183,7 @@ public final class TelephonyScanManager { * * <p> * Requires Permission: + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} * Or the calling app has carrier privileges. @see #hasCarrierPrivileges * @@ -192,11 +193,13 @@ public final class TelephonyScanManager { * @hide */ public NetworkScan requestNetworkScan(int subId, - NetworkScanRequest request, Executor executor, NetworkScanCallback callback) { + NetworkScanRequest request, Executor executor, NetworkScanCallback callback, + String callingPackage) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - int scanId = telephony.requestNetworkScan(subId, request, mMessenger, new Binder()); + int scanId = telephony.requestNetworkScan( + subId, request, mMessenger, new Binder(), callingPackage); saveScanInfo(scanId, request, executor, callback); return new NetworkScan(scanId, subId); } diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 40c6f70f5112..828e3e93b7a4 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -305,7 +305,7 @@ public class EuiccManager { */ @Nullable public String getEid() { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { return null; } try { @@ -328,7 +328,7 @@ public class EuiccManager { @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public int getOtaStatus() { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { return EUICC_OTA_STATUS_UNAVAILABLE; } try { @@ -363,7 +363,7 @@ public class EuiccManager { @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void downloadSubscription(DownloadableSubscription subscription, boolean switchAfterDownload, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -425,7 +425,7 @@ public class EuiccManager { @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { PendingIntent callbackIntent = resolutionIntent.getParcelableExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT); @@ -462,7 +462,7 @@ public class EuiccManager { @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDownloadableSubscriptionMetadata( DownloadableSubscription subscription, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -492,7 +492,7 @@ public class EuiccManager { @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -511,7 +511,7 @@ public class EuiccManager { */ @Nullable public EuiccInfo getEuiccInfo() { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { return null; } try { @@ -536,7 +536,7 @@ public class EuiccManager { */ @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -576,7 +576,7 @@ public class EuiccManager { */ @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -602,7 +602,7 @@ public class EuiccManager { @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void updateSubscriptionNickname( int subscriptionId, String nickname, PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -626,7 +626,7 @@ public class EuiccManager { @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -656,7 +656,7 @@ public class EuiccManager { * @hide */ public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) { - if (!refreshCardIdIfInvalid()) { + if (!refreshCardIdIfUninitialized()) { sendUnavailableError(callbackIntent); return; } @@ -667,16 +667,24 @@ public class EuiccManager { } } - private boolean refreshCardIdIfInvalid() { - if (!isEnabled()) { - return false; - } - // Refresh mCardId if it's invalid. - if (mCardId == TelephonyManager.INVALID_CARD_ID) { + /** + * Refreshes the cardId if its uninitialized, and returns whether we should continue the + * operation. + * <p> + * Note that after a successful refresh, the mCardId may be TelephonyManager.UNSUPPORTED_CARD_ID + * on older HALs. For backwards compatability, we continue to the LPA and let it decide which + * card to use. + */ + private boolean refreshCardIdIfUninitialized() { + // Refresh mCardId if its UNINITIALIZED_CARD_ID + if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) { TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); mCardId = tm.getCardIdForDefaultEuicc(); } + if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) { + return false; + } return true; } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 0f7b0f1a0daf..e6a55585506c 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -765,7 +765,7 @@ interface ITelephony { * @param subId the id of the subscription. * @return CellNetworkScanResult containing status of scan and networks. */ - CellNetworkScanResult getCellNetworkScanResults(int subId); + CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage); /** * Perform a radio network scan and return the id of this scan. @@ -774,10 +774,11 @@ interface ITelephony { * @param request Defines all the configs for network scan. * @param messenger Callback messages will be sent using this messenger. * @param binder the binder object instantiated in TelephonyManager. + * @param callingPackage the calling package * @return An id for this scan. */ int requestNetworkScan(int subId, in NetworkScanRequest request, in Messenger messenger, - in IBinder binder); + in IBinder binder, in String callingPackage); /** * Stop an existing radio network scan. @@ -1840,9 +1841,15 @@ interface ITelephony { * @hide */ int getNumOfActiveSims(); + /** * Get if reboot is required upon altering modems configurations * @hide */ boolean isRebootRequiredForModemConfigChange(); + + /** + * Get the mapping from logical slots to physical slots. + */ + int[] getSlotsMapping(); } diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java index 190eac4d8c02..ffdc4b676f90 100644 --- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java +++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java @@ -41,6 +41,9 @@ public abstract class SmsMessageBase { @UnsupportedAppUsage protected SmsAddress mOriginatingAddress; + /** {@hide} The address of the receiver */ + protected SmsAddress mRecipientAddress; + /** {@hide} The message body as a string. May be null if the message isn't text */ @UnsupportedAppUsage protected String mMessageBody; @@ -457,4 +460,17 @@ public abstract class SmsMessageBase { return ted; } + + /** + * {@hide} + * Returns the receiver address of this SMS message in String + * form or null if unavailable + */ + public String getRecipientAddress() { + if (mRecipientAddress == null) { + return null; + } + + return mRecipientAddress.getAddressString(); + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 1da5eac27002..a31fa0b6a725 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -601,18 +601,24 @@ public class SmsMessage extends SmsMessageBase { } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) { if (numberType == 2) - Rlog.e(LOG_TAG, "TODO: Originating Addr is email id"); + Rlog.e(LOG_TAG, "TODO: Addr is email id"); else Rlog.e(LOG_TAG, - "TODO: Originating Addr is data network address"); + "TODO: Addr is data network address"); } else { - Rlog.e(LOG_TAG, "Originating Addr is of incorrect type"); + Rlog.e(LOG_TAG, "Addr is of incorrect type"); } } else { Rlog.e(LOG_TAG, "Incorrect Digit mode"); } addr.origBytes = data; - Rlog.i(LOG_TAG, "Originating Addr=" + addr.toString()); + Rlog.pii(LOG_TAG, "Addr=" + addr.toString()); + mOriginatingAddress = addr; + if (parameterId == DESTINATION_ADDRESS) { + // Original address awlays indicates one sender's address for 3GPP2 + // Here add recipient address support along with 3GPP + mRecipientAddress = addr; + } break; case ORIGINATING_SUB_ADDRESS: case DESTINATION_SUB_ADDRESS: @@ -667,7 +673,7 @@ public class SmsMessage extends SmsMessageBase { } /** - * Parses a SMS message from its BearerData stream. (mobile-terminated only) + * Parses a SMS message from its BearerData stream. */ public void parseSms() { // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6 @@ -697,16 +703,15 @@ public class SmsMessage extends SmsMessageBase { } if (mOriginatingAddress != null) { - mOriginatingAddress.address = new String(mOriginatingAddress.origBytes); - if (mOriginatingAddress.ton == CdmaSmsAddress.TON_INTERNATIONAL_OR_IP) { - if (mOriginatingAddress.address.charAt(0) != '+') { - mOriginatingAddress.address = "+" + mOriginatingAddress.address; - } - } + decodeSmsDisplayAddress(mOriginatingAddress); if (VDBG) Rlog.v(LOG_TAG, "SMS originating address: " + mOriginatingAddress.address); } + if (mRecipientAddress != null) { + decodeSmsDisplayAddress(mRecipientAddress); + } + if (mBearerData.msgCenterTimeStamp != null) { mScTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true); } @@ -731,7 +736,8 @@ public class SmsMessage extends SmsMessageBase { status = mBearerData.errorClass << 8; status |= mBearerData.messageStatus; } - } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) { + } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER + && mBearerData.messageType != BearerData.MESSAGE_TYPE_SUBMIT) { throw new RuntimeException("Unsupported message type: " + mBearerData.messageType); } @@ -743,6 +749,16 @@ public class SmsMessage extends SmsMessageBase { } } + private void decodeSmsDisplayAddress(SmsAddress addr) { + addr.address = new String(addr.origBytes); + if (addr.ton == CdmaSmsAddress.TON_INTERNATIONAL_OR_IP) { + if (addr.address.charAt(0) != '+') { + addr.address = "+" + addr.address; + } + } + Rlog.pii(LOG_TAG, " decodeSmsDisplayAddress = " + addr.address); + } + /** * Parses a broadcast SMS, possibly containing a CMAS alert. * diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index 015efa6a0c7d..19465a44e4e8 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -71,9 +71,6 @@ public class SmsMessage extends SmsMessageBase { // e.g. 23.040 9.2.2.1 private boolean mReplyPathPresent = false; - /** The address of the receiver. */ - private GsmSmsAddress mRecipientAddress; - /** * TP-Status - status of a previously submitted SMS. * This field applies to SMS-STATUS-REPORT messages. 0 indicates success; diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 963b6851efea..c83ab84d6683 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -3791,11 +3791,14 @@ public class ConnectivityServiceTest { } @Test - public void testNattSocketKeepalives() throws Exception { + public void testNattSocketKeepalives_SingleThreadExecutor() throws Exception { final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor(); doTestNattSocketKeepalivesWithExecutor(executorSingleThread); executorSingleThread.shutdown(); + } + @Test + public void testNattSocketKeepalives_InlineExecutor() throws Exception { final Executor executorInline = (Runnable r) -> r.run(); doTestNattSocketKeepalivesWithExecutor(executorInline); } @@ -3937,6 +3940,7 @@ public class ConnectivityServiceTest { testSocket2.close(); mWiFiNetworkAgent.disconnect(); + waitFor(mWiFiNetworkAgent.getDisconnectedCV()); } @Test diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index b6356076db60..a4a735d1a89d 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -35,6 +35,7 @@ import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -274,6 +275,11 @@ public class TetheringTest { isTetheringSupportedCalls++; return true; } + + @Override + public int getDefaultDataSubscriptionId() { + return INVALID_SUBSCRIPTION_ID; + } } private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java index ec286759354a..193f3806dbf6 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java @@ -21,6 +21,7 @@ import static android.net.ConnectivityManager.TETHERING_WIFI; import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN; import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -140,7 +141,8 @@ public final class EntitlementManagerTest { mMockContext = new MockContext(mContext); mSM = new TestStateMachine(); mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, mSystemProperties); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); } @After @@ -168,7 +170,8 @@ public final class EntitlementManagerTest { @Test public void canRequireProvisioning() { setupForRequiredProvisioning(); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); assertTrue(mEnMgr.isTetherProvisioningRequired()); } @@ -177,7 +180,8 @@ public final class EntitlementManagerTest { setupForRequiredProvisioning(); when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) .thenReturn(null); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); // Couldn't get the CarrierConfigManager, but still had a declared provisioning app. // Therefore provisioning still be required. assertTrue(mEnMgr.isTetherProvisioningRequired()); @@ -187,7 +191,8 @@ public final class EntitlementManagerTest { public void toleratesCarrierConfigMissing() { setupForRequiredProvisioning(); when(mCarrierConfigManager.getConfig()).thenReturn(null); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); // We still have a provisioning app configured, so still require provisioning. assertTrue(mEnMgr.isTetherProvisioningRequired()); } @@ -197,11 +202,13 @@ public final class EntitlementManagerTest { setupForRequiredProvisioning(); when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) .thenReturn(null); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); assertFalse(mEnMgr.isTetherProvisioningRequired()); when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) .thenReturn(new String[] {"malformedApp"}); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration( + new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); assertFalse(mEnMgr.isTetherProvisioningRequired()); } @@ -223,7 +230,8 @@ public final class EntitlementManagerTest { assertFalse(mEnMgr.everRunUiEntitlement); setupForRequiredProvisioning(); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); + mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, + INVALID_SUBSCRIPTION_ID)); // 2. No cache value and don't need to run entitlement check. mEnMgr.everRunUiEntitlement = false; receiver = new ResultReceiver(null) { diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java index 521778484d91..01b904d8f088 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java @@ -22,10 +22,12 @@ import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_NOT_REQUIRED; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_REQUIRED; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_UNSPECIFIED; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -44,26 +46,39 @@ import android.test.mock.MockContentResolver; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; -import java.util.Iterator; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Iterator; @RunWith(AndroidJUnit4.class) @SmallTest public class TetheringConfigurationTest { private final SharedLog mLog = new SharedLog("TetheringConfigurationTest"); + + private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; @Mock private Context mContext; @Mock private TelephonyManager mTelephonyManager; @Mock private Resources mResources; + @Mock private Resources mResourcesForSubId; private MockContentResolver mContentResolver; private Context mMockContext; private boolean mHasTelephonyManager; + private class MockTetheringConfiguration extends TetheringConfiguration { + MockTetheringConfiguration(Context ctx, SharedLog log, int id) { + super(ctx, log, id); + } + + @Override + protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) { + return mResourcesForSubId; + } + } + private class MockContext extends BroadcastInterceptingContext { MockContext(Context base) { super(base); @@ -99,6 +114,9 @@ public class TetheringConfigurationTest { .thenReturn(new String[0]); when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types)) .thenReturn(new int[0]); + when(mResources.getStringArray( + com.android.internal.R.array.config_mobile_hotspot_provision_app)) + .thenReturn(new String[0]); mContentResolver = new MockContentResolver(); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); mMockContext = new MockContext(mContext); @@ -111,7 +129,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = true; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_REQUIRED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertTrue(cfg.isDunRequired); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE)); @@ -127,7 +146,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = true; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_NOT_REQUIRED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertFalse(cfg.isDunRequired); assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE)); @@ -143,7 +163,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = false; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertTrue(cfg.isDunRequired); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); // Just to prove we haven't clobbered Wi-Fi: @@ -160,7 +181,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = false; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); assertTrue(upstreamIterator.hasNext()); assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue()); @@ -181,7 +203,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = false; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); assertTrue(upstreamIterator.hasNext()); assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue()); @@ -199,7 +222,8 @@ public class TetheringConfigurationTest { mHasTelephonyManager = false; when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); assertTrue(upstreamIterator.hasNext()); assertEquals(TYPE_WIFI, upstreamIterator.next().intValue()); @@ -214,7 +238,8 @@ public class TetheringConfigurationTest { public void testNewDhcpServerDisabled() { Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertTrue(cfg.enableLegacyDhcpServer); } @@ -222,7 +247,41 @@ public class TetheringConfigurationTest { public void testNewDhcpServerEnabled() { Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertFalse(cfg.enableLegacyDhcpServer); } + + @Test + public void testGetResourcesBySubId() { + setUpResourceForSubId(); + final TetheringConfiguration cfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + assertTrue(cfg.provisioningApp.length == 0); + final int anyValidSubId = 1; + final MockTetheringConfiguration mockCfg = + new MockTetheringConfiguration(mMockContext, mLog, anyValidSubId); + assertEquals(mockCfg.provisioningApp[0], PROVISIONING_APP_NAME[0]); + assertEquals(mockCfg.provisioningApp[1], PROVISIONING_APP_NAME[1]); + } + + private void setUpResourceForSubId() { + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_tether_dhcp_range)).thenReturn(new String[0]); + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_tether_usb_regexs)).thenReturn(new String[0]); + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_tether_wifi_regexs)) + .thenReturn(new String[]{ "test_wlan\\d" }); + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_tether_bluetooth_regexs)) + .thenReturn(new String[0]); + when(mResourcesForSubId.getIntArray( + com.android.internal.R.array.config_tether_upstream_types)) + .thenReturn(new int[0]); + when(mResourcesForSubId.getStringArray( + com.android.internal.R.array.config_mobile_hotspot_provision_app)) + .thenReturn(PROVISIONING_APP_NAME); + } + } |