summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp5
-rw-r--r--ApiDocs.bp4
-rw-r--r--METADATA3
-rw-r--r--StubLibraries.bp22
-rw-r--r--apex/sdkextensions/framework/Android.bp19
-rw-r--r--api/current.txt4
-rwxr-xr-xapi/system-current.txt1
-rw-r--r--api/test-current.txt1
-rw-r--r--cmds/bootanimation/bootanim.rc2
-rw-r--r--cmds/statsd/Android.bp2
-rw-r--r--core/java/android/annotation/CallbackExecutor.java10
-rw-r--r--core/java/android/annotation/RequiresPermission.java9
-rw-r--r--core/java/android/app/Activity.java1
-rw-r--r--core/java/android/app/ActivityManager.java3
-rw-r--r--core/java/android/app/IActivityManager.aidl3
-rw-r--r--core/java/android/app/Instrumentation.java2
-rw-r--r--core/java/android/app/Notification.java6
-rw-r--r--core/java/android/app/NotificationManager.java2
-rw-r--r--core/java/android/app/backup/BackupManager.java2
-rw-r--r--core/java/android/app/job/JobScheduler.java4
-rw-r--r--core/java/android/app/role/RoleManager.java2
-rw-r--r--core/java/android/content/Context.java1
-rw-r--r--core/java/android/hardware/hdmi/HdmiControlManager.java7
-rw-r--r--core/java/android/net/Ikev2VpnProfile.java2
-rw-r--r--core/java/android/net/MatchAllNetworkSpecifier.java3
-rw-r--r--core/java/android/net/NetworkCapabilities.java16
-rw-r--r--core/java/android/net/NetworkScoreManager.java3
-rw-r--r--core/java/android/net/VpnService.java2
-rw-r--r--core/java/android/os/StrictMode.java1
-rw-r--r--core/java/android/os/VibrationEffect.java6
-rw-r--r--core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java1
-rw-r--r--core/java/android/provider/CalendarContract.java3
-rw-r--r--core/java/android/provider/DocumentsContract.java25
-rw-r--r--core/java/android/service/autofill/CustomDescription.java2
-rw-r--r--core/java/android/service/autofill/ImageTransformation.java2
-rw-r--r--core/java/android/service/autofill/SaveInfo.java4
-rw-r--r--core/java/android/telephony/PhoneStateListener.java6
-rw-r--r--core/java/android/view/View.java4
-rw-r--r--core/java/android/view/WindowManager.java1
-rw-r--r--core/java/android/view/inspector/StaticInspectionCompanionProvider.java2
-rw-r--r--core/java/com/android/internal/os/RoSystemProperties.java12
-rw-r--r--core/jni/fd_utils.cpp16
-rw-r--r--core/res/res/values-mcc334-mnc020/config.xml5
-rw-r--r--core/res/res/values-mcc334-mnc020/strings.xml25
-rw-r--r--core/res/res/values/attrs.xml2
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--core/res/res/values/strings.xml6
-rw-r--r--core/res/res/values/symbols.xml8
-rw-r--r--graphics/java/android/graphics/RenderNode.java2
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java2
-rw-r--r--graphics/java/android/graphics/fonts/FontStyle.java2
-rw-r--r--graphics/java/android/graphics/text/LineBreaker.java4
-rw-r--r--keystore/java/android/security/KeyStore.java11
-rw-r--r--media/Android.bp5
-rw-r--r--media/java/android/media/AudioFocusRequest.java4
-rw-r--r--media/java/android/media/AudioTrack.java2
-rw-r--r--native/android/Android.bp10
-rw-r--r--native/android/trace/android/trace.h29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java18
-rw-r--r--packages/Tethering/Android.bp9
-rw-r--r--packages/Tethering/apex/Android.bp11
-rw-r--r--packages/Tethering/common/TetheringLib/Android.bp12
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml6
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml12
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml6
-rw-r--r--packages/Tethering/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/Tethering/res/values/config.xml7
-rw-r--r--packages/Tethering/res/values/overlayable.xml1
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java177
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java19
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/Tethering.java27
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java20
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java20
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java93
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java133
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java114
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java19
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java122
-rw-r--r--services/Android.bp4
-rw-r--r--services/core/Android.bp4
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java8
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java11
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java2
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java26
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java7
-rw-r--r--services/core/java/com/android/server/connectivity/VpnIkev2Utils.java10
-rw-r--r--services/core/java/com/android/server/hdmi/Constants.java43
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java12
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java6
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java7
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java4
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java101
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/OWNERS2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java44
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java28
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java48
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java15
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java5
-rw-r--r--services/net/Android.bp6
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java41
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java1
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java2
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java114
-rw-r--r--telephony/java/android/telephony/CellIdentity.java2
-rw-r--r--telephony/java/android/telephony/CellIdentityCdma.java1
-rw-r--r--telephony/java/android/telephony/CellIdentityGsm.java1
-rw-r--r--telephony/java/android/telephony/CellIdentityLte.java2
-rw-r--r--telephony/java/android/telephony/CellIdentityNr.java2
-rw-r--r--telephony/java/android/telephony/CellIdentityTdscdma.java2
-rw-r--r--telephony/java/android/telephony/CellIdentityWcdma.java2
-rw-r--r--telephony/java/android/telephony/MbmsDownloadSession.java66
-rw-r--r--telephony/java/android/telephony/TelephonyDisplayInfo.java13
-rw-r--r--telephony/java/android/telephony/euicc/EuiccManager.java68
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java14
-rw-r--r--telephony/java/android/telephony/ims/RegistrationManager.java2
-rw-r--r--telephony/java/android/telephony/ims/feature/MmTelFeature.java8
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java3
-rw-r--r--telephony/java/android/telephony/mbms/MbmsErrors.java41
-rwxr-xr-xtelephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl2
-rw-r--r--telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java22
-rw-r--r--telephony/java/com/android/internal/telephony/DctConstants.java9
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java2
-rw-r--r--tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt4
-rw-r--r--tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt6
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java2
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsServiceTest.java36
-rw-r--r--tools/aapt2/cmd/Link.cpp7
-rw-r--r--tools/aapt2/cmd/Link.h3
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java2
-rw-r--r--wifi/java/android/net/wifi/WpsInfo.java2
137 files changed, 1425 insertions, 689 deletions
diff --git a/Android.bp b/Android.bp
index 1aaa6044111a..e7845467e758 100644
--- a/Android.bp
+++ b/Android.bp
@@ -608,7 +608,7 @@ filegroup {
java_library {
name: "framework-annotations-lib",
srcs: [ ":framework-annotations" ],
- sdk_version: "current",
+ sdk_version: "core_current",
}
filegroup {
@@ -739,7 +739,7 @@ java_library {
"core/proto/android/privacy.proto",
"core/proto/android/section.proto",
],
- sdk_version: "current",
+ sdk_version: "9",
srcs: [
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
@@ -762,6 +762,7 @@ java_library {
"core/proto/android/privacy.proto",
"core/proto/android/section.proto",
],
+ sdk_version: "core_current",
// Protos have lots of MissingOverride and similar.
errorprone: {
javacflags: ["-XepDisableAllChecks"],
diff --git a/ApiDocs.bp b/ApiDocs.bp
index bd4a32bfab7a..60f56de73598 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -79,7 +79,7 @@ stubs_defaults {
"sdk-dir",
"api-versions-jars-dir",
],
- previous_api: ":last-released-public-api",
+ previous_api: ":android.api.public.latest",
merge_annotations_dirs: [
"metalava-manual",
],
@@ -101,7 +101,7 @@ droidstubs {
arg_files: [
"core/res/AndroidManifest.xml",
],
- args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS,process=android.annotation.SystemApi.Process.ALL\\) ",
+ args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ",
write_sdk_values: true,
}
diff --git a/METADATA b/METADATA
new file mode 100644
index 000000000000..d97975ca3b99
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 74b0524f4fd2..4a77463160f6 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -48,13 +48,12 @@ stubs_defaults {
":opt-telephony-srcs",
":opt-net-voip-srcs",
":art-module-public-api-stubs-source",
- ":conscrypt.module.public.api.stubs.source",
":android_icu4j_public_api_files",
],
libs: ["framework-internal-utils"],
installable: false,
annotations_enabled: true,
- previous_api: ":last-released-public-api",
+ previous_api: ":android.api.public.latest",
merge_annotations_dirs: [
"metalava-manual",
],
@@ -65,7 +64,10 @@ stubs_defaults {
stubs_defaults {
name: "metalava-full-api-stubs-default",
defaults: ["metalava-base-api-stubs-default"],
- srcs: [":framework-updatable-sources"],
+ srcs: [
+ ":conscrypt.module.public.api.stubs.source",
+ ":framework-updatable-sources",
+ ],
sdk_version: "core_platform",
}
@@ -97,13 +99,13 @@ droidstubs {
removed_api_file: "api/removed.txt",
},
last_released: {
- api_file: ":last-released-public-api",
+ api_file: ":android.api.public.latest",
removed_api_file: "api/removed.txt",
baseline_file: ":public-api-incompatibilities-with-last-released",
},
api_lint: {
enabled: true,
- new_since: ":last-released-public-api",
+ new_since: ":android.api.public.latest",
baseline_file: "api/lint-baseline.txt",
},
},
@@ -139,13 +141,13 @@ droidstubs {
removed_api_file: "api/system-removed.txt",
},
last_released: {
- api_file: ":last-released-system-api",
+ api_file: ":android.api.system.latest",
removed_api_file: "api/system-removed.txt",
baseline_file: ":system-api-incompatibilities-with-last-released"
},
api_lint: {
enabled: true,
- new_since: ":last-released-system-api",
+ new_since: ":android.api.system.latest",
baseline_file: "api/system-lint-baseline.txt",
},
},
@@ -207,13 +209,13 @@ droidstubs {
removed_api_file: "api/module-lib-removed.txt",
},
last_released: {
- api_file: ":last-released-module-lib-api",
+ api_file: ":android.api.module-lib.latest",
removed_api_file: "api/module-lib-removed.txt",
baseline_file: ":module-lib-api-incompatibilities-with-last-released"
},
api_lint: {
enabled: true,
- new_since: ":last-released-module-lib-api",
+ new_since: ":android.api.module-lib.latest",
baseline_file: "api/module-lib-lint-baseline.txt",
},
},
@@ -314,7 +316,7 @@ droidstubs {
installable: false,
sdk_version: "core_platform",
annotations_enabled: true,
- previous_api: ":last-released-public-api",
+ previous_api: ":android.api.public.latest",
merge_annotations_dirs: [
"metalava-manual",
],
diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp
index 707113b9672c..6a787116c005 100644
--- a/apex/sdkextensions/framework/Android.bp
+++ b/apex/sdkextensions/framework/Android.bp
@@ -48,7 +48,7 @@ stubs_defaults {
name: "framework-sdkextensions-stubs-defaults",
srcs: [ ":framework-sdkextensions-sources" ],
libs: [ "framework-annotations-lib" ],
- sdk_version: "system_current",
+ dist: { dest: "framework-sdkextensions.txt" },
}
droidstubs {
@@ -56,7 +56,7 @@ droidstubs {
defaults: [
"framework-module-stubs-defaults-publicapi",
"framework-sdkextensions-stubs-defaults",
- ]
+ ],
}
droidstubs {
@@ -64,7 +64,7 @@ droidstubs {
defaults: [
"framework-module-stubs-defaults-systemapi",
"framework-sdkextensions-stubs-defaults",
- ]
+ ],
}
droidstubs {
@@ -72,7 +72,7 @@ droidstubs {
defaults: [
"framework-module-api-defaults-module_libs_api",
"framework-sdkextensions-stubs-defaults",
- ]
+ ],
}
droidstubs {
@@ -80,7 +80,7 @@ droidstubs {
defaults: [
"framework-module-stubs-defaults-module_libs_api",
"framework-sdkextensions-stubs-defaults",
- ]
+ ],
}
java_library {
@@ -90,7 +90,8 @@ java_library {
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
+ ],
+ dist: { dest: "framework-sdkextensions.jar" },
}
java_library {
@@ -100,7 +101,8 @@ java_library {
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
+ ],
+ dist: { dest: "framework-sdkextensions.jar" },
}
java_library {
@@ -110,5 +112,6 @@ java_library {
visibility: [
"//frameworks/base", // Framework
"//frameworks/base/apex/sdkextensions", // sdkextensions SDK
- ]
+ ],
+ dist: { dest: "framework-sdkextensions.jar" },
}
diff --git a/api/current.txt b/api/current.txt
index d5fe8cd585e8..e63cb45e5e30 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -29175,6 +29175,7 @@ package android.net {
field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
field public static final int NET_CAPABILITY_RCS = 8; // 0x8
field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
+ field public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25; // 0x19
field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
@@ -45341,12 +45342,14 @@ package android.telephony {
public class MbmsDownloadSession implements java.lang.AutoCloseable {
method public void addProgressListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.DownloadProgressListener);
+ method public void addServiceAnnouncementFile(@NonNull byte[]);
method public void addStatusListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.DownloadStatusListener);
method public void cancelDownload(@NonNull android.telephony.mbms.DownloadRequest);
method public void close();
method public static android.telephony.MbmsDownloadSession create(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.mbms.MbmsDownloadSessionCallback);
method @Nullable public static android.telephony.MbmsDownloadSession create(@NonNull android.content.Context, @NonNull java.util.concurrent.Executor, int, @NonNull android.telephony.mbms.MbmsDownloadSessionCallback);
method public void download(@NonNull android.telephony.mbms.DownloadRequest);
+ method public static int getMaximumServiceAnnouncementFileSize();
method @Nullable public java.io.File getTempFileRootDirectory();
method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads();
method public void removeProgressListener(@NonNull android.telephony.mbms.DownloadRequest, @NonNull android.telephony.mbms.DownloadProgressListener);
@@ -46953,6 +46956,7 @@ package android.telephony.mbms {
public static class MbmsErrors.DownloadErrors {
field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
+ field public static final int ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE = 404; // 0x194
field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
field public static final int ERROR_UNKNOWN_FILE_INFO = 403; // 0x193
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 3b349bf6a9bb..4a1bf0d803a6 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -10320,6 +10320,7 @@ package android.telephony.mbms.vendor {
public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface {
ctor public MbmsDownloadServiceBase();
method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
+ method public int addServiceAnnouncementFile(int, @NonNull byte[]);
method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
method public android.os.IBinder asBinder();
method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 31b4ca82c68e..d3e1e8c4c2bc 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4098,6 +4098,7 @@ package android.telephony.mbms.vendor {
public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface {
ctor public MbmsDownloadServiceBase();
method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
+ method public int addServiceAnnouncementFile(int, @NonNull byte[]);
method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
method public android.os.IBinder asBinder();
method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc
index 9f4f314a4324..ad4de0ab737a 100644
--- a/cmds/bootanimation/bootanim.rc
+++ b/cmds/bootanimation/bootanim.rc
@@ -5,4 +5,4 @@ service bootanim /system/bin/bootanimation
disabled
oneshot
ioprio rt 0
- writepid /dev/stune/top-app/tasks
+ task_profiles MaxPerformance
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 72a8bea9a918..24fbf21f463f 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -382,7 +382,7 @@ cc_benchmark {
// ==== java proto device library (for test only) ==============================
java_library {
name: "statsdprotolite",
- sdk_version: "core_platform",
+ sdk_version: "core_current",
proto: {
type: "lite",
include_dirs: ["external/protobuf/src"],
diff --git a/core/java/android/annotation/CallbackExecutor.java b/core/java/android/annotation/CallbackExecutor.java
index 5671a3d2b6d6..4258f730eb16 100644
--- a/core/java/android/annotation/CallbackExecutor.java
+++ b/core/java/android/annotation/CallbackExecutor.java
@@ -19,9 +19,6 @@ package android.annotation;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.SOURCE;
-import android.content.Context;
-import android.os.AsyncTask;
-
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.concurrent.Executor;
@@ -30,9 +27,10 @@ import java.util.concurrent.Executor;
* @paramDoc Callback and listener events are dispatched through this
* {@link Executor}, providing an easy way to control which thread is
* used. To dispatch events through the main thread of your
- * application, you can use {@link Context#getMainExecutor()}. To
- * dispatch events through a shared thread pool, you can use
- * {@link AsyncTask#THREAD_POOL_EXECUTOR}.
+ * application, you can use
+ * {@link android.content.Context#getMainExecutor() Context.getMainExecutor()}.
+ * To dispatch events through a shared thread pool, you can use
+ * {@link android.os.AsyncTask#THREAD_POOL_EXECUTOR AsyncTask#THREAD_POOL_EXECUTOR}.
* @hide
*/
@Retention(SOURCE)
diff --git a/core/java/android/annotation/RequiresPermission.java b/core/java/android/annotation/RequiresPermission.java
index e5c0654f8bbe..1d89e31b2b99 100644
--- a/core/java/android/annotation/RequiresPermission.java
+++ b/core/java/android/annotation/RequiresPermission.java
@@ -15,9 +15,6 @@
*/
package android.annotation;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
@@ -25,6 +22,9 @@ import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.SOURCE;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
/**
* Denotes that the annotated element requires (or may require) one or more permissions.
* <p/>
@@ -55,7 +55,8 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
* <p>
* When specified on a parameter, the annotation indicates that the method requires
* a permission which depends on the value of the parameter. For example, consider
- * {@link android.app.Activity#startActivity(android.content.Intent)}:
+ * {@link android.app.Activity#startActivity(android.content.Intent)
+ * Activity#startActivity(Intent)}:
* <pre>{@code
* public void startActivity(@RequiresPermission Intent intent) { ... }
* }</pre>
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b6f61a2b8f01..4f1d7f2c761c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3618,7 +3618,6 @@ public class Activity extends ContextThemeWrapper
* To receive this callback, you must return true from onKeyDown for the current
* event stream.
*
- * @see KeyEvent.Callback#onKeyLongPress()
* @see KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
*/
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index bdaa44034565..85cd21dec283 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2082,8 +2082,7 @@ public class ActivityManager {
* has access to it.
*
* @see ActivityOptions#setLaunchDisplayId(int)
- * @see android.view.Display.FLAG_PRIVATE
- * @see android.view.Display.TYPE_VIRTUAL
+ * @see android.view.Display#FLAG_PRIVATE
*
* @param context Source context, from which an activity will be started.
* @param displayId Target display id.
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 7a560c07a365..0feed7383020 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -299,7 +299,8 @@ interface IActivityManager {
void handleApplicationStrictModeViolation(in IBinder app, int penaltyMask,
in StrictMode.ViolationInfo crashInfo);
boolean isTopActivityImmersive();
- void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message);
+ void crashApplication(int uid, int initialPid, in String packageName, int userId,
+ in String message, boolean force);
@UnsupportedAppUsage
String getProviderMimeType(in Uri uri, int userId);
// Cause the specified process to dump the specified heap.
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index cff6411c882c..2049b3408c64 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -729,7 +729,7 @@ public class Instrumentation {
* a non-null value if the intent needs to be intercepted.
*
* <p> Whenever a new activity is started, this method will be called on instances created
- * using {@link #Instrumentation.ActivityMonitor()} to check if there is a match. In case
+ * using {@link #ActivityMonitor()} to check if there is a match. In case
* of a match, the activity start will be blocked and the returned result will be used.
*
* @param intent The intent used for starting the activity.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index cefec441e702..f2b2635c8636 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3437,7 +3437,7 @@ public class Notification implements Parcelable
}
/**
- * @deprecated use {@link Notification.Builder#Notification.Builder(Context, String)}
+ * @deprecated use {@link #Builder(Context, String)}
* instead. All posted Notifications must specify a NotificationChannel Id.
*/
@Deprecated
@@ -7071,7 +7071,7 @@ public class Notification implements Parcelable
* Should be unique amongst all individuals in the conversation, and should be
* consistent during re-posts of the notification.
*
- * @see Message#Notification.MessagingStyle.Message(CharSequence, long, CharSequence)
+ * @see Message#Message(CharSequence, long, CharSequence)
*
* @return this object for method chaining
*
@@ -7091,7 +7091,7 @@ public class Notification implements Parcelable
* Should be <code>null</code> for messages by the current user, in which case
* the platform will insert the user set in {@code MessagingStyle(Person)}.
*
- * @see Message#Notification.MessagingStyle.Message(CharSequence, long, CharSequence)
+ * @see Message#Message(CharSequence, long, CharSequence)
*
* @return this object for method chaining
*/
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index e25558f16f26..925586feaf1d 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -294,7 +294,7 @@ public class NotificationManager {
* </p>
* </p>
*
- * @see {@link #addAutomaticZenRule(AutomaticZenRule)}
+ * @see #addAutomaticZenRule(AutomaticZenRule)
*/
@SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_AUTOMATIC_ZEN_RULE =
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index dc815b631e46..067a35fe1aba 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -803,7 +803,7 @@ public class BackupManager {
* has a work profile that was restored from another work profile with serial number
* {@code ancestralSerialNumber}.
*
- * @see UserManager#getSerialNumberForUser(UserHandle)
+ * @see android.os.UserManager#getSerialNumberForUser(UserHandle)
*/
@Nullable
public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
index 08b1c2b9f548..ec9c57466310 100644
--- a/core/java/android/app/job/JobScheduler.java
+++ b/core/java/android/app/job/JobScheduler.java
@@ -41,7 +41,7 @@ import java.util.List;
* system will execute this job on your application's {@link android.app.job.JobService}.
* You identify the service component that implements the logic for your job when you
* construct the JobInfo using
- * {@link android.app.job.JobInfo.Builder#JobInfo.Builder(int,android.content.ComponentName)}.
+ * {@link android.app.job.JobInfo.Builder#Builder(int,android.content.ComponentName)}.
* </p>
* <p>
* The framework will be intelligent about when it executes jobs, and attempt to batch
@@ -147,7 +147,7 @@ public abstract class JobScheduler {
* method is ignored.
*
* @param jobId unique identifier for the job to be canceled, as supplied to
- * {@link JobInfo.Builder#JobInfo.Builder(int, android.content.ComponentName)
+ * {@link JobInfo.Builder#Builder(int, android.content.ComponentName)
* JobInfo.Builder(int, android.content.ComponentName)}.
*/
public abstract void cancel(int jobId);
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index 2eb9459af877..4e5443a18bf2 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -102,8 +102,6 @@ public final class RoleManager {
/**
* The name of the emergency role
- *
- * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE
*/
public static final String ROLE_EMERGENCY = "android.app.role.EMERGENCY";
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3ed585c18e57..6e0ce3ff032a 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3519,7 +3519,6 @@ public abstract class Context {
* @see android.telephony.CarrierConfigManager
* @see #EUICC_SERVICE
* @see android.telephony.euicc.EuiccManager
- * @see #MMS_SERVICE
* @see android.telephony.MmsManager
* @see #INPUT_METHOD_SERVICE
* @see android.view.inputmethod.InputMethodManager
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index d5dadbff419f..7e8bb08e0086 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -16,8 +16,6 @@
package android.hardware.hdmi;
-import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
-
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -31,7 +29,7 @@ import android.annotation.SystemService;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.RemoteException;
-import android.os.SystemProperties;
+import android.sysprop.HdmiProperties;
import android.util.ArrayMap;
import android.util.Log;
@@ -316,8 +314,7 @@ public final class HdmiControlManager {
mHasPlaybackDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PLAYBACK);
mHasAudioSystemDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mHasSwitchDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
- mIsSwitchDevice = SystemProperties.getBoolean(
- PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
+ mIsSwitchDevice = HdmiProperties.is_switch().orElse(false);
}
private static boolean hasDeviceType(int[] types, int type) {
diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java
index afa63039b6f7..836624beb3b2 100644
--- a/core/java/android/net/Ikev2VpnProfile.java
+++ b/core/java/android/net/Ikev2VpnProfile.java
@@ -803,7 +803,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile {
* @param isMetered {@code true} if the VPN network should be treated as metered regardless
* of underlying network meteredness. Defaults to {@code true}.
* @return this {@link Builder} object to facilitate chaining of method calls
- * @see NetworkCapabilities.NET_CAPABILITY_NOT_METERED
+ * @see NetworkCapabilities#NET_CAPABILITY_NOT_METERED
*/
@NonNull
public Builder setMetered(boolean isMetered) {
diff --git a/core/java/android/net/MatchAllNetworkSpecifier.java b/core/java/android/net/MatchAllNetworkSpecifier.java
index 68a39355198b..70c4a7235b9d 100644
--- a/core/java/android/net/MatchAllNetworkSpecifier.java
+++ b/core/java/android/net/MatchAllNetworkSpecifier.java
@@ -43,7 +43,8 @@ public final class MatchAllNetworkSpecifier extends NetworkSpecifier implements
}
/** @hide */
- public boolean satisfiedBy(NetworkSpecifier other) {
+ @Override
+ public boolean canBeSatisfiedBy(NetworkSpecifier other) {
/*
* The method is called by a NetworkRequest to see if it is satisfied by a proposed
* network (e.g. as offered by a network factory). Since MatchAllNetweorkSpecifier must
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index fea3245784b2..74eced796b04 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -169,6 +169,7 @@ public final class NetworkCapabilities implements Parcelable {
NET_CAPABILITY_OEM_PAID,
NET_CAPABILITY_MCX,
NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+ NET_CAPABILITY_TEMPORARILY_NOT_METERED,
})
public @interface NetCapability { }
@@ -336,8 +337,16 @@ public final class NetworkCapabilities implements Parcelable {
@SystemApi
public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24;
+ /**
+ * This capability will be set for networks that are generally metered, but are currently
+ * unmetered, e.g., because the user is in a particular area. This capability can be changed at
+ * any time. When it is removed, applications are responsible for stopping any data transfer
+ * that should not occur on a metered network.
+ */
+ public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25;
+
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_PARTIAL_CONNECTIVITY;
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_TEMPORARILY_NOT_METERED;
/**
* Network capabilities that are expected to be mutable, i.e., can change while a particular
@@ -353,7 +362,8 @@ public final class NetworkCapabilities implements Parcelable {
| (1 << NET_CAPABILITY_FOREGROUND)
| (1 << NET_CAPABILITY_NOT_CONGESTED)
| (1 << NET_CAPABILITY_NOT_SUSPENDED)
- | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
+ | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY
+ | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED));
/**
* Network capabilities that are not allowed in NetworkRequests. This exists because the
@@ -424,6 +434,7 @@ public final class NetworkCapabilities implements Parcelable {
*/
private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES =
(1 << NET_CAPABILITY_NOT_METERED)
+ | (1 << NET_CAPABILITY_TEMPORARILY_NOT_METERED)
| (1 << NET_CAPABILITY_NOT_RESTRICTED)
| (1 << NET_CAPABILITY_NOT_VPN)
| (1 << NET_CAPABILITY_NOT_ROAMING)
@@ -1866,6 +1877,7 @@ public final class NetworkCapabilities implements Parcelable {
case NET_CAPABILITY_OEM_PAID: return "OEM_PAID";
case NET_CAPABILITY_MCX: return "MCX";
case NET_CAPABILITY_PARTIAL_CONNECTIVITY: return "PARTIAL_CONNECTIVITY";
+ case NET_CAPABILITY_TEMPORARILY_NOT_METERED: return "TEMPORARILY_NOT_METERED";
default: return Integer.toString(capability);
}
}
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index c233ec0e52cf..6539e0563794 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -24,6 +24,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
@@ -468,11 +469,13 @@ public class NetworkScoreManager {
*
* @param networks List of {@link ScoredNetwork} containing updated scores.
*/
+ @SuppressLint("CallbackMethodName")
void updateScores(@NonNull List<ScoredNetwork> networks);
/**
* Invokes when all the previously provided scores are no longer valid.
*/
+ @SuppressLint("CallbackMethodName")
void clearScores();
}
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 63e510733907..9c2c5b839302 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -836,7 +836,7 @@ public class VpnService extends Service {
* @param isMetered {@code true} if VPN network should be treated as metered regardless of
* underlying network meteredness
* @return this {@link Builder} object to facilitate chaining method calls
- * @see #setUnderlyingNetworks(Networks[])
+ * @see #setUnderlyingNetworks(Network[])
* @see ConnectivityManager#isActiveNetworkMetered()
*/
@NonNull
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 3faaff73a0ea..81457074f2fc 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -1015,7 +1015,6 @@ public final class StrictMode {
* behaviors or empty states. Instead, apps should store data needed
* while a user is locked under device protected storage areas.
*
- * @see Context#createCredentialProtectedStorageContext()
* @see Context#createDeviceProtectedStorageContext()
*/
public @NonNull Builder detectCredentialProtectedWhileLocked() {
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 75b4724c7d26..890057371471 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -55,21 +55,16 @@ public abstract class VibrationEffect implements Parcelable {
/**
* A click effect. Use this effect as a baseline, as it's the most common type of click effect.
- *
- * @see #get(int)
*/
public static final int EFFECT_CLICK = Effect.CLICK;
/**
* A double click effect.
- *
- * @see #get(int)
*/
public static final int EFFECT_DOUBLE_CLICK = Effect.DOUBLE_CLICK;
/**
* A tick effect. This effect is less strong compared to {@link #EFFECT_CLICK}.
- * @see #get(int)
*/
public static final int EFFECT_TICK = Effect.TICK;
@@ -93,7 +88,6 @@ public abstract class VibrationEffect implements Parcelable {
/**
* A heavy click effect. This effect is stronger than {@link #EFFECT_CLICK}.
- * @see #get(int)
*/
public static final int EFFECT_HEAVY_CLICK = Effect.HEAVY_CLICK;
diff --git a/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java b/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java
index 12503f650ab5..89cd43003529 100644
--- a/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java
+++ b/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java
@@ -28,7 +28,6 @@ import android.content.Context;
* store data needed while a user is locked under device protected storage
* areas.
*
- * @see Context#createCredentialProtectedStorageContext()
* @see Context#createDeviceProtectedStorageContext()
*/
public final class CredentialProtectedWhileLockedViolation extends Violation {
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 9c6c92ace483..17fae1cafe62 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -797,7 +797,6 @@ public final class CalendarContract {
* to changes.
*
* @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
- * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
*/
@NonNull
public static final Uri ENTERPRISE_CONTENT_URI =
@@ -1796,7 +1795,6 @@ public final class CalendarContract {
* to changes.
*
* @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
- * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
*/
@NonNull
public static final Uri ENTERPRISE_CONTENT_URI =
@@ -2010,7 +2008,6 @@ public final class CalendarContract {
* {@link DevicePolicyManager#setCrossProfileCalendarPackages(ComponentName, Set)}.
*
* @see DevicePolicyManager#getCrossProfileCalendarPackages(ComponentName)
- * @see Settings.Secure#CROSS_PROFILE_CALENDAR_ENABLED
*/
@NonNull
public static final Uri ENTERPRISE_CONTENT_URI =
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 4bbd213753c2..3980a5f75eda 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -23,7 +23,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ContentInterface;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -248,14 +247,14 @@ public final class DocumentsContract {
* Get string array identifies the type or types of metadata returned
* using DocumentsContract#getDocumentMetadata.
*
- * @see #getDocumentMetadata(ContentInterface, Uri)
+ * @see #getDocumentMetadata(ContentResolver, Uri)
*/
public static final String METADATA_TYPES = "android:documentMetadataTypes";
/**
* Get Exif information using DocumentsContract#getDocumentMetadata.
*
- * @see #getDocumentMetadata(ContentInterface, Uri)
+ * @see #getDocumentMetadata(ContentResolver, Uri)
*/
public static final String METADATA_EXIF = "android:documentExif";
@@ -263,7 +262,7 @@ public final class DocumentsContract {
* Get total count of all documents currently stored under the given
* directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
*
- * @see #getDocumentMetadata(ContentInterface, Uri)
+ * @see #getDocumentMetadata(ContentResolver, Uri)
*/
public static final String METADATA_TREE_COUNT = "android:metadataTreeCount";
@@ -271,7 +270,7 @@ public final class DocumentsContract {
* Get total size of all documents currently stored under the given
* directory tree. Only valid for {@link Document#MIME_TYPE_DIR} documents.
*
- * @see #getDocumentMetadata(ContentInterface, Uri)
+ * @see #getDocumentMetadata(ContentResolver, Uri)
*/
public static final String METADATA_TREE_SIZE = "android:metadataTreeSize";
@@ -395,7 +394,7 @@ public final class DocumentsContract {
* Flag indicating that a document can be represented as a thumbnail.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#getDocumentThumbnail(ContentInterface, Uri,
+ * @see DocumentsContract#getDocumentThumbnail(ContentResolver, Uri,
* Point, CancellationSignal)
* @see DocumentsProvider#openDocumentThumbnail(String, Point,
* android.os.CancellationSignal)
@@ -421,7 +420,7 @@ public final class DocumentsContract {
* Flag indicating that a document is deletable.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#deleteDocument(ContentInterface, Uri)
+ * @see DocumentsContract#deleteDocument(ContentResolver, Uri)
* @see DocumentsProvider#deleteDocument(String)
*/
public static final int FLAG_SUPPORTS_DELETE = 1 << 2;
@@ -459,7 +458,7 @@ public final class DocumentsContract {
* Flag indicating that a document can be renamed.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#renameDocument(ContentInterface, Uri, String)
+ * @see DocumentsContract#renameDocument(ContentResolver, Uri, String)
* @see DocumentsProvider#renameDocument(String, String)
*/
public static final int FLAG_SUPPORTS_RENAME = 1 << 6;
@@ -469,7 +468,7 @@ public final class DocumentsContract {
* within the same document provider.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#copyDocument(ContentInterface, Uri, Uri)
+ * @see DocumentsContract#copyDocument(ContentResolver, Uri, Uri)
* @see DocumentsProvider#copyDocument(String, String)
*/
public static final int FLAG_SUPPORTS_COPY = 1 << 7;
@@ -479,7 +478,7 @@ public final class DocumentsContract {
* within the same document provider.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#moveDocument(ContentInterface, Uri, Uri, Uri)
+ * @see DocumentsContract#moveDocument(ContentResolver, Uri, Uri, Uri)
* @see DocumentsProvider#moveDocument(String, String, String)
*/
public static final int FLAG_SUPPORTS_MOVE = 1 << 8;
@@ -503,7 +502,7 @@ public final class DocumentsContract {
* Flag indicating that a document can be removed from a parent.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#removeDocument(ContentInterface, Uri, Uri)
+ * @see DocumentsContract#removeDocument(ContentResolver, Uri, Uri)
* @see DocumentsProvider#removeDocument(String, String)
*/
public static final int FLAG_SUPPORTS_REMOVE = 1 << 10;
@@ -539,7 +538,7 @@ public final class DocumentsContract {
* using DocumentsContract#getDocumentMetadata
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#getDocumentMetadata(ContentInterface, Uri)
+ * @see DocumentsContract#getDocumentMetadata(ContentResolver, Uri)
*/
public static final int FLAG_SUPPORTS_METADATA = 1 << 14;
}
@@ -721,7 +720,7 @@ public final class DocumentsContract {
* Flag indicating that this root can be ejected.
*
* @see #COLUMN_FLAGS
- * @see DocumentsContract#ejectRoot(ContentInterface, Uri)
+ * @see DocumentsContract#ejectRoot(ContentResolver, Uri)
* @see DocumentsProvider#ejectRoot(String)
*/
public static final int FLAG_SUPPORTS_EJECT = 1 << 5;
diff --git a/core/java/android/service/autofill/CustomDescription.java b/core/java/android/service/autofill/CustomDescription.java
index c28d2bbe30ea..e274460cdf03 100644
--- a/core/java/android/service/autofill/CustomDescription.java
+++ b/core/java/android/service/autofill/CustomDescription.java
@@ -262,7 +262,7 @@ public final class CustomDescription implements Parcelable {
*
* @param condition condition used to trigger the updates.
* @param updates actions to be applied to the
- * {@link #CustomDescription.Builder(RemoteViews) template presentation} when the condition
+ * {@link #Builder(RemoteViews) template presentation} when the condition
* is satisfied.
*
* @return this builder
diff --git a/core/java/android/service/autofill/ImageTransformation.java b/core/java/android/service/autofill/ImageTransformation.java
index 12376e85e63e..974f0ead9d19 100644
--- a/core/java/android/service/autofill/ImageTransformation.java
+++ b/core/java/android/service/autofill/ImageTransformation.java
@@ -123,7 +123,7 @@ public final class ImageTransformation extends InternalTransformation implements
* {@link RemoteViews presentation} must contain a {@link ImageView} child with that id.
*
* @deprecated use
- * {@link #ImageTransformation.Builder(AutofillId, Pattern, int, CharSequence)} instead.
+ * {@link #Builder(AutofillId, Pattern, int, CharSequence)} instead.
*/
@Deprecated
public Builder(@NonNull AutofillId id, @NonNull Pattern regex, @DrawableRes int resId) {
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 94b9d050a44d..3a70befb3558 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -628,7 +628,7 @@ public final class SaveInfo implements Parcelable {
*
* <p>The sanitizer can also be used as an alternative for a
* {@link #setValidator(Validator) validator}. If any of the {@code ids} is a
- * {@link #SaveInfo.Builder(int, AutofillId[]) required id} and the {@code sanitizer} fails
+ * {@link #Builder(int, AutofillId[]) required id} and the {@code sanitizer} fails
* because of it, then the save UI is not shown.
*
* @param sanitizer an implementation provided by the Android System.
@@ -686,7 +686,7 @@ public final class SaveInfo implements Parcelable {
* Builds a new {@link SaveInfo} instance.
*
* @throws IllegalStateException if no
- * {@link #SaveInfo.Builder(int, AutofillId[]) required ids},
+ * {@link #Builder(int, AutofillId[]) required ids},
* or {@link #setOptionalIds(AutofillId[]) optional ids}, or {@link #FLAG_DELAY_SAVE}
* were set
*/
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 7267db3b3a1f..d64077525905 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -379,8 +379,6 @@ public class PhoneStateListener {
*
* <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
* app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
- *
- * @see #onEmergencyNumberListChanged
*/
public static final int LISTEN_EMERGENCY_NUMBER_LIST = 0x01000000;
@@ -459,7 +457,7 @@ public class PhoneStateListener {
* <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
* app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
*
- * @see #onRegistrationFailed()
+ * @see #onRegistrationFailed
*/
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000;
@@ -470,7 +468,7 @@ public class PhoneStateListener {
* <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
* app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
*
- * @see #onBarringInfoChanged()
+ * @see #onBarringInfoChanged
*/
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
public static final int LISTEN_BARRING_INFO = 0x80000000;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fe60bba92739..40dfcfc391a0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -25801,9 +25801,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Returns the View object that had been passed to the
- * {@link #View.DragShadowBuilder(View)}
+ * {@link #DragShadowBuilder(View)}
* constructor. If that View parameter was {@code null} or if the
- * {@link #View.DragShadowBuilder()}
+ * {@link #DragShadowBuilder()}
* constructor was used to instantiate the builder object, this method will return
* null.
*
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d9d92788a434..859b137dc2ce 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -614,7 +614,6 @@ public interface WindowManager extends ViewManager {
* @see #TYPE_TOAST
* @see #TYPE_SYSTEM_OVERLAY
* @see #TYPE_PRIORITY_PHONE
- * @see #TYPE_STATUS_BAR_PANEL
* @see #TYPE_SYSTEM_DIALOG
* @see #TYPE_KEYGUARD_DIALOG
* @see #TYPE_SYSTEM_ERROR
diff --git a/core/java/android/view/inspector/StaticInspectionCompanionProvider.java b/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
index 42a892dedf4d..903fc13a03ea 100644
--- a/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
+++ b/core/java/android/view/inspector/StaticInspectionCompanionProvider.java
@@ -21,8 +21,6 @@ import android.annotation.Nullable;
/**
* An inspection companion provider that finds companions as inner classes or generated code.
- *
- * @see android.processor.view.inspector.PlatformInspectableProcessor
*/
public class StaticInspectionCompanionProvider implements InspectionCompanionProvider {
/**
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 8182d60ef459..8b659f927633 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -18,6 +18,7 @@ package com.android.internal.os;
import android.os.SystemProperties;
import android.sysprop.CryptoProperties;
+import android.sysprop.HdmiProperties;
/**
* This is a cache of various ro.* properties so that they can be read just once
@@ -37,16 +38,7 @@ public class RoSystemProperties {
* mode is off.
*/
public static final boolean CEC_AUDIO_DEVICE_FORWARD_VOLUME_KEYS_SYSTEM_AUDIO_MODE_OFF =
- SystemProperties.getBoolean(
- "ro.hdmi.cec_audio_device_forward_volume_keys_system_audio_mode_off", false);
-
- /**
- * Property to indicate if the current device is a cec switch device.
- *
- * <p> Default is false.
- */
- public static final String PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH =
- "ro.hdmi.property_is_device_hdmi_cec_switch";
+ HdmiProperties.forward_volume_keys_when_system_audio_mode_off().orElse(false);
// ------ ro.config.* -------- //
public static final boolean CONFIG_AVOID_GFX_ACCEL =
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index ca4735ec665a..8fc1758c44dc 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -35,6 +35,7 @@
static const char* kPathWhitelist[] = {
"/apex/com.android.conscrypt/javalib/conscrypt.jar",
"/apex/com.android.ipsec/javalib/ike.jar",
+ "/apex/com.android.i18n/javalib/core-icu4j.jar",
"/apex/com.android.media/javalib/updatable-media.jar",
"/apex/com.android.sdkext/javalib/framework-sdkextensions.jar",
"/apex/com.android.tethering/javalib/framework-tethering.jar",
@@ -81,11 +82,18 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const {
}
// Framework jars are allowed.
- static const char* kFrameworksPrefix = "/system/framework/";
+ static const char* kFrameworksPrefix[] = {
+ "/system/framework/",
+ "/system_ext/framework/",
+ };
+
static const char* kJarSuffix = ".jar";
- if (android::base::StartsWith(path, kFrameworksPrefix)
- && android::base::EndsWith(path, kJarSuffix)) {
- return true;
+
+ for (const auto& frameworks_prefix : kFrameworksPrefix) {
+ if (android::base::StartsWith(path, frameworks_prefix)
+ && android::base::EndsWith(path, kJarSuffix)) {
+ return true;
+ }
}
// Jars from the ART APEX are allowed.
diff --git a/core/res/res/values-mcc334-mnc020/config.xml b/core/res/res/values-mcc334-mnc020/config.xml
index 0970517835b6..82b3ee6448e3 100644
--- a/core/res/res/values-mcc334-mnc020/config.xml
+++ b/core/res/res/values-mcc334-mnc020/config.xml
@@ -18,4 +18,7 @@
-->
<resources>
<bool name="config_use_sim_language_file">false</bool>
-</resources> \ No newline at end of file
+
+ <bool name="config_pdp_reject_enable_retry">true</bool>
+ <integer name="config_pdp_reject_retry_delay_ms">45000</integer>
+</resources>
diff --git a/core/res/res/values-mcc334-mnc020/strings.xml b/core/res/res/values-mcc334-mnc020/strings.xml
new file mode 100644
index 000000000000..91b560aeef7e
--- /dev/null
+++ b/core/res/res/values-mcc334-mnc020/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2020, 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="config_pdp_reject_dialog_title"></string>
+ <string name="config_pdp_reject_user_authentication_failed">AUTHENTICATION FAILURE -29-.</string>
+ <string name="config_pdp_reject_service_not_subscribed">NOT SUBSCRIBED TO SERVICE -33-.</string>
+ <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed">Multiple PDN connections for a given APN not allowed -55-.</string>
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2f301946402b..b908ab8b709e 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4742,7 +4742,7 @@
May be a string value, which is a comma-separated language tag list, such as "ja-JP,zh-CN".
When not specified or an empty string is given, it will fallback to the default one.
{@see android.os.LocaleList#forLanguageTags(String)}
- {@see android.text.TextView#setTextLocales(android.os.LocaleList)} -->
+ {@see android.widget.TextView#setTextLocales(android.os.LocaleList)} -->
<attr name="textLocale" format="string" />
<!-- Text color for links. -->
<attr name="textColorLink" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d7ab426ec9dd..6cbea4074484 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4367,4 +4367,9 @@
<!-- Boolean indicating whether frameworks needs to reset cell broadcast geo-fencing
check after reboot or airplane mode toggling -->
<bool translatable="false" name="reset_geo_fencing_check_after_boot_or_apm">false</bool>
+
+ <!-- pdp data retry for cause 29, 33 and 55-->
+ <bool name="config_pdp_reject_enable_retry">false</bool>
+ <!--pdp data reject retry delay in ms-->
+ <integer name="config_pdp_reject_retry_delay_ms">-1</integer>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7f463807e1e9..12fc1bb8553c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5653,4 +5653,10 @@ ul.</string>
<string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS">IMPI unlock successful.</string>
<!-- Success message displayed on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
<string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS">Network subset service provider unlock successful.</string>
+
+ <!-- pdp data reject dialog string for cause 29, 33 and 55-->
+ <string name="config_pdp_reject_dialog_title"></string>
+ <string name="config_pdp_reject_user_authentication_failed"></string>
+ <string name="config_pdp_reject_service_not_subscribed"></string>
+ <string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed"></string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d65d09233052..a844d8ae5a61 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3872,4 +3872,12 @@
<java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" />
<java-symbol type="bool" name="reset_geo_fencing_check_after_boot_or_apm" />
+
+ <!-- For Pdn throttle feature -->
+ <java-symbol type="bool" name="config_pdp_reject_enable_retry" />
+ <java-symbol type="integer" name="config_pdp_reject_retry_delay_ms" />
+ <java-symbol type="string" name="config_pdp_reject_dialog_title" />
+ <java-symbol type="string" name="config_pdp_reject_user_authentication_failed" />
+ <java-symbol type="string" name="config_pdp_reject_service_not_subscribed" />
+ <java-symbol type="string" name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" />
</resources>
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index ae7fe6c46f2f..c3c56dbbc6aa 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -998,7 +998,7 @@ public final class RenderNode {
* Sets the rotation value for the display list around the Z axis.
*
* @param rotation The rotation value of the display list, in degrees
- * @see View#setRotationZ(float)
+ * @see View#setRotation(float)
* @see #getRotationZ()
* @return True if the value changed, false if the new value was the same as the previous value.
*/
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index e70529b6cd1a..9cf12f121e0a 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -617,7 +617,7 @@ public abstract class Drawable {
* {@link #setTintList(ColorStateList) tint}.
* </p>
*
- * @see {@link #setColorFilter(ColorFilter)} }
+ * @see #setColorFilter(ColorFilter)
* @deprecated use {@link #setColorFilter(ColorFilter)} with an instance
* of {@link android.graphics.BlendModeColorFilter}
*/
diff --git a/graphics/java/android/graphics/fonts/FontStyle.java b/graphics/java/android/graphics/fonts/FontStyle.java
index af517d623b01..09799fdf5a13 100644
--- a/graphics/java/android/graphics/fonts/FontStyle.java
+++ b/graphics/java/android/graphics/fonts/FontStyle.java
@@ -217,7 +217,7 @@ public final class FontStyle {
/**
* Gets the weight value
*
- * @see FontStyle#setWeight(int)
+ * @see #FontStyle(int, int)
* @return a weight value
*/
public @IntRange(from = 0, to = 1000) int getWeight() {
diff --git a/graphics/java/android/graphics/text/LineBreaker.java b/graphics/java/android/graphics/text/LineBreaker.java
index 54622c5e74df..babcfc3815f4 100644
--- a/graphics/java/android/graphics/text/LineBreaker.java
+++ b/graphics/java/android/graphics/text/LineBreaker.java
@@ -320,7 +320,7 @@ public class LineBreaker {
/**
* Returns the array of tab stops in pixels.
*
- * @see #setTabStops(float[], int)
+ * @see #setTabStops
*/
public @Nullable float[] getTabStops() {
return mVariableTabStops;
@@ -329,7 +329,7 @@ public class LineBreaker {
/**
* Returns the default tab stops in pixels.
*
- * @see #setTabStop(float[], int)
+ * @see #setTabStops
*/
public @Px @FloatRange(from = 0) float getDefaultTabStop() {
return mDefaultTabStop;
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index e9bc8026d25e..d35642e362b1 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -1067,6 +1067,17 @@ public class KeyStore {
return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword);
}
+ /**
+ * Notify keystore about the latest user locked state. This is to support keyguard-bound key.
+ */
+ public void onUserLockedStateChanged(int userHandle, boolean locked) {
+ try {
+ mBinder.onKeyguardVisibilityChanged(locked, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to update user locked state " + userHandle, e);
+ }
+ }
+
private class KeyAttestationCallbackResult {
private KeystoreResponse keystoreResponse;
private KeymasterCertificateChain certificateChain;
diff --git a/media/Android.bp b/media/Android.bp
index 43635684d9b3..a432c8d2a64d 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -26,8 +26,10 @@ java_library {
installable: true,
- // Make sure that the implementaion only relies on SDK or system APIs.
+ // TODO: build against stable API surface. Use core_platform for now to avoid
+ // link-check failure with exoplayer building against "current".
sdk_version: "core_platform",
+ min_sdk_version: "29",
libs: [
// The order matters. android_system_* library should come later.
"framework_media_annotation",
@@ -94,4 +96,5 @@ java_library {
name: "framework_media_annotation",
srcs: [":framework-media-annotation-srcs"],
installable: false,
+ sdk_version: "core_current",
}
diff --git a/media/java/android/media/AudioFocusRequest.java b/media/java/android/media/AudioFocusRequest.java
index 4e7050129058..4c0850b675a8 100644
--- a/media/java/android/media/AudioFocusRequest.java
+++ b/media/java/android/media/AudioFocusRequest.java
@@ -80,9 +80,9 @@ import android.os.Looper;
* <p>An {@code AudioFocusRequest} instance always contains one of the four types of requests
* explained above. It is passed when building an {@code AudioFocusRequest} instance with its
* builder in the {@link Builder} constructor
- * {@link AudioFocusRequest.Builder#AudioFocusRequest.Builder(int)}, or
+ * {@link AudioFocusRequest.Builder#Builder(int)}, or
* with {@link AudioFocusRequest.Builder#setFocusGain(int)} after copying an existing instance with
- * {@link AudioFocusRequest.Builder#AudioFocusRequest.Builder(AudioFocusRequest)}.
+ * {@link AudioFocusRequest.Builder#Builder(AudioFocusRequest)}.
*
* <h3>Qualifying your focus request</h3>
* <h4>Use case requiring a focus request</h4>
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 0ced68ef8695..babe0723dc01 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1098,7 +1098,7 @@ public class AudioTrack extends PlayerBase
* Can only be called only if the AudioTrack is opened in offload mode
* {@see Builder#setOffloadedPlayback(boolean)}.
* Can only be called only if the AudioTrack is in state {@link #PLAYSTATE_PLAYING}
- * {@see #getPlaystate()}.
+ * {@see #getPlayState()}.
* Use this method in the same thread as any write() operation.
*/
public void setOffloadEndOfStream() {
diff --git a/native/android/Android.bp b/native/android/Android.bp
index ae8cb3a47a05..9f52d856ea75 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -93,6 +93,14 @@ cc_library_shared {
},
}
+// Header-only library used for atrace in platform NDK builds
+cc_library_headers {
+ name: "libandroid_trace",
+ host_supported: true,
+ vendor_available: true,
+ export_include_dirs: ["trace"],
+}
+
// Network library.
cc_library_shared {
name: "libandroid_net",
@@ -137,4 +145,4 @@ filegroup {
"aidl/com/android/internal/compat/IPlatformCompatNative.aidl",
],
path: "aidl",
-} \ No newline at end of file
+}
diff --git a/native/android/trace/android/trace.h b/native/android/trace/android/trace.h
new file mode 100644
index 000000000000..4e569e566bc2
--- /dev/null
+++ b/native/android/trace/android/trace.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+#ifndef ANDROID_ATRACE_HEADERS_H
+#define ANDROID_ATRACE_HEADERS_H
+
+#include <cutils/trace.h>
+
+inline void ATrace_beginSection(const char* sectionName) {
+ atrace_begin(ATRACE_TAG_APP, sectionName);
+}
+
+inline void ATrace_endSection() {
+ atrace_end(ATRACE_TAG_APP);
+}
+
+#endif // ANDROID_ATRACE_HEADERS_H
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 688e8eb8f2e3..7c49c3f961c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -566,6 +566,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
addOnExpandedHeightChangedListener(mRoundnessManager::setExpanded);
+ mLockscreenUserManager.addUserChangedListener(userId ->
+ updateSensitiveness(false /* animated */));
setOutlineProvider(mOutlineProvider);
// Blocking helper manager wants to know the expanded state, update as well.
@@ -4602,7 +4604,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void setHideSensitive(boolean hideSensitive, boolean animate) {
+ private void updateSensitiveness(boolean animate) {
+ boolean hideSensitive = mLockscreenUserManager.isAnyProfilePublicMode();
if (hideSensitive != mAmbientState.isHideSensitive()) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -5306,7 +5309,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
SysuiStatusBarStateController state = (SysuiStatusBarStateController)
Dependency.get(StatusBarStateController.class);
- setHideSensitive(publicMode, state.goingToFullShade() /* animate */);
+ updateSensitiveness(state.goingToFullShade() /* animate */);
setDimmed(onKeyguard, state.fromShadeLocked() /* animate */);
setExpandingEnabled(!onKeyguard);
ActivatableNotificationView activatedChild = getActivatedChild();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 31054260eb15..f2ed3e648220 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -57,6 +57,8 @@ import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.EmptyShadeView;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShelf;
@@ -119,6 +121,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Mock private MetricsLogger mMetricsLogger;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private KeyguardBypassController mKeyguardBypassController;
+ @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
+ private UserChangedListener mUserChangedListener;
private TestableNotificationEntryManager mEntryManager;
private int mOriginalInterruptionModelSetting;
@@ -137,7 +141,9 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mDependency.injectTestDependency(
NotificationBlockingHelperManager.class,
mBlockingHelperManager);
- mDependency.injectTestDependency(SysuiStatusBarStateController.class, mBarState);
+ mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
+ mLockscreenUserManager);
+ mDependency.injectTestDependency(StatusBarStateController.class, mBarState);
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mDependency.injectTestDependency(NotificationRemoteInputManager.class,
mRemoteInputManager);
@@ -152,6 +158,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
NotificationShelf notificationShelf = mock(NotificationShelf.class);
+ ArgumentCaptor<UserChangedListener> userChangedCaptor = ArgumentCaptor
+ .forClass(UserChangedListener.class);
// The actual class under test. You may need to work with this class directly when
// testing anonymous class members of mStackScroller, like mMenuEventListener,
@@ -174,6 +182,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mStackScroller.setGroupManager(mGroupManager);
mStackScroller.setEmptyShadeView(mEmptyShadeView);
mStackScroller.setIconAreaController(mNotificationIconAreaController);
+ verify(mLockscreenUserManager).addUserChangedListener(userChangedCaptor.capture());
+ mUserChangedListener = userChangedCaptor.getValue();
// Stub out functionality that isn't necessary to test.
doNothing().when(mBar)
@@ -247,6 +257,12 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
+ public void testOnStatePostChange_verifyIfProfileIsPublic() {
+ mUserChangedListener.onUserChanged(0);
+ verify(mLockscreenUserManager).isAnyProfilePublicMode();
+ }
+
+ @Test
public void manageNotifications_visible() {
FooterView view = mock(FooterView.class);
mStackScroller.setFooterView(view);
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 27297c44573c..29660a9c4dce 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -27,7 +27,7 @@ java_defaults {
"androidx.annotation_annotation",
"netd_aidl_interface-V3-java",
"netlink-client",
- "networkstack-aidl-interfaces-unstable-java",
+ "networkstack-aidl-interfaces-java",
"android.hardware.tetheroffload.config-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
"net-utils-framework-common",
@@ -50,6 +50,11 @@ android_library {
cc_library {
name: "libtetherutilsjni",
sdk_version: "current",
+ apex_available: [
+ "//apex_available:platform", // Used by InProcessTethering
+ "com.android.tethering",
+ ],
+ min_sdk_version: "current",
srcs: [
"jni/android_net_util_TetheringUtils.cpp",
],
@@ -108,6 +113,7 @@ android_app {
manifest: "AndroidManifest_InProcess.xml",
// InProcessTethering is a replacement for Tethering
overrides: ["Tethering"],
+ apex_available: ["com.android.tethering"],
}
// Updatable tethering packaged as an application
@@ -121,4 +127,5 @@ android_app {
// The permission configuration *must* be included to ensure security of the device
required: ["NetworkPermissionConfig"],
apex_available: ["com.android.tethering"],
+ min_sdk_version: "current",
}
diff --git a/packages/Tethering/apex/Android.bp b/packages/Tethering/apex/Android.bp
index 24df5f696077..67097a79e5c0 100644
--- a/packages/Tethering/apex/Android.bp
+++ b/packages/Tethering/apex/Android.bp
@@ -17,7 +17,7 @@
apex {
name: "com.android.tethering",
updatable: true,
- min_sdk_version: "R",
+ min_sdk_version: "current",
java_libs: ["framework-tethering"],
apps: ["Tethering"],
manifest: "manifest.json",
@@ -36,3 +36,12 @@ android_app_certificate {
name: "com.android.tethering.certificate",
certificate: "com.android.tethering",
}
+
+override_apex {
+ name: "com.android.tethering.inprocess",
+ base: "com.android.tethering",
+ package_name: "com.android.tethering.inprocess",
+ apps: [
+ "InProcessTethering",
+ ],
+}
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index ee6b9f12f9d2..7ac9d251e1bb 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -37,6 +37,12 @@ aidl_interface {
cpp: {
enabled: false,
},
+ java: {
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
+ ],
+ },
},
}
@@ -67,6 +73,7 @@ java_library {
stubs_defaults {
name: "framework-tethering-stubs-defaults",
srcs: [":framework-tethering-srcs"],
+ dist: { dest: "framework-tethering.txt" },
}
filegroup {
@@ -123,16 +130,19 @@ java_library {
name: "framework-tethering-stubs-publicapi",
srcs: [":framework-tethering-stubs-srcs-publicapi"],
defaults: ["framework-module-stubs-lib-defaults-publicapi"],
+ dist: { dest: "framework-tethering.jar" },
}
java_library {
name: "framework-tethering-stubs-systemapi",
srcs: [":framework-tethering-stubs-srcs-systemapi"],
defaults: ["framework-module-stubs-lib-defaults-systemapi"],
+ dist: { dest: "framework-tethering.jar" },
}
java_library {
name: "framework-tethering-stubs-module_libs_api",
srcs: [":framework-tethering-stubs-srcs-module_libs_api"],
- defaults: ["framework-module-stubs-lib-defaults-systemapi"],
+ defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
+ dist: { dest: "framework-tethering.jar" },
}
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
index 2a7330098faf..d074f1569933 100644
--- a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (5030042590486713460) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (3843613362272973447) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिङमार्फत इन्टरनेट कनेक्सन प्राप्त हुन सकेन"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
<string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
index ea04821e33bd..f4b15aab19b7 100644
--- a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (5030042590486713460) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (3843613362272973447) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"சாதனங்களால் இணைய முடியவில்லை"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"இணைப்பு முறையை ஆஃப் செய்"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
<string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
index 05b90692ea7b..528a1e52925c 100644
--- a/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
@@ -16,9 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過數據連線連上網際網路"</string>
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過網路共用連上網際網路"</string>
<string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連線"</string>
- <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉數據連線"</string>
- <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"無線基地台或數據連線已開啟"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉網路共用"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"無線基地台或網路共用已開啟"</string>
<string name="upstream_roaming_notification_message" msgid="6724434706748439902">"使用漫遊服務可能須支付額外費用"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
index 617c50dd0ce8..1503244f5000 100644
--- a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (611650570559011140) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (6508394877641864863) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिङमार्फत इन्टरनेट कनेक्सन प्राप्त हुन सकेन"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"यन्त्रहरू कनेक्ट गर्न सकिएन"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिङ निष्क्रिय पार्नुहोस्"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हटस्पट वा टेदरिङ सक्रिय छ"</string>
<string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
index 0e437593ee87..2ea2467e5879 100644
--- a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
@@ -16,13 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for no_upstream_notification_title (611650570559011140) -->
- <skip />
- <!-- no translation found for no_upstream_notification_message (6508394877641864863) -->
- <skip />
- <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) -->
- <skip />
- <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) -->
- <skip />
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"இணைப்பு முறைக்கு இணைய இணைப்பு இல்லை"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"சாதனங்களால் இணைய முடியவில்லை"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"இணைப்பு முறையை ஆஃப் செய்"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ஹாட்ஸ்பாட் அல்லது இணைப்பு முறை ஆன் செய்யப்பட்டுள்ளது"</string>
<string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
index ea01b943fbe8..cd653df1dac6 100644
--- a/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
@@ -16,9 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過數據連線連上網際網路"</string>
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過網路共用連上網際網路"</string>
<string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連線"</string>
- <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉數據連線"</string>
- <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"無線基地台或數據連線已開啟"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉網路共用"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"無線基地台或網路共用已開啟"</string>
<string name="upstream_roaming_notification_message" msgid="7599056263326217523">"使用漫遊服務可能須支付額外費用"</string>
</resources>
diff --git a/packages/Tethering/res/values-zh-rTW/strings.xml b/packages/Tethering/res/values-zh-rTW/strings.xml
index 9d738a76eb0e..50a50bf7a996 100644
--- a/packages/Tethering/res/values-zh-rTW/strings.xml
+++ b/packages/Tethering/res/values-zh-rTW/strings.xml
@@ -16,11 +16,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="6426563586025792944">"數據連線或無線基地台已啟用"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"網路共用或無線基地台已啟用"</string>
<string name="tethered_notification_message" msgid="64800879503420696">"輕觸即可進行設定。"</string>
- <string name="disable_tether_notification_title" msgid="3004509127903564191">"數據連線已停用"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"網路共用已停用"</string>
<string name="disable_tether_notification_message" msgid="6717523799293901476">"詳情請洽你的管理員"</string>
- <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與數據連線狀態"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與網路共用狀態"</string>
<string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
<string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
<string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
diff --git a/packages/Tethering/res/values/config.xml b/packages/Tethering/res/values/config.xml
index effc24ac4de5..c99922196346 100644
--- a/packages/Tethering/res/values/config.xml
+++ b/packages/Tethering/res/values/config.xml
@@ -62,6 +62,13 @@
<string-array translatable="false" name="config_tether_dhcp_range">
</string-array>
+ <!-- Used to config periodic polls tether offload stats from tethering offload HAL to make the
+ data warnings work. 5000(ms) by default. If the device doesn't want to poll tether
+ offload stats, this should be -1. Note that this setting could be override by
+ runtime resource overlays.
+ -->
+ <integer translatable="false" name="config_tether_offload_poll_interval">5000</integer>
+
<!-- Array of ConnectivityManager.TYPE_{BLUETOOTH, ETHERNET, MOBILE, MOBILE_DUN, MOBILE_HIPRI,
WIFI} values allowable for tethering.
diff --git a/packages/Tethering/res/values/overlayable.xml b/packages/Tethering/res/values/overlayable.xml
index 16ae8ade19da..4c78a74d5358 100644
--- a/packages/Tethering/res/values/overlayable.xml
+++ b/packages/Tethering/res/values/overlayable.xml
@@ -24,6 +24,7 @@
<item type="array" name="config_tether_bluetooth_regexs"/>
<item type="array" name="config_tether_dhcp_range"/>
<item type="bool" name="config_tether_enable_legacy_dhcp_server"/>
+ <item type="integer" name="config_tether_offload_poll_interval"/>
<item type="array" name="config_tether_upstream_types"/>
<item type="bool" name="config_tether_upstream_automatic"/>
<!-- Configuration values for tethering entitlement check -->
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
index 049a9f68bbd2..3c6e8d88ed13 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java
@@ -37,6 +37,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.util.SharedLog;
import android.os.Bundle;
+import android.os.ConditionVariable;
import android.os.Handler;
import android.os.Parcel;
import android.os.PersistableBundle;
@@ -45,13 +46,12 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
-import android.util.ArraySet;
import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.StateMachine;
import java.io.PrintWriter;
+import java.util.BitSet;
/**
* Re-check tethering provisioning for enabled downstream tether types.
@@ -73,39 +73,39 @@ public class EntitlementManager {
private final ComponentName mSilentProvisioningService;
private static final int MS_PER_HOUR = 60 * 60 * 1000;
+ private static final int DUMP_TIMEOUT = 10_000;
- // The ArraySet contains enabled downstream types, ex:
+ // The BitSet is the bit map of each enabled downstream types, ex:
// {@link TetheringManager.TETHERING_WIFI}
// {@link TetheringManager.TETHERING_USB}
// {@link TetheringManager.TETHERING_BLUETOOTH}
- private final ArraySet<Integer> mCurrentTethers;
+ private final BitSet mCurrentDownstreams;
+ private final BitSet mExemptedDownstreams;
private final Context mContext;
- private final int mPermissionChangeMessageCode;
private final SharedLog mLog;
private final SparseIntArray mEntitlementCacheValue;
private final Handler mHandler;
- private final StateMachine mTetherMasterSM;
// Key: TetheringManager.TETHERING_*(downstream).
// Value: TetheringManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result).
- private final SparseIntArray mCellularPermitted;
+ private final SparseIntArray mCurrentEntitlementResults;
+ private final Runnable mPermissionChangeCallback;
private PendingIntent mProvisioningRecheckAlarm;
- private boolean mCellularUpstreamPermitted = true;
+ private boolean mLastCellularUpstreamPermitted = true;
private boolean mUsingCellularAsUpstream = false;
private boolean mNeedReRunProvisioningUi = false;
private OnUiEntitlementFailedListener mListener;
private TetheringConfigurationFetcher mFetcher;
- public EntitlementManager(Context ctx, StateMachine tetherMasterSM, SharedLog log,
- int permissionChangeMessageCode) {
-
+ public EntitlementManager(Context ctx, Handler h, SharedLog log,
+ Runnable callback) {
mContext = ctx;
mLog = log.forSubComponent(TAG);
- mCurrentTethers = new ArraySet<Integer>();
- mCellularPermitted = new SparseIntArray();
+ mCurrentDownstreams = new BitSet();
+ mExemptedDownstreams = new BitSet();
+ mCurrentEntitlementResults = new SparseIntArray();
mEntitlementCacheValue = new SparseIntArray();
- mTetherMasterSM = tetherMasterSM;
- mPermissionChangeMessageCode = permissionChangeMessageCode;
- mHandler = tetherMasterSM.getHandler();
+ mPermissionChangeCallback = callback;
+ mHandler = h;
mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PROVISIONING_ALARM),
null, mHandler);
mSilentProvisioningService = ComponentName.unflattenFromString(
@@ -144,13 +144,35 @@ public class EntitlementManager {
* Check if cellular upstream is permitted.
*/
public boolean isCellularUpstreamPermitted() {
- // If provisioning is required and EntitlementManager don't know any downstream,
- // cellular upstream should not be allowed.
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- if (mCurrentTethers.size() == 0 && isTetherProvisioningRequired(config)) {
- return false;
- }
- return mCellularUpstreamPermitted;
+
+ return isCellularUpstreamPermitted(config);
+ }
+
+ private boolean isCellularUpstreamPermitted(final TetheringConfiguration config) {
+ if (!isTetherProvisioningRequired(config)) return true;
+
+ // If provisioning is required and EntitlementManager doesn't know any downstreams, cellular
+ // upstream should not be enabled. Enable cellular upstream for exempted downstreams only
+ // when there is no non-exempted downstream.
+ if (mCurrentDownstreams.isEmpty()) return !mExemptedDownstreams.isEmpty();
+
+ return mCurrentEntitlementResults.indexOfValue(TETHER_ERROR_NO_ERROR) > -1;
+ }
+
+ /**
+ * Set exempted downstream type. If there is only exempted downstream type active,
+ * corresponding entitlement check will not be run and cellular upstream will be permitted
+ * by default. If a privileged app enables tethering without a provisioning check, and then
+ * another app enables tethering of the same type but does not disable the provisioning check,
+ * then the downstream immediately loses exempt status and a provisioning check is run.
+ * If any non-exempted downstream type is active, the cellular upstream will be gated by the
+ * result of entitlement check from non-exempted downstreams. If entitlement check is still
+ * in progress on non-exempt downstreams, ceullar upstream would default be disabled. When any
+ * non-exempted downstream gets positive entitlement result, ceullar upstream will be enabled.
+ */
+ public void setExemptedDownstreamType(final int type) {
+ mExemptedDownstreams.set(type, true);
}
/**
@@ -164,29 +186,24 @@ public class EntitlementManager {
public void startProvisioningIfNeeded(int downstreamType, boolean showProvisioningUi) {
if (!isValidDownstreamType(downstreamType)) return;
- if (!mCurrentTethers.contains(downstreamType)) mCurrentTethers.add(downstreamType);
+ mCurrentDownstreams.set(downstreamType, true);
+
+ mExemptedDownstreams.set(downstreamType, false);
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
- if (isTetherProvisioningRequired(config)) {
- // If provisioning is required and the result is not available yet,
- // cellular upstream should not be allowed.
- if (mCellularPermitted.size() == 0) {
- mCellularUpstreamPermitted = false;
- }
- // If upstream is not cellular, provisioning app would not be launched
- // till upstream change to cellular.
- if (mUsingCellularAsUpstream) {
- if (showProvisioningUi) {
- runUiTetherProvisioning(downstreamType, config.activeDataSubId);
- } else {
- runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
- }
- mNeedReRunProvisioningUi = false;
+ if (!isTetherProvisioningRequired(config)) return;
+
+ // If upstream is not cellular, provisioning app would not be launched
+ // till upstream change to cellular.
+ if (mUsingCellularAsUpstream) {
+ if (showProvisioningUi) {
+ runUiTetherProvisioning(downstreamType, config.activeDataSubId);
} else {
- mNeedReRunProvisioningUi |= showProvisioningUi;
+ runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
}
+ mNeedReRunProvisioningUi = false;
} else {
- mCellularUpstreamPermitted = true;
+ mNeedReRunProvisioningUi |= showProvisioningUi;
}
}
@@ -195,14 +212,15 @@ public class EntitlementManager {
*
* @param type tethering type from TetheringManager.TETHERING_{@code *}
*/
- public void stopProvisioningIfNeeded(int type) {
- if (!isValidDownstreamType(type)) return;
+ public void stopProvisioningIfNeeded(int downstreamType) {
+ if (!isValidDownstreamType(downstreamType)) return;
- mCurrentTethers.remove(type);
+ mCurrentDownstreams.set(downstreamType, false);
// There are lurking bugs where the notion of "provisioning required" or
// "tethering supported" may change without without tethering being notified properly.
// Remove the mapping all the time no matter provisioning is required or not.
- removeDownstreamMapping(type);
+ removeDownstreamMapping(downstreamType);
+ mExemptedDownstreams.set(downstreamType, false);
}
/**
@@ -213,7 +231,7 @@ public class EntitlementManager {
public void notifyUpstream(boolean isCellular) {
if (DBG) {
mLog.i("notifyUpstream: " + isCellular
- + ", mCellularUpstreamPermitted: " + mCellularUpstreamPermitted
+ + ", mLastCellularUpstreamPermitted: " + mLastCellularUpstreamPermitted
+ ", mNeedReRunProvisioningUi: " + mNeedReRunProvisioningUi);
}
mUsingCellularAsUpstream = isCellular;
@@ -231,7 +249,7 @@ public class EntitlementManager {
}
private void maybeRunProvisioning(final TetheringConfiguration config) {
- if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired(config)) {
+ if (mCurrentDownstreams.isEmpty() || !isTetherProvisioningRequired(config)) {
return;
}
@@ -239,8 +257,9 @@ public class EntitlementManager {
// are allowed. Therefore even if the silent check here ends in a failure and the UI later
// yields success, then the downstream that got a failure will re-evaluate as a result of
// the change and get the new correct value.
- for (Integer downstream : mCurrentTethers) {
- if (mCellularPermitted.indexOfKey(downstream) < 0) {
+ for (int downstream = mCurrentDownstreams.nextSetBit(0); downstream >= 0;
+ downstream = mCurrentDownstreams.nextSetBit(downstream + 1)) {
+ if (mCurrentEntitlementResults.indexOfKey(downstream) < 0) {
if (mNeedReRunProvisioningUi) {
mNeedReRunProvisioningUi = false;
runUiTetherProvisioning(downstream, config.activeDataSubId);
@@ -286,7 +305,7 @@ public class EntitlementManager {
mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread");
}
mEntitlementCacheValue.clear();
- mCellularPermitted.clear();
+ mCurrentEntitlementResults.clear();
// TODO: refine provisioning check to isTetherProvisioningRequired() ??
if (!config.hasMobileHotspotProvisionApp()
@@ -410,26 +429,25 @@ public class EntitlementManager {
}
private void evaluateCellularPermission(final TetheringConfiguration config) {
- final boolean oldPermitted = mCellularUpstreamPermitted;
- mCellularUpstreamPermitted = (!isTetherProvisioningRequired(config)
- || mCellularPermitted.indexOfValue(TETHER_ERROR_NO_ERROR) > -1);
+ final boolean permitted = isCellularUpstreamPermitted(config);
if (DBG) {
- mLog.i("Cellular permission change from " + oldPermitted
- + " to " + mCellularUpstreamPermitted);
+ mLog.i("Cellular permission change from " + mLastCellularUpstreamPermitted
+ + " to " + permitted);
}
- if (mCellularUpstreamPermitted != oldPermitted) {
- mLog.log("Cellular permission change: " + mCellularUpstreamPermitted);
- mTetherMasterSM.sendMessage(mPermissionChangeMessageCode);
+ if (mLastCellularUpstreamPermitted != permitted) {
+ mLog.log("Cellular permission change: " + permitted);
+ mPermissionChangeCallback.run();
}
// Only schedule periodic re-check when tether is provisioned
// and the result is ok.
- if (mCellularUpstreamPermitted && mCellularPermitted.size() > 0) {
+ if (permitted && mCurrentEntitlementResults.size() > 0) {
scheduleProvisioningRechecks(config);
} else {
cancelTetherProvisioningRechecks();
}
+ mLastCellularUpstreamPermitted = permitted;
}
/**
@@ -441,10 +459,10 @@ public class EntitlementManager {
*/
protected void addDownstreamMapping(int type, int resultCode) {
mLog.i("addDownstreamMapping: " + type + ", result: " + resultCode
- + " ,TetherTypeRequested: " + mCurrentTethers.contains(type));
- if (!mCurrentTethers.contains(type)) return;
+ + " ,TetherTypeRequested: " + mCurrentDownstreams.get(type));
+ if (!mCurrentDownstreams.get(type)) return;
- mCellularPermitted.put(type, resultCode);
+ mCurrentEntitlementResults.put(type, resultCode);
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
evaluateCellularPermission(config);
}
@@ -455,7 +473,7 @@ public class EntitlementManager {
*/
protected void removeDownstreamMapping(int type) {
mLog.i("removeDownstreamMapping: " + type);
- mCellularPermitted.delete(type);
+ mCurrentEntitlementResults.delete(type);
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
evaluateCellularPermission(config);
}
@@ -488,18 +506,33 @@ public class EntitlementManager {
* @param pw {@link PrintWriter} is used to print formatted
*/
public void dump(PrintWriter pw) {
- pw.print("mCellularUpstreamPermitted: ");
- pw.println(mCellularUpstreamPermitted);
- for (Integer type : mCurrentTethers) {
- pw.print("Type: ");
- pw.print(typeString(type));
- if (mCellularPermitted.indexOfKey(type) > -1) {
- pw.print(", Value: ");
- pw.println(errorString(mCellularPermitted.get(type)));
- } else {
- pw.println(", Value: empty");
+ final ConditionVariable mWaiting = new ConditionVariable();
+ mHandler.post(() -> {
+ pw.print("isCellularUpstreamPermitted: ");
+ pw.println(isCellularUpstreamPermitted());
+ for (int type = mCurrentDownstreams.nextSetBit(0); type >= 0;
+ type = mCurrentDownstreams.nextSetBit(type + 1)) {
+ pw.print("Type: ");
+ pw.print(typeString(type));
+ if (mCurrentEntitlementResults.indexOfKey(type) > -1) {
+ pw.print(", Value: ");
+ pw.println(errorString(mCurrentEntitlementResults.get(type)));
+ } else {
+ pw.println(", Value: empty");
+ }
}
+ mWaiting.open();
+ });
+ if (!mWaiting.block(DUMP_TIMEOUT)) {
+ pw.println("... dump timed out after " + DUMP_TIMEOUT + "ms");
+ }
+ pw.print("Exempted: [");
+ for (int type = mExemptedDownstreams.nextSetBit(0); type >= 0;
+ type = mExemptedDownstreams.nextSetBit(type + 1)) {
+ pw.print(typeString(type));
+ pw.print(", ");
}
+ pw.println("]");
}
private static String typeString(int type) {
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java
index 1817f35f1dcd..88c77b07e7e3 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java
@@ -26,6 +26,8 @@ import static android.net.NetworkStats.UID_TETHERING;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
+import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.usage.NetworkStatsManager;
@@ -77,7 +79,6 @@ public class OffloadController {
private static final boolean DBG = false;
private static final String ANYIP = "0.0.0.0";
private static final ForwardedStats EMPTY_STATS = new ForwardedStats();
- private static final int DEFAULT_PERFORM_POLL_INTERVAL_MS = 5000;
@VisibleForTesting
enum StatsType {
@@ -134,11 +135,9 @@ public class OffloadController {
private final Dependencies mDeps;
// TODO: Put more parameters in constructor into dependency object.
- static class Dependencies {
- int getPerformPollInterval() {
- // TODO: Consider make this configurable.
- return DEFAULT_PERFORM_POLL_INTERVAL_MS;
- }
+ interface Dependencies {
+ @NonNull
+ TetheringConfiguration getTetherConfig();
}
public OffloadController(Handler h, OffloadHardwareInterface hwi,
@@ -452,12 +451,16 @@ public class OffloadController {
if (mHandler.hasCallbacks(mScheduledPollingTask)) {
mHandler.removeCallbacks(mScheduledPollingTask);
}
- mHandler.postDelayed(mScheduledPollingTask, mDeps.getPerformPollInterval());
+ mHandler.postDelayed(mScheduledPollingTask,
+ mDeps.getTetherConfig().getOffloadPollInterval());
}
private boolean isPollingStatsNeeded() {
return started() && mRemainingAlertQuota > 0
- && !TextUtils.isEmpty(currentUpstreamInterface());
+ && !TextUtils.isEmpty(currentUpstreamInterface())
+ && mDeps.getTetherConfig() != null
+ && mDeps.getTetherConfig().getOffloadPollInterval()
+ >= DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
}
private boolean maybeUpdateDataLimit(String iface) {
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 00b94a8bbfc1..d1440a7c7be9 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -62,7 +62,6 @@ import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
-import android.app.usage.NetworkStatsManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
@@ -268,12 +267,15 @@ public class Tethering {
mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper, deps);
mTetherMasterSM.start();
- final NetworkStatsManager statsManager =
- (NetworkStatsManager) mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
mHandler = mTetherMasterSM.getHandler();
- mOffloadController = new OffloadController(mHandler,
- mDeps.getOffloadHardwareInterface(mHandler, mLog), mContext.getContentResolver(),
- statsManager, mLog, new OffloadController.Dependencies());
+ mOffloadController = mDeps.getOffloadController(mHandler, mLog,
+ new OffloadController.Dependencies() {
+
+ @Override
+ public TetheringConfiguration getTetherConfig() {
+ return mConfig;
+ }
+ });
mUpstreamNetworkMonitor = mDeps.getUpstreamNetworkMonitor(mContext, mTetherMasterSM, mLog,
TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
mForwardedDownstreams = new LinkedHashSet<>();
@@ -282,8 +284,9 @@ public class Tethering {
filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
// EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
// permission is changed according to entitlement check result.
- mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog,
- TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED);
+ mEntitlementMgr = mDeps.getEntitlementManager(mContext, mHandler, mLog,
+ () -> mTetherMasterSM.sendMessage(
+ TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED));
mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
mLog.log("OBSERVED UiEnitlementFailed");
stopTethering(downstream);
@@ -513,8 +516,12 @@ public class Tethering {
}
mActiveTetheringRequests.put(request.tetheringType, request);
- mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
- request.showProvisioningUi);
+ if (request.exemptFromEntitlementCheck) {
+ mEntitlementMgr.setExemptedDownstreamType(request.tetheringType);
+ } else {
+ mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
+ request.showProvisioningUi);
+ }
enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
});
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index aeac437e24e3..9d4e74732729 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -78,6 +78,12 @@ public class TetheringConfiguration {
public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
"tether_enable_legacy_dhcp_server";
+ /**
+ * Default value that used to periodic polls tether offload stats from tethering offload HAL
+ * to make the data warnings work.
+ */
+ public static final int DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS = 5000;
+
public final String[] tetherableUsbRegexs;
public final String[] tetherableWifiRegexs;
public final String[] tetherableWifiP2pRegexs;
@@ -96,6 +102,8 @@ public class TetheringConfiguration {
public final int activeDataSubId;
+ private final int mOffloadPollInterval;
+
public TetheringConfiguration(Context ctx, SharedLog log, int id) {
final SharedLog configLog = log.forSubComponent("config");
@@ -129,6 +137,10 @@ public class TetheringConfiguration {
R.integer.config_mobile_hotspot_provision_check_period,
0 /* No periodic re-check */);
+ mOffloadPollInterval = getResourceInteger(res,
+ R.integer.config_tether_offload_poll_interval,
+ DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+
configLog.log(toString());
}
@@ -189,6 +201,9 @@ public class TetheringConfiguration {
dumpStringArray(pw, "legacyDhcpRanges", legacyDhcpRanges);
dumpStringArray(pw, "defaultIPv4DNS", defaultIPv4DNS);
+ pw.print("offloadPollInterval: ");
+ pw.println(mOffloadPollInterval);
+
dumpStringArray(pw, "provisioningApp", provisioningApp);
pw.print("provisioningAppNoUi: ");
pw.println(provisioningAppNoUi);
@@ -208,6 +223,7 @@ public class TetheringConfiguration {
makeString(tetherableBluetoothRegexs)));
sj.add(String.format("isDunRequired:%s", isDunRequired));
sj.add(String.format("chooseUpstreamAutomatically:%s", chooseUpstreamAutomatically));
+ sj.add(String.format("offloadPollInterval:%d", mOffloadPollInterval));
sj.add(String.format("preferredUpstreamIfaceTypes:%s",
toIntArray(preferredUpstreamIfaceTypes)));
sj.add(String.format("provisioningApp:%s", makeString(provisioningApp)));
@@ -246,6 +262,10 @@ public class TetheringConfiguration {
return (tm != null) ? tm.isTetheringApnRequired() : false;
}
+ public int getOffloadPollInterval() {
+ return mOffloadPollInterval;
+ }
+
private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) {
final int[] ifaceTypes = res.getIntArray(R.array.config_tether_upstream_types);
final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
index 9b54b5ff2403..ce546c701a61 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java
@@ -16,6 +16,7 @@
package com.android.networkstack.tethering;
+import android.app.usage.NetworkStatsManager;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.INetd;
@@ -47,6 +48,19 @@ public abstract class TetheringDependencies {
}
/**
+ * Get a reference to the offload controller to be used by tethering.
+ */
+ @NonNull
+ public OffloadController getOffloadController(@NonNull Handler h,
+ @NonNull SharedLog log, @NonNull OffloadController.Dependencies deps) {
+ final NetworkStatsManager statsManager =
+ (NetworkStatsManager) getContext().getSystemService(Context.NETWORK_STATS_SERVICE);
+ return new OffloadController(h, getOffloadHardwareInterface(h, log),
+ getContext().getContentResolver(), statsManager, log, deps);
+ }
+
+
+ /**
* Get a reference to the UpstreamNetworkMonitor to be used by tethering.
*/
public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx, StateMachine target,
@@ -82,9 +96,9 @@ public abstract class TetheringDependencies {
/**
* Get a reference to the EntitlementManager to be used by tethering.
*/
- public EntitlementManager getEntitlementManager(Context ctx, StateMachine target,
- SharedLog log, int what) {
- return new EntitlementManager(ctx, target, log, what);
+ public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
+ Runnable callback) {
+ return new EntitlementManager(ctx, h, log, callback);
}
/**
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
index c82e2be72ad2..af349f2b92a2 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
@@ -16,6 +16,8 @@
package com.android.networkstack.tethering;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.TETHER_PRIVILEGED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
@@ -151,7 +153,12 @@ public class TetheringService extends Service {
@Override
public void startTethering(TetheringRequestParcel request, String callerPkg,
String callingAttributionTag, IIntResultListener listener) {
- if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
+ if (checkAndNotifyCommonError(callerPkg,
+ callingAttributionTag,
+ request.exemptFromEntitlementCheck /* onlyAllowPrivileged */,
+ listener)) {
+ return;
+ }
mTethering.startTethering(request, listener);
}
@@ -179,7 +186,7 @@ public class TetheringService extends Service {
public void registerTetheringEventCallback(ITetheringEventCallback callback,
String callerPkg) {
try {
- if (!mService.hasTetherAccessPermission()) {
+ if (!hasTetherAccessPermission()) {
callback.onCallbackStopped(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
return;
}
@@ -191,7 +198,7 @@ public class TetheringService extends Service {
public void unregisterTetheringEventCallback(ITetheringEventCallback callback,
String callerPkg) {
try {
- if (!mService.hasTetherAccessPermission()) {
+ if (!hasTetherAccessPermission()) {
callback.onCallbackStopped(TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION);
return;
}
@@ -226,10 +233,18 @@ public class TetheringService extends Service {
mTethering.dump(fd, writer, args);
}
- private boolean checkAndNotifyCommonError(String callerPkg, String callingAttributionTag,
- IIntResultListener listener) {
+ private boolean checkAndNotifyCommonError(final String callerPkg,
+ final String callingAttributionTag, final IIntResultListener listener) {
+ return checkAndNotifyCommonError(callerPkg, callingAttributionTag,
+ false /* onlyAllowPrivileged */, listener);
+ }
+
+ private boolean checkAndNotifyCommonError(final String callerPkg,
+ final String callingAttributionTag, final boolean onlyAllowPrivileged,
+ final IIntResultListener listener) {
try {
- if (!mService.hasTetherChangePermission(callerPkg, callingAttributionTag)) {
+ if (!hasTetherChangePermission(callerPkg, callingAttributionTag,
+ onlyAllowPrivileged)) {
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
return true;
}
@@ -244,9 +259,10 @@ public class TetheringService extends Service {
return false;
}
- private boolean checkAndNotifyCommonError(String callerPkg, String callingAttributionTag,
- ResultReceiver receiver) {
- if (!mService.hasTetherChangePermission(callerPkg, callingAttributionTag)) {
+ private boolean checkAndNotifyCommonError(final String callerPkg,
+ final String callingAttributionTag, final ResultReceiver receiver) {
+ if (!hasTetherChangePermission(callerPkg, callingAttributionTag,
+ false /* onlyAllowPrivileged */)) {
receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null);
return true;
}
@@ -258,6 +274,30 @@ public class TetheringService extends Service {
return false;
}
+ private boolean hasTetherPrivilegedPermission() {
+ return mService.checkCallingOrSelfPermission(TETHER_PRIVILEGED) == PERMISSION_GRANTED;
+ }
+
+ private boolean hasTetherChangePermission(final String callerPkg,
+ final String callingAttributionTag, final boolean onlyAllowPrivileged) {
+ if (hasTetherPrivilegedPermission()) return true;
+
+ if (onlyAllowPrivileged || mTethering.isTetherProvisioningRequired()) return false;
+
+ int uid = Binder.getCallingUid();
+ // If callerPkg's uid is not same as Binder.getCallingUid(),
+ // checkAndNoteWriteSettingsOperation will return false and the operation will be
+ // denied.
+ return TetheringService.checkAndNoteWriteSettingsOperation(mService, uid, callerPkg,
+ callingAttributionTag, false /* throwException */);
+ }
+
+ private boolean hasTetherAccessPermission() {
+ if (hasTetherPrivilegedPermission()) return true;
+
+ return mService.checkCallingOrSelfPermission(
+ ACCESS_NETWORK_STATE) == PERMISSION_GRANTED;
+ }
}
// if ro.tether.denied = true we default to no tethering
@@ -274,26 +314,6 @@ public class TetheringService extends Service {
return tetherEnabledInSettings && mTethering.hasTetherableConfiguration();
}
- private boolean hasTetherChangePermission(String callerPkg, String callingAttributionTag) {
- if (checkCallingOrSelfPermission(
- android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) {
- return true;
- }
-
- if (mTethering.isTetherProvisioningRequired()) return false;
-
-
- int uid = Binder.getCallingUid();
- // If callerPkg's uid is not same as Binder.getCallingUid(),
- // checkAndNoteWriteSettingsOperation will return false and the operation will be denied.
- if (checkAndNoteWriteSettingsOperation(mContext, uid, callerPkg,
- callingAttributionTag, false /* throwException */)) {
- return true;
- }
-
- return false;
- }
-
/**
* Check if the package is a allowed to write settings. This also accounts that such an access
* happened.
@@ -308,21 +328,6 @@ public class TetheringService extends Service {
throwException);
}
- private boolean hasTetherAccessPermission() {
- if (checkCallingOrSelfPermission(
- android.Manifest.permission.TETHER_PRIVILEGED) == PERMISSION_GRANTED) {
- return true;
- }
-
- if (checkCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NETWORK_STATE) == PERMISSION_GRANTED) {
- return true;
- }
-
- return false;
- }
-
-
/**
* An injection method for testing.
*/
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
index 8bd0edc2490d..cdd0e243e31f 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
@@ -37,6 +37,8 @@ import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -45,7 +47,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.net.util.SharedLog;
import android.os.Bundle;
-import android.os.Message;
+import android.os.Handler;
import android.os.PersistableBundle;
import android.os.ResultReceiver;
import android.os.SystemProperties;
@@ -56,26 +58,22 @@ import android.telephony.CarrierConfigManager;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
import com.android.internal.util.test.BroadcastInterceptingContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
-import java.util.ArrayList;
-
@RunWith(AndroidJUnit4.class)
@SmallTest
public final class EntitlementManagerTest {
- private static final int EVENT_EM_UPDATE = 1;
private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
@@ -90,8 +88,8 @@ public final class EntitlementManagerTest {
private final PersistableBundle mCarrierConfig = new PersistableBundle();
private final TestLooper mLooper = new TestLooper();
private Context mMockContext;
+ private Runnable mPermissionChangeCallback;
- private TestStateMachine mSM;
private WrappedEntitlementManager mEnMgr;
private TetheringConfiguration mConfig;
private MockitoSession mMockingSession;
@@ -112,9 +110,9 @@ public final class EntitlementManagerTest {
public int uiProvisionCount = 0;
public int silentProvisionCount = 0;
- public WrappedEntitlementManager(Context ctx, StateMachine target,
- SharedLog log, int what) {
- super(ctx, target, log, what);
+ public WrappedEntitlementManager(Context ctx, Handler h, SharedLog log,
+ Runnable callback) {
+ super(ctx, h, log, callback);
}
public void reset() {
@@ -169,8 +167,9 @@ public final class EntitlementManagerTest {
when(mLog.forSubComponent(anyString())).thenReturn(mLog);
mMockContext = new MockContext(mContext);
- mSM = new TestStateMachine();
- mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, EVENT_EM_UPDATE);
+ mPermissionChangeCallback = spy(() -> { });
+ mEnMgr = new WrappedEntitlementManager(mMockContext, new Handler(mLooper.getLooper()), mLog,
+ mPermissionChangeCallback);
mEnMgr.setOnUiEntitlementFailedListener(mEntitlementFailedListener);
mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
mEnMgr.setTetheringConfigurationFetcher(() -> {
@@ -180,10 +179,6 @@ public final class EntitlementManagerTest {
@After
public void tearDown() throws Exception {
- if (mSM != null) {
- mSM.quit();
- mSM = null;
- }
mMockingSession.finishMocking();
}
@@ -350,68 +345,105 @@ public final class EntitlementManagerTest {
mEnMgr.reset();
}
+ private void assertPermissionChangeCallback(InOrder inOrder) {
+ inOrder.verify(mPermissionChangeCallback, times(1)).run();
+ }
+
+ private void assertNoPermissionChange(InOrder inOrder) {
+ inOrder.verifyNoMoreInteractions();
+ }
+
@Test
public void verifyPermissionResult() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
setupForRequiredProvisioning();
mEnMgr.notifyUpstream(true);
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
mLooper.dispatchAll();
+ // Permitted: true -> false
+ assertPermissionChangeCallback(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
+
mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
mLooper.dispatchAll();
+ // Permitted: false -> false
+ assertNoPermissionChange(inOrder);
+
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
mLooper.dispatchAll();
+ // Permitted: false -> true
+ assertPermissionChangeCallback(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
}
@Test
public void verifyPermissionIfAllNotApproved() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
setupForRequiredProvisioning();
mEnMgr.notifyUpstream(true);
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
mLooper.dispatchAll();
+ // Permitted: true -> false
+ assertPermissionChangeCallback(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
+
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
mLooper.dispatchAll();
+ // Permitted: false -> false
+ assertNoPermissionChange(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
+
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
mLooper.dispatchAll();
+ // Permitted: false -> false
+ assertNoPermissionChange(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
}
@Test
public void verifyPermissionIfAnyApproved() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
setupForRequiredProvisioning();
mEnMgr.notifyUpstream(true);
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
mLooper.dispatchAll();
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
- mLooper.dispatchAll();
+
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
mLooper.dispatchAll();
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
+
mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
mLooper.dispatchAll();
+ // Permitted: true -> false
+ assertPermissionChangeCallback(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
-
}
@Test
public void verifyPermissionWhenProvisioningNotStarted() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
+ assertNoPermissionChange(inOrder);
setupForRequiredProvisioning();
assertFalse(mEnMgr.isCellularUpstreamPermitted());
+ assertNoPermissionChange(inOrder);
}
@Test
public void testRunTetherProvisioning() {
+ final InOrder inOrder = inOrder(mPermissionChangeCallback);
setupForRequiredProvisioning();
// 1. start ui provisioning, upstream is mobile
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
@@ -421,16 +453,22 @@ public final class EntitlementManagerTest {
mLooper.dispatchAll();
assertEquals(1, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 2. start no-ui provisioning
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, false);
mLooper.dispatchAll();
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(1, mEnMgr.silentProvisionCount);
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 3. tear down mobile, then start ui provisioning
mEnMgr.notifyUpstream(false);
mLooper.dispatchAll();
@@ -438,44 +476,58 @@ public final class EntitlementManagerTest {
mLooper.dispatchAll();
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ assertNoPermissionChange(inOrder);
mEnMgr.reset();
+
// 4. switch upstream back to mobile
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.notifyUpstream(true);
mLooper.dispatchAll();
assertEquals(1, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ // Permitted: true -> true
+ assertNoPermissionChange(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 5. tear down mobile, then switch SIM
mEnMgr.notifyUpstream(false);
mLooper.dispatchAll();
mEnMgr.reevaluateSimCardProvisioning(mConfig);
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ assertNoPermissionChange(inOrder);
mEnMgr.reset();
+
// 6. switch upstream back to mobile again
mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
mEnMgr.notifyUpstream(true);
mLooper.dispatchAll();
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(3, mEnMgr.silentProvisionCount);
+ // Permitted: true -> false
+ assertPermissionChangeCallback(inOrder);
assertFalse(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 7. start ui provisioning, upstream is mobile, downstream is ethernet
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_ETHERNET, true);
mLooper.dispatchAll();
assertEquals(1, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ // Permitted: false -> true
+ assertPermissionChangeCallback(inOrder);
assertTrue(mEnMgr.isCellularUpstreamPermitted());
mEnMgr.reset();
+
// 8. downstream is invalid
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI_P2P, true);
mLooper.dispatchAll();
assertEquals(0, mEnMgr.uiProvisionCount);
assertEquals(0, mEnMgr.silentProvisionCount);
+ assertNoPermissionChange(inOrder);
mEnMgr.reset();
}
@@ -492,31 +544,32 @@ public final class EntitlementManagerTest {
verify(mEntitlementFailedListener, times(1)).onUiEntitlementFailed(TETHERING_WIFI);
}
- public class TestStateMachine extends StateMachine {
- public final ArrayList<Message> messages = new ArrayList<>();
- private final State
- mLoggingState = new EntitlementManagerTest.TestStateMachine.LoggingState();
+ @Test
+ public void testsetExemptedDownstreamType() throws Exception {
+ setupForRequiredProvisioning();
+ // Cellular upstream is not permitted when no entitlement result.
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
- class LoggingState extends State {
- @Override public void enter() {
- messages.clear();
- }
+ // If there is exempted downstream and no other non-exempted downstreams, cellular is
+ // permitted.
+ mEnMgr.setExemptedDownstreamType(TETHERING_WIFI);
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
- @Override public void exit() {
- messages.clear();
- }
+ // If second downstream run entitlement check fail, cellular upstream is not permitted.
+ mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
+ mEnMgr.notifyUpstream(true);
+ mLooper.dispatchAll();
+ mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
+ mLooper.dispatchAll();
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
- @Override public boolean processMessage(Message msg) {
- messages.add(msg);
- return false;
- }
- }
+ // When second downstream is down, exempted downstream can use cellular upstream.
+ assertEquals(1, mEnMgr.uiProvisionCount);
+ verify(mEntitlementFailedListener).onUiEntitlementFailed(TETHERING_USB);
+ mEnMgr.stopProvisioningIfNeeded(TETHERING_USB);
+ assertTrue(mEnMgr.isCellularUpstreamPermitted());
- public TestStateMachine() {
- super("EntitlementManagerTest.TestStateMachine", mLooper.getLooper());
- addState(mLoggingState);
- setInitialState(mLoggingState);
- super.start();
- }
+ mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
+ assertFalse(mEnMgr.isCellularUpstreamPermitted());
}
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
index 088a663190b8..b291438937c7 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
@@ -29,15 +29,15 @@ import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_IFACE;
import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_UID;
import static com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
+import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
import static com.android.testutils.MiscAssertsKt.assertContainsAll;
import static com.android.testutils.MiscAssertsKt.assertThrows;
-import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals;
+import static com.android.testutils.NetworkStatsUtilsKt.assertNetworkStatsEquals;
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
@@ -63,10 +63,10 @@ import android.net.LinkProperties;
import android.net.NetworkStats;
import android.net.NetworkStats.Entry;
import android.net.RouteInfo;
-import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
import android.net.util.SharedLog;
import android.os.Handler;
-import android.os.Looper;
+import android.os.test.TestLooper;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.test.mock.MockContentResolver;
@@ -75,7 +75,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.TestableNetworkStatsProviderCbBinder;
import org.junit.After;
import org.junit.Before;
@@ -109,17 +109,20 @@ public class OffloadControllerTest {
@Mock private ApplicationInfo mApplicationInfo;
@Mock private Context mContext;
@Mock private NetworkStatsManager mStatsManager;
- @Mock private INetworkStatsProviderCallback mTetherStatsProviderCb;
+ @Mock private TetheringConfiguration mTetherConfig;
+ // Late init since methods must be called by the thread that created this object.
+ private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider;
private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
ArgumentCaptor.forClass(ArrayList.class);
private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor =
ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class);
private MockContentResolver mContentResolver;
+ private final TestLooper mTestLooper = new TestLooper();
private OffloadController.Dependencies mDeps = new OffloadController.Dependencies() {
@Override
- int getPerformPollInterval() {
- return 0;
+ public TetheringConfiguration getTetherConfig() {
+ return mTetherConfig;
}
};
@@ -131,6 +134,7 @@ public class OffloadControllerTest {
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mContext.getContentResolver()).thenReturn(mContentResolver);
FakeSettingsProvider.clearSettingsProvider();
+ when(mTetherConfig.getOffloadPollInterval()).thenReturn(-1); // Disabled.
}
@After public void tearDown() throws Exception {
@@ -150,12 +154,16 @@ public class OffloadControllerTest {
Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0);
}
+ private void setOffloadPollInterval(int interval) {
+ when(mTetherConfig.getOffloadPollInterval()).thenReturn(interval);
+ }
+
private void waitForIdle() {
- HandlerUtilsKt.waitForIdle(new Handler(Looper.getMainLooper()), WAIT_FOR_IDLE_TIMEOUT);
+ mTestLooper.dispatchAll();
}
private OffloadController makeOffloadController() throws Exception {
- OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()),
+ OffloadController offload = new OffloadController(new Handler(mTestLooper.getLooper()),
mHardware, mContentResolver, mStatsManager, new SharedLog("test"), mDeps);
final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
tetherStatsProviderCaptor =
@@ -164,6 +172,7 @@ public class OffloadControllerTest {
tetherStatsProviderCaptor.capture());
mTetherStatsProvider = tetherStatsProviderCaptor.getValue();
assertNotNull(mTetherStatsProvider);
+ mTetherStatsProviderCb = new TestableNetworkStatsProviderCbBinder();
mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb);
return offload;
}
@@ -352,9 +361,9 @@ public class OffloadControllerTest {
stacked.setInterfaceName("stacked");
stacked.addLinkAddress(new LinkAddress("192.0.2.129/25"));
stacked.addRoute(new RouteInfo(null, InetAddress.getByName("192.0.2.254"), null,
- RTN_UNICAST));
+ RTN_UNICAST));
stacked.addRoute(new RouteInfo(null, InetAddress.getByName("fe80::bad:f00"), null,
- RTN_UNICAST));
+ RTN_UNICAST));
assertTrue(lp.addStackedLink(stacked));
offload.setUpstreamLinkProperties(lp);
// No change in local addresses means no call to setLocalPrefixes().
@@ -459,20 +468,12 @@ public class OffloadControllerTest {
.addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
.addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
- assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStats));
- assertTrue(orderInsensitiveEquals(expectedUidStats, uidStats));
-
- final ArgumentCaptor<NetworkStats> ifaceStatsCaptor = ArgumentCaptor.forClass(
- NetworkStats.class);
- final ArgumentCaptor<NetworkStats> uidStatsCaptor = ArgumentCaptor.forClass(
- NetworkStats.class);
+ assertNetworkStatsEquals(expectedIfaceStats, ifaceStats);
+ assertNetworkStatsEquals(expectedUidStats, uidStats);
// Force pushing stats update to verify the stats reported.
mTetherStatsProvider.pushTetherStats();
- verify(mTetherStatsProviderCb, times(1))
- .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
- assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStatsCaptor.getValue()));
- assertTrue(orderInsensitiveEquals(expectedUidStats, uidStatsCaptor.getValue()));
+ mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStats, expectedUidStats);
when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
new ForwardedStats(100000, 100000));
@@ -498,11 +499,10 @@ public class OffloadControllerTest {
.addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
.addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
- assertTrue(orderInsensitiveEquals(expectedIfaceStatsAccu, ifaceStatsAccu));
- assertTrue(orderInsensitiveEquals(expectedUidStatsAccu, uidStatsAccu));
+ assertNetworkStatsEquals(expectedIfaceStatsAccu, ifaceStatsAccu);
+ assertNetworkStatsEquals(expectedUidStatsAccu, uidStatsAccu);
// Verify that only diff of stats is reported.
- reset(mTetherStatsProviderCb);
mTetherStatsProvider.pushTetherStats();
final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2)
.addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
@@ -511,10 +511,8 @@ public class OffloadControllerTest {
final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2)
.addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
.addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
- verify(mTetherStatsProviderCb, times(1))
- .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
- assertTrue(orderInsensitiveEquals(expectedIfaceStatsDiff, ifaceStatsCaptor.getValue()));
- assertTrue(orderInsensitiveEquals(expectedUidStatsDiff, uidStatsCaptor.getValue()));
+ mTetherStatsProviderCb.expectNotifyStatsUpdated(expectedIfaceStatsDiff,
+ expectedUidStatsDiff);
}
@Test
@@ -591,7 +589,7 @@ public class OffloadControllerTest {
OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
callback.onStoppedLimitReached();
- verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
+ mTetherStatsProviderCb.expectNotifyStatsUpdated();
}
@Test
@@ -695,8 +693,8 @@ public class OffloadControllerTest {
verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
// TODO: verify the exact stats reported.
- verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
- verifyNoMoreInteractions(mTetherStatsProviderCb);
+ mTetherStatsProviderCb.expectNotifyStatsUpdated();
+ mTetherStatsProviderCb.assertNoCallback();
verifyNoMoreInteractions(mHardware);
}
@@ -760,8 +758,8 @@ public class OffloadControllerTest {
// Verify forwarded stats behaviour.
verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
- verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
- verifyNoMoreInteractions(mTetherStatsProviderCb);
+ mTetherStatsProviderCb.expectNotifyStatsUpdated();
+ mTetherStatsProviderCb.assertNoCallback();
// TODO: verify local prefixes and downstreams are also pushed to the HAL.
verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
@@ -780,4 +778,50 @@ public class OffloadControllerTest {
verifyNoMoreInteractions(mHardware);
}
+ @Test
+ public void testOnSetAlert() throws Exception {
+ setupFunctioningHardwareInterface();
+ enableOffload();
+ setOffloadPollInterval(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ final OffloadController offload = makeOffloadController();
+ offload.start();
+
+ // Initialize with fake eth upstream.
+ final String ethernetIface = "eth1";
+ InOrder inOrder = inOrder(mHardware);
+ final LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName(ethernetIface);
+ offload.setUpstreamLinkProperties(lp);
+ // Previous upstream was null, so no stats are fetched.
+ inOrder.verify(mHardware, never()).getForwardedStats(any());
+
+ // Verify that set quota to 0 will immediately triggers an callback.
+ mTetherStatsProvider.onSetAlert(0);
+ waitForIdle();
+ mTetherStatsProviderCb.expectNotifyAlertReached();
+
+ // Verify that notifyAlertReached never fired if quota is not yet reached.
+ when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
+ new ForwardedStats(0, 0));
+ mTetherStatsProvider.onSetAlert(100);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ waitForIdle();
+ mTetherStatsProviderCb.assertNoCallback();
+
+ // Verify that notifyAlertReached fired when quota is reached.
+ when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
+ new ForwardedStats(50, 50));
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ waitForIdle();
+ mTetherStatsProviderCb.expectNotifyAlertReached();
+
+ // Verify that set quota with UNLIMITED won't trigger any callback, and won't fetch
+ // any stats since the polling is stopped.
+ reset(mHardware);
+ mTetherStatsProvider.onSetAlert(NetworkStatsProvider.QUOTA_UNLIMITED);
+ mTestLooper.moveTimeForward(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
+ waitForIdle();
+ mTetherStatsProviderCb.assertNoCallback();
+ verify(mHardware, never()).getForwardedStats(any());
+ }
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
index 07ddea43f4e8..e8ba5b8168d7 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
@@ -115,6 +115,8 @@ public class TetheringConfigurationTest {
when(mResources.getStringArray(R.array.config_tether_dhcp_range)).thenReturn(
new String[0]);
+ when(mResources.getInteger(R.integer.config_tether_offload_poll_interval)).thenReturn(
+ TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
when(mResources.getStringArray(R.array.config_tether_usb_regexs)).thenReturn(new String[0]);
when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
.thenReturn(new String[]{ "test_wlan\\d" });
@@ -314,6 +316,23 @@ public class TetheringConfigurationTest {
}
@Test
+ public void testOffloadIntervalByResource() {
+ final TetheringConfiguration intervalByDefault =
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ assertEquals(TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS,
+ intervalByDefault.getOffloadPollInterval());
+
+ final int[] testOverrides = {0, 3000, -1};
+ for (final int override : testOverrides) {
+ when(mResources.getInteger(R.integer.config_tether_offload_poll_interval)).thenReturn(
+ override);
+ final TetheringConfiguration overrideByRes =
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ assertEquals(override, overrideByRes.getOffloadPollInterval());
+ }
+ }
+
+ @Test
public void testGetResourcesBySubId() {
setUpResourceForSubId();
final TetheringConfiguration cfg = new TetheringConfiguration(
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 4471f649691f..85c2f2b984ae 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -57,6 +57,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
@@ -150,6 +151,8 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.util.ArrayList;
@@ -170,6 +173,8 @@ public class TetheringTest {
private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
private static final String TEST_NCM_IFNAME = "test_ncm0";
private static final String TETHERING_NAME = "Tethering";
+ private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
+ private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
@@ -212,6 +217,9 @@ public class TetheringTest {
private Tethering mTethering;
private PhoneStateListener mPhoneStateListener;
private InterfaceConfigurationParcel mInterfaceConfiguration;
+ private TetheringConfiguration mConfig;
+ private EntitlementManager mEntitleMgr;
+ private OffloadController mOffloadCtrl;
private class TestContext extends BroadcastInterceptingContext {
TestContext(Context base) {
@@ -297,8 +305,9 @@ public class TetheringTest {
}
}
- private class MockTetheringConfiguration extends TetheringConfiguration {
- MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
+ // MyTetheringConfiguration is used to override static method for testing.
+ private class MyTetheringConfiguration extends TetheringConfiguration {
+ MyTetheringConfiguration(Context ctx, SharedLog log, int id) {
super(ctx, log, id);
}
@@ -328,6 +337,15 @@ public class TetheringTest {
}
@Override
+ public OffloadController getOffloadController(Handler h, SharedLog log,
+ OffloadController.Dependencies deps) {
+ mOffloadCtrl = spy(super.getOffloadController(h, log, deps));
+ // Return real object here instead of mock because
+ // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object.
+ return mOffloadCtrl;
+ }
+
+ @Override
public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
StateMachine target, SharedLog log, int what) {
mUpstreamNetworkMonitorMasterSM = target;
@@ -352,6 +370,13 @@ public class TetheringTest {
}
@Override
+ public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
+ Runnable callback) {
+ mEntitleMgr = spy(super.getEntitlementManager(ctx, h, log, callback));
+ return mEntitleMgr;
+ }
+
+ @Override
public boolean isTetheringSupported() {
return true;
}
@@ -359,7 +384,8 @@ public class TetheringTest {
@Override
public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
int subId) {
- return new MockTetheringConfiguration(ctx, log, subId);
+ mConfig = spy(new MyTetheringConfiguration(ctx, log, subId));
+ return mConfig;
}
@Override
@@ -516,16 +542,16 @@ public class TetheringTest {
}
private TetheringRequestParcel createTetheringRequestParcel(final int type) {
- return createTetheringRequestParcel(type, null, null);
+ return createTetheringRequestParcel(type, null, null, false);
}
private TetheringRequestParcel createTetheringRequestParcel(final int type,
- final LinkAddress serverAddr, final LinkAddress clientAddr) {
+ final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt) {
final TetheringRequestParcel request = new TetheringRequestParcel();
request.tetheringType = type;
request.localIPv4Address = serverAddr;
request.staticClientAddress = clientAddr;
- request.exemptFromEntitlementCheck = false;
+ request.exemptFromEntitlementCheck = exempt;
request.showProvisioningUi = false;
return request;
@@ -1636,7 +1662,7 @@ public class TetheringTest {
// Enable USB tethering and check that Tethering starts USB.
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- null, null), firstResult);
+ null, null, false), firstResult);
mLooper.dispatchAll();
firstResult.assertHasResult();
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
@@ -1644,7 +1670,7 @@ public class TetheringTest {
// Enable USB tethering again with the same request and expect no change to USB.
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- null, null), secondResult);
+ null, null, false), secondResult);
mLooper.dispatchAll();
secondResult.assertHasResult();
verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
@@ -1653,7 +1679,7 @@ public class TetheringTest {
// Enable USB tethering with a different request and expect that USB is stopped and
// started.
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- serverLinkAddr, clientLinkAddr), thirdResult);
+ serverLinkAddr, clientLinkAddr, false), thirdResult);
mLooper.dispatchAll();
thirdResult.assertHasResult();
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
@@ -1677,7 +1703,7 @@ public class TetheringTest {
final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
- serverLinkAddr, clientLinkAddr), null);
+ serverLinkAddr, clientLinkAddr, false), null);
mLooper.dispatchAll();
verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
@@ -1726,6 +1752,82 @@ public class TetheringTest {
verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any());
}
+ @Test
+ public void testDumpTetheringLog() throws Exception {
+ final FileDescriptor mockFd = mock(FileDescriptor.class);
+ final PrintWriter mockPw = mock(PrintWriter.class);
+ runUsbTethering(null);
+ mLooper.startAutoDispatch();
+ mTethering.dump(mockFd, mockPw, new String[0]);
+ verify(mConfig).dump(any());
+ verify(mEntitleMgr).dump(any());
+ verify(mOffloadCtrl).dump(any());
+ mLooper.stopAutoDispatch();
+ }
+
+ @Test
+ public void testExemptFromEntitlementCheck() throws Exception {
+ setupForRequiredProvisioning();
+ final TetheringRequestParcel wifiNotExemptRequest =
+ createTetheringRequestParcel(TETHERING_WIFI, null, null, false);
+ mTethering.startTethering(wifiNotExemptRequest, null);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
+ verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
+ assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
+ mTethering.stopTethering(TETHERING_WIFI);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
+ reset(mEntitleMgr);
+
+ setupForRequiredProvisioning();
+ final TetheringRequestParcel wifiExemptRequest =
+ createTetheringRequestParcel(TETHERING_WIFI, null, null, true);
+ mTethering.startTethering(wifiExemptRequest, null);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
+ verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
+ assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
+ mTethering.stopTethering(TETHERING_WIFI);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
+ reset(mEntitleMgr);
+
+ // If one app enables tethering without provisioning check first, then another app enables
+ // tethering of the same type but does not disable the provisioning check.
+ setupForRequiredProvisioning();
+ mTethering.startTethering(wifiExemptRequest, null);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
+ verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
+ assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
+ reset(mEntitleMgr);
+ setupForRequiredProvisioning();
+ mTethering.startTethering(wifiNotExemptRequest, null);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
+ verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
+ assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
+ mTethering.stopTethering(TETHERING_WIFI);
+ mLooper.dispatchAll();
+ verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
+ reset(mEntitleMgr);
+ }
+
+ private void setupForRequiredProvisioning() {
+ // Produce some acceptable looking provision app setting if requested.
+ when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
+ .thenReturn(PROVISIONING_APP_NAME);
+ when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
+ .thenReturn(PROVISIONING_NO_UI_APP_NAME);
+ // Act like the CarrierConfigManager is present and ready unless told otherwise.
+ when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
+ .thenReturn(mCarrierConfigManager);
+ when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
+ mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
+ mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
+ sendConfigurationChanged();
+ }
// TODO: Test that a request for hotspot mode doesn't interfere with an
// already operating tethering mode interface.
}
diff --git a/services/Android.bp b/services/Android.bp
index b4d8393683ba..0d221b930f5d 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -122,13 +122,13 @@ droidstubs {
removed_api_file: "api/removed.txt",
},
last_released: {
- api_file: ":last-released-system-server-api",
+ api_file: ":android.api.system-server.latest",
removed_api_file: "api/removed.txt",
baseline_file: ":system-server-api-incompatibilities-with-last-released"
},
api_lint: {
enabled: true,
- new_since: ":last-released-system-server-api",
+ new_since: ":android.api.system-server.latest",
baseline_file: "api/lint-baseline.txt",
},
},
diff --git a/services/core/Android.bp b/services/core/Android.bp
index a2f73a6730b5..d9a534916da6 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -53,8 +53,8 @@ java_library_static {
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
- "dnsresolver_aidl_interface-V4-java",
- "netd_event_listener_interface-java",
+ "dnsresolver_aidl_interface-java",
+ "netd_aidl_interfaces-platform-java",
],
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 58e06e00ef2d..08aab2aea6f9 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -7123,6 +7123,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
if (!createNativeNetwork(networkAgent)) return;
+ if (networkAgent.isVPN()) {
+ // Initialize the VPN capabilities to their starting values according to the
+ // underlying networks. This will avoid a spurious callback to
+ // onCapabilitiesUpdated being sent in updateAllVpnCapabilities below as
+ // the VPN would switch from its default, blank capabilities to those
+ // that reflect the capabilities of its underlying networks.
+ updateAllVpnsCapabilities();
+ }
networkAgent.created = true;
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 0ba41736ce15..0ba6a5536cbf 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -842,6 +842,15 @@ public final class ActiveServices {
}
}
+ void killMisbehavingService(ServiceRecord r,
+ int appUid, int appPid, String localPackageName) {
+ synchronized (mAm) {
+ stopServiceLocked(r);
+ mAm.crashApplication(appUid, appPid, localPackageName, -1,
+ "Bad notification for startForeground", true /*force*/);
+ }
+ }
+
IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(),
@@ -3946,7 +3955,7 @@ public final class ActiveServices {
void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) {
mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId,
"Context.startForegroundService() did not then call Service.startForeground(): "
- + serviceRecord);
+ + serviceRecord, false /*force*/);
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 39ea499f21d0..ece21f667418 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3597,7 +3597,7 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public void crashApplication(int uid, int initialPid, String packageName, int userId,
- String message) {
+ String message, boolean force) {
if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: crashApplication() from pid="
@@ -3609,7 +3609,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
synchronized(this) {
- mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
+ mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId,
+ message, force);
}
}
@@ -4788,7 +4789,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@GuardedBy("this")
- private final boolean attachApplicationLocked(IApplicationThread thread,
+ private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// Find the application record that is being attached... either via
@@ -5211,6 +5212,9 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
+ if (thread == null) {
+ throw new SecurityException("Invalid application interface");
+ }
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 5078b8a14eb2..5ab18d95b84d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1058,7 +1058,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
} catch (NumberFormatException e) {
packageName = arg;
}
- mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
+ mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false);
return 0;
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index a4c695067139..bbd2d34e92a6 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -314,20 +314,24 @@ class AppErrors {
}
void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
- app.setCrashing(false);
- app.crashingReport = null;
- app.setNotResponding(false);
- app.notRespondingReport = null;
if (app.anrDialog == fromDialog) {
app.anrDialog = null;
}
if (app.waitDialog == fromDialog) {
app.waitDialog = null;
}
+ killAppImmediateLocked(app, "user-terminated", "user request after error");
+ }
+
+ private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) {
+ app.setCrashing(false);
+ app.crashingReport = null;
+ app.setNotResponding(false);
+ app.notRespondingReport = null;
if (app.pid > 0 && app.pid != MY_PID) {
- handleAppCrashLocked(app, "user-terminated" /*reason*/,
+ handleAppCrashLocked(app, reason,
null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
- app.kill("user request after error", true);
+ app.kill(killReason, true);
}
}
@@ -341,7 +345,7 @@ class AppErrors {
* @param message
*/
void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
- String message) {
+ String message, boolean force) {
ProcessRecord proc = null;
// Figure out which process to kill. We don't trust that initialPid
@@ -374,6 +378,14 @@ class AppErrors {
}
proc.scheduleCrash(message);
+ if (force) {
+ // If the app is responsive, the scheduled crash will happen as expected
+ // and then the delayed summary kill will be a no-op.
+ final ProcessRecord p = proc;
+ mService.mHandler.postDelayed(
+ () -> killAppImmediateLocked(p, "forced", "killed for invalid state"),
+ 5000L);
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index dee8e3b285a7..c408695bcb66 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -798,6 +798,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
final String localPackageName = packageName;
final int localForegroundId = foregroundId;
final Notification _foregroundNoti = foregroundNoti;
+ final ServiceRecord record = this;
ams.mHandler.post(new Runnable() {
public void run() {
NotificationManagerInternal nm = LocalServices.getService(
@@ -896,10 +897,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
Slog.w(TAG, "Error showing notification for service", e);
// If it gave us a garbage notification, it doesn't
// get to be foreground.
- ams.setServiceForeground(instanceName, ServiceRecord.this,
- 0, null, 0, 0);
- ams.crashApplication(appUid, appPid, localPackageName, -1,
- "Bad notification for startForeground: " + e);
+ ams.mServices.killMisbehavingService(record,
+ appUid, appPid, localPackageName);
}
}
});
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index 228966cbee5b..103f659cc258 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -17,7 +17,6 @@
package com.android.server.connectivity;
import static android.net.ConnectivityManager.NetworkCallback;
-import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP;
import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP;
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
@@ -85,6 +84,12 @@ import java.util.List;
public class VpnIkev2Utils {
private static final String TAG = VpnIkev2Utils.class.getSimpleName();
+ // TODO: Use IKE library exposed constants when @SystemApi is updated.
+ /** IANA-defined 3072 group for use in IKEv2 */
+ private static final int DH_GROUP_3072_BIT_MODP = 15;
+ /** IANA-defined 4096 group for use in IKEv2 */
+ private static final int DH_GROUP_4096_BIT_MODP = 16;
+
static IkeSessionParams buildIkeSessionParams(
@NonNull Context context, @NonNull Ikev2VpnProfile profile, @NonNull Network network) {
final IkeIdentification localId = parseIkeIdentification(profile.getUserIdentity());
@@ -177,8 +182,9 @@ public class VpnIkev2Utils {
// Add dh, prf for both builders
for (final IkeSaProposal.Builder builder : Arrays.asList(normalModeBuilder, aeadBuilder)) {
+ builder.addDhGroup(DH_GROUP_4096_BIT_MODP);
+ builder.addDhGroup(DH_GROUP_3072_BIT_MODP);
builder.addDhGroup(DH_GROUP_2048_BIT_MODP);
- builder.addDhGroup(DH_GROUP_1024_BIT_MODP);
builder.addPseudorandomFunction(PSEUDORANDOM_FUNCTION_AES128_XCBC);
builder.addPseudorandomFunction(PSEUDORANDOM_FUNCTION_HMAC_SHA1);
}
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 3006ef41931f..d7bf37db6afd 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -306,49 +306,6 @@ final class Constants {
static final String PROPERTY_PREFERRED_ADDRESS_PLAYBACK = "persist.sys.hdmi.addr.playback";
static final String PROPERTY_PREFERRED_ADDRESS_TV = "persist.sys.hdmi.addr.tv";
-
- // TODO(OEM): Set this to false to keep the playback device in sleep upon hotplug event.
- // True by default.
- static final String PROPERTY_WAKE_ON_HOTPLUG = "ro.hdmi.wake_on_hotplug";
-
- // TODO(OEM): Set this to true to enable 'Set Menu Language' feature. False by default.
- static final String PROPERTY_SET_MENU_LANGUAGE = "ro.hdmi.set_menu_language";
-
- /**
- * Property to save the ARC port id on system audio device.
- * <p>When ARC is initiated, this port will be used to turn on ARC.
- */
- static final String PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT =
- "ro.hdmi.property_sytem_audio_device_arc_port";
-
- /**
- * Property to disable muting logic in System Audio Control handling. Default is true.
- *
- * <p>True means enabling muting logic.
- * <p>False means never mute device.
- */
- static final String PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE =
- "ro.hdmi.property_system_audio_mode_muting_enable";
-
- /**
- * When set to true the HdmiControlService will never request a Logical Address for the
- * playback device type. Default is false.
- *
- * <p> This is useful when HDMI CEC multiple device types is not supported by the cec driver
- */
- static final String PROPERTY_HDMI_CEC_NEVER_CLAIM_PLAYBACK_LOGICAL_ADDRESS =
- "ro.hdmi.property_hdmi_cec_never_claim_playback_logical_address";
-
- /**
- * A comma separated list of logical addresses that HdmiControlService
- * will never assign local CEC devices to.
- *
- * <p> This is useful when HDMI CEC hardware module can't assign multiple logical addresses
- * in the range same range of 0-7 or 8-15.
- */
- static final String PROPERTY_HDMI_CEC_NEVER_ASSIGN_LOGICAL_ADDRESSES =
- "ro.hdmi.property_hdmi_cec_never_assign_logical_addresses";
-
// Set to false to allow playback device to go to suspend mode even
// when it's an active source. True by default.
static final String PROPERTY_KEEP_AWAKE = "persist.sys.hdmi.keep_awake";
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 9e2fd4e9e91e..496273b6bf0e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -35,6 +35,7 @@ import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager.TvInputCallback;
import android.os.SystemProperties;
import android.provider.Settings.Global;
+import android.sysprop.HdmiProperties;
import android.util.Slog;
import android.util.SparseArray;
@@ -90,8 +91,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
// If the current device uses TvInput for ARC. We assume all other inputs also use TvInput
// when ARC is using TvInput.
- private boolean mArcIntentUsed = SystemProperties
- .get(Constants.PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT, "0").contains("tvinput");
+ private boolean mArcIntentUsed = HdmiProperties.arc_port().orElse("0").contains("tvinput");
// Keeps the mapping (HDMI port ID to TV input URI) to keep track of the TV inputs ready to
// accept input switching request from HDMI devices.
@@ -823,7 +823,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
private void enableAudioReturnChannel(boolean enabled) {
assertRunOnServiceThread();
mService.enableAudioReturnChannel(
- SystemProperties.getInt(Constants.PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT, 0),
+ Integer.parseInt(HdmiProperties.arc_port().orElse("0")),
enabled);
}
@@ -895,9 +895,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
boolean currentMuteStatus =
mService.getAudioManager().isStreamMute(AudioManager.STREAM_MUSIC);
if (currentMuteStatus == newSystemAudioMode) {
- if (mService.readBooleanSystemProperty(
- Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, true)
- || newSystemAudioMode) {
+ if (HdmiProperties.system_audio_mode_muting().orElse(true) || newSystemAudioMode) {
mService.getAudioManager()
.adjustStreamVolume(
AudioManager.STREAM_MUSIC,
@@ -1133,7 +1131,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
if (portId == Constants.CEC_SWITCH_HOME && mService.isPlaybackDevice()) {
switchToHomeTvInput();
} else if (portId == Constants.CEC_SWITCH_ARC) {
- switchToTvInput(SystemProperties.get(Constants.PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT));
+ switchToTvInput(HdmiProperties.arc_port().orElse("0"));
setLocalActivePort(portId);
return;
} else {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 560f7a03b20f..603dfafc6ff5 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -24,6 +24,7 @@ import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemProperties;
import android.provider.Settings.Global;
+import android.sysprop.HdmiProperties;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -43,11 +44,10 @@ import java.util.Locale;
public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
private static final String TAG = "HdmiCecLocalDevicePlayback";
- private static final boolean WAKE_ON_HOTPLUG =
- SystemProperties.getBoolean(Constants.PROPERTY_WAKE_ON_HOTPLUG, true);
+ private static final boolean WAKE_ON_HOTPLUG = false;
private static final boolean SET_MENU_LANGUAGE =
- SystemProperties.getBoolean(Constants.PROPERTY_SET_MENU_LANGUAGE, false);
+ HdmiProperties.set_menu_language_enabled().orElse(false);
// Used to keep the device awake while it is the active source. For devices that
// cannot wake up via CEC commands, this address the inconvenience of having to
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
index ae008b4bfa7a..eb6612fffc0c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -16,12 +16,10 @@
package com.android.server.hdmi;
-import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
-
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.IHdmiControlCallback;
-import android.os.SystemProperties;
+import android.sysprop.HdmiProperties;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -44,8 +42,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
// Device has cec switch functionality or not.
// Default is false.
- protected boolean mIsSwitchDevice = SystemProperties.getBoolean(
- PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
+ protected boolean mIsSwitchDevice = HdmiProperties.is_switch().orElse(false);
// Routing port number used for Routing Control.
// This records the default routing port or the previous valid routing port.
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 6a0cc2661f3d..51d363a41116 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -19,7 +19,6 @@ package com.android.server.hdmi;
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;
-import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
import static com.android.server.hdmi.Constants.DISABLED;
import static com.android.server.hdmi.Constants.ENABLED;
@@ -2520,8 +2519,7 @@ public class HdmiControlService extends SystemService {
}
boolean isSwitchDevice() {
- return SystemProperties.getBoolean(
- PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
+ return HdmiProperties.is_switch().orElse(false);
}
boolean isTvDeviceEnabled() {
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 26808587437c..e21a01d2048f 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -46,7 +46,6 @@ import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
-import static android.net.NetworkTemplate.getCollapsedRatType;
import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.os.Trace.TRACE_TAG_NETWORK;
@@ -67,9 +66,6 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
-import static android.telephony.PhoneStateListener.LISTEN_NONE;
-import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -133,9 +129,7 @@ import android.provider.Settings.Global;
import android.service.NetworkInterfaceProto;
import android.service.NetworkStatsServiceDumpProto;
import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
import android.telephony.SubscriptionPlan;
-import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -184,6 +178,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// Perform polling, persist network, and register the global alert again.
private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
private static final int MSG_UPDATE_IFACES = 3;
+ // A message for broadcasting ACTION_NETWORK_STATS_UPDATED in handler thread to prevent
+ // deadlock.
+ private static final int MSG_BROADCAST_NETWORK_STATS_UPDATED = 4;
/** Flags to control detail level of poll event. */
private static final int FLAG_PERSIST_NETWORK = 0x1;
@@ -206,7 +203,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final NetworkStatsFactory mStatsFactory;
private final AlarmManager mAlarmManager;
private final Clock mClock;
- private final TelephonyManager mTeleManager;
private final NetworkStatsSettings mSettings;
private final NetworkStatsObservers mStatsObservers;
@@ -352,6 +348,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@NonNull
private final Dependencies mDeps;
+ @NonNull
+ private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
+
private static @NonNull File getDefaultSystemDir() {
return new File(Environment.getDataDirectory(), "system");
}
@@ -390,6 +389,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
registerGlobalAlert();
break;
}
+ case MSG_BROADCAST_NETWORK_STATS_UPDATED: {
+ final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
+ updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
+ READ_NETWORK_USAGE_HISTORY);
+ break;
+ }
}
}
}
@@ -401,8 +407,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
PowerManager.WakeLock wakeLock =
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
- NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
- wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class),
+ final NetworkStatsService service = new NetworkStatsService(context, networkManager,
+ alarmManager, wakeLock, getDefaultClock(),
new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
new Dependencies());
@@ -416,16 +422,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@VisibleForTesting
NetworkStatsService(Context context, INetworkManagementService networkManager,
AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
- TelephonyManager teleManager, NetworkStatsSettings settings,
- NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
- File baseDir, @NonNull Dependencies deps) {
+ NetworkStatsSettings settings, NetworkStatsFactory factory,
+ NetworkStatsObservers statsObservers, File systemDir, File baseDir,
+ @NonNull Dependencies deps) {
mContext = Objects.requireNonNull(context, "missing Context");
mNetworkManager = Objects.requireNonNull(networkManager,
- "missing INetworkManagementService");
+ "missing INetworkManagementService");
mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
mClock = Objects.requireNonNull(clock, "missing Clock");
mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
- mTeleManager = Objects.requireNonNull(teleManager, "missing TelephonyManager");
mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
mStatsFactory = Objects.requireNonNull(factory, "missing factory");
mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
@@ -437,7 +442,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final HandlerThread handlerThread = mDeps.makeHandlerThread();
handlerThread.start();
mHandler = new NetworkStatsHandler(handlerThread.getLooper());
- mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler));
+ mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
+ new HandlerExecutor(mHandler), this);
}
/**
@@ -453,6 +459,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public HandlerThread makeHandlerThread() {
return new HandlerThread(TAG);
}
+
+ /**
+ * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change
+ * event in NetworkStatsService.
+ */
+ @NonNull
+ public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context,
+ @NonNull Executor executor, @NonNull NetworkStatsService service) {
+ // TODO: Update RatType passively in NSS, instead of querying into the monitor
+ // when forceUpdateIface.
+ return new NetworkStatsSubscriptionsMonitor(context, executor, (subscriberId, type) ->
+ service.handleOnCollapsedRatTypeChanged());
+ }
}
private void registerLocalService() {
@@ -517,11 +536,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
mSettings.getPollInterval(), pollIntent);
- // TODO: 1. listen to changes from all subscriptions.
- // 2. listen to settings changed to support dynamically enable/disable.
+ // TODO: listen to settings changed to support dynamically enable/disable.
// watch for networkType changes
if (!mSettings.getCombineSubtypeEnabled()) {
- mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE);
+ mNetworkStatsSubscriptionsMonitor.start();
}
registerGlobalAlert();
@@ -544,7 +562,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mContext.unregisterReceiver(mUserReceiver);
mContext.unregisterReceiver(mShutdownReceiver);
- mTeleManager.listen(mPhoneListener, LISTEN_NONE);
+ if (!mSettings.getCombineSubtypeEnabled()) {
+ mNetworkStatsSubscriptionsMonitor.stop();
+ }
final long currentTime = mClock.millis();
@@ -1197,35 +1217,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
};
/**
- * Receiver that watches for {@link TelephonyManager} changes, such as
- * transitioning between Radio Access Technology(RAT) types.
+ * Handle collapsed RAT type changed event.
*/
- @NonNull
- private final NetworkTypeListener mPhoneListener;
-
- class NetworkTypeListener extends PhoneStateListener {
- private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN;
-
- NetworkTypeListener(@NonNull Executor executor) {
- super(executor);
- }
-
- @Override
- public void onServiceStateChanged(@NonNull ServiceState ss) {
- final int networkType = ss.getDataNetworkType();
- final int collapsedRatType = getCollapsedRatType(networkType);
- if (collapsedRatType == mLastCollapsedRatType) return;
-
- if (LOGD) {
- Log.d(TAG, "subtype changed for mobile: "
- + mLastCollapsedRatType + " -> " + collapsedRatType);
- }
- // Protect service from frequently updating. Remove pending messages if any.
- mHandler.removeMessages(MSG_UPDATE_IFACES);
- mLastCollapsedRatType = collapsedRatType;
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
- }
+ @VisibleForTesting
+ public void handleOnCollapsedRatTypeChanged() {
+ // Protect service from frequently updating. Remove pending messages if any.
+ mHandler.removeMessages(MSG_UPDATE_IFACES);
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
}
private void updateIfaces(
@@ -1352,8 +1351,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return 0;
}
- // TODO: return different subType for different subscriptions.
- return mPhoneListener.mLastCollapsedRatType;
+ return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId);
}
private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
@@ -1520,10 +1518,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
// finally, dispatch updated event to any listeners
- final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
- updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
- READ_NETWORK_USAGE_HISTORY);
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_BROADCAST_NETWORK_STATS_UPDATED));
Trace.traceEnd(TRACE_TAG_NETWORK);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a2f191444b63..2d39e9169245 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -920,7 +920,7 @@ public class NotificationManagerService extends SystemService {
() -> mAm.crashApplication(uid, initialPid, pkg, -1,
"Bad notification(tag=" + tag + ", id=" + id + ") posted from package "
+ pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): "
- + message));
+ + message, true /* force */));
}
}
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 0d7494cfbeab..6fdde7a196cc 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -30,7 +30,7 @@ per-file CrossProfileAppsServiceImpl.java = omakoto@google.com, yamasani@google.
per-file CrossProfileAppsService.java = omakoto@google.com, yamasani@google.com
per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com
per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com
-per-file UserManagerService.java = omakoto@google.com, yamasani@google.com
+per-file UserManagerService.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
per-file RestrictionsSet.java = bookatz@google.com, omakoto@google.com, yamasani@google.com, rubinxu@google.com, sandness@google.com
per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e82102f3379d..50bbfa96bfab 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3004,8 +3004,7 @@ public class PackageManagerService extends IPackageManager.Stub
mWellbeingPackage = getWellbeingPackageName();
mDocumenterPackage = getDocumenterPackageName();
- mConfiguratorPackage =
- mContext.getString(R.string.config_deviceConfiguratorPackageName);
+ mConfiguratorPackage = getDeviceConfiguratorPackageName();
mAppPredictionServicePackage = getAppPredictionServicePackageName();
mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
mTelephonyPackages = getTelephonyPackageNames();
@@ -20537,7 +20536,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public String getSystemTextClassifierPackageName() {
- return mContext.getString(R.string.config_defaultTextClassifierPackage);
+ return ensureSystemPackageName(mContext.getString(
+ R.string.config_defaultTextClassifierPackage));
}
@Override
@@ -20547,7 +20547,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (flattenedComponentName != null) {
ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName);
if (componentName != null && componentName.getPackageName() != null) {
- return componentName.getPackageName();
+ return ensureSystemPackageName(componentName.getPackageName());
}
}
return null;
@@ -20572,9 +20572,15 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ @Nullable
+ private String getDeviceConfiguratorPackageName() {
+ return ensureSystemPackageName(mContext.getString(
+ R.string.config_deviceConfiguratorPackageName));
+ }
+
@Override
public String getWellbeingPackageName() {
- return mContext.getString(R.string.config_defaultWellbeingPackage);
+ return ensureSystemPackageName(mContext.getString(R.string.config_defaultWellbeingPackage));
}
@Override
@@ -20589,7 +20595,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (appPredictionServiceComponentName == null) {
return null;
}
- return appPredictionServiceComponentName.getPackageName();
+ return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
}
@Override
@@ -20606,11 +20612,33 @@ public class PackageManagerService extends IPackageManager.Stub
if (systemCaptionsServiceComponentName == null) {
return null;
}
- return systemCaptionsServiceComponentName.getPackageName();
+ return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName());
}
public String getIncidentReportApproverPackageName() {
- return mContext.getString(R.string.config_incidentReportApproverPackage);
+ return ensureSystemPackageName(mContext.getString(
+ R.string.config_incidentReportApproverPackage));
+ }
+
+ @Nullable
+ private String ensureSystemPackageName(@Nullable String packageName) {
+ if (packageName == null) {
+ return null;
+ }
+ long token = Binder.clearCallingIdentity();
+ try {
+ if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
+ PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
+ if (packageInfo != null) {
+ EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
+ "");
+ }
+ return null;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return packageName;
}
@Override
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index f78d2639df1a..add0b01f1879 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -19,8 +19,6 @@ package com.android.server.policy.keyguard;
import android.app.ActivityManager;
import android.content.Context;
import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.security.keystore.IKeystoreService;
import android.util.Slog;
import com.android.internal.policy.IKeyguardService;
@@ -53,16 +51,11 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
private final LockPatternUtils mLockPatternUtils;
private final StateCallback mCallback;
- IKeystoreService mKeystoreService;
-
public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) {
mLockPatternUtils = new LockPatternUtils(context);
mCurrentUserId = ActivityManager.getCurrentUser();
mCallback = callback;
- mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
- .getService("android.security.keystore"));
-
try {
service.addStateMonitorCallback(this);
} catch (RemoteException e) {
@@ -95,23 +88,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
mIsShowing = showing;
mCallback.onShowingChanged();
- int retry = 2;
- while (retry > 0) {
- try {
- mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId);
- break;
- } catch (RemoteException e) {
- if (retry == 2) {
- Slog.w(TAG, "Error informing keystore of screen lock. Keystore may have died"
- + " -> refreshing service token and retrying");
- mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
- .getService("android.security.keystore"));
- } else {
- Slog.e(TAG, "Error informing keystore of screen lock after retrying once", e);
- }
- --retry;
- }
- }
}
@Override // Binder interface
@@ -123,10 +99,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
mCurrentUserId = userId;
}
- private synchronized int getCurrentUser() {
- return mCurrentUserId;
- }
-
@Override // Binder interface
public void onInputRestrictedStateChanged(boolean inputRestricted) {
mInputRestricted = inputRestricted;
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 7408dd40b5ca..5f5cd3c46117 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -53,6 +53,7 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.security.KeyStore;
import android.service.trust.TrustAgentService;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -135,6 +136,33 @@ public class TrustManagerService extends SystemService {
@GuardedBy("mUserIsTrusted")
private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
+ /**
+ * Stores the locked state for users on the device. There are three different type of users
+ * which are handled slightly differently:
+ * <ul>
+ * <li> Users with real keyguard
+ * These are users who can be switched to ({@link UserInfo#supportsSwitchToByUser()}). Their
+ * locked state is derived by a combination of user secure state, keyguard state, trust agent
+ * decision and biometric authentication result. These are updated via
+ * {@link #refreshDeviceLockedForUser(int)} and result stored in {@link #mDeviceLockedForUser}.
+ * <li> Managed profiles with unified challenge
+ * Managed profile with unified challenge always shares the same locked state as their parent,
+ * so their locked state is not recorded in {@link #mDeviceLockedForUser}. Instead,
+ * {@link ITrustManager#isDeviceLocked(int)} always resolves their parent user handle and
+ * queries its locked state instead.
+ * <li> Managed profiles with separate challenge
+ * Locked state for profile with separate challenge is determined by other parts of the
+ * framework (mostly PowerManager) and pushed to TrustManagerService via
+ * {@link ITrustManager#setDeviceLockedForUser(int, boolean)}. Although in a corner case when
+ * the profile has a separate but empty challenge, setting its {@link #mDeviceLockedForUser} to
+ * {@code false} is actually done by {@link #refreshDeviceLockedForUser(int)}.
+ * </ul>
+ * TODO: Rename {@link ITrustManager#setDeviceLockedForUser(int, boolean)} to
+ * {@code setDeviceLockedForProfile} to better reflect its purpose. Unifying
+ * {@code setDeviceLockedForProfile} and {@link #setDeviceLockedForUser} would also be nice.
+ * At the moment they both update {@link #mDeviceLockedForUser} but have slightly different
+ * side-effects: one notifies trust agents while the other sends out a broadcast.
+ */
@GuardedBy("mDeviceLockedForUser")
private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
@@ -601,6 +629,10 @@ public class TrustManagerService extends SystemService {
}
}
+ /**
+ * Update the user's locked state. Only applicable to users with a real keyguard
+ * ({@link UserInfo#supportsSwitchToByUser}) and unsecured managed profiles.
+ */
private void refreshDeviceLockedForUser(int userId) {
if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
@@ -661,6 +693,15 @@ public class TrustManagerService extends SystemService {
}
if (changed) {
dispatchDeviceLocked(userId, locked);
+
+ KeyStore.getInstance().onUserLockedStateChanged(userId, locked);
+ // Also update the user's profiles who have unified challenge, since they
+ // share the same unlocked state (see {@link #isDeviceLocked(int)})
+ for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) {
+ if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) {
+ KeyStore.getInstance().onUserLockedStateChanged(profileHandle, locked);
+ }
+ }
}
}
@@ -1194,6 +1235,10 @@ public class TrustManagerService extends SystemService {
return "0x" + Integer.toHexString(i);
}
+ /**
+ * Changes the lock status for the given user. This is only applicable to managed profiles,
+ * other users should be handled by Keyguard.
+ */
@Override
public void setDeviceLockedForUser(int userId, boolean locked) {
enforceReportPermission();
@@ -1204,6 +1249,9 @@ public class TrustManagerService extends SystemService {
synchronized (mDeviceLockedForUser) {
mDeviceLockedForUser.put(userId, locked);
}
+
+ KeyStore.getInstance().onUserLockedStateChanged(userId, locked);
+
if (locked) {
try {
ActivityManager.getService().notifyLockedProfile(userId);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 848971d3b044..1592f239fd2e 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -4268,6 +4268,11 @@ class ActivityStack extends ConfigurationContainer {
final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
Intent resultData) {
+ if (!srec.attachedToProcess()) {
+ // Nothing to do if the caller is not attached, because this method should be called
+ // from an alive activity.
+ return false;
+ }
final TaskRecord task = srec.getTaskRecord();
final ArrayList<ActivityRecord> activities = task.mActivities;
final int start = activities.indexOf(srec);
@@ -4321,14 +4326,14 @@ class ActivityStack extends ConfigurationContainer {
}
if (parent != null && foundParentInTask) {
+ final int callingUid = srec.info.applicationInfo.uid;
final int parentLaunchMode = parent.info.launchMode;
final int destIntentFlags = destIntent.getFlags();
if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
- parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
- srec.packageName);
+ parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName);
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
@@ -4341,10 +4346,10 @@ class ActivityStack extends ConfigurationContainer {
.setActivityInfo(aInfo)
.setResultTo(parent.appToken)
.setCallingPid(-1)
- .setCallingUid(parent.launchedFromUid)
- .setCallingPackage(parent.launchedFromPackage)
+ .setCallingUid(callingUid)
+ .setCallingPackage(srec.packageName)
.setRealCallingPid(-1)
- .setRealCallingUid(parent.launchedFromUid)
+ .setRealCallingUid(callingUid)
.setComponentSpecified(true)
.execute();
foundParentInTask = res == ActivityManager.START_SUCCESS;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 5b697ee89602..f37698de34d5 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2763,6 +2763,11 @@ class ActivityStarter {
return mRequest.intent;
}
+ @VisibleForTesting
+ int getCallingUid() {
+ return mRequest.callingUid;
+ }
+
ActivityStarter setReason(String reason) {
mRequest.reason = reason;
return this;
diff --git a/services/net/Android.bp b/services/net/Android.bp
index bb5409b3e032..8b444b0fed41 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -12,8 +12,7 @@ java_library_static {
":services.net-sources",
],
static_libs: [
- "dnsresolver_aidl_interface-V4-java",
- "netd_aidl_interface-V3-java",
+ "netd_aidl_interfaces-platform-java",
"netlink-client",
"networkstack-client",
"net-utils-services-common",
@@ -44,7 +43,8 @@ java_library {
"framework-wifi-util-lib",
],
static_libs: [
- "dnsresolver_aidl_interface-V2-java",
+ // All the classes in netd_aidl_interface must be jarjar so they do not conflict with the
+ // classes generated by netd_aidl_interfaces-platform-java above.
"netd_aidl_interface-V3-java",
"netlink-client",
"networkstack-client",
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 163832983b5b..3465ea99bdae 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -73,7 +73,6 @@ public class HdmiCecLocalDeviceAudioSystemTest {
private static final int HDMI_3_PHYSICAL_ADDRESS = 0x2300;
private int mInvokeDeviceEventState;
private HdmiDeviceInfo mDeviceInfo;
- private boolean mMutingEnabled;
private boolean mArcSupport;
private HdmiPortInfo[] mHdmiPortInfo;
@@ -154,8 +153,6 @@ public class HdmiCecLocalDeviceAudioSystemTest {
@Override
boolean readBooleanSystemProperty(String key, boolean defVal) {
switch (key) {
- case Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE:
- return mMutingEnabled;
case Constants.PROPERTY_ARC_SUPPORT:
return mArcSupport;
default:
@@ -209,7 +206,6 @@ public class HdmiCecLocalDeviceAudioSystemTest {
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
mNativeWrapper.clearResultMessages();
- mMutingEnabled = true;
mArcSupport = true;
mInvokeDeviceEventState = 0;
mDeviceInfo = null;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index bde0ef6aa39e..ff27b9bb1c9e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -28,7 +28,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
@@ -54,8 +54,11 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import android.app.ActivityManager;
+import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.os.UserHandle;
@@ -82,8 +85,9 @@ public class ActivityStackTests extends ActivityTestsBase {
@Before
public void setUp() throws Exception {
mDefaultDisplay = mRootActivityContainer.getDefaultDisplay();
- mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
- true /* onTop */));
+ mStack = mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
+ true /* onTop */);
+ spyOn(mStack);
mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
}
@@ -1078,6 +1082,37 @@ public class ActivityStackTests extends ActivityTestsBase {
assertTrue(listener.mChanged);
}
+ @Test
+ public void testNavigateUpTo() {
+ final ActivityStartController controller = mock(ActivityStartController.class);
+ final ActivityStarter starter = new ActivityStarter(controller,
+ mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+ doReturn(controller).when(mService).getActivityStartController();
+ spyOn(starter);
+ doReturn(ActivityManager.START_SUCCESS).when(starter).execute();
+
+ final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask)
+ .setUid(firstActivity.getUid() + 1).build();
+ doReturn(starter).when(controller).obtainStarter(eq(firstActivity.intent), anyString());
+
+ final IApplicationThread thread = secondActivity.app.getThread();
+ secondActivity.app.setThread(null);
+ // This should do nothing from a non-attached caller.
+ assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */,
+ firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
+
+ secondActivity.app.setThread(thread);
+ assertTrue(mStack.navigateUpToLocked(secondActivity /* source record */,
+ firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
+ // The firstActivity uses default launch mode, so the activities between it and itself will
+ // be finished.
+ assertTrue(secondActivity.finishing);
+ assertTrue(firstActivity.finishing);
+ // The calling uid of the new activity should be the current real caller.
+ assertEquals(secondActivity.getUid(), starter.getCallingUid());
+ }
+
private void verifyShouldSleepActivities(boolean focusedStack,
boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
final ActivityDisplay display = mock(ActivityDisplay.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 84bdecb86826..f94f00203521 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -290,6 +290,7 @@ class ActivityTestsBase {
aInfo.applicationInfo.packageName = mComponent.getPackageName();
aInfo.applicationInfo.uid = mUid;
aInfo.packageName = mComponent.getPackageName();
+ aInfo.name = mComponent.getClassName();
if (mTargetActivity != null) {
aInfo.targetActivity = mTargetActivity;
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 8d53158b9f32..ce71511c0361 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -398,7 +398,7 @@ public class TelecomManager {
* Optional extra for communicating the call network technology used by a
* {@link android.telecom.Connection} to Telecom and InCallUI.
*
- * @see {@code NETWORK_TYPE_*} in {@link android.telephony.TelephonyManager}.
+ * {@code NETWORK_TYPE_*} in {@link android.telephony.TelephonyManager}.
*/
public static final String EXTRA_CALL_NETWORK_TYPE =
"android.telecom.extra.CALL_NETWORK_TYPE";
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5149ad232705..41bab25af115 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -3025,19 +3025,95 @@ public class CarrierConfigManager {
public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string";
/**
- * Timeout in seconds for displaying 5G icon, default value is 0 which means the timer is
- * disabled.
+ * This configuration allows the system UI to determine how long to continue to display 5G icons
+ * when the device switches between different 5G scenarios.
+ *
+ * There are seven 5G scenarios:
+ * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using
+ * millimeter wave.
+ * 2. connected: device currently connected to 5G cell as the secondary cell but not using
+ * millimeter wave.
+ * 3. not_restricted_rrc_idle: device camped on a network that has 5G capability (not necessary
+ * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+ * currently in IDLE state.
+ * 4. not_restricted_rrc_con: device camped on a network that has 5G capability (not necessary
+ * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+ * currently in CONNECTED state.
+ * 5. restricted: device camped on a network that has 5G capability (not necessary to connect a
+ * 5G cell as a secondary cell) but the use of 5G is restricted.
+ * 6. legacy: device is not camped on a network that has 5G capability
+ * 7. any: any of the above scenarios
+ *
+ * The configured string contains various timer rules separated by a semicolon.
+ * Each rule will have three items: prior 5G scenario, current 5G scenario, and grace period
+ * in seconds before changing the icon. When the 5G state changes from the prior to the current
+ * 5G scenario, the system UI will continue to show the icon for the prior 5G scenario (defined
+ * in {@link #KEY_5G_ICON_CONFIGURATION_STRING}) for the amount of time specified by the grace
+ * period. If the prior 5G scenario is reestablished, the timer will reset and start again if
+ * the UE changes 5G scenarios again. Defined states (5G scenarios #1-5) take precedence over
+ * 'any' (5G scenario #6), and unspecified transitions have a default grace period of 0.
+ * The order of rules in the configuration determines the priority (the first applicable timer
+ * rule will be used).
*
- * System UI will show the 5G icon and start a timer with the timeout from this config when the
- * device connects to a 5G cell. System UI stops displaying 5G icon when both the device
- * disconnects from 5G cell and the timer is expired.
+ * Here is an example: "connected_mmwave,connected,30;connected_mmwave,any,10;connected,any,10"
+ * This configuration defines 3 timers:
+ * 1. When UE goes from 'connected_mmwave' to 'connected', system UI will continue to display
+ * the 5G icon for 'connected_mmwave' for 30 seconds.
+ * 2. When UE goes from 'connected_mmwave' to any other state (except for connected, since
+ * rule 1 would be used instead), system UI will continue to display the 5G icon for
+ * 'connected_mmwave' for 10 seconds.
+ * 3. When UE goes from 'connected' to any other state, system UI will continue to display the
+ * 5G icon for 'connected' for 10 seconds.
*
- * If 5G is reacquired during this timer, the timer is canceled and restarted when 5G is next
- * lost. Allows us to momentarily lose 5G without blinking the icon.
* @hide
*/
- public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT =
- "5g_icon_display_grace_period_sec_int";
+ public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING =
+ "5g_icon_display_grace_period_string";
+
+ /**
+ * This configuration extends {@link #KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING} to allow the
+ * system UI to continue displaying 5G icons after the initial timer expires.
+ *
+ * There are seven 5G scenarios:
+ * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using
+ * millimeter wave.
+ * 2. connected: device currently connected to 5G cell as the secondary cell but not using
+ * millimeter wave.
+ * 3. not_restricted_rrc_idle: device camped on a network that has 5G capability (not necessary
+ * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+ * currently in IDLE state.
+ * 4. not_restricted_rrc_con: device camped on a network that has 5G capability (not necessary
+ * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC
+ * currently in CONNECTED state.
+ * 5. restricted: device camped on a network that has 5G capability (not necessary to connect a
+ * 5G cell as a secondary cell) but the use of 5G is restricted.
+ * 6. legacy: device is not camped on a network that has 5G capability
+ * 7. any: any of the above scenarios
+ *
+ * The configured string contains various timer rules separated by a semicolon.
+ * Each rule will have three items: primary 5G scenario, secondary 5G scenario, and
+ * grace period in seconds before changing the icon. When the timer for the primary 5G timer
+ * expires, the system UI will continue to show the icon for the primary 5G scenario (defined
+ * in {@link #KEY_5G_ICON_CONFIGURATION_STRING}) for the amount of time specified by the grace
+ * period. If the primary 5G scenario is reestablished, the timers will reset and the system UI
+ * will continue to display the icon for the primary 5G scenario without interruption. If the
+ * secondary 5G scenario is lost, the timer will reset and the icon will reflect the true state.
+ * Defined states (5G scenarios #1-5) take precedence over 'any' (5G scenario #6), and
+ * unspecified transitions have a default grace period of 0. The order of rules in the
+ * configuration determines the priority (the first applicable timer rule will be used).
+ *
+ * Here is an example: "connected,not_restricted_rrc_idle,30"
+ * This configuration defines a secondary timer that extends the primary 'connected' timer.
+ * When the primary 'connected' timer expires while the UE is in the 'not_restricted_rrc_idle'
+ * 5G state, system UI will continue to display the 5G icon for 'connected' for 30 seconds.
+ * If the 5G state returns to 'connected', the timer will be reset without change to the icon,
+ * and if the 5G state changes to neither 'connected' not 'not_restricted_rrc_idle', the icon
+ * will change to reflect the true state.
+ *
+ * @hide
+ */
+ public static final String KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING =
+ "5g_icon_display_secondary_grace_period_string";
/**
* Controls time in milliseconds until DcTracker reevaluates 5G connection state.
@@ -3629,6 +3705,17 @@ public class CarrierConfigManager {
public static final String KEY_MISSED_INCOMING_CALL_SMS_ORIGINATOR_STRING_ARRAY =
"missed_incoming_call_sms_originator_string_array";
+
+ /**
+ * String array of Apn Type configurations.
+ * The entries should be of form "APN_TYPE_NAME:priority".
+ * priority is an integer that is sorted from highest to lowest.
+ * example: cbs:5
+ *
+ * @hide
+ */
+ public static final String KEY_APN_PRIORITY_STRING_ARRAY = "apn_priority_string_array";
+
/**
* The patterns of missed incoming call sms. This is the regular expression used for
* matching the missed incoming call's date, time, and caller id. The pattern should match
@@ -4070,7 +4157,7 @@ public class CarrierConfigManager {
sDefaults.putStringArray(KEY_BANDWIDTH_STRING_ARRAY, new String[]{
"GPRS:24,24", "EDGE:70,18", "UMTS:115,115", "CDMA-IS95A:14,14", "CDMA-IS95B:14,14",
"1xRTT:30,30", "EvDo-rev.0:750,48", "EvDo-rev.A:950,550", "HSDPA:4300,620",
- "HSUPA:4300,1800", "HSPA:4300,1800", "EvDo-rev.B:1500,550:", "eHRPD:750,48",
+ "HSUPA:4300,1800", "HSPA:4300,1800", "EvDo-rev.B:1500,550", "eHRPD:750,48",
"HSPAP:13000,3400", "TD-SCDMA:115,115", "LTE:30000,15000", "NR_NSA:47000,15000",
"NR_NSA_MMWAVE:145000,15000", "NR_SA:145000,15000"});
sDefaults.putBoolean(KEY_BANDWIDTH_NR_NSA_USE_LTE_VALUE_FOR_UPSTREAM_BOOL, false);
@@ -4089,7 +4176,8 @@ public class CarrierConfigManager {
sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING,
"connected_mmwave:5G,connected:5G,not_restricted_rrc_idle:5G,"
+ "not_restricted_rrc_con:5G");
- sDefaults.putInt(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0);
+ sDefaults.putString(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING, "");
+ sDefaults.putString(KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING, "");
/* Default value is 1 hour. */
sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_BOOL, false);
@@ -4159,6 +4247,10 @@ public class CarrierConfigManager {
sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG, TimeUnit.DAYS.toMillis(1));
sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_ORIGINATOR_STRING_ARRAY,
new String[0]);
+ sDefaults.putStringArray(KEY_APN_PRIORITY_STRING_ARRAY, new String[] {
+ "default:0", "mms:2", "supl:2", "dun:2", "hipri:3", "fota:2",
+ "ims:2", "cbs:2", "ia:2", "emergency:2", "mcx:3", "xcap:3"
+ });
sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]);
}
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 33a43c1e0319..1e5ce05ff28a 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -211,7 +211,7 @@ public abstract class CellIdentity implements Parcelable {
}
/** @hide */
- protected String getPlmn() {
+ public @Nullable String getPlmn() {
if (mMccStr == null || mMncStr == null) return null;
return mMccStr + mMncStr;
}
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index f21277cdd83c..68c833c37c99 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -279,6 +279,7 @@ public final class CellIdentityCdma extends CellIdentity {
mLongitude = in.readInt();
mLatitude = in.readInt();
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 1a913105db2e..849c613da748 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -323,6 +323,7 @@ public final class CellIdentityGsm extends CellIdentity {
mBsic = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 13a8273d64d4..1993550d52b8 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -403,6 +403,8 @@ public final class CellIdentityLte extends CellIdentity {
mBandwidth = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
mCsgInfo = in.readParcelable(null);
+
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index f0d878001bf4..8dd7bdd57841 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -273,6 +273,8 @@ public final class CellIdentityNr extends CellIdentity {
mBands = in.createIntArray();
mNci = in.readLong();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
+
+ updateGlobalCellId();
}
/** Implement the Parcelable interface */
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 6dffe922ffd1..e74b70939d14 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -321,6 +321,8 @@ public final class CellIdentityTdscdma extends CellIdentity {
mUarfcn = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
mCsgInfo = in.readParcelable(null);
+
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index eab174ade3b7..40cb27e95151 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -336,6 +336,8 @@ public final class CellIdentityWcdma extends CellIdentity {
mUarfcn = in.readInt();
mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
mCsgInfo = in.readParcelable(null);
+
+ updateGlobalCellId();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index 45deea206cfc..3d96fc634d6a 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -231,6 +231,8 @@ public class MbmsDownloadSession implements AutoCloseable {
private static final String DESTINATION_SANITY_CHECK_FILE_NAME = "destinationSanityCheckFile";
+ private static final int MAX_SERVICE_ANNOUNCEMENT_FILE_SIZE = 10 * 1024; // 10KB
+
private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
private final Context mContext;
@@ -318,6 +320,16 @@ public class MbmsDownloadSession implements AutoCloseable {
return session;
}
+ /**
+ * Returns the maximum size of the service announcement file that can be provided via
+ * {@link #addServiceAnnouncementFile}
+ * @return The maximum length of the byte array passed as an argument to
+ * {@link #addServiceAnnouncementFile}.
+ */
+ public static int getMaximumServiceAnnouncementFileSize() {
+ return MAX_SERVICE_ANNOUNCEMENT_FILE_SIZE;
+ }
+
private int bindAndInitialize() {
mServiceConnection = new ServiceConnection() {
@Override
@@ -424,6 +436,60 @@ public class MbmsDownloadSession implements AutoCloseable {
}
/**
+ * Inform the middleware of a service announcement file received from a group communication
+ * server.
+ *
+ * When participating in a group call via the {@link MbmsGroupCallSession} API, applications may
+ * receive a service announcement file from the group call server that informs them of
+ * files that may be relevant to users communicating on the group call.
+ *
+ * After supplying the service announcement file received from the server to the middleware via
+ * this API, applications will receive information on the available files via
+ * {@link MbmsDownloadSessionCallback#onFileServicesUpdated}, and the available files will be
+ * downloadable via {@link MbmsDownloadSession#download} like other files published via
+ * {@link MbmsDownloadSessionCallback#onFileServicesUpdated}.
+ *
+ * Asynchronous error codes via the {@link MbmsDownloadSessionCallback#onError(int, String)}
+ * callback may include any of the errors that are not specific to the streaming use-case.
+ *
+ * May throw an {@link IllegalStateException} when the middleware has not yet been bound,
+ * or an {@link IllegalArgumentException} if the file is too large.
+ *
+ * @param fileContents The contents of the service announcement file received from the group
+ * call server. If the size of this array is greater than the value of
+ * {@link #getMaximumServiceAnnouncementFileSize()}, an
+ * {@link IllegalArgumentException} will be thrown.
+ */
+ public void addServiceAnnouncementFile(@NonNull byte[] fileContents) {
+ IMbmsDownloadService downloadService = mService.get();
+ if (downloadService == null) {
+ throw new IllegalStateException("Middleware not yet bound");
+ }
+
+ if (fileContents.length > MAX_SERVICE_ANNOUNCEMENT_FILE_SIZE) {
+ throw new IllegalArgumentException("File too large");
+ }
+
+ try {
+ int returnCode = downloadService.addServiceAnnouncementFile(
+ mSubscriptionId, fileContents);
+ if (returnCode == MbmsErrors.UNKNOWN) {
+ // Unbind and throw an obvious error
+ close();
+ throw new IllegalStateException("Middleware must not return an unknown error code");
+ }
+ if (returnCode != MbmsErrors.SUCCESS) {
+ sendErrorToApp(returnCode, null);
+ }
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Remote process died");
+ mService.set(null);
+ sIsInitialized.set(false);
+ sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+ }
+ }
+
+ /**
* Sets the temp file root for downloads.
* All temp files created for the middleware to write to will be contained in the specified
* directory. Applications that wish to specify a location only need to call this method once
diff --git a/telephony/java/android/telephony/TelephonyDisplayInfo.java b/telephony/java/android/telephony/TelephonyDisplayInfo.java
index 2c4d5ae3b82b..3d5c6aad1042 100644
--- a/telephony/java/android/telephony/TelephonyDisplayInfo.java
+++ b/telephony/java/android/telephony/TelephonyDisplayInfo.java
@@ -62,8 +62,6 @@ public final class TelephonyDisplayInfo implements Parcelable {
* {@link TelephonyManager#NETWORK_TYPE_LTE} network and has E-UTRA-NR Dual Connectivity(EN-DC)
* capability or is currently connected to the secondary
* {@link TelephonyManager#NETWORK_TYPE_NR} cellular network on millimeter wave bands.
- *
- * @see AccessNetworkConstants.NgranBands#FREQUENCY_RANGE_GROUP_2
*/
public static final int OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE = 4;
@@ -154,7 +152,14 @@ public final class TelephonyDisplayInfo implements Parcelable {
return Objects.hash(mNetworkType, mOverrideNetworkType);
}
- private static String overrideNetworkTypeToString(@OverrideNetworkType int type) {
+ /**
+ * Convert override network type to string.
+ *
+ * @param type Override network type
+ * @return Override network type in string format
+ * @hide
+ */
+ public static String overrideNetworkTypeToString(@OverrideNetworkType int type) {
switch (type) {
case OVERRIDE_NETWORK_TYPE_NONE: return "NONE";
case OVERRIDE_NETWORK_TYPE_LTE_CA: return "LTE_CA";
@@ -168,6 +173,6 @@ public final class TelephonyDisplayInfo implements Parcelable {
@Override
public String toString() {
return "TelephonyDisplayInfo {network=" + TelephonyManager.getNetworkTypeName(mNetworkType)
- + ", override=" + overrideNetworkTypeToString(mOverrideNetworkType);
+ + ", override=" + overrideNetworkTypeToString(mOverrideNetworkType) + "}";
}
}
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 44b0968eaa90..5500d635d2ff 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -269,10 +269,10 @@ public class EuiccManager {
* only contains {@link #OPERATION_DOWNLOAD} and ErrorCode is 0 implies this is an unknown
* Download error.
*
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE}
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE}
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE}
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE}
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE
*/
public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE =
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
@@ -552,7 +552,7 @@ public class EuiccManager {
/**
* List of OperationCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}'s
- * value, an integer. @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * value, an integer. @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*
* @hide
*/
@@ -575,44 +575,44 @@ public class EuiccManager {
/**
* Internal system error.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SYSTEM = 1;
/**
* SIM slot error. Failed to switch slot, failed to access the physical slot etc.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SIM_SLOT = 2;
/**
* eUICC card error.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_EUICC_CARD = 3;
/**
* Generic switching profile error
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SWITCH = 4;
/**
* Download profile error.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_DOWNLOAD = 5;
/**
* Subscription's metadata error
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_METADATA = 6;
/**
* eUICC returned an error defined in GSMA (SGP.22 v2.2) while running one of the ES10x
* functions.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_EUICC_GSMA = 7;
@@ -620,13 +620,13 @@ public class EuiccManager {
* The exception of failing to execute an APDU command. It can be caused by an error
* happening on opening the basic or logical channel, or the response of the APDU command is
* not success (0x9000).
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_APDU = 8;
/**
* SMDX(SMDP/SMDS) error
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SMDX = 9;
@@ -655,19 +655,19 @@ public class EuiccManager {
* Thus the integer stored in {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} is
* 0xA8B1051(176885841)
*
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10;
/**
* HTTP error
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int OPERATION_HTTP = 11;
/**
* List of ErrorCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@@ -695,56 +695,56 @@ public class EuiccManager {
/**
* Operation such as downloading/switching to another profile failed due to device being
* carrier locked.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_CARRIER_LOCKED = 10000;
/**
* The activation code(SGP.22 v2.2 section[4.1]) is invalid.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INVALID_ACTIVATION_CODE = 10001;
/**
* The confirmation code(SGP.22 v2.2 section[4.7]) is invalid.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002;
/**
* The profile's carrier is incompatible with the LPA.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INCOMPATIBLE_CARRIER = 10003;
/**
* There is no more space available on the eUICC for new profiles.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004;
/**
* Timed out while waiting for an operation to complete. i.e restart, disable,
* switch reset etc.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_TIME_OUT = 10005;
/**
* eUICC is missing or defective on the device.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_EUICC_MISSING = 10006;
/**
* The eUICC card(hardware) version is incompatible with the software
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_UNSUPPORTED_VERSION = 10007;
/**
* No SIM card is available in the device.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_SIM_MISSING = 10008;
@@ -754,52 +754,52 @@ public class EuiccManager {
* 2. GSMA(.22 v2.2) Profile Install Result - installFailedDueToDataMismatch
* 3. operation was interrupted
* 4. SIMalliance error in PEStatus(SGP.22 v2.2 section 2.5.6.1)
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INSTALL_PROFILE = 10009;
/**
* Failed to load profile onto eUICC due to Profile Poicly Rules.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_DISALLOWED_BY_PPR = 10010;
/**
* Address is missing e.g SMDS/SMDP address is missing.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_ADDRESS_MISSING = 10011;
/**
* Certificate needed for authentication is not valid or missing. E.g SMDP/SMDS authentication
* failed.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_CERTIFICATE_ERROR = 10012;
/**
* No profiles available.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_NO_PROFILES_AVAILABLE = 10013;
/**
* Failure to create a connection.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_CONNECTION_ERROR = 10014;
/**
* Response format is invalid. e.g SMDP/SMDS response contains invalid json, header or/and ASN1.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_INVALID_RESPONSE = 10015;
/**
* The operation is currently busy, try again later.
- * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+ * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
*/
public static final int ERROR_OPERATION_BUSY = 10016;
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 95ebbf39e944..872f49d65d25 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -141,8 +141,7 @@ public class ImsMmTelManager implements RegistrationManager {
}
/**
- * Receives IMS capability status updates from the ImsService. This information is also
- * available via the {@see #isAvailable(int, int)} method below.
+ * Receives IMS capability status updates from the ImsService.
*
* @see #registerMmTelCapabilityCallback(Executor, CapabilityCallback) (CapabilityCallback)
* @see #unregisterMmTelCapabilityCallback(CapabilityCallback)
@@ -195,8 +194,6 @@ public class ImsMmTelManager implements RegistrationManager {
* If unavailable, the feature is not able to support the unavailable capability at this
* time.
*
- * This information can also be queried using the {@see #isAvailable(int, int)} API.
- *
* @param capabilities The new availability of the capabilities.
*/
public void onCapabilitiesStatusChanged(
@@ -497,8 +494,7 @@ public class ImsMmTelManager implements RegistrationManager {
/**
* Registers a {@link CapabilityCallback} with the system, which will provide MmTel service
* availability updates for the subscription specified in
- * {@link ImsManager#getImsMmTelManager(int)}. The method {@see #isAvailable(int, int)}
- * can also be used to query this information at any time.
+ * {@link ImsManager#getImsMmTelManager(int)}.
*
* Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to
* subscription changed events and call
@@ -640,7 +636,6 @@ public class ImsMmTelManager implements RegistrationManager {
* @see android.telephony.CarrierConfigManager#KEY_HIDE_ENHANCED_4G_LTE_BOOL
* @see android.telephony.CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
- * @see #setAdvancedCallingSettingEnabled(boolean)
* @throws IllegalArgumentException if the subscription associated with this operation is not
* active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user's setting for advanced calling is enabled, false otherwise.
@@ -859,7 +854,6 @@ public class ImsMmTelManager implements RegistrationManager {
* @throws IllegalArgumentException if the subscription associated with this operation is not
* active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user’s “Video Calling” setting is currently enabled.
- * @see #setVtSettingEnabled(boolean)
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
@@ -934,7 +928,6 @@ public class ImsMmTelManager implements RegistrationManager {
*
* @throws IllegalArgumentException if the subscription associated with this operation is not
* active (SIM is not inserted, ESIM inactive) or invalid.
- * @see #setVoWiFiSettingEnabled(boolean)
*/
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(anyOf = {
@@ -1012,7 +1005,6 @@ public class ImsMmTelManager implements RegistrationManager {
* active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user's setting for Voice over WiFi while roaming is enabled, false
* if disabled.
- * @see #setVoWiFiRoamingSettingEnabled(boolean)
*/
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(anyOf = {
@@ -1131,7 +1123,6 @@ public class ImsMmTelManager implements RegistrationManager {
* - {@link #WIFI_MODE_WIFI_ONLY}
* - {@link #WIFI_MODE_CELLULAR_PREFERRED}
* - {@link #WIFI_MODE_WIFI_PREFERRED}
- * @see #setVoWiFiSettingEnabled(boolean)
*/
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(anyOf = {
@@ -1316,7 +1307,6 @@ public class ImsMmTelManager implements RegistrationManager {
*
* @throws IllegalArgumentException if the subscription associated with this operation is not
* active (SIM is not inserted, ESIM inactive) or invalid.
- * @see android.telecom.TelecomManager#getCurrentTtyMode
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
*/
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index 1dbaff5df802..e085dec10546 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -270,7 +270,7 @@ public interface RegistrationManager {
* inactive subscription, it will result in a no-op.
*
* @param c The {@link RegistrationCallback} to be removed.
- * @see SubscriptionManager.OnSubscriptionsChangedListener
+ * @see android.telephony.SubscriptionManager.OnSubscriptionsChangedListener
* @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index a3ce1b585f76..9ec3f61ba6a7 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -218,13 +218,7 @@ public class MmTelFeature extends ImsFeature {
* {@link MmTelCapabilities#CAPABILITY_TYPE_UT}, and
* {@link MmTelCapabilities#CAPABILITY_TYPE_SMS}.
*
- * The capabilities of this MmTelFeature will be set by the framework and can be queried with
- * {@see #queryCapabilityStatus()}.
- *
- * This MmTelFeature can then return the status of each of these capabilities (enabled or not)
- * by sending a {@see #notifyCapabilitiesStatusChanged} callback to the framework. The current
- * status can also be queried using {@see #queryCapabilityStatus()}.
- * @see #isCapable(int)
+ * The capabilities of this MmTelFeature will be set by the framework.
*/
public static class MmTelCapabilities extends Capabilities {
diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
index ce9a73a21657..a9a33c0e1507 100644
--- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
@@ -403,8 +403,7 @@ public class ImsSmsImplBase {
message.mWrappedSmsMessage.mMessageRef,
STATUS_REPORT_STATUS_ERROR);
} else {
- Log.w(LOG_TAG,
- "onSmsStatusReportReceivedWithoutMessageRef: Invalid pdu entered.");
+ Log.w(LOG_TAG, "onSmsStatusReportReceived: Invalid pdu entered.");
acknowledgeSmsReport(token, 0, STATUS_REPORT_STATUS_ERROR);
}
}
diff --git a/telephony/java/android/telephony/mbms/MbmsErrors.java b/telephony/java/android/telephony/mbms/MbmsErrors.java
index 52e4d333b29d..8611d26bc85b 100644
--- a/telephony/java/android/telephony/mbms/MbmsErrors.java
+++ b/telephony/java/android/telephony/mbms/MbmsErrors.java
@@ -16,8 +16,12 @@
package android.telephony.mbms;
+import android.annotation.IntDef;
import android.telephony.MbmsStreamingSession;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
public class MbmsErrors {
/**
* Indicates that the middleware has sent an error code that is not defined in the version of
@@ -138,6 +142,13 @@ public class MbmsErrors {
/** Indicates the the middleware has no record of the supplied {@link FileInfo} */
public static final int ERROR_UNKNOWN_FILE_INFO = 403;
+
+ /**
+ * Indicates that the service announcement file passed via
+ * {@link android.telephony.MbmsDownloadSession#addServiceAnnouncementFile(byte[])}
+ * is malformed.
+ */
+ public static final int ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE = 404;
}
/**
@@ -156,5 +167,35 @@ public class MbmsErrors {
public static final int ERROR_DUPLICATE_START_GROUP_CALL = 502;
}
+ /** @hide */
+ @IntDef(value = {
+ SUCCESS,
+ ERROR_NO_UNIQUE_MIDDLEWARE,
+ ERROR_MIDDLEWARE_NOT_BOUND,
+ ERROR_MIDDLEWARE_LOST,
+ InitializationErrors.ERROR_DUPLICATE_INITIALIZE,
+ InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED,
+ InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY,
+ GeneralErrors.ERROR_OUT_OF_MEMORY,
+ GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE,
+ GeneralErrors.ERROR_IN_E911,
+ GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE,
+ GeneralErrors.ERROR_UNABLE_TO_READ_SIM,
+ GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED,
+ StreamingErrors.ERROR_CONCURRENT_SERVICE_LIMIT_REACHED,
+ StreamingErrors.ERROR_UNABLE_TO_START_SERVICE,
+ StreamingErrors.ERROR_DUPLICATE_START_STREAM,
+ DownloadErrors.ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT,
+ DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST,
+ DownloadErrors.ERROR_UNKNOWN_FILE_INFO,
+ DownloadErrors.ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE,
+ GroupCallErrors.ERROR_UNABLE_TO_START_SERVICE,
+ GroupCallErrors.ERROR_DUPLICATE_START_GROUP_CALL,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MbmsError {
+ }
+
private MbmsErrors() {}
}
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
index 445087fb78d5..36136ab280c4 100755
--- a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
@@ -35,6 +35,8 @@ interface IMbmsDownloadService
int setTempFileRootDirectory(int subId, String rootDirectoryPath);
+ int addServiceAnnouncementFile(int subId, in byte[] fileContents);
+
int download(in DownloadRequest downloadRequest);
int addStatusListener(in DownloadRequest downloadRequest,
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
index 9f22d0a49806..3279ce66cd17 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
@@ -216,6 +216,28 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub {
}
/**
+ * Called when the client application wishes to receive file information according to a
+ * service announcement file received from a group call server.
+ *
+ * The service announcement file is in the format of a multipart MIME file with XML parts,
+ * though no validation is performed on the contents of the {@code fileContents} argument --
+ * implementing middleware applications should perform their own validation and return
+ * {@link MbmsErrors.DownloadErrors#ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE} if the file is
+ * malformed.
+ *
+ * @param subscriptionId The subscription id the service announcement applies to.
+ * @param fileContents The contents of the service announcement file.
+ * @return {@link MbmsErrors#SUCCESS}, or
+ * {@link MbmsErrors.DownloadErrors#ERROR_MALFORMED_SERVICE_ANNOUNCEMENT_FILE}
+ */
+ // TODO: are there any public specifications of what the file format is that I can link to?
+ @Override
+ public @MbmsErrors.MbmsError int addServiceAnnouncementFile(
+ int subscriptionId, @NonNull byte[] fileContents) {
+ return 0;
+ }
+
+ /**
* Issues a request to download a set of files.
*
* The middleware should expect that {@link #setTempFileRootDirectory(int, String)} has been
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 18e25921555a..76fc4f7d0519 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -109,11 +109,10 @@ public class DctConstants {
public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50;
public static final int EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51;
- public static final int EVENT_SERVICE_STATE_CHANGED = BASE + 52;
- public static final int EVENT_5G_TIMER_HYSTERESIS = BASE + 53;
- public static final int EVENT_5G_TIMER_WATCHDOG = BASE + 54;
- public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 55;
- public static final int EVENT_SIM_STATE_UPDATED = BASE + 56;
+ public static final int EVENT_TELEPHONY_DISPLAY_INFO_CHANGED = BASE + 52;
+ public static final int EVENT_NR_TIMER_WATCHDOG = BASE + 53;
+ public static final int EVENT_CARRIER_CONFIG_CHANGED = BASE + 54;
+ public static final int EVENT_SIM_STATE_UPDATED = BASE + 55;
/***** Constants *****/
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index ff70f8ba3936..29286e8f429e 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -240,5 +240,5 @@ public interface TelephonyProperties
* two.
* Type: int
*/
- static final String PROPERTY_MAX_ACTIVE_MODEMS = "ro.telephony.max.active.modems";
+ static final String PROPERTY_MAX_ACTIVE_MODEMS = "telephony.active_modems.max_count";
}
diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
index ef15b668e24c..a50f0461fae6 100644
--- a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
+++ b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
@@ -39,12 +39,12 @@ class MatchAllNetworkSpecifierTest {
}
@Test(expected = IllegalStateException::class)
- fun testSatisfiedBy() {
+ fun testCanBeSatisfiedBy() {
val specifier = MatchAllNetworkSpecifier()
val discoverySession = Mockito.mock(DiscoverySession::class.java)
val peerHandle = Mockito.mock(PeerHandle::class.java)
val wifiAwareNetworkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession,
peerHandle).build()
- specifier.satisfiedBy(wifiAwareNetworkSpecifier)
+ specifier.canBeSatisfiedBy(wifiAwareNetworkSpecifier)
}
}
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
index eec3cdbe8d7f..8c2de4035d0b 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
@@ -52,7 +52,7 @@ class TestNetworkStackService : Service() {
doReturn(mock(IBinder::class.java)).`when`(it).getSystemService(Context.NETD_SERVICE)
}
- private class TestPermissionChecker : NetworkStackConnector.PermissionChecker() {
+ private class TestPermissionChecker : NetworkStackService.PermissionChecker() {
override fun enforceNetworkStackCallingPermission() = Unit
}
@@ -62,8 +62,8 @@ class TestNetworkStackService : Service() {
override fun sendNetworkConditionsBroadcast(context: Context, broadcast: Intent) = Unit
}
- private inner class TestNetworkStackConnector(context: Context) :
- NetworkStackConnector(context, TestPermissionChecker()) {
+ private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector(
+ context, TestPermissionChecker(), NetworkStackService.Dependencies()) {
private val network = Network(TEST_NETID)
private val privateDnsBypassNetwork = TestNetwork(TEST_NETID)
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 656fe489d8b8..bef682b2822f 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -5394,8 +5394,6 @@ public class ConnectivityServiceTest {
// Even though the VPN is unvalidated, it becomes the default network for our app.
callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
- // TODO: this looks like a spurious callback.
- callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
callback.assertNoCallback();
assertTrue(vpnNetworkAgent.getScore() > mEthernetNetworkAgent.getScore());
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 1db90b71e2b1..a1bb0d586916 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -60,14 +60,13 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.AlarmManager;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
@@ -95,8 +94,6 @@ import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.SimpleClock;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import androidx.test.InstrumentationRegistry;
@@ -126,6 +123,7 @@ import java.io.File;
import java.time.Clock;
import java.time.ZoneOffset;
import java.util.Objects;
+import java.util.concurrent.Executor;
/**
* Tests for {@link NetworkStatsService}.
@@ -168,14 +166,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
private @Mock NetworkStatsSettings mSettings;
private @Mock IBinder mBinder;
private @Mock AlarmManager mAlarmManager;
- private @Mock TelephonyManager mTelephonyManager;
+ @Mock
+ private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
private HandlerThread mHandlerThread;
private NetworkStatsService mService;
private INetworkStatsSession mSession;
private INetworkManagementEventObserver mNetworkObserver;
- @Nullable
- private PhoneStateListener mPhoneStateListener;
private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
@Override
@@ -203,8 +200,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
mHandlerThread = new HandlerThread("HandlerThread");
final NetworkStatsService.Dependencies deps = makeDependencies();
mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock,
- mClock, mTelephonyManager, mSettings,
- mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps);
+ mClock, mSettings, mStatsFactory, new NetworkStatsObservers(), mStatsDir,
+ getBaseDir(mStatsDir), deps);
mElapsedRealtime = 0L;
@@ -224,12 +221,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
verify(mNetManager).registerObserver(networkObserver.capture());
mNetworkObserver = networkObserver.getValue();
-
- // Capture the phone state listener that created by service.
- final ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
- ArgumentCaptor.forClass(PhoneStateListener.class);
- verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(), anyInt());
- mPhoneStateListener = phoneStateListenerCaptor.getValue();
}
@NonNull
@@ -239,6 +230,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public HandlerThread makeHandlerThread() {
return mHandlerThread;
}
+
+ @Override
+ public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(
+ @NonNull Context context, @NonNull Executor executor,
+ @NonNull NetworkStatsService service) {
+
+ return mNetworkStatsSubscriptionsMonitor;
+ }
};
}
@@ -678,10 +677,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// TODO: support per IMSI state
private void setMobileRatTypeAndWaitForIdle(int ratType) {
- final ServiceState mockSs = mock(ServiceState.class);
- when(mockSs.getDataNetworkType()).thenReturn(ratType);
- mPhoneStateListener.onServiceStateChanged(mockSs);
-
+ when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString()))
+ .thenReturn(ratType);
+ mService.handleOnCollapsedRatTypeChanged();
HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
}
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index f354bb610224..77e2a6bb21de 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -1659,9 +1659,12 @@ class Linker {
return 1;
}
- // First extract the Package name without modifying it (via --rename-manifest-package).
- if (Maybe<AppInfo> maybe_app_info =
+ // Determine the package name under which to merge resources.
+ if (options_.rename_resources_package) {
+ context_->SetCompilationPackage(options_.rename_resources_package.value());
+ } else if (Maybe<AppInfo> maybe_app_info =
ExtractAppInfoFromManifest(manifest_xml.get(), context_->GetDiagnostics())) {
+ // Extract the package name from the manifest ignoring the value of --rename-manifest-package.
const AppInfo& app_info = maybe_app_info.value();
context_->SetCompilationPackage(app_info.package);
}
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index be4d474ebdf3..e62e0a6b9f62 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -43,6 +43,7 @@ struct LinkOptions {
bool output_to_directory = false;
bool auto_add_overlay = false;
OutputFormat output_format = OutputFormat::kApk;
+ Maybe<std::string> rename_resources_package;
// Java/Proguard options.
Maybe<std::string> generate_java_class_path;
@@ -244,6 +245,8 @@ class LinkCommand : public Command {
&options_.auto_add_overlay);
AddOptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml.",
&options_.manifest_fixer_options.rename_manifest_package);
+ AddOptionalFlag("--rename-resources-package", "Renames the package in resources table",
+ &options_.rename_resources_package);
AddOptionalFlag("--rename-instrumentation-target-package",
"Changes the name of the target package for instrumentation. Most useful\n"
"when used in conjunction with --rename-manifest-package.",
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 47d8f13bf9ef..29e09a11590b 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -892,7 +892,7 @@ public class WifiManager {
* The RSSI (signal strength) has changed.
*
* Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
- * @see {@link #EXTRA_NEW_RSSI}
+ * @see #EXTRA_NEW_RSSI
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
diff --git a/wifi/java/android/net/wifi/WpsInfo.java b/wifi/java/android/net/wifi/WpsInfo.java
index 00cb243efcaa..689ace5bf5b9 100644
--- a/wifi/java/android/net/wifi/WpsInfo.java
+++ b/wifi/java/android/net/wifi/WpsInfo.java
@@ -22,7 +22,7 @@ import android.os.Parcelable;
/**
* A class representing Wi-Fi Protected Setup
*
- * {@see WifiP2pConfig}
+ * {@see android.net.wifi.p2p.WifiP2pConfig}
*/
public class WpsInfo implements Parcelable {