Merge "Use a mock PermissionSettings for PMSettingsTest"
diff --git a/Android.bp b/Android.bp
index 9e838b3..121decb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -162,49 +162,54 @@
path: "wifi/java",
}
-framework_srcs = [
- // Java/AIDL sources under frameworks/base
- ":framework-core-sources",
- ":framework-drm-sources",
- ":framework-graphics-sources",
- ":framework-keystore-sources",
- ":framework-location-sources",
- ":framework-lowpan-sources",
- ":framework-media-sources",
- ":framework-mca-effect-sources",
- ":framework-mca-filterfw-sources",
- ":framework-mca-filterpacks-sources",
- ":framework-opengl-sources",
- ":framework-rs-sources",
- ":framework-sax-sources",
- ":framework-telecomm-sources",
- ":framework-telephony-sources",
- ":framework-wifi-sources",
- ":PacProcessor-aidl-sources",
- ":ProxyHandler-aidl-sources",
+filegroup {
+ name: "framework-srcs",
+ srcs: [
+ // Java/AIDL sources under frameworks/base
+ ":framework-core-sources",
+ ":framework-drm-sources",
+ ":framework-graphics-sources",
+ ":framework-keystore-sources",
+ ":framework-location-sources",
+ ":framework-lowpan-sources",
+ ":framework-media-sources",
+ ":framework-mca-effect-sources",
+ ":framework-mca-filterfw-sources",
+ ":framework-mca-filterpacks-sources",
+ ":framework-opengl-sources",
+ ":framework-rs-sources",
+ ":framework-sax-sources",
+ ":framework-telecomm-sources",
+ ":framework-telephony-sources",
+ ":framework-wifi-sources",
+ ":PacProcessor-aidl-sources",
+ ":ProxyHandler-aidl-sources",
- // AIDL sources from external directories
- ":dumpstate_aidl",
- ":framework_native_aidl",
- ":gatekeeper_aidl",
- ":gsiservice_aidl",
- ":incidentcompanion_aidl",
- ":installd_aidl",
- ":keystore_aidl",
- ":libaudioclient_aidl",
- ":libbinder_aidl",
- ":libbluetooth-binder-aidl",
- ":libcamera_client_aidl",
- ":libcamera_client_framework_aidl",
- ":libupdate_engine_aidl",
- ":storaged_aidl",
- ":vold_aidl",
+ // AIDL sources from external directories
+ ":dumpstate_aidl",
+ ":framework_native_aidl",
+ ":gatekeeper_aidl",
+ ":gsiservice_aidl",
+ ":incidentcompanion_aidl",
+ ":installd_aidl",
+ ":keystore_aidl",
+ ":libaudioclient_aidl",
+ ":libbinder_aidl",
+ ":libbluetooth-binder-aidl",
+ ":libcamera_client_aidl",
+ ":libcamera_client_framework_aidl",
+ ":libupdate_engine_aidl",
+ ":storaged_aidl",
+ ":vold_aidl",
- // etc.
- "core/java/**/*.logtags",
- ":framework-javastream-protos",
- ":framework-statslog-gen",
-]
+ // For the generated R.java and Manifest.java
+ ":framework-res{.aapt.srcjar}",
+
+ // etc.
+ ":framework-javastream-protos",
+ ":framework-statslog-gen",
+ ],
+}
java_defaults {
name: "framework-aidl-export-defaults",
@@ -231,32 +236,11 @@
},
}
-java_defaults {
- name: "framework-defaults",
- defaults: ["framework-aidl-export-defaults"],
- installable: true,
-
- srcs: framework_srcs,
-
- aidl: {
- generate_get_transaction_name: true,
- },
-
- exclude_srcs: [
- // See comment on framework-atb-backward-compatibility module below
- "core/java/android/content/pm/AndroidTestBaseUpdater.java",
- ],
-
- sdk_version: "core_platform",
- libs: [
- "ext",
- "updatable_media_stubs",
- ],
-
- jarjar_rules: ":framework-jarjar-rules",
-
+// Collection of classes that are generated from non-Java files that are not listed in
+// framework_srcs. These have no or very limited dependency to the framework.
+java_library {
+ name: "framework-internal-utils",
static_libs: [
- "mimemap",
"apex_aidl_interface-java",
"suspend_control_aidl_interface-java",
"framework-protos",
@@ -290,6 +274,38 @@
"com.android.sysprop.apex",
"PlatformProperties",
],
+ sdk_version: "core_platform",
+ installable: false,
+}
+
+java_defaults {
+ name: "framework-defaults",
+ defaults: ["framework-aidl-export-defaults"],
+ installable: true,
+
+ srcs: [
+ ":framework-srcs",
+ "core/java/**/*.logtags",
+ ],
+
+ aidl: {
+ generate_get_transaction_name: true,
+ },
+
+ exclude_srcs: [
+ // See comment on framework-atb-backward-compatibility module below
+ "core/java/android/content/pm/AndroidTestBaseUpdater.java",
+ ],
+
+ sdk_version: "core_platform",
+ libs: [
+ "ext",
+ "updatable_media_stubs",
+ ],
+
+ jarjar_rules: ":framework-jarjar-rules",
+
+ static_libs: ["framework-internal-utils"],
required: [
// TODO: remove gps_debug when the build system propagates "required" properly.
@@ -374,7 +390,6 @@
platform_compat_config {
name: "framework-platform-compat-config",
- prefix: "framework",
src: ":framework-annotation-proc",
}
@@ -760,7 +775,7 @@
],
}
-// TODO: Don't rely on this list once droiddoc can take a list of packages to document
+// TODO: Don't rely on this list by switching package.html into package-info.java
frameworks_base_subdirs = [
"core/java",
"graphics/java",
@@ -780,13 +795,6 @@
"rs/java",
]
-packages_to_document = [
- "android",
- "javax/microedition/khronos",
- "org/apache/http/conn",
- "org/apache/http/params",
-]
-
// Make the api/current.txt file available for use by modules in other
// directories.
filegroup {
@@ -879,17 +887,17 @@
stubs_defaults {
name: "framework-doc-stubs-default",
srcs: [
+ ":framework-srcs",
+ "core/java/**/*.logtags",
"test-base/src/**/*.java",
":opt-telephony-srcs",
":opt-net-voip-srcs",
":core_public_api_files",
- ":updatable-media-srcs-without-aidls",
+ ":updatable-media-srcs",
"test-mock/src/**/*.java",
"test-runner/src/**/*.java",
":jobscheduler-framework-source",
],
- srcs_lib: "framework-minus-apex",
- srcs_lib_whitelist_pkgs: packages_to_document,
libs: framework_docs_only_libs,
local_sourcepaths: frameworks_base_subdirs,
create_doc_stubs: true,
@@ -936,17 +944,23 @@
create_stubs: false,
}
+doc_defaults {
+ name: "framework-dokka-docs-default",
+ create_stubs: false,
+}
+
stubs_defaults {
name: "metalava-api-stubs-default",
srcs: [
+ ":framework-srcs",
+ "core/java/**/*.logtags",
":opt-telephony-srcs",
":opt-net-voip-srcs",
":core_public_api_files",
- ":updatable-media-srcs-without-aidls",
+ ":updatable-media-srcs",
":jobscheduler-framework-source",
],
- srcs_lib: "framework-minus-apex",
- srcs_lib_whitelist_pkgs: packages_to_document,
+ libs: ["framework-internal-utils"],
local_sourcepaths: frameworks_base_subdirs,
installable: false,
annotations_enabled: true,
@@ -960,6 +974,7 @@
"sdk-dir",
"api-versions-jars-dir",
],
+ sdk_version: "core_platform",
}
droidstubs {
@@ -1109,7 +1124,7 @@
}
droiddoc {
- name: "ds-docs",
+ name: "ds-docs-java",
defaults: ["framework-docs-default"],
srcs: [
":framework-doc-stubs",
@@ -1138,6 +1153,58 @@
}
droiddoc {
+ name: "ds-docs-kt",
+ defaults: ["framework-dokka-docs-default"],
+ srcs: [
+ ":framework-doc-stubs",
+ ],
+ args: "-noJdkLink -links https://kotlinlang.org/api/latest/jvm/stdlib/^external/dokka/package-list " +
+ "-noStdlibLink",
+ proofread_file: "ds-dokka-proofread.txt",
+ dokka_enabled: true,
+}
+
+java_genrule {
+ name: "ds-docs",
+ tools: [
+ "zip2zip",
+ "merge_zips",
+ ],
+ srcs: [
+ ":ds-docs-java{.docs.zip}",
+ ":ds-docs-kt{.docs.zip}",
+ ],
+ out: ["ds-docs.zip"],
+ dist: {
+ targets: ["docs"],
+ },
+ cmd: "$(location zip2zip) -i $(location :ds-docs-kt{.docs.zip}) -o $(genDir)/ds-docs-kt-moved.zip **/*:en/reference/kotlin && " +
+ "$(location merge_zips) $(out) $(location :ds-docs-java{.docs.zip}) $(genDir)/ds-docs-kt-moved.zip",
+}
+
+java_genrule {
+ name: "ds-docs-switched",
+ tools: [
+ "switcher4",
+ "soong_zip",
+ ],
+ srcs: [
+ ":ds-docs-java{.docs.zip}",
+ ":ds-docs-kt{.docs.zip}",
+ ],
+ out: ["ds-docs-switched.zip"],
+ dist: {
+ targets: ["docs"],
+ },
+ cmd: "unzip $(location :ds-docs-java{.docs.zip}) -d $(genDir) && " +
+ "unzip $(location :ds-docs-kt{.docs.zip}) -d $(genDir)/en/reference/kotlin && " +
+ "SWITCHER=$$(cd $$(dirname $(location switcher4)) && pwd)/$$(basename $(location switcher4)) && " +
+ "(cd $(genDir)/en/reference && $$SWITCHER --work platform) && " +
+ "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)",
+}
+
+
+droiddoc {
name: "ds-static-docs",
defaults: ["framework-docs-default"],
srcs: [
@@ -1271,6 +1338,7 @@
":openjdk_java_files",
":opt-telephony-common-srcs",
],
+
arg_files: [
"core/res/AndroidManifest.xml",
],
@@ -1405,7 +1473,7 @@
// annotations to private apis
aidl_mapping {
name: "framework-aidl-mappings",
- srcs: framework_srcs,
+ srcs: [":framework-srcs"],
output: "framework-aidl-mappings.txt",
}
diff --git a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl
index aa255bf..9d5becb 100644
--- a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl
+++ b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl
@@ -16,7 +16,6 @@
package android.os;
-import android.os.IMaintenanceActivityListener;
import android.os.UserHandle;
/** @hide */
@@ -44,8 +43,6 @@
long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
long addPowerSaveTempWhitelistAppForSms(String name, int userId, String reason);
void exitIdle(String reason);
- boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener);
- void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener);
int setPreIdleTimeoutMode(int Mode);
void resetPreIdleTimeoutMode();
}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 62930b0..d0e38b4 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -51,14 +51,12 @@
import android.os.FileUtils;
import android.os.Handler;
import android.os.IDeviceIdleController;
-import android.os.IMaintenanceActivityListener;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.Process;
-import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -448,7 +446,6 @@
// down.
private boolean mJobsActive;
private boolean mAlarmsActive;
- private boolean mReportedMaintenanceActivity;
/* Factor to apply to INACTIVE_TIMEOUT and IDLE_AFTER_INACTIVE_TIMEOUT in order to enter
* STATE_IDLE faster or slower. Don't apply this to SENSING_TIMEOUT or LOCATING_TIMEOUT because:
@@ -463,9 +460,6 @@
public final AtomicFile mConfigFile;
- private final RemoteCallbackList<IMaintenanceActivityListener> mMaintenanceActivityListeners =
- new RemoteCallbackList<IMaintenanceActivityListener>();
-
/**
* Package names the system has white-listed to opt out of power save restrictions,
* except for device idle mode.
@@ -1309,7 +1303,6 @@
private static final int MSG_REPORT_IDLE_OFF = 4;
private static final int MSG_REPORT_ACTIVE = 5;
private static final int MSG_TEMP_APP_WHITELIST_TIMEOUT = 6;
- private static final int MSG_REPORT_MAINTENANCE_ACTIVITY = 7;
private static final int MSG_FINISH_IDLE_OP = 8;
private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9;
private static final int MSG_SEND_CONSTRAINT_MONITORING = 10;
@@ -1410,22 +1403,6 @@
int appId = msg.arg1;
checkTempAppWhitelistTimeout(appId);
} break;
- case MSG_REPORT_MAINTENANCE_ACTIVITY: {
- // TODO: What is keeping the device awake at this point? Does it need to be?
- boolean active = (msg.arg1 == 1);
- final int size = mMaintenanceActivityListeners.beginBroadcast();
- try {
- for (int i = 0; i < size; i++) {
- try {
- mMaintenanceActivityListeners.getBroadcastItem(i)
- .onMaintenanceActivityChanged(active);
- } catch (RemoteException ignored) {
- }
- }
- } finally {
- mMaintenanceActivityListeners.finishBroadcast();
- }
- } break;
case MSG_FINISH_IDLE_OP: {
// mActiveIdleWakeLock is held at this point
decActiveIdleOps();
@@ -1594,16 +1571,6 @@
}
}
- @Override public boolean registerMaintenanceActivityListener(
- IMaintenanceActivityListener listener) {
- return DeviceIdleController.this.registerMaintenanceActivityListener(listener);
- }
-
- @Override public void unregisterMaintenanceActivityListener(
- IMaintenanceActivityListener listener) {
- DeviceIdleController.this.unregisterMaintenanceActivityListener(listener);
- }
-
@Override public int setPreIdleTimeoutMode(int mode) {
getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
null);
@@ -3131,7 +3098,6 @@
void setJobsActive(boolean active) {
synchronized (this) {
mJobsActive = active;
- reportMaintenanceActivityIfNeededLocked();
if (!active) {
exitMaintenanceEarlyIfNeededLocked();
}
@@ -3147,19 +3113,6 @@
}
}
- boolean registerMaintenanceActivityListener(IMaintenanceActivityListener listener) {
- synchronized (this) {
- mMaintenanceActivityListeners.register(listener);
- return mReportedMaintenanceActivity;
- }
- }
-
- void unregisterMaintenanceActivityListener(IMaintenanceActivityListener listener) {
- synchronized (this) {
- mMaintenanceActivityListeners.unregister(listener);
- }
- }
-
@VisibleForTesting
int setPreIdleTimeoutMode(int mode) {
return setPreIdleTimeoutFactor(getPreIdleTimeoutByMode(mode));
@@ -3281,17 +3234,6 @@
}
}
- void reportMaintenanceActivityIfNeededLocked() {
- boolean active = mJobsActive;
- if (active == mReportedMaintenanceActivity) {
- return;
- }
- mReportedMaintenanceActivity = active;
- Message msg = mHandler.obtainMessage(MSG_REPORT_MAINTENANCE_ACTIVITY,
- mReportedMaintenanceActivity ? 1 : 0, 0);
- mHandler.sendMessage(msg);
- }
-
@VisibleForTesting
long getNextAlarmTime() {
return mNextAlarmTime;
diff --git a/apex/statsd/Android.bp b/apex/statsd/Android.bp
new file mode 100644
index 0000000..d76a40e
--- /dev/null
+++ b/apex/statsd/Android.bp
@@ -0,0 +1,46 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+apex {
+ name: "com.android.os.statsd",
+
+ manifest: "apex_manifest.json",
+
+ // optional. if unspecified, a default one is auto-generated
+ //androidManifest: "AndroidManifest.xml",
+
+ // libc.so and libcutils.so are included in the apex
+ // native_shared_libs: ["libc", "libcutils"],
+ // binaries: ["vold"],
+ // java_libs: ["core-all"],
+ // prebuilts: ["my_prebuilt"],
+
+ compile_multilib: "both",
+
+ key: "com.android.os.statsd.key",
+ certificate: ":com.android.os.statsd.certificate",
+}
+
+apex_key {
+ name: "com.android.os.statsd.key",
+ public_key: "com.android.os.statsd.avbpubkey",
+ private_key: "com.android.os.statsd.pem",
+}
+
+android_app_certificate {
+ name: "com.android.os.statsd.certificate",
+ // This will use com.android.os.statsd.x509.pem (the cert) and
+ // com.android.os.statsd.pk8 (the private key)
+ certificate: "com.android.os.statsd",
+}
diff --git a/apex/statsd/apex_manifest.json b/apex/statsd/apex_manifest.json
new file mode 100644
index 0000000..0c0ad86
--- /dev/null
+++ b/apex/statsd/apex_manifest.json
@@ -0,0 +1,5 @@
+{
+ "name": "com.android.os.statsd",
+ "version": 1
+}
+
diff --git a/apex/statsd/com.android.os.statsd.avbpubkey b/apex/statsd/com.android.os.statsd.avbpubkey
new file mode 100644
index 0000000..d78af8b
--- /dev/null
+++ b/apex/statsd/com.android.os.statsd.avbpubkey
Binary files differ
diff --git a/apex/statsd/com.android.os.statsd.pem b/apex/statsd/com.android.os.statsd.pem
new file mode 100644
index 0000000..558e17f
--- /dev/null
+++ b/apex/statsd/com.android.os.statsd.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKgIBAAKCAgEA893bbpkivKEiNgfknYBSlzC0csaKU/ddBm5Pb4ZFuab+LQSR
+9DDc5JrsmxyrsrvuwL/zAtMbkyYWzEiUxJtx/w0bw8rC90GoPRSCmxyI0ZK8FuPy
+IAQ7UeNfTWZ485mAUaTSasGIfQ3DY4F0P+aUSijeG3NUY02nALHDMqJX7lXR+mL1
+DUYDg05KB0jxQwlYqBeujTPPiAzEqm3PlBoHuan8/qgK2wdQMTVg/fieUD3lupmV
+Wj2dRZgqfBPA16ZbV4Uo0j0bZSf+fQLiXlU2VJGb5i/FQfjLqMKGABDI0MgK7Sc2
+m4ySpV4g4XKDv/vw6Dw4kwWC7mATEVAkH+q6V7uiZeN6a7w30UMtPI8fPaUvAP3L
+VBjCBIv/3m+CKkWcNxOZ3sQBQl5bS05dxcfiVsBvBLYbvQgC+Wy0Sc3b+1pXFT/E
+uAsbZ4CyVsi1+PAdx3h5e2QAyNCXgZDOcvTUyxY6JLTE0LOVHmI4fJEujBex//Oz
+PCRHvC8K+KiljyQWf/NYrLSD3QGYAjVMtQh7yu2yhzWzgBUxyhuv3rY4ATXsN3bJ
+wW4w7/L/RSLSW5+lp/NoJOD9utbsKTyGMHOY6K8JLOmhv3ORoAEmLYlFTI+FqBi9
+AH1HQEKCyh8Z/bYHLUzGWl6FqAMtcnuintv40BbKyt0/D1ItdbSNKmOZ5rkCAwEA
+AQKCAgAY7ll8mRNADYkd1Pi+UVwgMM6B3WJO6z8LZUOhtyxxqmzZ1VnGiShMBrqh
+sPCsuSHTeswxQbvT81TpVZI/91RUKtbn0VbVSFUWyX4AtY4XPtUT0gHy2/vkh0Y6
+93ruDIdd0Wfhmh+GCV4sUhO8ZKpMWpk6XTQHYuzr2UCHcKlkqElrO6qpzLqXNe3D
+iOWBYPc7WBB0RxO0aPnCIq/SCEc55/MBZdSWR80e+sILtNsagPl3djQaoanub3wI
+a0yPv2YfMHHX7H9cfBY8WYsi8bs4MhqqEcAs2m6XtitU3mJpVcooLJYcmOZ1GYZr
+BfYKLouWcnGmNi4IiLHqVzMaQDkEhAZsRaAXCkoVVrFBedLlmLPpiUIQlINF4vxe
+3IcekTKWyMzkU6h+K8T15MU5mLSqeL2Gji1JIwKJno51FZ9uc++pUJVtfYQmNny8
+8RKvQ1hv/S5yLQKgN+VkNbaWlUoMP73dtUe3m/At71/2Dj7xB0KtcgT1lEMrM1GR
+oynJAJLz/d0n5RUUREwkZZMcA4fQVC7Db6vpK69jPiQMShpZ3JKCEjfYLUuN0slt
+FPhjiR175E0vTRuLoIj4kXNwLLswH0c9zqrKM2S92SCxAV3E4JJGKhUZalvT9s1g
+LrPhMCl6CsOES98T87d3RyAIK0iVRCnRUG3bc+8rzyRd4fzkAQKCAQEA/UjmCSm3
+H46t/1w7YBZPew7SFQOAJe81iDzbonc3fNPD2R8lxtD3MwdvrQ5f9fhT4+uveWNr
+dyBX7ppnissyM3LZRN+7BdeIVVeIPVen6Ou9W2i7q18ZoQx9IpRcZEw5tGJFZaGx
+EmyPN4i1K0ccUkGbBvbXXQ/tcG3wElRpBAc5/TQ8vrpUgHll2/MbYhowx6P9uHv5
+thoyG98X+7Fbg8ikzw5GtyuedXfyX1CpJ7yUQVS2PEaOMXOkZdx2bbWRAYYCpsqB
+dMmjs2PsFhZHu6CpLhlocHbfUiRztCUCaMZJPQXFSVmy8QDMvZEdVLvad9Poi8ny
+lmHVRgxaNbAtIQKCAQEA9nscqRaaO7hIX9bOUxcDbI0486Ws4H0hAFApIN+6/LP4
+hkxey3xWArTYWrvSG1d5GkJAdn99ayWzo2PevmJlrhIJiO1QqYBAk+87cnhwSCmB
+kb0sGkNWcc/xNRy7eqdhyCmVhaUnIbORee+cD6qiu/l2BAclTf2ZARFOGXjhQkvt
+cDbc/9ZR467ceXbiTIU34Be4xnNAY1mo59jvwl9eqxgpefYTqPhcZ7OmlDli77Hd
+XuRfuxLZCscv7A9M5Enc2zwOEP5VwRNwYzYtMm2Yh9CQZxNWC7JVh1Gw5MPFzsGl
+sgEdb4WGneN6PPLQHK7NF0f7wYSNnF0i3XSME9MumQKCAQEA0qMbWydr+TyJC0LC
+xigHtUkgAQXGPsXuePxTk4sdhBwAVcKHgg4qZi+a+gpoV4BLE9LfPU4nAwzM08to
+rI5Lk2nBsnt1Z2hVItQGoy0QoK3b7fbti5ktETf3oRhMtcSGgLLxD5ImVjId8Isq
+T3F15hpVOLdzZxtl1Qg4jKXSJ91yplYY5mzC9Yz/3qkQbsdlJcIFsLS5eG3UmkUw
+Bsr6VmA4X1F6Eb6eqwYzdHz6D+fOS36NhxcODaYkY+myO46xptixv8/NVTiTgQ5q
+OfwRb8Iur/3FUzIoioFyD7Bvjn7ITY1NArEsFS0bF9Nk1yDakKiUThyGN/Xojbac
+FuYKwQKCAQEAxOWJ+qU8phJLdowBHC0ZJiEWasRhep9auoZOpJ01IWOfV6EwZLs5
+dkYDQ1Agwoi5DDn6hu7HQM3IV/CS4mF2OnzcMw7ozc7PR53nTkVZ5LuLbuHAlmZO
+avKjDDucpJmLqjtV34IT5X8t6kt3zqgQAbuBBCy1Jz07ebfaPMzsnWpMDcU1/AW4
+OvrX0wweMOSGwzQP/i/ZMsRQAo2w0gQfeuv9Thk+kU99ebXwjx3co//hCEnFE4s1
+6L8/0AJU+VTr4hJyZi7WUDt4HzkLF+qm22/Hux+eMA/Q9R1UAxtFLCpTdAQiAJGY
+/Q3X+1I434DgAwYU3f1Gpq9cB65vq/KamQKCAQEAjIub5wde/ttHlLALvnOXrbqe
+nUIfWHExMzhul/rkr8fFEJwij2nZUuN2EWUGzBWQQoNXw5QKHLZyPsyFUOa/P2BS
+osnffAa+sumL4k36E71xFdTVV5ExyTXZVB49sPmUpivP9gEucFFqDHKjGsF45dBF
++DZdykLUIv+/jQUzXGkZ5Wv/r52YUNho4EZdwnlJ2so7cxnsYnjW+c1nlp17tkq5
+DfwktkeD9iFzlaZ66vLoO44luaBm+lC3xM2sHinOTwbk0gvhJAIoLfkOYhpmGc8A
+4W/E1OHfVz6xqVDsMBFhRbQpHNkf8XZNqkIoqHVMTaMOJJlM+lb0+A9B8Bm/XA==
+-----END RSA PRIVATE KEY-----
diff --git a/apex/statsd/com.android.os.statsd.pk8 b/apex/statsd/com.android.os.statsd.pk8
new file mode 100644
index 0000000..49910f8
--- /dev/null
+++ b/apex/statsd/com.android.os.statsd.pk8
Binary files differ
diff --git a/apex/statsd/com.android.os.statsd.x509.pem b/apex/statsd/com.android.os.statsd.x509.pem
new file mode 100644
index 0000000..e7b16b2
--- /dev/null
+++ b/apex/statsd/com.android.os.statsd.x509.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFDTCCAvWgAwIBAgIUCnta1LAl5fMMLLQx//4zWz9A2A8wDQYJKoZIhvcNAQEL
+BQAwFTETMBEGA1UECgwKR29vZ2xlIExMQzAgFw0xOTA4MTIyMjM5MzBaGA80NzU3
+MDcwODIyMzkzMFowFTETMBEGA1UECgwKR29vZ2xlIExMQzCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAOranWZ19jkXCF9WIlXv01tUUvLKMHWKV7X9Earw
+cL7/aax0pFbNJutgyBUiOszbR+0T7quZxz6jACu+6y7iaMJnvMluZsfTi+p2UvQt
+y6Ql7ZUOQ7bVluCFIW5hZ+8d9RrLmZdvX1r4YfF6HufDBkAbj+os+y6407OezJAV
+8EATpemc9gsCC4RJZpwzTs1RUXMD4UoNrLZAE8+7iaJZeBxmz0MAPj92pYc9M7/d
+xInzYvOR08/uEpHt8jlMdVgSQS/FaRlIOIqcGBk3cjkjDlpVATQ4Hyjy+IPQPjTD
+bJUmDJiYeBCyY/pYZQvTQjl8s+fvykTsF9Lfb+E+PhZ0+N8pRi7sUSpisZHSiqaN
+W3oxYWc0YQSuzygHHog8HH/azHX5L805g/+Rwfb/cUF9eJgjq0vrkFnsz4UKgKNV
+hHL90mfqpbc2UvJ8VY8BvIjbsHQ77LrBKlqI9VMPorttpTOuwHHJPKsyN972F0Ul
+lRB6CwFE8csVGWXoNaDZWBv7xTDdbdirmlKDNueg9pw6ksYV2Is9Dv8PxmsZvb+4
+oftC/hb4X1Pudn01PPs9Tx44CwHuVLENUwlDEVzG5zNetsv9kAuCYt3VRVF+NYqj
+NAfLbxCKLe25wGzJrZUEJ1YrYIjpUbfwnttEad/9Pu13DAS7HZwn5vwqEKB/1LlT
+NSUXAgMBAAGjUzBRMB0GA1UdDgQWBBSKElkhJSbzgh8+iysye8SrkmJ62DAfBgNV
+HSMEGDAWgBSKElkhJSbzgh8+iysye8SrkmJ62DAPBgNVHRMBAf8EBTADAQH/MA0G
+CSqGSIb3DQEBCwUAA4ICAQANFGnc2wJBrFbh2nzhl06g4TjPKGRCw365vZ1A3T9O
+jXP0lToHDxB33TpKk6d7zszR1uPphQQxgzhSVZB/jx8q4kWSSoKoF9Dlx7h8rAt+
+2TM5DaBvxrwu5mqOALwQuF81wap1Pl2L2fFHvygCm8b+Ci4iS5vcr0axNnp1rK1b
+vUtRWY4mfxTjJYcgeCVUGskqTb+cCxQZ6Icno6VTKajT1FybRmD3KZJaUuLbNEN+
+IE4nGTMG2WZ5Hl2vR8JJp1sYYn8T3ElMAb0MSNFkqsfI+tToEwGsuJDgYEdtEnzf
+lTycQvn5NhrIZRRN3pqSyWpAU7p9mmyTK0PHMz2D/Rtfb7lE692vXzxCmZND51mc
+YXCCoanV6eZZ7Sbqzh60+5QV38hgFBst5l8CcFaWWSFK9nBWdzS5lhs9lmQ4aiYd
+IE0qsNZgMob+TTP1VW39hu4EDjNmOrKfimM9J2tcPZ5QP01DgETPvAsB7vn2Xz9J
+HGt5ntiSV4W2izDP8viQ1M5NvfdBaUhcnNsE6/sxfU0USRs2hrEp1oiqrv4p6V0P
+qOt7C2/YtJzkrxfsHZAxBUSRHa7LwtzgeiJDUivHn94VnAzSAH8MLx6CzDPQ8HWN
+NiZFxTKfMVyjEmbQ2PalHWB8pWtpdEh7X4rzaqhnLBTis3pGssASgo3ArLIYleAU
++g==
+-----END CERTIFICATE-----
diff --git a/api/current.txt b/api/current.txt
index 81ecceb..99ae1c8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2816,7 +2816,7 @@
method public int describeContents();
method public int getDisplayId();
method public int getGestureId();
- method public void writeToParcel(android.os.Parcel, int);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.accessibilityservice.AccessibilityGestureInfo> CREATOR;
}
@@ -10875,9 +10875,7 @@
method @Nullable public String getString(String, @Nullable String);
method @Nullable public java.util.Set<java.lang.String> getStringSet(String, @Nullable java.util.Set<java.lang.String>);
method public void registerOnSharedPreferenceChangeListener(android.content.SharedPreferences.OnSharedPreferenceChangeListener);
- method public default void registerOnSharedPreferencesClearListener(@NonNull android.content.SharedPreferences.OnSharedPreferencesClearListener);
method public void unregisterOnSharedPreferenceChangeListener(android.content.SharedPreferences.OnSharedPreferenceChangeListener);
- method public default void unregisterOnSharedPreferencesClearListener(@NonNull android.content.SharedPreferences.OnSharedPreferencesClearListener);
}
public static interface SharedPreferences.Editor {
@@ -10897,10 +10895,6 @@
method public void onSharedPreferenceChanged(android.content.SharedPreferences, String);
}
- public static interface SharedPreferences.OnSharedPreferencesClearListener {
- method public void onSharedPreferencesClear(@NonNull android.content.SharedPreferences, @NonNull java.util.Set<java.lang.String>);
- }
-
public class SyncAdapterType implements android.os.Parcelable {
ctor public SyncAdapterType(String, String, boolean, boolean);
ctor public SyncAdapterType(android.os.Parcel);
@@ -28204,7 +28198,7 @@
method public android.media.tv.TvTrackInfo.Builder setAudioChannelCount(int);
method public android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
method public android.media.tv.TvTrackInfo.Builder setDescription(CharSequence);
- method public android.media.tv.TvTrackInfo.Builder setEncrypted(boolean);
+ method @NonNull public android.media.tv.TvTrackInfo.Builder setEncrypted(boolean);
method public android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
method public android.media.tv.TvTrackInfo.Builder setLanguage(String);
method public android.media.tv.TvTrackInfo.Builder setVideoActiveFormatDescription(byte);
@@ -44082,7 +44076,7 @@
public class CarrierConfigManager {
method @Nullable public android.os.PersistableBundle getConfig();
- method @Nullable public android.os.PersistableBundle getConfigByComponentForSubId(String, int);
+ method @Nullable public android.os.PersistableBundle getConfigByComponentForSubId(@NonNull String, int);
method @Nullable public android.os.PersistableBundle getConfigForSubId(int);
method public static boolean isConfigForIdentifiedCarrier(android.os.PersistableBundle);
method public void notifyConfigChangedForSubId(int);
@@ -53727,6 +53721,7 @@
public final class TextClassificationSessionId implements android.os.Parcelable {
method public int describeContents();
+ method @NonNull public String flattenToString();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.view.textclassifier.TextClassificationSessionId> CREATOR;
}
@@ -53814,6 +53809,7 @@
field public static final int TYPE_AUTO_SELECTION = 5; // 0x5
field public static final int TYPE_COPY_ACTION = 9; // 0x9
field public static final int TYPE_CUT_ACTION = 11; // 0xb
+ field public static final int TYPE_LINKS_GENERATED = 21; // 0x15
field public static final int TYPE_LINK_CLICKED = 7; // 0x7
field public static final int TYPE_MANUAL_REPLY = 19; // 0x13
field public static final int TYPE_OTHER_ACTION = 16; // 0x10
diff --git a/api/removed.txt b/api/removed.txt
index db784a8..74a9346 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -5,10 +5,6 @@
method @Deprecated public static int getMaxNumPictureInPictureActions();
}
- public class KeyguardManager {
- method @Deprecated public void dismissKeyguard(@NonNull android.app.Activity, @Nullable android.app.KeyguardManager.KeyguardDismissCallback, @Nullable android.os.Handler);
- }
-
public class Notification implements android.os.Parcelable {
method @Deprecated public String getChannel();
method public static Class<? extends android.app.Notification.Style> getNotificationStyleClass(String);
diff --git a/api/system-current.txt b/api/system-current.txt
index 61ca84a..e87007f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1150,7 +1150,8 @@
method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent);
method @WorkerThread public abstract boolean onClearRoleHolders(@NonNull String, int);
method @WorkerThread public abstract boolean onGrantDefaultRoles();
- method public abstract boolean onIsApplicationQualifiedForRole(@NonNull String, @NonNull String);
+ method @Deprecated public abstract boolean onIsApplicationQualifiedForRole(@NonNull String, @NonNull String);
+ method public boolean onIsApplicationVisibleForRole(@NonNull String, @NonNull String);
method public abstract boolean onIsRoleVisible(@NonNull String);
method @WorkerThread public abstract boolean onRemoveRoleHolder(@NonNull String, @NonNull String, int);
field public static final String SERVICE_INTERFACE = "android.app.role.RoleControllerService";
@@ -1206,7 +1207,7 @@
public static final class UsageEvents.Event {
method public int getInstanceId();
- method public String getNotificationChannelId();
+ method @Nullable public String getNotificationChannelId();
method @Nullable public String getTaskRootClassName();
method @Nullable public String getTaskRootPackageName();
method public boolean isInstantApp();
diff --git a/api/test-current.txt b/api/test-current.txt
index 7e1c67d..b2ed91b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -82,6 +82,7 @@
}
public class ActivityOptions {
+ method public static void setExitTransitionTimeout(long);
method public void setLaunchActivityType(int);
method public void setLaunchTaskId(int);
method public void setLaunchWindowingMode(int);
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 76b905d..ed717c4 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -125,6 +125,11 @@
return;
}
+ if ("autorestore".equals(op)) {
+ doAutoRestore(userId);
+ return;
+ }
+
if ("enabled".equals(op)) {
doEnabled(userId);
return;
@@ -213,6 +218,26 @@
return true;
}
+ private void doAutoRestore(int userId) {
+ String arg = nextArg();
+ if (arg == null) {
+ showUsage();
+ return;
+ }
+
+ try {
+ boolean enable = Boolean.parseBoolean(arg);
+ mBmgr.setAutoRestore(enable);
+ System.out.println(
+ "Auto restore is now "
+ + (enable ? "enabled" : "disabled")
+ + " for user "
+ + userId);
+ } catch (RemoteException e) {
+ handleRemoteException(e);
+ }
+ }
+
private String activatedToString(boolean activated) {
return activated ? "activated" : "deactivated";
}
@@ -918,6 +943,7 @@
System.err.println(" bmgr init TRANSPORT...");
System.err.println(" bmgr activate BOOL");
System.err.println(" bmgr activated");
+ System.err.println(" bmgr autorestore BOOL");
System.err.println("");
System.err.println("The '--user' option specifies the user on which the operation is run.");
System.err.println("It must be the first argument before the operation.");
@@ -992,6 +1018,9 @@
System.err.println("");
System.err.println("The 'activated' command reports the current activated/deactivated");
System.err.println("state of the backup mechanism.");
+ System.err.println("");
+ System.err.println("The 'autorestore' command enables or disables automatic restore when");
+ System.err.println("a new package is installed.");
}
private static class BackupMonitor extends IBackupManagerMonitor.Stub {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index b01b0a8..2732779 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -337,7 +337,7 @@
}
// Pulled events will start at field 10000.
- // Next: 10062
+ // Next: 10064
oneof pulled {
WifiBytesTransfer wifi_bytes_transfer = 10000;
WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -401,6 +401,8 @@
CoolingDevice cooling_device = 10059;
AppOps app_ops = 10060;
ProcessSystemIonHeapSize process_system_ion_heap_size = 10061;
+ SurfaceflingerStatsGlobalInfo surfaceflinger_stats_global_info = 10062;
+ SurfaceflingerStatsLayerInfo surfaceflinger_stats_layer_info = 10063;
}
// DO NOT USE field numbers above 100,000 in AOSP.
@@ -7087,3 +7089,77 @@
// The number of reboot of the device during a successful update.
optional int32 reboot_count = 7;
}
+
+/**
+ * Global display pipeline metrics reported by SurfaceFlinger.
+ * Pulled from:
+ * frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp
+ */
+message SurfaceflingerStatsGlobalInfo {
+ // Total number of frames presented during the tracing period
+ optional int64 total_frames = 1;
+ // Total number of frames missed
+ optional int64 missed_frames = 2;
+ // Total number of frames that fell back to client composition
+ optional int64 client_composition_frames = 3;
+ // Total time the display was turned on
+ optional int64 display_on_millis = 4;
+ // Total time that was spent performing animations.
+ // This is derived from the present-to-present layer histogram
+ optional int64 animation_millis = 5;
+}
+
+/**
+ * Per-layer display pipeline metrics reported by SurfaceFlinger.
+ * The number of layers uploaded will be restricted due to size limitations.
+ * Pulled from:
+ * frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp
+ */
+message SurfaceflingerStatsLayerInfo {
+ // The layer for this set of metrics
+ // For now we can infer that the package name is included in the layer
+ // name.
+ optional string layer_name = 1;
+ // Total number of frames presented
+ optional int64 total_frames = 2;
+ // Total number of dropped frames while latching a buffer for this layer.
+ optional int64 dropped_frames = 3;
+ // Set of timings measured between successive presentation timestamps.
+ optional FrameTimingHistogram present_to_present = 4
+ [(android.os.statsd.log_mode) = MODE_BYTES];
+ // Set of timings measured from when an app queued a buffer for
+ // presentation, until the buffer was actually presented to the
+ // display.
+ optional FrameTimingHistogram post_to_present = 5
+ [(android.os.statsd.log_mode) = MODE_BYTES];
+ // Set of timings measured from when a buffer is ready to be presented,
+ // until the buffer was actually presented to the display.
+ optional FrameTimingHistogram acquire_to_present = 6
+ [(android.os.statsd.log_mode) = MODE_BYTES];
+ // Set of timings measured from when a buffer was latched by
+ // SurfaceFlinger, until the buffer was presented to the display
+ optional FrameTimingHistogram latch_to_present = 7
+ [(android.os.statsd.log_mode) = MODE_BYTES];
+ // Set of timings measured from the desired presentation to the actual
+ // presentation time
+ optional FrameTimingHistogram desired_to_present = 8
+ [(android.os.statsd.log_mode) = MODE_BYTES];
+ // Set of timings measured from when an app queued a buffer for
+ // presentation, until the buffer was ready to be presented.
+ optional FrameTimingHistogram post_to_acquire = 9
+ [(android.os.statsd.log_mode) = MODE_BYTES];
+}
+
+/**
+ * Histogram of frame counts bucketed by time in milliseconds.
+ * Because of size limitations, we hard-cap the number of buckets, with
+ * buckets for corresponding to larger milliseconds being less precise.
+ */
+message FrameTimingHistogram {
+ // Timings in milliseconds that describes a set of histogram buckets
+ repeated int32 time_millis_buckets = 1;
+ // Number of frames that match to each time_millis, i.e. the bucket
+ // contents
+ // It's required that len(time_millis) == len(frame_count)
+ repeated int64 frame_counts = 2;
+}
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 68082c2..42132ee 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -78,7 +78,7 @@
ps->giveThreadPoolName();
IPCThreadState::self()->disableBackgroundScheduling(true);
- ::android::hardware::configureRpcThreadpool(1 /*threads*/, false /*willJoin*/);
+ ::android::hardware::configureRpcThreadpool(4 /*threads*/, false /*willJoin*/);
std::shared_ptr<LogEventQueue> eventQueue =
std::make_shared<LogEventQueue>(2000 /*buffer limit. Buffer is NOT pre-allocated*/);
diff --git a/config/hiddenapi-greylist-max-o.txt b/config/hiddenapi-greylist-max-o.txt
index d9c1cd0..15026b0 100644
--- a/config/hiddenapi-greylist-max-o.txt
+++ b/config/hiddenapi-greylist-max-o.txt
@@ -3040,7 +3040,6 @@
Landroid/app/admin/IDevicePolicyManager$Stub$Proxy;->retrieveSecurityLogs(Landroid/content/ComponentName;)Landroid/content/pm/ParceledListSlice;
Landroid/app/admin/IDevicePolicyManager$Stub$Proxy;->setAccountManagementDisabled(Landroid/content/ComponentName;Ljava/lang/String;Z)V
Landroid/app/admin/IDevicePolicyManager$Stub$Proxy;->setActiveAdmin(Landroid/content/ComponentName;ZI)V
-Landroid/app/admin/IDevicePolicyManager$Stub$Proxy;->setActivePasswordState(Landroid/app/admin/PasswordMetrics;I)V
Landroid/app/admin/IDevicePolicyManager$Stub$Proxy;->setAffiliationIds(Landroid/content/ComponentName;Ljava/util/List;)V
Landroid/app/admin/IDevicePolicyManager$Stub$Proxy;->setAlwaysOnVpnPackage(Landroid/content/ComponentName;Ljava/lang/String;Z)Z
Landroid/app/admin/IDevicePolicyManager$Stub$Proxy;->setApplicationHidden(Landroid/content/ComponentName;Ljava/lang/String;Ljava/lang/String;Z)Z
@@ -3305,7 +3304,6 @@
Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_retrieveSecurityLogs:I
Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_setAccountManagementDisabled:I
Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_setActiveAdmin:I
-Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_setActivePasswordState:I
Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_setAffiliationIds:I
Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_setAlwaysOnVpnPackage:I
Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_setApplicationHidden:I
@@ -3569,7 +3567,6 @@
Landroid/app/admin/IDevicePolicyManager;->retrieveSecurityLogs(Landroid/content/ComponentName;)Landroid/content/pm/ParceledListSlice;
Landroid/app/admin/IDevicePolicyManager;->setAccountManagementDisabled(Landroid/content/ComponentName;Ljava/lang/String;Z)V
Landroid/app/admin/IDevicePolicyManager;->setActiveAdmin(Landroid/content/ComponentName;ZI)V
-Landroid/app/admin/IDevicePolicyManager;->setActivePasswordState(Landroid/app/admin/PasswordMetrics;I)V
Landroid/app/admin/IDevicePolicyManager;->setAffiliationIds(Landroid/content/ComponentName;Ljava/util/List;)V
Landroid/app/admin/IDevicePolicyManager;->setAlwaysOnVpnPackage(Landroid/content/ComponentName;Ljava/lang/String;Z)Z
Landroid/app/admin/IDevicePolicyManager;->setApplicationHidden(Landroid/content/ComponentName;Ljava/lang/String;Ljava/lang/String;Z)Z
diff --git a/core/java/android/accessibilityservice/AccessibilityGestureInfo.java b/core/java/android/accessibilityservice/AccessibilityGestureInfo.java
index dc50a4c..28c1dea 100644
--- a/core/java/android/accessibilityservice/AccessibilityGestureInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityGestureInfo.java
@@ -114,6 +114,7 @@
return mGestureId;
}
+ @NonNull
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder("AccessibilityGestureInfo[");
@@ -133,7 +134,7 @@
}
@Override
- public void writeToParcel(Parcel parcel, int flags) {
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
parcel.writeInt(mGestureId);
parcel.writeInt(mDisplayId);
}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 4730bd0..a8daf91 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -635,7 +635,7 @@
* Gets the root node in the currently active window if this service
* can retrieve window content. The active window is the one that the user
* is currently touching or the window with input focus, if the user is not
- * touching any window.
+ * touching any window. It could be from any logical display.
* <p>
* The currently active window is defined as the window that most recently fired one
* of the following events:
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index b8d9575..6772884 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -829,6 +829,17 @@
return exit;
}
+ /**
+ * Needed for virtual devices because they can be slow enough that the 1 second timeout
+ * triggers when it doesn't on normal devices.
+ *
+ * @hide
+ */
+ @TestApi
+ public static void setExitTransitionTimeout(long timeoutMillis) {
+ ExitTransitionCoordinator.sMaxWaitMillis = timeoutMillis;
+ }
+
/** @hide */
static ActivityOptions makeSceneTransitionAnimation(Activity activity,
ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 34045c9..9353e0b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -30,7 +30,6 @@
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes.AttributeUsage;
import android.os.Binder;
@@ -3220,7 +3219,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -3251,6 +3250,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
return getClass().getSimpleName() + "[from:"
@@ -3486,7 +3486,7 @@
};
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -3718,7 +3718,7 @@
};
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -4072,7 +4072,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0478ac8..d74399c 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -127,6 +127,7 @@
* @hide
*/
public static final boolean DEBUG_TRACE_GRANTS = false;
+ public static final boolean DEBUG_TRACE_PERMISSION_UPDATES = false;
private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB
@@ -690,7 +691,7 @@
UserHandle user) {
if (DEBUG_TRACE_GRANTS
&& shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
- Log.i(TAG, "App " + mContext.getPackageName() + " is granting "
+ Log.i(TAG, "App " + mContext.getPackageName() + " is granting " + packageName + " "
+ permissionName + " for user " + user.getIdentifier(), new RuntimeException());
}
try {
@@ -708,9 +709,9 @@
@Override
public void revokeRuntimePermission(String packageName, String permName, UserHandle user) {
- if (DEBUG_TRACE_GRANTS
+ if (DEBUG_TRACE_PERMISSION_UPDATES
&& shouldTraceGrant(packageName, permName, user.getIdentifier())) {
- Log.i(TAG, "App " + mContext.getPackageName() + " is revoking "
+ Log.i(TAG, "App " + mContext.getPackageName() + " is revoking " + packageName + " "
+ permName + " for user " + user.getIdentifier(), new RuntimeException());
}
try {
@@ -734,9 +735,10 @@
@Override
public void updatePermissionFlags(String permName, String packageName,
int flagMask, int flagValues, UserHandle user) {
- if (DEBUG_TRACE_GRANTS
+ if (DEBUG_TRACE_PERMISSION_UPDATES
&& shouldTraceGrant(packageName, permName, user.getIdentifier())) {
Log.i(TAG, "App " + mContext.getPackageName() + " is updating flags for "
+ + packageName + " "
+ permName + " for user " + user.getIdentifier() + ": "
+ DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", flagMask)
+ " := " + DebugUtils.flagsToString(
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 48a711e..68824cd 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -48,7 +48,7 @@
*/
class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
private static final String TAG = "ExitTransitionCoordinator";
- private static final long MAX_WAIT_MS = 1000;
+ static long sMaxWaitMillis = 1000;
private Bundle mSharedElementBundle;
private boolean mExitNotified;
@@ -120,7 +120,7 @@
private void delayCancel() {
if (mHandler != null) {
- mHandler.sendEmptyMessageDelayed(MSG_CANCEL, MAX_WAIT_MS);
+ mHandler.sendEmptyMessageDelayed(MSG_CANCEL, sMaxWaitMillis);
}
}
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 6677587..9b667a11 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -32,7 +32,6 @@
import android.hardware.biometrics.BiometricPrompt;
import android.os.Binder;
import android.os.Build;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -508,13 +507,6 @@
}
}
- /** @removed */
- @Deprecated
- public void dismissKeyguard(@NonNull Activity activity,
- @Nullable KeyguardDismissCallback callback, @Nullable Handler handler) {
- requestDismissKeyguard(activity, callback);
- }
-
/**
* If the device is currently locked (see {@link #isKeyguardLocked()}, requests the Keyguard to
* be dismissed.
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 9162626..9f865b4 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -16,17 +16,19 @@
package android.app;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
+import android.compat.Compatibility;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.content.SharedPreferences;
+import android.os.Build;
import android.os.FileUtils;
import android.os.Looper;
import android.system.ErrnoException;
import android.system.Os;
import android.system.StructStat;
import android.system.StructTimespec;
-import android.util.ArraySet;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -62,6 +64,15 @@
/** If a fsync takes more than {@value #MAX_FSYNC_DURATION_MILLIS} ms, warn */
private static final long MAX_FSYNC_DURATION_MILLIS = 256;
+ /**
+ * There will now be a callback to {@link
+ * OnSharedPreferenceChangeListener#onSharedPreferenceChanged(SharedPreferences, String)} with
+ * a {@code null} key on {@link Editor#clear()}.
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
+ private static final long CALLBACK_ON_CLEAR_CHANGE = 119147584L;
+
// Lock ordering rules:
// - acquire SharedPreferencesImpl.mLock before EditorImpl.mLock
// - acquire mWritingToDiskLock before EditorImpl.mLock
@@ -94,10 +105,6 @@
private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =
new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
- @GuardedBy("mLock")
- private final WeakHashMap<OnSharedPreferencesClearListener, Object> mClearListeners =
- new WeakHashMap<>();
-
/** Current memory state (always increasing) */
@GuardedBy("this")
private long mCurrentMemoryStateGeneration;
@@ -258,28 +265,6 @@
}
}
- @Override
- public void registerOnSharedPreferencesClearListener(
- @NonNull OnSharedPreferencesClearListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null.");
- }
- synchronized (mLock) {
- mClearListeners.put(listener, CONTENT);
- }
- }
-
- @Override
- public void unregisterOnSharedPreferencesClearListener(
- @NonNull OnSharedPreferencesClearListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null.");
- }
- synchronized (mLock) {
- mClearListeners.remove(listener);
- }
- }
-
@GuardedBy("mLock")
private void awaitLoadedLocked() {
if (!mLoaded) {
@@ -388,10 +373,9 @@
// Return value from EditorImpl#commitToMemory()
private static class MemoryCommitResult {
final long memoryStateGeneration;
+ final boolean keysCleared;
@Nullable final List<String> keysModified;
- @Nullable final Set<String> keysCleared;
@Nullable final Set<OnSharedPreferenceChangeListener> listeners;
- @Nullable final Set<OnSharedPreferencesClearListener> clearListeners;
final Map<String, Object> mapToWriteToDisk;
final CountDownLatch writtenToDiskLatch = new CountDownLatch(1);
@@ -399,16 +383,14 @@
volatile boolean writeToDiskResult = false;
boolean wasWritten = false;
- private MemoryCommitResult(long memoryStateGeneration, @Nullable List<String> keysModified,
+ private MemoryCommitResult(long memoryStateGeneration, boolean keysCleared,
+ @Nullable List<String> keysModified,
@Nullable Set<OnSharedPreferenceChangeListener> listeners,
- @Nullable Set<String> keysCleared,
- @Nullable Set<OnSharedPreferencesClearListener> clearListeners,
Map<String, Object> mapToWriteToDisk) {
this.memoryStateGeneration = memoryStateGeneration;
+ this.keysCleared = keysCleared;
this.keysModified = keysModified;
this.listeners = listeners;
- this.keysCleared = keysCleared;
- this.clearListeners = clearListeners;
this.mapToWriteToDisk = mapToWriteToDisk;
}
@@ -526,16 +508,14 @@
// SharedPreferences instance back, which has the
// changes reflected in memory.
notifyListeners(mcr);
- notifyClearListeners(mcr);
}
// Returns true if any changes were made
private MemoryCommitResult commitToMemory() {
long memoryStateGeneration;
+ boolean keysCleared = false;
List<String> keysModified = null;
- Set<String> keysCleared = null;
Set<OnSharedPreferenceChangeListener> listeners = null;
- Set<OnSharedPreferencesClearListener> clearListeners = null;
Map<String, Object> mapToWriteToDisk;
synchronized (SharedPreferencesImpl.this.mLock) {
@@ -557,23 +537,16 @@
keysModified = new ArrayList<String>();
listeners = new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
}
- boolean hasClearListeners = !mClearListeners.isEmpty();
- if (hasClearListeners) {
- keysCleared = new ArraySet<>();
- clearListeners = new HashSet<>(mClearListeners.keySet());
- }
synchronized (mEditorLock) {
boolean changesMade = false;
if (mClear) {
if (!mapToWriteToDisk.isEmpty()) {
- if (hasClearListeners) {
- keysCleared.addAll(mapToWriteToDisk.keySet());
- }
changesMade = true;
mapToWriteToDisk.clear();
}
+ keysCleared = true;
mClear = false;
}
@@ -613,8 +586,8 @@
memoryStateGeneration = mCurrentMemoryStateGeneration;
}
}
- return new MemoryCommitResult(memoryStateGeneration, keysModified, listeners,
- keysCleared, clearListeners, mapToWriteToDisk);
+ return new MemoryCommitResult(memoryStateGeneration, keysCleared, keysModified,
+ listeners, mapToWriteToDisk);
}
@Override
@@ -641,16 +614,21 @@
}
}
notifyListeners(mcr);
- notifyClearListeners(mcr);
return mcr.writeToDiskResult;
}
private void notifyListeners(final MemoryCommitResult mcr) {
- if (mcr.listeners == null || mcr.keysModified == null ||
- mcr.keysModified.size() == 0) {
+ if (mcr.listeners == null || (mcr.keysModified == null && !mcr.keysCleared)) {
return;
}
if (Looper.myLooper() == Looper.getMainLooper()) {
+ if (mcr.keysCleared && Compatibility.isChangeEnabled(CALLBACK_ON_CLEAR_CHANGE)) {
+ for (OnSharedPreferenceChangeListener listener : mcr.listeners) {
+ if (listener != null) {
+ listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, null);
+ }
+ }
+ }
for (int i = mcr.keysModified.size() - 1; i >= 0; i--) {
final String key = mcr.keysModified.get(i);
for (OnSharedPreferenceChangeListener listener : mcr.listeners) {
@@ -664,24 +642,6 @@
ActivityThread.sMainThreadHandler.post(() -> notifyListeners(mcr));
}
}
-
- private void notifyClearListeners(final MemoryCommitResult mcr) {
- if (mcr.clearListeners == null || mcr.keysCleared == null
- || mcr.keysCleared.isEmpty()) {
- return;
- }
- if (Looper.myLooper() == Looper.getMainLooper()) {
- for (OnSharedPreferencesClearListener listener : mcr.clearListeners) {
- if (listener != null) {
- listener.onSharedPreferencesClear(SharedPreferencesImpl.this,
- mcr.keysCleared);
- }
- }
- } else {
- // Run this function on the main thread.
- ActivityThread.sMainThreadHandler.post(() -> notifyClearListeners(mcr));
- }
- }
}
/**
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 205e7a1..28413be 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -620,6 +620,7 @@
mNotificationIcons = true;
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/app/Vr2dDisplayProperties.java b/core/java/android/app/Vr2dDisplayProperties.java
index fc200bf..d2a49fb 100644
--- a/core/java/android/app/Vr2dDisplayProperties.java
+++ b/core/java/android/app/Vr2dDisplayProperties.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -74,6 +75,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
return "Vr2dDisplayProperties{"
@@ -86,7 +88,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ff5a043..a136bbd 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5764,21 +5764,6 @@
/**
* @hide
*/
- @UnsupportedAppUsage
- @RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
- public void setActivePasswordState(PasswordMetrics metrics, int userHandle) {
- if (mService != null) {
- try {
- mService.setActivePasswordState(metrics, userHandle);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
- /**
- * @hide
- */
@RequiresFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN)
public void reportPasswordChanged(@UserIdInt int userId) {
if (mService != null) {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 5cdef6d..0da5b7a 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -131,7 +131,6 @@
void forceRemoveActiveAdmin(in ComponentName policyReceiver, int userHandle);
boolean hasGrantedPolicy(in ComponentName policyReceiver, int usesPolicy, int userHandle);
- void setActivePasswordState(in PasswordMetrics metrics, int userHandle);
void reportPasswordChanged(int userId);
void reportFailedPasswordAttempt(int userHandle);
void reportSuccessfulPasswordAttempt(int userHandle);
diff --git a/core/java/android/app/backup/RestoreDescription.java b/core/java/android/app/backup/RestoreDescription.java
index 7854394..498b686 100644
--- a/core/java/android/app/backup/RestoreDescription.java
+++ b/core/java/android/app/backup/RestoreDescription.java
@@ -16,6 +16,7 @@
package android.app.backup;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -52,6 +53,7 @@
/** This package's restore data is a tarball-type full data stream */
public static final int TYPE_FULL_STREAM = 2;
+ @NonNull
@Override
public String toString() {
return "RestoreDescription{" + mPackageName + " : "
diff --git a/core/java/android/app/prediction/AppPredictionContext.java b/core/java/android/app/prediction/AppPredictionContext.java
index 298b003..d14238b 100644
--- a/core/java/android/app/prediction/AppPredictionContext.java
+++ b/core/java/android/app/prediction/AppPredictionContext.java
@@ -90,7 +90,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o == this) return true;
if (!getClass().equals(o != null ? o.getClass() : null)) return false;
diff --git a/core/java/android/app/prediction/AppPredictionSessionId.java b/core/java/android/app/prediction/AppPredictionSessionId.java
index 281a16f..e5e06f8 100644
--- a/core/java/android/app/prediction/AppPredictionSessionId.java
+++ b/core/java/android/app/prediction/AppPredictionSessionId.java
@@ -16,6 +16,7 @@
package android.app.prediction;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -46,7 +47,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (!getClass().equals(o != null ? o.getClass() : null)) return false;
AppPredictionSessionId other = (AppPredictionSessionId) o;
diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java
index 147c500..6f21490 100644
--- a/core/java/android/app/prediction/AppTarget.java
+++ b/core/java/android/app/prediction/AppTarget.java
@@ -151,7 +151,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (!getClass().equals(o != null ? o.getClass() : null)) return false;
AppTarget other = (AppTarget) o;
diff --git a/core/java/android/app/prediction/AppTargetEvent.java b/core/java/android/app/prediction/AppTargetEvent.java
index 54b9563..26ff0c1 100644
--- a/core/java/android/app/prediction/AppTargetEvent.java
+++ b/core/java/android/app/prediction/AppTargetEvent.java
@@ -98,7 +98,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (!getClass().equals(o != null ? o.getClass() : null)) return false;
AppTargetEvent other = (AppTargetEvent) o;
diff --git a/core/java/android/app/prediction/AppTargetId.java b/core/java/android/app/prediction/AppTargetId.java
index 3603f5f..052fdc1 100644
--- a/core/java/android/app/prediction/AppTargetId.java
+++ b/core/java/android/app/prediction/AppTargetId.java
@@ -16,6 +16,7 @@
package android.app.prediction;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -59,7 +60,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (!getClass().equals(o != null ? o.getClass() : null)) return false;
AppTargetId other = (AppTargetId) o;
diff --git a/core/java/android/app/role/IRoleController.aidl b/core/java/android/app/role/IRoleController.aidl
index 19762e0..8a43d7f 100644
--- a/core/java/android/app/role/IRoleController.aidl
+++ b/core/java/android/app/role/IRoleController.aidl
@@ -36,5 +36,8 @@
void isApplicationQualifiedForRole(in String roleName, in String packageName,
in RemoteCallback callback);
+ void isApplicationVisibleForRole(in String roleName, in String packageName,
+ in RemoteCallback callback);
+
void isRoleVisible(in String roleName, in RemoteCallback callback);
}
diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java
index 98b11a7..16ddbc1 100644
--- a/core/java/android/app/role/RoleControllerManager.java
+++ b/core/java/android/app/role/RoleControllerManager.java
@@ -183,6 +183,9 @@
/**
* @see RoleControllerService#onIsApplicationQualifiedForRole(String, String)
+ *
+ * @deprecated Use {@link #isApplicationVisibleForRole(String, String, Executor, Consumer)}
+ * instead.
*/
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
public void isApplicationQualifiedForRole(@NonNull String roleName, @NonNull String packageName,
@@ -197,6 +200,21 @@
}
/**
+ * @see RoleControllerService#onIsApplicationVisibleForRole(String, String)
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
+ public void isApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName,
+ @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) {
+ AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> {
+ AndroidFuture<Bundle> future = new AndroidFuture<>();
+ service.isApplicationVisibleForRole(roleName, packageName,
+ new RemoteCallback(future::complete));
+ return future;
+ });
+ propagateCallback(operation, "isApplicationVisibleForRole", executor, callback);
+ }
+
+ /**
* @see RoleControllerService#onIsRoleVisible(String)
*/
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
diff --git a/core/java/android/app/role/RoleControllerService.java b/core/java/android/app/role/RoleControllerService.java
index 2bc9456..85db6a4 100644
--- a/core/java/android/app/role/RoleControllerService.java
+++ b/core/java/android/app/role/RoleControllerService.java
@@ -153,6 +153,20 @@
}
@Override
+ public void isApplicationVisibleForRole(String roleName, String packageName,
+ RemoteCallback callback) {
+ enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null);
+
+ Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
+ Preconditions.checkStringNotEmpty(packageName,
+ "packageName cannot be null or empty");
+ Preconditions.checkNotNull(callback, "callback cannot be null");
+
+ boolean visible = onIsApplicationVisibleForRole(roleName, packageName);
+ callback.sendResult(visible ? Bundle.EMPTY : null);
+ }
+
+ @Override
public void isRoleVisible(String roleName, RemoteCallback callback) {
enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null);
@@ -256,11 +270,26 @@
* @param packageName package name of the application to check for
*
* @return whether the application is qualified for the role
+ *
+ * @deprecated Implement {@link #onIsApplicationVisibleForRole(String, String)} instead.
*/
public abstract boolean onIsApplicationQualifiedForRole(@NonNull String roleName,
@NonNull String packageName);
/**
+ * Check whether an application is visible for a role.
+ *
+ * @param roleName name of the role to check for
+ * @param packageName package name of the application to check for
+ *
+ * @return whether the application is visible for the role
+ */
+ public boolean onIsApplicationVisibleForRole(@NonNull String roleName,
+ @NonNull String packageName) {
+ return onIsApplicationQualifiedForRole(roleName, packageName);
+ }
+
+ /**
* Check whether a role should be visible to user.
*
* @param roleName name of the role to check for
diff --git a/core/java/android/app/usage/CacheQuotaHint.java b/core/java/android/app/usage/CacheQuotaHint.java
index b92d538..b5aed49f 100644
--- a/core/java/android/app/usage/CacheQuotaHint.java
+++ b/core/java/android/app/usage/CacheQuotaHint.java
@@ -81,7 +81,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o instanceof CacheQuotaHint) {
final CacheQuotaHint other = (CacheQuotaHint) o;
return Objects.equals(mUuid, other.mUuid)
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index b564c31..84c6855 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -554,6 +554,7 @@
* event is of type {@link #NOTIFICATION_INTERRUPTION}, otherwise it returns null;
* @hide
*/
+ @Nullable
@SystemApi
public String getNotificationChannelId() {
return mNotificationChannelId;
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index fb78789..cfb363a08 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -118,6 +118,8 @@
*/
public static final int PAN_OPERATION_SUCCESS = 1004;
+ private final Context mContext;
+
private BluetoothAdapter mAdapter;
private final BluetoothProfileConnector<IBluetoothPan> mProfileConnector =
new BluetoothProfileConnector(this, BluetoothProfile.PAN,
@@ -136,6 +138,7 @@
@UnsupportedAppUsage
/*package*/ BluetoothPan(Context context, ServiceListener listener) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
+ mContext = context;
mProfileConnector.connect(context, listener);
}
@@ -287,11 +290,12 @@
@UnsupportedAppUsage
public void setBluetoothTethering(boolean value) {
- if (DBG) log("setBluetoothTethering(" + value + ")");
+ String pkgName = mContext.getOpPackageName();
+ if (DBG) log("setBluetoothTethering(" + value + "), calling package:" + pkgName);
final IBluetoothPan service = getService();
if (service != null && isEnabled()) {
try {
- service.setBluetoothTethering(value);
+ service.setBluetoothTethering(value, pkgName);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index f297c06..9dbfbc7 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -1033,12 +1033,13 @@
/** @hide */
public final void setTransportLoggingEnabled(boolean enabled) {
- if (mTransport != null) {
- if (enabled) {
- mTransport.mInterface = new LoggingContentInterface(getClass().getSimpleName(), this);
- } else {
- mTransport.mInterface = this;
- }
+ if (mTransport == null) {
+ return;
+ }
+ if (enabled) {
+ mTransport.mInterface = new LoggingContentInterface(getClass().getSimpleName(), this);
+ } else {
+ mTransport.mInterface = this;
}
}
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index 621f331..5c2de57 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -684,10 +684,26 @@
return new ContentProviderOperation(this);
}
- private void setValue(@NonNull String key, @NonNull Object value) {
+ private void ensureValues() {
if (mValues == null) {
mValues = new ArrayMap<>();
}
+ }
+
+ private void ensureExtras() {
+ if (mExtras == null) {
+ mExtras = new ArrayMap<>();
+ }
+ }
+
+ private void ensureSelectionArgs() {
+ if (mSelectionArgs == null) {
+ mSelectionArgs = new SparseArray<>();
+ }
+ }
+
+ private void setValue(@NonNull String key, @NonNull Object value) {
+ ensureValues();
final boolean oldReference = mValues.get(key) instanceof BackReference;
final boolean newReference = value instanceof BackReference;
if (!oldReference || newReference) {
@@ -696,9 +712,7 @@
}
private void setExtra(@NonNull String key, @NonNull Object value) {
- if (mExtras == null) {
- mExtras = new ArrayMap<>();
- }
+ ensureExtras();
final boolean oldReference = mExtras.get(key) instanceof BackReference;
final boolean newReference = value instanceof BackReference;
if (!oldReference || newReference) {
@@ -707,9 +721,7 @@
}
private void setSelectionArg(int index, @NonNull Object value) {
- if (mSelectionArgs == null) {
- mSelectionArgs = new SparseArray<>();
- }
+ ensureSelectionArgs();
final boolean oldReference = mSelectionArgs.get(index) instanceof BackReference;
final boolean newReference = value instanceof BackReference;
if (!oldReference || newReference) {
@@ -728,6 +740,7 @@
*/
public @NonNull Builder withValues(@NonNull ContentValues values) {
assertValuesAllowed();
+ ensureValues();
final ArrayMap<String, Object> rawValues = values.getValues();
for (int i = 0; i < rawValues.size(); i++) {
setValue(rawValues.keyAt(i), rawValues.valueAt(i));
@@ -815,6 +828,7 @@
*/
public @NonNull Builder withExtras(@NonNull Bundle extras) {
assertExtrasAllowed();
+ ensureExtras();
for (String key : extras.keySet()) {
setExtra(key, extras.get(key));
}
@@ -885,6 +899,7 @@
assertSelectionAllowed();
mSelection = selection;
if (selectionArgs != null) {
+ ensureSelectionArgs();
for (int i = 0; i < selectionArgs.length; i++) {
setSelectionArg(i, selectionArgs[i]);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5dcc291..b612f1c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -854,11 +854,16 @@
* to any callers for the same name, meaning they will see each other's
* edits as soon as they are made.
*
- * This method is thead-safe.
+ * <p>This method is thread-safe.
*
- * @param name Desired preferences file. If a preferences file by this name
- * does not exist, it will be created when you retrieve an
- * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
+ * <p>If the preferences directory does not already exist, it will be created when this method
+ * is called.
+ *
+ * <p>If a preferences file by this name does not exist, it will be created when you retrieve an
+ * editor ({@link SharedPreferences#edit()}) and then commit changes ({@link
+ * SharedPreferences.Editor#commit()} or {@link SharedPreferences.Editor#apply()}).
+ *
+ * @param name Desired preferences file.
* @param mode Operating mode.
*
* @return The single {@link SharedPreferences} instance that can be used
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index 9d87e25..c193868 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -16,7 +16,6 @@
package android.content;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import java.util.Map;
@@ -58,33 +57,18 @@
*
* <p>This callback will be run on your main thread.
*
- * <p><em>Note: This callback will not be triggered when preferences are cleared via
- * {@link Editor#clear()}. However, from {@link android.os.Build.VERSION_CODES#R Android R}
- * onwards, you can use {@link OnSharedPreferencesClearListener} to register for
- * {@link Editor#clear()} callbacks.</em>
- *
- * @param sharedPreferences The {@link SharedPreferences} that received
- * the change.
- * @param key The key of the preference that was changed, added, or
- * removed.
- */
- void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);
- }
-
- /**
- * Interface definition for a callback to be invoked when shared preferences are cleared.
- */
- public interface OnSharedPreferencesClearListener {
- /**
- * Called when shared preferences are cleared via {@link Editor#clear()}.
- *
- * <p>This callback will be run on your main thread.
+ * <p><em>Note: This callback will not be triggered when preferences are cleared
+ * via {@link Editor#clear()}, unless targeting {@link android.os.Build.VERSION_CODES#R}
+ * on devices running OS versions {@link android.os.Build.VERSION_CODES#R Android R}
+ * or later.</em>
*
* @param sharedPreferences The {@link SharedPreferences} that received the change.
- * @param keys The set of keys that were cleared.
+ * @param key The key of the preference that was changed, added, or removed. Apps targeting
+ * {@link android.os.Build.VERSION_CODES#R} on devices running OS versions
+ * {@link android.os.Build.VERSION_CODES#R Android R} or later, will receive
+ * a {@code null} value when preferences are cleared.
*/
- void onSharedPreferencesClear(@NonNull SharedPreferences sharedPreferences,
- @NonNull Set<String> keys);
+ void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);
}
/**
@@ -405,35 +389,4 @@
* @see #registerOnSharedPreferenceChangeListener
*/
void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);
-
- /**
- * Registers a callback to be invoked when preferences are cleared via {@link Editor#clear()}.
- *
- * <p class="caution"><strong>Caution:</strong> The preference manager does
- * not currently store a strong reference to the listener. You must store a
- * strong reference to the listener, or it will be susceptible to garbage
- * collection. We recommend you keep a reference to the listener in the
- * instance data of an object that will exist as long as you need the
- * listener.</p>
- *
- * @param listener The callback that will run.
- * @see #unregisterOnSharedPreferencesClearListener
- */
- default void registerOnSharedPreferencesClearListener(
- @NonNull OnSharedPreferencesClearListener listener) {
- throw new UnsupportedOperationException(
- "registerOnSharedPreferencesClearListener not implemented");
- }
-
- /**
- * Unregisters a previous callback for {@link Editor#clear()}.
- *
- * @param listener The callback that should be unregistered.
- * @see #registerOnSharedPreferencesClearListener
- */
- default void unregisterOnSharedPreferencesClearListener(
- @NonNull OnSharedPreferencesClearListener listener) {
- throw new UnsupportedOperationException(
- "unregisterOnSharedPreferencesClearListener not implemented");
- }
}
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
index f39fc66..1a78f79 100644
--- a/core/java/android/content/om/OverlayInfo.java
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -413,7 +413,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -448,6 +448,7 @@
return true;
}
+ @NonNull
@Override
public String toString() {
return "OverlayInfo { overlay=" + packageName + ", targetPackage=" + targetPackageName
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 037a149..c74daa8 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -503,9 +503,38 @@
}
/**
- * Retrieves a list of launchable activities that match {@link Intent#ACTION_MAIN} and
- * {@link Intent#CATEGORY_LAUNCHER}, for a specified user. Result may include
- * synthesized activities like app details Activity injected by system.
+ * Retrieves a list of activities that specify {@link Intent#ACTION_MAIN} and
+ * {@link Intent#CATEGORY_LAUNCHER}, across all apps, for a specified user. If an app doesn't
+ * have any activities that specify <code>ACTION_MAIN</code> or <code>CATEGORY_LAUNCHER</code>,
+ * the system adds a synthesized activity to the list. This synthesized activity represents the
+ * app's details page within system settings.
+ *
+ * <p class="note"><b>Note: </b>It's possible for system apps, such as app stores, to prevent
+ * the system from adding synthesized activities to the returned list.</p>
+ *
+ * <p>As of <a href="/reference/android/os/Build.VERSION_CODES.html#Q">Android Q</a>, at least
+ * one of the app's activities or synthesized activities appears in the returned list unless the
+ * app satisfies at least one of the following conditions:</p>
+ * <ul>
+ * <li>The app is a system app.</li>
+ * <li>The app doesn't request any <a href="/guide/topics/permissions/overview">permissions</a>.
+ * </li>
+ * <li>The <code><application></code> tag in the app's manifest doesn't contain any child
+ * elements that represent
+ * <a href="/guide/components/fundamentals#DeclaringComponents">app components</a>.</li>
+ * </ul>
+ *
+ * <p>Additionally, the system hides synthesized activities for some or all apps in the
+ * following enterprise-related cases:</p>
+ * <ul>
+ * <li>If the device is a
+ * <a href="https://developers.google.com/android/work/overview#company-owned-devices-for-knowledge-workers">fully
+ * managed device</a>, no synthesized activities for any app appear in the returned list.</li>
+ * <li>If the current user has a
+ * <a href="https://developers.google.com/android/work/overview#employee-owned-devices-byod">work
+ * profile</a>, no synthesized activities for the user's work apps appear in the returned
+ * list.</li>
+ * </ul>
*
* @param packageName The specific package to query. If null, it checks all installed packages
* in the profile.
diff --git a/core/java/android/content/pm/SuspendDialogInfo.java b/core/java/android/content/pm/SuspendDialogInfo.java
index db8f8c2..73b75df 100644
--- a/core/java/android/content/pm/SuspendDialogInfo.java
+++ b/core/java/android/content/pm/SuspendDialogInfo.java
@@ -185,7 +185,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -200,6 +200,7 @@
&& Objects.equals(mDialogMessage, otherDialogInfo.mDialogMessage);
}
+ @NonNull
@Override
public String toString() {
final StringBuilder builder = new StringBuilder("SuspendDialogInfo: {");
diff --git a/core/java/android/content/rollback/RollbackManager.java b/core/java/android/content/rollback/RollbackManager.java
index 1609f53..73b8a48 100644
--- a/core/java/android/content/rollback/RollbackManager.java
+++ b/core/java/android/content/rollback/RollbackManager.java
@@ -74,10 +74,7 @@
}
/**
- * Returns a list of all currently available rollbacks. This includes ones for very recently
- * installed packages (even if onFinished has not yet been called). As a result, packages that
- * very recently failed to install may also be included, but those rollbacks will fail with
- * 'rollback not available'.
+ * Returns a list of all currently available rollbacks.
*
* @throws SecurityException if the caller does not have appropriate permissions.
*/
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index 3e130c5..c28cf8f 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -129,7 +129,7 @@
public CameraLooper(int cameraId) {
mCameraId = cameraId;
- mThread = new Thread(this);
+ mThread = new Thread(this, "LegacyCameraLooper");
mThread.start();
}
diff --git a/core/java/android/hardware/display/AmbientBrightnessDayStats.java b/core/java/android/hardware/display/AmbientBrightnessDayStats.java
index b25ef8d..350bc30d 100644
--- a/core/java/android/hardware/display/AmbientBrightnessDayStats.java
+++ b/core/java/android/hardware/display/AmbientBrightnessDayStats.java
@@ -17,6 +17,7 @@
package android.hardware.display;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -136,7 +137,7 @@
};
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -161,6 +162,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
StringBuilder bucketBoundariesString = new StringBuilder();
diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java
index 5b63dcf..4c2e297 100644
--- a/core/java/android/hardware/display/BrightnessConfiguration.java
+++ b/core/java/android/hardware/display/BrightnessConfiguration.java
@@ -145,6 +145,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder("BrightnessConfiguration{[");
@@ -184,7 +185,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o == this) {
return true;
}
diff --git a/core/java/android/hardware/display/BrightnessCorrection.java b/core/java/android/hardware/display/BrightnessCorrection.java
index b029acc..22df778 100644
--- a/core/java/android/hardware/display/BrightnessCorrection.java
+++ b/core/java/android/hardware/display/BrightnessCorrection.java
@@ -18,6 +18,7 @@
import android.annotation.FloatRange;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -98,13 +99,13 @@
*
* @return A string representation.
*/
+ @NonNull
public String toString() {
return mImplementation.toString();
}
-
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o == this) {
return true;
}
diff --git a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
index 1362116..55b0726 100644
--- a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
+++ b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java
@@ -16,6 +16,8 @@
package android.hardware.hdmi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -458,6 +460,7 @@
}
}
+ @NonNull
@Override
public String toString() {
StringBuffer s = new StringBuffer();
@@ -493,7 +496,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (!(obj instanceof HdmiDeviceInfo)) {
return false;
}
diff --git a/core/java/android/hardware/hdmi/HdmiPortInfo.java b/core/java/android/hardware/hdmi/HdmiPortInfo.java
index f53f458..2623458 100644
--- a/core/java/android/hardware/hdmi/HdmiPortInfo.java
+++ b/core/java/android/hardware/hdmi/HdmiPortInfo.java
@@ -15,6 +15,8 @@
*/
package android.hardware.hdmi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -162,6 +164,7 @@
dest.writeInt(mMhlSupported ? 1 : 0);
}
+ @NonNull
@Override
public String toString() {
StringBuffer s = new StringBuffer();
@@ -175,7 +178,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (!(o instanceof HdmiPortInfo)) {
return false;
}
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index b5da381..a11f2e9 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -15,6 +15,7 @@
*/
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.hardware.contexthub.V1_0.ContextHub;
@@ -248,6 +249,7 @@
return mChrePatchVersion;
}
+ @NonNull
@Override
public String toString() {
String retVal = "";
diff --git a/core/java/android/hardware/location/ContextHubIntentEvent.java b/core/java/android/hardware/location/ContextHubIntentEvent.java
index d1190ab..754327a 100644
--- a/core/java/android/hardware/location/ContextHubIntentEvent.java
+++ b/core/java/android/hardware/location/ContextHubIntentEvent.java
@@ -192,6 +192,7 @@
return mNanoAppMessage;
}
+ @NonNull
@Override
public String toString() {
String out = "ContextHubIntentEvent[eventType = " + mEventType
diff --git a/core/java/android/hardware/location/ContextHubMessage.java b/core/java/android/hardware/location/ContextHubMessage.java
index 1c98427..6777c53 100644
--- a/core/java/android/hardware/location/ContextHubMessage.java
+++ b/core/java/android/hardware/location/ContextHubMessage.java
@@ -16,6 +16,7 @@
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -127,7 +128,7 @@
out.writeByteArray(mData);
}
- public static final @android.annotation.NonNull Parcelable.Creator<ContextHubMessage> CREATOR
+ public static final @NonNull Parcelable.Creator<ContextHubMessage> CREATOR
= new Parcelable.Creator<ContextHubMessage>() {
public ContextHubMessage createFromParcel(Parcel in) {
return new ContextHubMessage(in);
@@ -138,6 +139,7 @@
}
};
+ @NonNull
@Override
public String toString() {
int length = mData.length;
diff --git a/core/java/android/hardware/location/GeofenceHardwareMonitorEvent.java b/core/java/android/hardware/location/GeofenceHardwareMonitorEvent.java
index fbbf687..78cca96 100644
--- a/core/java/android/hardware/location/GeofenceHardwareMonitorEvent.java
+++ b/core/java/android/hardware/location/GeofenceHardwareMonitorEvent.java
@@ -16,6 +16,7 @@
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.location.Location;
import android.os.Parcel;
@@ -72,7 +73,7 @@
return mLocation;
}
- public static final @android.annotation.NonNull Creator<GeofenceHardwareMonitorEvent> CREATOR =
+ public static final @NonNull Creator<GeofenceHardwareMonitorEvent> CREATOR =
new Creator<GeofenceHardwareMonitorEvent>() {
@Override
public GeofenceHardwareMonitorEvent createFromParcel(Parcel source) {
@@ -108,6 +109,7 @@
parcel.writeParcelable(mLocation, flags);
}
+ @NonNull
@Override
public String toString() {
return String.format(
diff --git a/core/java/android/hardware/location/MemoryRegion.java b/core/java/android/hardware/location/MemoryRegion.java
index ecd369a..c033228 100644
--- a/core/java/android/hardware/location/MemoryRegion.java
+++ b/core/java/android/hardware/location/MemoryRegion.java
@@ -16,6 +16,7 @@
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
@@ -79,6 +80,7 @@
return mIsExecutable;
}
+ @NonNull
@Override
public String toString() {
String mask = "";
diff --git a/core/java/android/hardware/location/NanoApp.java b/core/java/android/hardware/location/NanoApp.java
index 3fbb069..6a734f3 100644
--- a/core/java/android/hardware/location/NanoApp.java
+++ b/core/java/android/hardware/location/NanoApp.java
@@ -15,6 +15,7 @@
*/
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -370,6 +371,7 @@
}
};
+ @NonNull
@Override
public String toString() {
String retVal = "Id : " + mAppId;
diff --git a/core/java/android/hardware/location/NanoAppFilter.java b/core/java/android/hardware/location/NanoAppFilter.java
index 0700dd1..1d8b69d 100644
--- a/core/java/android/hardware/location/NanoAppFilter.java
+++ b/core/java/android/hardware/location/NanoAppFilter.java
@@ -16,6 +16,7 @@
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -131,6 +132,7 @@
(versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()));
}
+ @NonNull
@Override
public String toString() {
return "nanoAppId: 0x" + Long.toHexString(mAppId)
diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.java b/core/java/android/hardware/location/NanoAppInstanceInfo.java
index a6c754d..ea11756 100644
--- a/core/java/android/hardware/location/NanoAppInstanceInfo.java
+++ b/core/java/android/hardware/location/NanoAppInstanceInfo.java
@@ -219,6 +219,7 @@
}
};
+ @NonNull
@Override
public String toString() {
String retVal = "handle : " + mHandle;
diff --git a/core/java/android/hardware/location/NanoAppMessage.java b/core/java/android/hardware/location/NanoAppMessage.java
index 078532a..bb3e81a 100644
--- a/core/java/android/hardware/location/NanoAppMessage.java
+++ b/core/java/android/hardware/location/NanoAppMessage.java
@@ -15,6 +15,7 @@
*/
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
@@ -136,7 +137,7 @@
out.writeByteArray(mMessageBody);
}
- public static final @android.annotation.NonNull Creator<NanoAppMessage> CREATOR =
+ public static final @NonNull Creator<NanoAppMessage> CREATOR =
new Creator<NanoAppMessage>() {
@Override
public NanoAppMessage createFromParcel(Parcel in) {
@@ -149,6 +150,7 @@
}
};
+ @NonNull
@Override
public String toString() {
int length = mMessageBody.length;
diff --git a/core/java/android/hardware/radio/ProgramList.java b/core/java/android/hardware/radio/ProgramList.java
index f4fd1b6..ec318b7 100644
--- a/core/java/android/hardware/radio/ProgramList.java
+++ b/core/java/android/hardware/radio/ProgramList.java
@@ -377,7 +377,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof Filter)) return false;
Filter other = (Filter) obj;
@@ -389,6 +389,7 @@
return true;
}
+ @NonNull
@Override
public String toString() {
return "Filter [mIdentifierTypes=" + mIdentifierTypes
diff --git a/core/java/android/hardware/radio/ProgramSelector.java b/core/java/android/hardware/radio/ProgramSelector.java
index b321855..d525753 100644
--- a/core/java/android/hardware/radio/ProgramSelector.java
+++ b/core/java/android/hardware/radio/ProgramSelector.java
@@ -485,6 +485,7 @@
return new ProgramSelector(programType, primary, secondary, null);
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder("ProgramSelector(type=").append(mProgramType)
@@ -502,7 +503,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof ProgramSelector)) return false;
ProgramSelector other = (ProgramSelector) obj;
@@ -611,6 +612,7 @@
return mValue;
}
+ @NonNull
@Override
public String toString() {
return "Identifier(" + mType + ", " + mValue + ")";
@@ -622,7 +624,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof Identifier)) return false;
Identifier other = (Identifier) obj;
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index a7ff644..6ea2ac4 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -485,6 +485,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "ModuleProperties [mId=" + mId
@@ -507,7 +508,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof ModuleProperties)) return false;
ModuleProperties other = (ModuleProperties) obj;
@@ -660,6 +661,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "BandDescriptor [mRegion=" + mRegion + ", mType=" + mType + ", mLowerLimit="
@@ -679,7 +681,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (!(obj instanceof BandDescriptor))
@@ -788,6 +790,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "FmBandDescriptor [ "+ super.toString() + " mStereo=" + mStereo
@@ -808,7 +811,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
@@ -877,6 +880,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "AmBandDescriptor [ "+ super.toString() + " mStereo=" + mStereo + "]";
@@ -891,7 +895,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
@@ -997,6 +1001,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "BandConfig [ " + mDescriptor.toString() + "]";
@@ -1011,7 +1016,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (!(obj instanceof BandConfig))
@@ -1125,6 +1130,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "FmBandConfig [" + super.toString()
@@ -1145,7 +1151,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
@@ -1317,6 +1323,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "AmBandConfig [" + super.toString()
@@ -1332,7 +1339,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
@@ -1656,6 +1663,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "ProgramInfo"
@@ -1676,7 +1684,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof ProgramInfo)) return false;
ProgramInfo other = (ProgramInfo) obj;
diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java
index 76304bd..a882c2f 100644
--- a/core/java/android/hardware/radio/RadioMetadata.java
+++ b/core/java/android/hardware/radio/RadioMetadata.java
@@ -16,6 +16,7 @@
package android.hardware.radio;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -279,7 +280,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof RadioMetadata)) return false;
Bundle otherBundle = ((RadioMetadata) obj).mBundle;
@@ -308,6 +309,7 @@
mBundle = in.readBundle();
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder("RadioMetadata[");
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index 5b5bd76..f96f47d 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -22,6 +22,7 @@
import static android.system.OsConstants.EPERM;
import static android.system.OsConstants.EPIPE;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
@@ -829,7 +830,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (obj == null)
@@ -869,6 +870,7 @@
return true;
}
+ @NonNull
@Override
public String toString() {
return "RecognitionEvent [status=" + status + ", soundModelHandle=" + soundModelHandle
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index c674480..506230e 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -327,7 +327,7 @@
return false;
}
-
+ @NonNull
@Override
public String toString() {
return "UsbPort{id=" + mId + ", supportedModes=" + modeToString(mSupportedModes)
diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java
index 5e9a410..43c418e 100644
--- a/core/java/android/hardware/usb/UsbPortStatus.java
+++ b/core/java/android/hardware/usb/UsbPortStatus.java
@@ -17,6 +17,7 @@
package android.hardware.usb;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.hardware.usb.V1_0.Constants;
import android.os.Parcel;
@@ -322,6 +323,7 @@
return mContaminantProtectionStatus;
}
+ @NonNull
@Override
public String toString() {
return "UsbPortStatus{connected=" + isConnected()
@@ -352,7 +354,7 @@
dest.writeInt(mContaminantDetectionStatus);
}
- public static final @android.annotation.NonNull Parcelable.Creator<UsbPortStatus> CREATOR =
+ public static final @NonNull Parcelable.Creator<UsbPortStatus> CREATOR =
new Parcelable.Creator<UsbPortStatus>() {
@Override
public UsbPortStatus createFromParcel(Parcel in) {
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 82d4d1d..83391f3 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -19,6 +19,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -62,6 +63,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
@@ -595,12 +597,12 @@
if (DEBUG) Log.v(TAG, "hideSoftInput()");
final boolean wasVisible = mIsPreRendered
? mDecorViewVisible && mWindowVisible : isInputViewShown();
+ applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */);
if (mIsPreRendered) {
if (DEBUG) {
Log.v(TAG, "Making IME window invisible");
}
setImeWindowStatus(IME_ACTIVE | IME_INVISIBLE, mBackDisposition);
- applyVisibilityInInsetsConsumer(false /* setVisible */);
onPreRenderedWindowVisibilityChanged(false /* setVisible */);
} else {
mShowInputFlags = 0;
@@ -632,11 +634,11 @@
if (DEBUG) {
Log.v(TAG, "Making IME window visible");
}
- applyVisibilityInInsetsConsumer(true /* setVisible */);
onPreRenderedWindowVisibilityChanged(true /* setVisible */);
} else {
showWindow(true);
}
+ applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */);
}
// If user uses hard keyboard, IME button should always be shown.
setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
@@ -1974,16 +1976,20 @@
/**
* Apply the IME visibility in {@link android.view.ImeInsetsSourceConsumer} when
- * pre-rendering is enabled.
+ * {@link ViewRootImpl.sNewInsetsMode} is enabled.
* @param setVisible {@code true} to make it visible, false to hide it.
*/
- private void applyVisibilityInInsetsConsumer(boolean setVisible) {
- if (!mIsPreRendered) {
+ private void applyVisibilityInInsetsConsumerIfNecessary(boolean setVisible) {
+ if (!isVisibilityAppliedUsingInsetsConsumer()) {
return;
}
mPrivOps.applyImeVisibility(setVisible);
}
+ private boolean isVisibilityAppliedUsingInsetsConsumer() {
+ return ViewRootImpl.sNewInsetsMode > NEW_INSETS_MODE_NONE;
+ }
+
private void finishViews(boolean finishingInput) {
if (mInputViewStarted) {
if (DEBUG) Log.v(TAG, "CALL: onFinishInputView");
@@ -2007,7 +2013,11 @@
mWindowVisible = false;
finishViews(false /* finishingInput */);
if (mDecorViewVisible) {
- mWindow.hide();
+ // When insets API is enabled, it is responsible for client and server side
+ // visibility of IME window.
+ if (!isVisibilityAppliedUsingInsetsConsumer()) {
+ mWindow.hide();
+ }
mDecorViewVisible = false;
onWindowHidden();
mDecorViewWasVisible = false;
diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl
index 10667ae..106b7be 100644
--- a/core/java/android/net/INetworkPolicyListener.aidl
+++ b/core/java/android/net/INetworkPolicyListener.aidl
@@ -22,5 +22,5 @@
void onMeteredIfacesChanged(in String[] meteredIfaces);
void onRestrictBackgroundChanged(boolean restrictBackground);
void onUidPoliciesChanged(int uid, int uidPolicies);
- void onSubscriptionOverride(int subId, int overrideMask, int overrideValue);
+ void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, long networkTypeMask);
}
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 385cb1d..90327663 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -76,7 +76,7 @@
SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage);
void setSubscriptionPlans(int subId, in SubscriptionPlan[] plans, String callingPackage);
String getSubscriptionPlansOwner(int subId);
- void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, long timeoutMillis, String callingPackage);
+ void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, long networkTypeMask, long timeoutMillis, String callingPackage);
void factoryReset(String subscriber);
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 83813da..45d0c73 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -861,6 +861,7 @@
return mResourceId;
}
+ @NonNull
@Override
public String toString() {
return new StringBuilder()
diff --git a/core/java/android/net/NetworkKey.java b/core/java/android/net/NetworkKey.java
index 0a9a3c8..a101da7 100644
--- a/core/java/android/net/NetworkKey.java
+++ b/core/java/android/net/NetworkKey.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.wifi.ScanResult;
@@ -152,7 +153,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -166,6 +167,7 @@
return Objects.hash(type, wifiKey);
}
+ @NonNull
@Override
public String toString() {
switch (type) {
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index bf27262..628dcd2 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -380,6 +380,7 @@
@Override public void onMeteredIfacesChanged(String[] meteredIfaces) { }
@Override public void onRestrictBackgroundChanged(boolean restrictBackground) { }
@Override public void onUidPoliciesChanged(int uid, int uidPolicies) { }
- @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) { }
+ @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue,
+ long networkTypeMask) { }
}
}
diff --git a/core/java/android/net/RssiCurve.java b/core/java/android/net/RssiCurve.java
index a173b0c..668e966 100644
--- a/core/java/android/net/RssiCurve.java
+++ b/core/java/android/net/RssiCurve.java
@@ -16,6 +16,8 @@
package android.net;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -170,7 +172,7 @@
* not considered equal to each other.
*/
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -187,6 +189,7 @@
return Objects.hash(start, bucketWidth, activeNetworkRssiBoost) ^ Arrays.hashCode(rssiBuckets);
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/net/ScoredNetwork.java b/core/java/android/net/ScoredNetwork.java
index effc1aa..64b3bf1 100644
--- a/core/java/android/net/ScoredNetwork.java
+++ b/core/java/android/net/ScoredNetwork.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Bundle;
@@ -182,7 +183,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -220,6 +221,7 @@
return Objects.hash(networkKey, rssiCurve, meteredHint, attributes);
}
+ @NonNull
@Override
public String toString() {
StringBuilder out = new StringBuilder(
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index d6deba5..5bc9953 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -236,6 +236,7 @@
return lp;
}
+ @NonNull
@Override
public String toString() {
StringBuffer str = new StringBuffer();
@@ -267,7 +268,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticIpConfiguration)) return false;
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
index fbc281f..994c794 100644
--- a/core/java/android/net/WebAddress.java
+++ b/core/java/android/net/WebAddress.java
@@ -18,6 +18,7 @@
import static android.util.Patterns.GOOD_IRI_CHAR;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Build;
@@ -132,6 +133,7 @@
if (mScheme.equals("")) mScheme = "http";
}
+ @NonNull
@Override
public String toString() {
String port = "";
diff --git a/core/java/android/net/WifiKey.java b/core/java/android/net/WifiKey.java
index e3a93a8..bc9d8c5 100644
--- a/core/java/android/net/WifiKey.java
+++ b/core/java/android/net/WifiKey.java
@@ -16,6 +16,8 @@
package android.net;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -91,7 +93,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -105,6 +107,7 @@
return Objects.hash(ssid, bssid);
}
+ @NonNull
@Override
public String toString() {
return "WifiKey[SSID=" + ssid + ",BSSID=" + bssid + "]";
diff --git a/core/java/android/net/apf/ApfCapabilities.java b/core/java/android/net/apf/ApfCapabilities.java
index 4dd2ace..b1de74e 100644
--- a/core/java/android/net/apf/ApfCapabilities.java
+++ b/core/java/android/net/apf/ApfCapabilities.java
@@ -17,6 +17,7 @@
package android.net.apf;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.content.res.Resources;
@@ -91,6 +92,7 @@
}
};
+ @NonNull
@Override
public String toString() {
return String.format("%s{version: %d, maxSize: %d, format: %d}", getClass().getSimpleName(),
@@ -98,7 +100,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (!(obj instanceof ApfCapabilities)) return false;
final ApfCapabilities other = (ApfCapabilities) obj;
return apfVersionSupported == other.apfVersionSupported
diff --git a/core/java/android/net/metrics/ApfProgramEvent.java b/core/java/android/net/metrics/ApfProgramEvent.java
index e9c209c..8243be9 100644
--- a/core/java/android/net/metrics/ApfProgramEvent.java
+++ b/core/java/android/net/metrics/ApfProgramEvent.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
@@ -185,6 +186,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever";
@@ -193,7 +195,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj.getClass().equals(ApfProgramEvent.class))) return false;
final ApfProgramEvent other = (ApfProgramEvent) obj;
return lifetime == other.lifetime
diff --git a/core/java/android/net/metrics/ApfStats.java b/core/java/android/net/metrics/ApfStats.java
index b963777..eac5579f 100644
--- a/core/java/android/net/metrics/ApfStats.java
+++ b/core/java/android/net/metrics/ApfStats.java
@@ -17,6 +17,7 @@
package android.net.metrics;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
@@ -260,6 +261,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return new StringBuilder("ApfStats(")
@@ -276,7 +278,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj.getClass().equals(ApfStats.class))) return false;
final ApfStats other = (ApfStats) obj;
return durationMs == other.durationMs
diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java
index 2fed736..5f9f507 100644
--- a/core/java/android/net/metrics/DhcpClientEvent.java
+++ b/core/java/android/net/metrics/DhcpClientEvent.java
@@ -17,6 +17,7 @@
package android.net.metrics;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
@@ -97,13 +98,14 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return String.format("DhcpClientEvent(%s, %dms)", msg, durationMs);
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj.getClass().equals(DhcpClientEvent.class))) return false;
final DhcpClientEvent other = (DhcpClientEvent) obj;
return TextUtils.equals(msg, other.msg)
diff --git a/core/java/android/net/metrics/DhcpErrorEvent.java b/core/java/android/net/metrics/DhcpErrorEvent.java
index 8760004..32efb5a 100644
--- a/core/java/android/net/metrics/DhcpErrorEvent.java
+++ b/core/java/android/net/metrics/DhcpErrorEvent.java
@@ -16,6 +16,7 @@
package android.net.metrics;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -108,6 +109,7 @@
return (0xFFFF0000 & errorCode) | (0xFF & option);
}
+ @NonNull
@Override
public String toString() {
return String.format("DhcpErrorEvent(%s)", Decoder.constants.get(errorCode));
diff --git a/core/java/android/net/metrics/IpManagerEvent.java b/core/java/android/net/metrics/IpManagerEvent.java
index ba05c59..f14abb8 100644
--- a/core/java/android/net/metrics/IpManagerEvent.java
+++ b/core/java/android/net/metrics/IpManagerEvent.java
@@ -17,6 +17,8 @@
package android.net.metrics;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -95,6 +97,7 @@
}
};
+ @NonNull
@Override
public String toString() {
return String.format("IpManagerEvent(%s, %dms)",
@@ -102,7 +105,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj.getClass().equals(IpManagerEvent.class))) return false;
final IpManagerEvent other = (IpManagerEvent) obj;
return eventType == other.eventType
diff --git a/core/java/android/net/metrics/IpReachabilityEvent.java b/core/java/android/net/metrics/IpReachabilityEvent.java
index d4ba294..79e01d7 100644
--- a/core/java/android/net/metrics/IpReachabilityEvent.java
+++ b/core/java/android/net/metrics/IpReachabilityEvent.java
@@ -16,6 +16,8 @@
package android.net.metrics;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -85,6 +87,7 @@
}
};
+ @NonNull
@Override
public String toString() {
int hi = eventType & 0xff00;
@@ -94,7 +97,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj.getClass().equals(IpReachabilityEvent.class))) return false;
final IpReachabilityEvent other = (IpReachabilityEvent) obj;
return eventType == other.eventType;
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
index 0c57ec6..fe603cf 100644
--- a/core/java/android/net/metrics/NetworkEvent.java
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -17,6 +17,8 @@
package android.net.metrics;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -115,6 +117,7 @@
}
};
+ @NonNull
@Override
public String toString() {
return String.format("NetworkEvent(%s, %dms)",
@@ -122,7 +125,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj.getClass().equals(NetworkEvent.class))) return false;
final NetworkEvent other = (NetworkEvent) obj;
return eventType == other.eventType
diff --git a/core/java/android/net/metrics/RaEvent.java b/core/java/android/net/metrics/RaEvent.java
index 3fd87c2..661f648 100644
--- a/core/java/android/net/metrics/RaEvent.java
+++ b/core/java/android/net/metrics/RaEvent.java
@@ -17,6 +17,7 @@
package android.net.metrics;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -85,6 +86,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return new StringBuilder("RaEvent(lifetimes: ")
@@ -98,7 +100,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj.getClass().equals(RaEvent.class))) return false;
final RaEvent other = (RaEvent) obj;
return routerLifetime == other.routerLifetime
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
index 1aaa50d..8fab64a 100644
--- a/core/java/android/net/metrics/ValidationProbeEvent.java
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -164,6 +165,7 @@
return Decoder.constants.get(probeType & 0xff00, "UNKNOWN");
}
+ @NonNull
@Override
public String toString() {
return String.format("ValidationProbeEvent(%s:%d %s, %dms)",
@@ -171,7 +173,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj.getClass().equals(ValidationProbeEvent.class))) return false;
final ValidationProbeEvent other = (ValidationProbeEvent) obj;
return durationMs == other.durationMs
diff --git a/core/java/android/net/util/MultinetworkPolicyTracker.java b/core/java/android/net/util/MultinetworkPolicyTracker.java
index f7e494d..4e88149 100644
--- a/core/java/android/net/util/MultinetworkPolicyTracker.java
+++ b/core/java/android/net/util/MultinetworkPolicyTracker.java
@@ -64,7 +64,7 @@
private final Context mContext;
private final Handler mHandler;
- private final Runnable mReevaluateRunnable;
+ private final Runnable mAvoidBadWifiCallback;
private final List<Uri> mSettingsUris;
private final ContentResolver mResolver;
private final SettingObserver mSettingObserver;
@@ -81,12 +81,7 @@
public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) {
mContext = ctx;
mHandler = handler;
- mReevaluateRunnable = () -> {
- if (updateAvoidBadWifi() && avoidBadWifiCallback != null) {
- avoidBadWifiCallback.run();
- }
- updateMeteredMultipathPreference();
- };
+ mAvoidBadWifiCallback = avoidBadWifiCallback;
mSettingsUris = Arrays.asList(
Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI),
Settings.Global.getUriFor(NETWORK_METERED_MULTIPATH_PREFERENCE));
@@ -95,15 +90,15 @@
mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- reevaluate();
+ reevaluateInternal();
}
};
- TelephonyManager.from(ctx).listen(new PhoneStateListener() {
+ TelephonyManager.from(ctx).listen(new PhoneStateListener(handler.getLooper()) {
@Override
public void onActiveDataSubscriptionIdChanged(int subId) {
mActiveSubId = subId;
- reevaluate();
+ reevaluateInternal();
}
}, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
@@ -119,7 +114,7 @@
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
mContext.registerReceiverAsUser(
- mBroadcastReceiver, UserHandle.ALL, intentFilter, null, null);
+ mBroadcastReceiver, UserHandle.ALL, intentFilter, null, mHandler);
reevaluate();
}
@@ -164,7 +159,17 @@
@VisibleForTesting
public void reevaluate() {
- mHandler.post(mReevaluateRunnable);
+ mHandler.post(this::reevaluateInternal);
+ }
+
+ /**
+ * Reevaluate the settings. Must be called on the handler thread.
+ */
+ private void reevaluateInternal() {
+ if (updateAvoidBadWifi() && mAvoidBadWifiCallback != null) {
+ mAvoidBadWifiCallback.run();
+ }
+ updateMeteredMultipathPreference();
}
public boolean updateAvoidBadWifi() {
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 4675600..d9000e4 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -114,7 +114,7 @@
* @hide
*/
@UnsupportedAppUsage
- public ApduServiceInfo(ResolveInfo info, String description,
+ public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
boolean requiresUnlock, int bannerResource, int uid,
String settingsActivityName, String offHost, String staticOffHost) {
@@ -124,7 +124,7 @@
this.mDynamicAidGroups = new HashMap<String, AidGroup>();
this.mOffHostName = offHost;
this.mStaticOffHostName = staticOffHost;
- this.mOnHost = (offHost == null);
+ this.mOnHost = onHost;
this.mRequiresDeviceUnlock = requiresUnlock;
for (AidGroup aidGroup : staticAidGroups) {
this.mStaticAidGroups.put(aidGroup.category, aidGroup);
@@ -570,7 +570,7 @@
int bannerResource = source.readInt();
int uid = source.readInt();
String settingsActivityName = source.readString();
- return new ApduServiceInfo(info, description, staticAidGroups,
+ return new ApduServiceInfo(info, onHost, description, staticAidGroups,
dynamicAidGroups, requiresUnlock, bannerResource, uid,
settingsActivityName, offHostName, staticOffHostName);
}
diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java
index 3801cbd..3f6ce4f 100644
--- a/core/java/android/os/BatterySaverPolicyConfig.java
+++ b/core/java/android/os/BatterySaverPolicyConfig.java
@@ -161,6 +161,7 @@
dest.writeInt(mLocationMode);
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 6178b2b..5533721 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -645,6 +645,17 @@
* Called before onTransact.
*
* @return an object that will be passed back to #onTransactEnded (or null).
+ * @hide
+ */
+ @Nullable
+ default Object onTransactStarted(@NonNull IBinder binder, int transactionCode, int flags) {
+ return onTransactStarted(binder, transactionCode);
+ }
+
+ /**
+ * Called before onTransact.
+ *
+ * @return an object that will be passed back to #onTransactEnded (or null).
*/
@Nullable
Object onTransactStarted(@NonNull IBinder binder, int transactionCode);
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 97c0a13..c74cef8 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -496,7 +496,7 @@
if (transactListener != null) {
final int origWorkSourceUid = Binder.getCallingWorkSourceUid();
- session = transactListener.onTransactStarted(this, code);
+ session = transactListener.onTransactStarted(this, code, flags);
// Allow the listener to update the work source uid. We need to update the request
// header if the uid is updated.
diff --git a/core/java/android/os/IMaintenanceActivityListener.aidl b/core/java/android/os/IMaintenanceActivityListener.aidl
deleted file mode 100644
index 6a2581f..0000000
--- a/core/java/android/os/IMaintenanceActivityListener.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-/** @hide */
-oneway interface IMaintenanceActivityListener {
- void onMaintenanceActivityChanged(boolean active);
-}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 1351380..9b8a40a 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -150,6 +150,14 @@
void startTethering(in String[] dhcpRanges);
/**
+ * Start tethering services with the specified dhcp server range and
+ * DNS proxy config.
+ * {@code boolean} is used to control legacy DNS proxy server.
+ * {@code String[]} is a set of start end pairs defining the ranges.
+ */
+ void startTetheringWithConfiguration(boolean usingLegacyDnsProxy, in String[] dhcpRanges);
+
+ /**
* Stop currently running tethering services
*/
@UnsupportedAppUsage
diff --git a/core/java/android/os/IncidentManager.java b/core/java/android/os/IncidentManager.java
index a94fd65..09e1c0f 100644
--- a/core/java/android/os/IncidentManager.java
+++ b/core/java/android/os/IncidentManager.java
@@ -255,7 +255,7 @@
* @inheritDoc
*/
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
diff --git a/core/java/android/os/IncidentReportArgs.java b/core/java/android/os/IncidentReportArgs.java
index a1f2430..7e858e1 100644
--- a/core/java/android/os/IncidentReportArgs.java
+++ b/core/java/android/os/IncidentReportArgs.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -117,6 +118,7 @@
/**
* Print this report as a string.
*/
+ @NonNull
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Incident(");
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 2a4576a..271020d 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -616,10 +616,11 @@
public static File getFile(FileDescriptor fd) throws IOException {
try {
final String path = Os.readlink("/proc/self/fd/" + fd.getInt$());
- if (OsConstants.S_ISREG(Os.stat(path).st_mode)) {
+ if (OsConstants.S_ISREG(Os.stat(path).st_mode)
+ || OsConstants.S_ISCHR(Os.stat(path).st_mode)) {
return new File(path);
} else {
- throw new IOException("Not a regular file: " + path);
+ throw new IOException("Not a regular file or character device: " + path);
}
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
diff --git a/core/java/android/os/ServiceSpecificException.java b/core/java/android/os/ServiceSpecificException.java
index 03d5d3e..49ce40b 100644
--- a/core/java/android/os/ServiceSpecificException.java
+++ b/core/java/android/os/ServiceSpecificException.java
@@ -15,6 +15,7 @@
*/
package android.os;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -44,6 +45,7 @@
this.errorCode = errorCode;
}
+ @NonNull
@Override
public String toString() {
return super.toString() + " (code " + errorCode + ")";
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index f302263..ddd949d 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -15,6 +15,7 @@
*/
package android.os;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
@@ -231,4 +232,9 @@
* found.
*/
public abstract @Nullable UserInfo getUserInfo(@UserIdInt int userId);
+
+ /**
+ * Gets all {@link UserInfo UserInfos}.
+ */
+ public abstract @NonNull UserInfo[] getUserInfos();
}
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 702b41b..26da0a0 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -53,7 +53,7 @@
public static final int MAX_AMPLITUDE = 255;
/**
- * A click effect.
+ * A click effect. Use this effect as a baseline, as it's the most common type of click effect.
*
* @see #get(int)
*/
@@ -67,7 +67,7 @@
public static final int EFFECT_DOUBLE_CLICK = Effect.DOUBLE_CLICK;
/**
- * A tick effect.
+ * A tick effect. This effect is less strong compared to {@link #EFFECT_CLICK}.
* @see #get(int)
*/
public static final int EFFECT_TICK = Effect.TICK;
@@ -89,7 +89,7 @@
public static final int EFFECT_POP = Effect.POP;
/**
- * A heavy click effect.
+ * 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/WorkSource.java b/core/java/android/os/WorkSource.java
index 114de23..9cc9aac 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -1,5 +1,6 @@
package android.os;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -205,7 +206,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o instanceof WorkSource) {
WorkSource other = (WorkSource) o;
@@ -989,6 +990,7 @@
mTags = tags;
}
+ @NonNull
@Override
public String toString() {
StringBuilder result = new StringBuilder("WorkChain{");
@@ -1015,7 +1017,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o instanceof WorkChain) {
WorkChain other = (WorkChain) o;
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 42816c0..5e35958 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.annotation.IntRange;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
@@ -144,7 +145,7 @@
private final int mTargetSdk;
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SplitPermissionInfo that = (SplitPermissionInfo) o;
diff --git a/core/java/android/printservice/PrintServiceInfo.java b/core/java/android/printservice/PrintServiceInfo.java
index 565843e..0c1b61d 100644
--- a/core/java/android/printservice/PrintServiceInfo.java
+++ b/core/java/android/printservice/PrintServiceInfo.java
@@ -17,6 +17,7 @@
package android.printservice;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.ComponentName;
import android.content.Context;
@@ -292,7 +293,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -313,6 +314,7 @@
return true;
}
+ @NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index b7676b6..4b9daf1 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -775,8 +775,9 @@
*
* @param namespace The namespace these properties belong to.
* @param keyValueMap A map between property names and property values.
+ * @hide
*/
- Properties(@NonNull String namespace, @Nullable Map<String, String> keyValueMap) {
+ public Properties(@NonNull String namespace, @Nullable Map<String, String> keyValueMap) {
Preconditions.checkNotNull(namespace);
mNamespace = namespace;
mMap = new HashMap();
diff --git a/core/java/android/provider/SearchIndexableData.java b/core/java/android/provider/SearchIndexableData.java
index a60be53..87f9af3 100644
--- a/core/java/android/provider/SearchIndexableData.java
+++ b/core/java/android/provider/SearchIndexableData.java
@@ -16,6 +16,7 @@
package android.provider;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.Context;
@@ -139,6 +140,7 @@
context = ctx;
}
+ @NonNull
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/provider/SearchIndexableResource.java b/core/java/android/provider/SearchIndexableResource.java
index 1eb1734..0765b6b 100644
--- a/core/java/android/provider/SearchIndexableResource.java
+++ b/core/java/android/provider/SearchIndexableResource.java
@@ -16,6 +16,7 @@
package android.provider;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.Context;
@@ -66,6 +67,7 @@
super(context);
}
+ @NonNull
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f573d87..dd3942e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -16,20 +16,6 @@
package android.provider;
-import static android.provider.settings.validators.SettingsValidators.ANY_INTEGER_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.ANY_STRING_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.BOOLEAN_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.COMPONENT_NAME_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.JSON_OBJECT_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.LOCALE_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.NULLABLE_COMPONENT_NAME_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.TILE_LIST_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.TTS_LIST_VALIDATOR;
-import static android.provider.settings.validators.SettingsValidators.URI_VALIDATOR;
-
import android.Manifest;
import android.annotation.IntDef;
import android.annotation.IntRange;
@@ -63,9 +49,7 @@
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
-import android.hardware.display.ColorDisplayManager;
import android.location.LocationManager;
-import android.media.AudioFormat;
import android.net.ConnectivityManager;
import android.net.NetworkScoreManager;
import android.net.Uri;
@@ -83,12 +67,6 @@
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.UserHandle;
-import android.provider.settings.validators.ComponentNameListValidator;
-import android.provider.settings.validators.DiscreteValueValidator;
-import android.provider.settings.validators.InclusiveFloatRangeValidator;
-import android.provider.settings.validators.InclusiveIntegerRangeValidator;
-import android.provider.settings.validators.PackageNameListValidator;
-import android.provider.settings.validators.Validator;
import android.speech.tts.TextToSpeech;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
@@ -106,7 +84,6 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.URISyntaxException;
-import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
@@ -3120,30 +3097,6 @@
@Deprecated
public static final String STAY_ON_WHILE_PLUGGED_IN = Global.STAY_ON_WHILE_PLUGGED_IN;
- private static final Validator STAY_ON_WHILE_PLUGGED_IN_VALIDATOR = new Validator() {
- @Override
- public boolean validate(String value) {
- try {
- int val = Integer.parseInt(value);
- return (val == 0)
- || (val == BatteryManager.BATTERY_PLUGGED_AC)
- || (val == BatteryManager.BATTERY_PLUGGED_USB)
- || (val == BatteryManager.BATTERY_PLUGGED_WIRELESS)
- || (val == (BatteryManager.BATTERY_PLUGGED_AC
- | BatteryManager.BATTERY_PLUGGED_USB))
- || (val == (BatteryManager.BATTERY_PLUGGED_AC
- | BatteryManager.BATTERY_PLUGGED_WIRELESS))
- || (val == (BatteryManager.BATTERY_PLUGGED_USB
- | BatteryManager.BATTERY_PLUGGED_WIRELESS))
- || (val == (BatteryManager.BATTERY_PLUGGED_AC
- | BatteryManager.BATTERY_PLUGGED_USB
- | BatteryManager.BATTERY_PLUGGED_WIRELESS));
- } catch (NumberFormatException e) {
- return false;
- }
- }
- };
-
/**
* What happens when the user presses the end call button if they're not
* on a call.<br/>
@@ -3156,9 +3109,6 @@
*/
public static final String END_BUTTON_BEHAVIOR = "end_button_behavior";
- private static final Validator END_BUTTON_BEHAVIOR_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 3);
-
/**
* END_BUTTON_BEHAVIOR value for "go home".
* @hide
@@ -3183,8 +3133,6 @@
*/
public static final String ADVANCED_SETTINGS = "advanced_settings";
- private static final Validator ADVANCED_SETTINGS_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* ADVANCED_SETTINGS default value.
* @hide
@@ -3285,8 +3233,6 @@
@Deprecated
public static final String WIFI_USE_STATIC_IP = "wifi_use_static_ip";
- private static final Validator WIFI_USE_STATIC_IP_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* The static IP address.
* <p>
@@ -3297,8 +3243,6 @@
@Deprecated
public static final String WIFI_STATIC_IP = "wifi_static_ip";
- private static final Validator WIFI_STATIC_IP_VALIDATOR = LENIENT_IP_ADDRESS_VALIDATOR;
-
/**
* If using static IP, the gateway's IP address.
* <p>
@@ -3309,8 +3253,6 @@
@Deprecated
public static final String WIFI_STATIC_GATEWAY = "wifi_static_gateway";
- private static final Validator WIFI_STATIC_GATEWAY_VALIDATOR = LENIENT_IP_ADDRESS_VALIDATOR;
-
/**
* If using static IP, the net mask.
* <p>
@@ -3321,8 +3263,6 @@
@Deprecated
public static final String WIFI_STATIC_NETMASK = "wifi_static_netmask";
- private static final Validator WIFI_STATIC_NETMASK_VALIDATOR = LENIENT_IP_ADDRESS_VALIDATOR;
-
/**
* If using static IP, the primary DNS's IP address.
* <p>
@@ -3333,8 +3273,6 @@
@Deprecated
public static final String WIFI_STATIC_DNS1 = "wifi_static_dns1";
- private static final Validator WIFI_STATIC_DNS1_VALIDATOR = LENIENT_IP_ADDRESS_VALIDATOR;
-
/**
* If using static IP, the secondary DNS's IP address.
* <p>
@@ -3345,8 +3283,6 @@
@Deprecated
public static final String WIFI_STATIC_DNS2 = "wifi_static_dns2";
- private static final Validator WIFI_STATIC_DNS2_VALIDATOR = LENIENT_IP_ADDRESS_VALIDATOR;
-
/**
* Determines whether remote devices may discover and/or connect to
* this device.
@@ -3358,9 +3294,6 @@
public static final String BLUETOOTH_DISCOVERABILITY =
"bluetooth_discoverability";
- private static final Validator BLUETOOTH_DISCOVERABILITY_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 2);
-
/**
* Bluetooth discoverability timeout. If this value is nonzero, then
* Bluetooth becomes discoverable for a certain number of seconds,
@@ -3369,9 +3302,6 @@
public static final String BLUETOOTH_DISCOVERABILITY_TIMEOUT =
"bluetooth_discoverability_timeout";
- private static final Validator BLUETOOTH_DISCOVERABILITY_TIMEOUT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Secure#LOCK_PATTERN_ENABLED}
* instead
@@ -3404,32 +3334,11 @@
@Deprecated
public static final String NEXT_ALARM_FORMATTED = "next_alarm_formatted";
- private static final Validator NEXT_ALARM_FORMATTED_VALIDATOR = new Validator() {
- private static final int MAX_LENGTH = 1000;
-
- @Override
- public boolean validate(String value) {
- // TODO: No idea what the correct format is.
- return value == null || value.length() < MAX_LENGTH;
- }
- };
-
/**
* Scaling factor for fonts, float.
*/
public static final String FONT_SCALE = "font_scale";
- private static final Validator FONT_SCALE_VALIDATOR = new Validator() {
- @Override
- public boolean validate(@Nullable String value) {
- try {
- return Float.parseFloat(value) >= 0;
- } catch (NumberFormatException | NullPointerException e) {
- return false;
- }
- }
- };
-
/**
* The serialized system locale value.
*
@@ -3466,34 +3375,12 @@
@Deprecated
public static final String DIM_SCREEN = "dim_screen";
- private static final Validator DIM_SCREEN_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* The display color mode.
* @hide
*/
public static final String DISPLAY_COLOR_MODE = "display_color_mode";
- private static final Validator DISPLAY_COLOR_MODE_VALIDATOR = new Validator() {
- @Override
- public boolean validate(@Nullable String value) {
- // Assume the actual validation that this device can properly handle this kind of
- // color mode further down in ColorDisplayManager / ColorDisplayService.
- try {
- final int setting = Integer.parseInt(value);
- final boolean isInFrameworkRange =
- setting >= ColorDisplayManager.COLOR_MODE_NATURAL
- && setting <= ColorDisplayManager.COLOR_MODE_AUTOMATIC;
- final boolean isInVendorRange =
- setting >= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MIN
- && setting <= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MAX;
- return isInFrameworkRange || isInVendorRange;
- } catch (NumberFormatException | NullPointerException e) {
- return false;
- }
- }
- };
-
/**
* The user selected min refresh rate in frames per second.
*
@@ -3510,9 +3397,6 @@
*/
public static final String PEAK_REFRESH_RATE = "peak_refresh_rate";
- private static final Validator PEAK_REFRESH_RATE_VALIDATOR =
- new InclusiveFloatRangeValidator(24f, Float.MAX_VALUE);
-
/**
* The amount of time in milliseconds before the device goes to sleep or begins
* to dream after a period of inactivity. This value is also known as the
@@ -3525,9 +3409,6 @@
*/
public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
- private static final Validator SCREEN_OFF_TIMEOUT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* The screen backlight brightness between 0 and 255.
*/
@@ -3539,16 +3420,11 @@
*/
public static final String SCREEN_BRIGHTNESS_FOR_VR = "screen_brightness_for_vr";
- private static final Validator SCREEN_BRIGHTNESS_FOR_VR_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 255);
-
/**
* Control whether to enable automatic brightness mode.
*/
public static final String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode";
- private static final Validator SCREEN_BRIGHTNESS_MODE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Adjustment to auto-brightness to make it generally more (>0.0 <1.0)
* or less (<0.0 >-1.0) bright.
@@ -3557,9 +3433,6 @@
@UnsupportedAppUsage
public static final String SCREEN_AUTO_BRIGHTNESS_ADJ = "screen_auto_brightness_adj";
- private static final Validator SCREEN_AUTO_BRIGHTNESS_ADJ_VALIDATOR =
- new InclusiveFloatRangeValidator(-1, 1);
-
/**
* SCREEN_BRIGHTNESS_MODE value for manual mode.
*/
@@ -3576,8 +3449,6 @@
*/
public static final String ADAPTIVE_SLEEP = "adaptive_sleep";
- private static final Validator ADAPTIVE_SLEEP_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Control whether the process CPU usage meter should be shown.
*
@@ -3604,9 +3475,6 @@
*/
public static final String MODE_RINGER_STREAMS_AFFECTED = "mode_ringer_streams_affected";
- private static final Validator MODE_RINGER_STREAMS_AFFECTED_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Determines which streams are affected by mute. The
* stream type's bit should be set to 1 if it should be muted when a mute request
@@ -3614,17 +3482,12 @@
*/
public static final String MUTE_STREAMS_AFFECTED = "mute_streams_affected";
- private static final Validator MUTE_STREAMS_AFFECTED_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Whether vibrate is on for different events. This is used internally,
* changing this value will not change the vibrate. See AudioManager.
*/
public static final String VIBRATE_ON = "vibrate_on";
- private static final Validator VIBRATE_ON_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* If 1, redirects the system vibrator to all currently attached input devices
* that support vibration. If there are no such input devices, then the system
@@ -3639,8 +3502,6 @@
*/
public static final String VIBRATE_INPUT_DEVICES = "vibrate_input_devices";
- private static final Validator VIBRATE_INPUT_DEVICES_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* The intensity of notification vibrations, if configurable.
*
@@ -3691,9 +3552,6 @@
public static final String HAPTIC_FEEDBACK_INTENSITY =
"haptic_feedback_intensity";
- private static final Validator VIBRATION_INTENSITY_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 3);
-
/**
* Ringer volume. This is used internally, changing this value will not
* change the volume. See AudioManager.
@@ -3772,8 +3630,6 @@
@UnsupportedAppUsage
public static final String MASTER_MONO = "master_mono";
- private static final Validator MASTER_MONO_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Master balance (float -1.f = 100% left, 0.f = dead center, 1.f = 100% right).
*
@@ -3781,9 +3637,6 @@
*/
public static final String MASTER_BALANCE = "master_balance";
- private static final Validator MASTER_BALANCE_VALIDATOR =
- new InclusiveFloatRangeValidator(-1.f, 1.f);
-
/**
* Whether the notifications should use the ring volume (value of 1) or
* a separate notification volume (value of 0). In most cases, users
@@ -3802,8 +3655,6 @@
public static final String NOTIFICATIONS_USE_RING_VOLUME =
"notifications_use_ring_volume";
- private static final Validator NOTIFICATIONS_USE_RING_VOLUME_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether silent mode should allow vibration feedback. This is used
* internally in AudioService and the Sound settings activity to
@@ -3819,8 +3670,6 @@
@UnsupportedAppUsage
public static final String VIBRATE_IN_SILENT = "vibrate_in_silent";
- private static final Validator VIBRATE_IN_SILENT_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* The mapping of stream type (integer) to its setting.
*
@@ -3867,8 +3716,6 @@
*/
public static final String RINGTONE = "ringtone";
- private static final Validator RINGTONE_VALIDATOR = URI_VALIDATOR;
-
/**
* A {@link Uri} that will point to the current default ringtone at any
* given time.
@@ -3892,8 +3739,6 @@
*/
public static final String NOTIFICATION_SOUND = "notification_sound";
- private static final Validator NOTIFICATION_SOUND_VALIDATOR = URI_VALIDATOR;
-
/**
* A {@link Uri} that will point to the current default notification
* sound at any given time.
@@ -3915,8 +3760,6 @@
*/
public static final String ALARM_ALERT = "alarm_alert";
- private static final Validator ALARM_ALERT_VALIDATOR = URI_VALIDATOR;
-
/**
* A {@link Uri} that will point to the current default alarm alert at
* any given time.
@@ -3937,42 +3780,30 @@
*/
public static final String MEDIA_BUTTON_RECEIVER = "media_button_receiver";
- private static final Validator MEDIA_BUTTON_RECEIVER_VALIDATOR = COMPONENT_NAME_VALIDATOR;
-
/**
* Setting to enable Auto Replace (AutoText) in text editors. 1 = On, 0 = Off
*/
public static final String TEXT_AUTO_REPLACE = "auto_replace";
- private static final Validator TEXT_AUTO_REPLACE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Setting to enable Auto Caps in text editors. 1 = On, 0 = Off
*/
public static final String TEXT_AUTO_CAPS = "auto_caps";
- private static final Validator TEXT_AUTO_CAPS_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Setting to enable Auto Punctuate in text editors. 1 = On, 0 = Off. This
* feature converts two spaces to a "." and space.
*/
public static final String TEXT_AUTO_PUNCTUATE = "auto_punctuate";
- private static final Validator TEXT_AUTO_PUNCTUATE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Setting to showing password characters in text editors. 1 = On, 0 = Off
*/
public static final String TEXT_SHOW_PASSWORD = "show_password";
- private static final Validator TEXT_SHOW_PASSWORD_VALIDATOR = BOOLEAN_VALIDATOR;
-
public static final String SHOW_GTALK_SERVICE_STATUS =
"SHOW_GTALK_SERVICE_STATUS";
- private static final Validator SHOW_GTALK_SERVICE_STATUS_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Name of activity to use for wallpaper on the home screen.
*
@@ -3981,18 +3812,6 @@
@Deprecated
public static final String WALLPAPER_ACTIVITY = "wallpaper_activity";
- private static final Validator WALLPAPER_ACTIVITY_VALIDATOR = new Validator() {
- private static final int MAX_LENGTH = 1000;
-
- @Override
- public boolean validate(String value) {
- if (value != null && value.length() > MAX_LENGTH) {
- return false;
- }
- return ComponentName.unflattenFromString(value) != null;
- }
- };
-
/**
* @deprecated Use {@link android.provider.Settings.Global#AUTO_TIME}
* instead
@@ -4000,8 +3819,6 @@
@Deprecated
public static final String AUTO_TIME = Global.AUTO_TIME;
- private static final Validator AUTO_TIME_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#AUTO_TIME_ZONE}
* instead
@@ -4009,8 +3826,6 @@
@Deprecated
public static final String AUTO_TIME_ZONE = Global.AUTO_TIME_ZONE;
- private static final Validator AUTO_TIME_ZONE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Display times as 12 or 24 hours
* 12
@@ -4018,10 +3833,6 @@
*/
public static final String TIME_12_24 = "time_12_24";
- /** @hide */
- public static final Validator TIME_12_24_VALIDATOR =
- new DiscreteValueValidator(new String[] {"12", "24", null});
-
/**
* Date format string
* mm/dd/yyyy
@@ -4030,19 +3841,6 @@
*/
public static final String DATE_FORMAT = "date_format";
- /** @hide */
- public static final Validator DATE_FORMAT_VALIDATOR = new Validator() {
- @Override
- public boolean validate(@Nullable String value) {
- try {
- new SimpleDateFormat(value);
- return true;
- } catch (IllegalArgumentException | NullPointerException e) {
- return false;
- }
- }
- };
-
/**
* Whether the setup wizard has been run before (on first boot), or if
* it still needs to be run.
@@ -4052,9 +3850,6 @@
*/
public static final String SETUP_WIZARD_HAS_RUN = "setup_wizard_has_run";
- /** @hide */
- public static final Validator SETUP_WIZARD_HAS_RUN_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Scaling factor for normal window animations. Setting to 0 will disable window
* animations.
@@ -4091,9 +3886,6 @@
*/
public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
- /** @hide */
- public static final Validator ACCELEROMETER_ROTATION_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Default screen rotation when no other policy applies.
* When {@link #ACCELEROMETER_ROTATION} is zero and no on-screen Activity expresses a
@@ -4104,10 +3896,6 @@
*/
public static final String USER_ROTATION = "user_rotation";
- /** @hide */
- public static final Validator USER_ROTATION_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 3);
-
/**
* Control whether the rotation lock toggle in the System UI should be hidden.
* Typically this is done for accessibility purposes to make it harder for
@@ -4123,10 +3911,6 @@
public static final String HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY =
"hide_rotation_lock_toggle_for_accessibility";
- /** @hide */
- public static final Validator HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether the phone vibrates when it is ringing due to an incoming call. This will
* be used by Phone and Setting apps; it shouldn't affect other apps.
@@ -4139,9 +3923,6 @@
*/
public static final String VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
- /** @hide */
- public static final Validator VIBRATE_WHEN_RINGING_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* When {@code 1}, Telecom enhanced call blocking functionality is enabled. When
* {@code 0}, enhanced call blocking functionality is disabled.
@@ -4156,9 +3937,6 @@
*/
public static final String DTMF_TONE_WHEN_DIALING = "dtmf_tone";
- /** @hide */
- public static final Validator DTMF_TONE_WHEN_DIALING_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* CDMA only settings
* DTMF tone type played by the dialer when dialing.
@@ -4167,9 +3945,6 @@
*/
public static final String DTMF_TONE_TYPE_WHEN_DIALING = "dtmf_tone_type";
- /** @hide */
- public static final Validator DTMF_TONE_TYPE_WHEN_DIALING_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the hearing aid is enabled. The value is
* boolean (1 or 0).
@@ -4178,9 +3953,6 @@
@UnsupportedAppUsage
public static final String HEARING_AID = "hearing_aid";
- /** @hide */
- public static final Validator HEARING_AID_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* CDMA only settings
* TTY Mode
@@ -4193,28 +3965,18 @@
@UnsupportedAppUsage
public static final String TTY_MODE = "tty_mode";
- /** @hide */
- public static final Validator TTY_MODE_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 3);
-
/**
* Whether the sounds effects (key clicks, lid open ...) are enabled. The value is
* boolean (1 or 0).
*/
public static final String SOUND_EFFECTS_ENABLED = "sound_effects_enabled";
- /** @hide */
- public static final Validator SOUND_EFFECTS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether haptic feedback (Vibrate on tap) is enabled. The value is
* boolean (1 or 0).
*/
public static final String HAPTIC_FEEDBACK_ENABLED = "haptic_feedback_enabled";
- /** @hide */
- public static final Validator HAPTIC_FEEDBACK_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Each application that shows web suggestions should have its own
* setting for this.
@@ -4222,9 +3984,6 @@
@Deprecated
public static final String SHOW_WEB_SUGGESTIONS = "show_web_suggestions";
- /** @hide */
- public static final Validator SHOW_WEB_SUGGESTIONS_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the notification LED should repeatedly flash when a notification is
* pending. The value is boolean (1 or 0).
@@ -4233,9 +3992,6 @@
@UnsupportedAppUsage
public static final String NOTIFICATION_LIGHT_PULSE = "notification_light_pulse";
- /** @hide */
- public static final Validator NOTIFICATION_LIGHT_PULSE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Show pointer location on screen?
* 0 = no
@@ -4245,9 +4001,6 @@
@UnsupportedAppUsage
public static final String POINTER_LOCATION = "pointer_location";
- /** @hide */
- public static final Validator POINTER_LOCATION_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Show touch positions on screen?
* 0 = no
@@ -4257,9 +4010,6 @@
@UnsupportedAppUsage
public static final String SHOW_TOUCHES = "show_touches";
- /** @hide */
- public static final Validator SHOW_TOUCHES_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Log raw orientation data from
* {@link com.android.server.policy.WindowOrientationListener} for use with the
@@ -4271,9 +4021,6 @@
public static final String WINDOW_ORIENTATION_LISTENER_LOG =
"window_orientation_listener_log";
- /** @hide */
- public static final Validator WINDOW_ORIENTATION_LISTENER_LOG_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#POWER_SOUNDS_ENABLED}
* instead
@@ -4282,8 +4029,6 @@
@Deprecated
public static final String POWER_SOUNDS_ENABLED = Global.POWER_SOUNDS_ENABLED;
- private static final Validator POWER_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#DOCK_SOUNDS_ENABLED}
* instead
@@ -4293,8 +4038,6 @@
@UnsupportedAppUsage
public static final String DOCK_SOUNDS_ENABLED = Global.DOCK_SOUNDS_ENABLED;
- private static final Validator DOCK_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether to play sounds when the keyguard is shown and dismissed.
* @hide
@@ -4302,18 +4045,12 @@
@UnsupportedAppUsage
public static final String LOCKSCREEN_SOUNDS_ENABLED = "lockscreen_sounds_enabled";
- /** @hide */
- public static final Validator LOCKSCREEN_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the lockscreen should be completely disabled.
* @hide
*/
public static final String LOCKSCREEN_DISABLED = "lockscreen.disabled";
- /** @hide */
- public static final Validator LOCKSCREEN_DISABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#LOW_BATTERY_SOUND}
* instead
@@ -4384,9 +4121,6 @@
*/
public static final String SIP_RECEIVE_CALLS = "sip_receive_calls";
- /** @hide */
- public static final Validator SIP_RECEIVE_CALLS_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Call Preference String.
* "SIP_ALWAYS" : Always use SIP with network access
@@ -4395,29 +4129,18 @@
*/
public static final String SIP_CALL_OPTIONS = "sip_call_options";
- /** @hide */
- public static final Validator SIP_CALL_OPTIONS_VALIDATOR =
- new DiscreteValueValidator(
- new String[] {"SIP_ALWAYS", "SIP_ADDRESS_ONLY"});
-
/**
* One of the sip call options: Always use SIP with network access.
* @hide
*/
public static final String SIP_ALWAYS = "SIP_ALWAYS";
- /** @hide */
- public static final Validator SIP_ALWAYS_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* One of the sip call options: Only if destination is a SIP address.
* @hide
*/
public static final String SIP_ADDRESS_ONLY = "SIP_ADDRESS_ONLY";
- /** @hide */
- public static final Validator SIP_ADDRESS_ONLY_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use SIP_ALWAYS or SIP_ADDRESS_ONLY instead. Formerly used to indicate that
* the user should be prompted each time a call is made whether it should be placed using
@@ -4428,9 +4151,6 @@
@Deprecated
public static final String SIP_ASK_ME_EACH_TIME = "SIP_ASK_ME_EACH_TIME";
- /** @hide */
- public static final Validator SIP_ASK_ME_EACH_TIME_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Pointer speed setting.
* This is an integer value in a range between -7 and +7, so there are 15 possible values.
@@ -4442,19 +4162,12 @@
@UnsupportedAppUsage
public static final String POINTER_SPEED = "pointer_speed";
- /** @hide */
- public static final Validator POINTER_SPEED_VALIDATOR =
- new InclusiveFloatRangeValidator(-7, 7);
-
/**
* Whether lock-to-app will be triggered by long-press on recents.
* @hide
*/
public static final String LOCK_TO_APP_ENABLED = "lock_to_app_enabled";
- /** @hide */
- public static final Validator LOCK_TO_APP_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* I am the lolrus.
* <p>
@@ -4464,18 +4177,6 @@
*/
public static final String EGG_MODE = "egg_mode";
- /** @hide */
- public static final Validator EGG_MODE_VALIDATOR = new Validator() {
- @Override
- public boolean validate(@Nullable String value) {
- try {
- return Long.parseLong(value) >= 0;
- } catch (NumberFormatException e) {
- return false;
- }
- }
- };
-
/**
* Setting to determine whether or not to show the battery percentage in the status bar.
* 0 - Don't show percentage
@@ -4484,9 +4185,6 @@
*/
public static final String SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent";
- /** @hide */
- private static final Validator SHOW_BATTERY_PERCENT_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* IMPORTANT: If you add a new public settings you also have to add it to
* PUBLIC_SETTINGS below. If the new setting is hidden you have to add
@@ -4495,73 +4193,6 @@
*/
/**
- * Settings to backup. This is here so that it's in the same place as the settings
- * keys and easy to update.
- *
- * NOTE: Settings are backed up and restored in the order they appear
- * in this array. If you have one setting depending on another,
- * make sure that they are ordered appropriately.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static final String[] SETTINGS_TO_BACKUP = {
- STAY_ON_WHILE_PLUGGED_IN, // moved to global
- WIFI_USE_STATIC_IP,
- WIFI_STATIC_IP,
- WIFI_STATIC_GATEWAY,
- WIFI_STATIC_NETMASK,
- WIFI_STATIC_DNS1,
- WIFI_STATIC_DNS2,
- BLUETOOTH_DISCOVERABILITY,
- BLUETOOTH_DISCOVERABILITY_TIMEOUT,
- FONT_SCALE,
- DIM_SCREEN,
- SCREEN_OFF_TIMEOUT,
- SCREEN_BRIGHTNESS_MODE,
- SCREEN_AUTO_BRIGHTNESS_ADJ,
- SCREEN_BRIGHTNESS_FOR_VR,
- ADAPTIVE_SLEEP,
- VIBRATE_INPUT_DEVICES,
- MODE_RINGER_STREAMS_AFFECTED,
- TEXT_AUTO_REPLACE,
- TEXT_AUTO_CAPS,
- TEXT_AUTO_PUNCTUATE,
- TEXT_SHOW_PASSWORD,
- AUTO_TIME, // moved to global
- AUTO_TIME_ZONE, // moved to global
- TIME_12_24,
- DATE_FORMAT,
- DTMF_TONE_WHEN_DIALING,
- DTMF_TONE_TYPE_WHEN_DIALING,
- HEARING_AID,
- TTY_MODE,
- MASTER_MONO,
- MASTER_BALANCE,
- SOUND_EFFECTS_ENABLED,
- HAPTIC_FEEDBACK_ENABLED,
- POWER_SOUNDS_ENABLED, // moved to global
- DOCK_SOUNDS_ENABLED, // moved to global
- LOCKSCREEN_SOUNDS_ENABLED,
- SHOW_WEB_SUGGESTIONS,
- SIP_CALL_OPTIONS,
- SIP_RECEIVE_CALLS,
- POINTER_SPEED,
- VIBRATE_WHEN_RINGING,
- RINGTONE,
- LOCK_TO_APP_ENABLED,
- NOTIFICATION_SOUND,
- ACCELEROMETER_ROTATION,
- SHOW_BATTERY_PERCENT,
- NOTIFICATION_VIBRATION_INTENSITY,
- RING_VIBRATION_INTENSITY,
- HAPTIC_FEEDBACK_INTENSITY,
- DISPLAY_COLOR_MODE,
- ALARM_ALERT,
- NOTIFICATION_LIGHT_PULSE,
- };
-
- /**
* Keys we no longer back up under the current schema, but want to continue to
* process when restoring historical backup datasets.
*
@@ -4681,99 +4312,6 @@
}
/**
- * These are all public system settings
- *
- * All settings in {@link SETTINGS_TO_BACKUP} array *must* have a non-null validator,
- * otherwise they won't be restored.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
- static {
- VALIDATORS.put(STAY_ON_WHILE_PLUGGED_IN, STAY_ON_WHILE_PLUGGED_IN_VALIDATOR);
- VALIDATORS.put(END_BUTTON_BEHAVIOR, END_BUTTON_BEHAVIOR_VALIDATOR);
- VALIDATORS.put(WIFI_USE_STATIC_IP, WIFI_USE_STATIC_IP_VALIDATOR);
- VALIDATORS.put(BLUETOOTH_DISCOVERABILITY, BLUETOOTH_DISCOVERABILITY_VALIDATOR);
- VALIDATORS.put(BLUETOOTH_DISCOVERABILITY_TIMEOUT,
- BLUETOOTH_DISCOVERABILITY_TIMEOUT_VALIDATOR);
- VALIDATORS.put(NEXT_ALARM_FORMATTED, NEXT_ALARM_FORMATTED_VALIDATOR);
- VALIDATORS.put(FONT_SCALE, FONT_SCALE_VALIDATOR);
- VALIDATORS.put(DIM_SCREEN, DIM_SCREEN_VALIDATOR);
- VALIDATORS.put(DISPLAY_COLOR_MODE, DISPLAY_COLOR_MODE_VALIDATOR);
- VALIDATORS.put(SCREEN_OFF_TIMEOUT, SCREEN_OFF_TIMEOUT_VALIDATOR);
- VALIDATORS.put(SCREEN_BRIGHTNESS_FOR_VR, SCREEN_BRIGHTNESS_FOR_VR_VALIDATOR);
- VALIDATORS.put(SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_VALIDATOR);
- VALIDATORS.put(ADAPTIVE_SLEEP, ADAPTIVE_SLEEP_VALIDATOR);
- VALIDATORS.put(MODE_RINGER_STREAMS_AFFECTED, MODE_RINGER_STREAMS_AFFECTED_VALIDATOR);
- VALIDATORS.put(MUTE_STREAMS_AFFECTED, MUTE_STREAMS_AFFECTED_VALIDATOR);
- VALIDATORS.put(VIBRATE_ON, VIBRATE_ON_VALIDATOR);
- VALIDATORS.put(NOTIFICATION_VIBRATION_INTENSITY, VIBRATION_INTENSITY_VALIDATOR);
- VALIDATORS.put(RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_VALIDATOR);
- VALIDATORS.put(HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_VALIDATOR);
- VALIDATORS.put(RINGTONE, RINGTONE_VALIDATOR);
- VALIDATORS.put(NOTIFICATION_SOUND, NOTIFICATION_SOUND_VALIDATOR);
- VALIDATORS.put(ALARM_ALERT, ALARM_ALERT_VALIDATOR);
- VALIDATORS.put(TEXT_AUTO_REPLACE, TEXT_AUTO_REPLACE_VALIDATOR);
- VALIDATORS.put(TEXT_AUTO_CAPS, TEXT_AUTO_CAPS_VALIDATOR);
- VALIDATORS.put(TEXT_AUTO_PUNCTUATE, TEXT_AUTO_PUNCTUATE_VALIDATOR);
- VALIDATORS.put(TEXT_SHOW_PASSWORD, TEXT_SHOW_PASSWORD_VALIDATOR);
- VALIDATORS.put(AUTO_TIME, AUTO_TIME_VALIDATOR);
- VALIDATORS.put(AUTO_TIME_ZONE, AUTO_TIME_ZONE_VALIDATOR);
- VALIDATORS.put(SHOW_GTALK_SERVICE_STATUS, SHOW_GTALK_SERVICE_STATUS_VALIDATOR);
- VALIDATORS.put(WALLPAPER_ACTIVITY, WALLPAPER_ACTIVITY_VALIDATOR);
- VALIDATORS.put(TIME_12_24, TIME_12_24_VALIDATOR);
- VALIDATORS.put(DATE_FORMAT, DATE_FORMAT_VALIDATOR);
- VALIDATORS.put(SETUP_WIZARD_HAS_RUN, SETUP_WIZARD_HAS_RUN_VALIDATOR);
- VALIDATORS.put(ACCELEROMETER_ROTATION, ACCELEROMETER_ROTATION_VALIDATOR);
- VALIDATORS.put(USER_ROTATION, USER_ROTATION_VALIDATOR);
- VALIDATORS.put(DTMF_TONE_WHEN_DIALING, DTMF_TONE_WHEN_DIALING_VALIDATOR);
- VALIDATORS.put(SOUND_EFFECTS_ENABLED, SOUND_EFFECTS_ENABLED_VALIDATOR);
- VALIDATORS.put(HAPTIC_FEEDBACK_ENABLED, HAPTIC_FEEDBACK_ENABLED_VALIDATOR);
- VALIDATORS.put(POWER_SOUNDS_ENABLED, POWER_SOUNDS_ENABLED_VALIDATOR);
- VALIDATORS.put(DOCK_SOUNDS_ENABLED, DOCK_SOUNDS_ENABLED_VALIDATOR);
- VALIDATORS.put(SHOW_WEB_SUGGESTIONS, SHOW_WEB_SUGGESTIONS_VALIDATOR);
- VALIDATORS.put(WIFI_USE_STATIC_IP, WIFI_USE_STATIC_IP_VALIDATOR);
- VALIDATORS.put(END_BUTTON_BEHAVIOR, END_BUTTON_BEHAVIOR_VALIDATOR);
- VALIDATORS.put(ADVANCED_SETTINGS, ADVANCED_SETTINGS_VALIDATOR);
- VALIDATORS.put(SCREEN_AUTO_BRIGHTNESS_ADJ, SCREEN_AUTO_BRIGHTNESS_ADJ_VALIDATOR);
- VALIDATORS.put(VIBRATE_INPUT_DEVICES, VIBRATE_INPUT_DEVICES_VALIDATOR);
- VALIDATORS.put(MASTER_MONO, MASTER_MONO_VALIDATOR);
- VALIDATORS.put(MASTER_BALANCE, MASTER_BALANCE_VALIDATOR);
- VALIDATORS.put(NOTIFICATIONS_USE_RING_VOLUME, NOTIFICATIONS_USE_RING_VOLUME_VALIDATOR);
- VALIDATORS.put(VIBRATE_IN_SILENT, VIBRATE_IN_SILENT_VALIDATOR);
- VALIDATORS.put(MEDIA_BUTTON_RECEIVER, MEDIA_BUTTON_RECEIVER_VALIDATOR);
- VALIDATORS.put(HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY,
- HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY_VALIDATOR);
- VALIDATORS.put(VIBRATE_WHEN_RINGING, VIBRATE_WHEN_RINGING_VALIDATOR);
- VALIDATORS.put(DTMF_TONE_TYPE_WHEN_DIALING, DTMF_TONE_TYPE_WHEN_DIALING_VALIDATOR);
- VALIDATORS.put(HEARING_AID, HEARING_AID_VALIDATOR);
- VALIDATORS.put(TTY_MODE, TTY_MODE_VALIDATOR);
- VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, NOTIFICATION_LIGHT_PULSE_VALIDATOR);
- VALIDATORS.put(POINTER_LOCATION, POINTER_LOCATION_VALIDATOR);
- VALIDATORS.put(SHOW_TOUCHES, SHOW_TOUCHES_VALIDATOR);
- VALIDATORS.put(WINDOW_ORIENTATION_LISTENER_LOG,
- WINDOW_ORIENTATION_LISTENER_LOG_VALIDATOR);
- VALIDATORS.put(LOCKSCREEN_SOUNDS_ENABLED, LOCKSCREEN_SOUNDS_ENABLED_VALIDATOR);
- VALIDATORS.put(LOCKSCREEN_DISABLED, LOCKSCREEN_DISABLED_VALIDATOR);
- VALIDATORS.put(SIP_RECEIVE_CALLS, SIP_RECEIVE_CALLS_VALIDATOR);
- VALIDATORS.put(SIP_CALL_OPTIONS, SIP_CALL_OPTIONS_VALIDATOR);
- VALIDATORS.put(SIP_ALWAYS, SIP_ALWAYS_VALIDATOR);
- VALIDATORS.put(SIP_ADDRESS_ONLY, SIP_ADDRESS_ONLY_VALIDATOR);
- VALIDATORS.put(SIP_ASK_ME_EACH_TIME, SIP_ASK_ME_EACH_TIME_VALIDATOR);
- VALIDATORS.put(POINTER_SPEED, POINTER_SPEED_VALIDATOR);
- VALIDATORS.put(LOCK_TO_APP_ENABLED, LOCK_TO_APP_ENABLED_VALIDATOR);
- VALIDATORS.put(EGG_MODE, EGG_MODE_VALIDATOR);
- VALIDATORS.put(WIFI_STATIC_IP, WIFI_STATIC_IP_VALIDATOR);
- VALIDATORS.put(WIFI_STATIC_GATEWAY, WIFI_STATIC_GATEWAY_VALIDATOR);
- VALIDATORS.put(WIFI_STATIC_NETMASK, WIFI_STATIC_NETMASK_VALIDATOR);
- VALIDATORS.put(WIFI_STATIC_DNS1, WIFI_STATIC_DNS1_VALIDATOR);
- VALIDATORS.put(WIFI_STATIC_DNS2, WIFI_STATIC_DNS2_VALIDATOR);
- VALIDATORS.put(SHOW_BATTERY_PERCENT, SHOW_BATTERY_PERCENT_VALIDATOR);
- VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR);
- }
-
- /**
* These entries are considered common between the personal and the managed profile,
* since the managed profile doesn't get to change them.
*/
@@ -4859,8 +4397,6 @@
@Deprecated
public static final String BLUETOOTH_ON = Global.BLUETOOTH_ON;
- private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead
*/
@@ -4938,8 +4474,6 @@
@Deprecated
public static final String USB_MASS_STORAGE_ENABLED = Global.USB_MASS_STORAGE_ENABLED;
- private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#USE_GOOGLE_MAIL} instead
*/
@@ -4969,9 +4503,6 @@
public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON;
- private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use
* {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} instead
@@ -4980,9 +4511,6 @@
public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY =
Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY;
- private static final Validator WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#WIFI_NUM_OPEN_NETWORKS_KEPT}
* instead
@@ -4990,9 +4518,6 @@
@Deprecated
public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = Global.WIFI_NUM_OPEN_NETWORKS_KEPT;
- private static final Validator WIFI_NUM_OPEN_NETWORKS_KEPT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#WIFI_ON} instead
*/
@@ -5757,8 +5282,6 @@
@Deprecated
public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu";
- private static final Validator BUGREPORT_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#ADB_ENABLED} instead
*/
@@ -5776,8 +5299,6 @@
@Deprecated
public static final String ALLOW_MOCK_LOCATION = "mock_location";
- private static final Validator ALLOW_MOCK_LOCATION_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Setting to indicate that on device captions are enabled.
*
@@ -5786,8 +5307,6 @@
@SystemApi
public static final String ODI_CAPTIONS_ENABLED = "odi_captions_enabled";
- private static final Validator ODI_CAPTIONS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* On Android 8.0 (API level 26) and higher versions of the platform,
* a 64-bit number (expressed as a hexadecimal string), unique to
@@ -5833,8 +5352,6 @@
@Deprecated
public static final String BLUETOOTH_ON = Global.BLUETOOTH_ON;
- private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#DATA_ROAMING} instead
*/
@@ -5882,9 +5399,6 @@
@TestApi
public static final String AUTOFILL_SERVICE = "autofill_service";
- private static final Validator AUTOFILL_SERVICE_VALIDATOR =
- NULLABLE_COMPONENT_NAME_VALIDATOR;
-
/**
* Boolean indicating if Autofill supports field classification.
*
@@ -6098,8 +5612,6 @@
*/
public static final String SHOW_IME_WITH_HARD_KEYBOARD = "show_ime_with_hard_keyboard";
- private static final Validator SHOW_IME_WITH_HARD_KEYBOARD_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Host name and port for global http proxy. Uses ':' seperator for
* between host and port.
@@ -6367,9 +5879,6 @@
*/
public static final String LOCK_SCREEN_CUSTOM_CLOCK_FACE = "lock_screen_custom_clock_face";
- private static final Validator LOCK_SCREEN_CUSTOM_CLOCK_FACE_VALIDATOR =
- JSON_OBJECT_VALIDATOR;
-
/**
* Indicates which clock face to show on lock screen and AOD while docked.
* @hide
@@ -6435,8 +5944,6 @@
@Deprecated
public static final String USB_MASS_STORAGE_ENABLED = Global.USB_MASS_STORAGE_ENABLED;
- private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#USE_GOOGLE_MAIL} instead
*/
@@ -6448,8 +5955,6 @@
*/
public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled";
- private static final Validator ACCESSIBILITY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Setting specifying if the accessibility shortcut is enabled.
* @hide
@@ -6457,8 +5962,6 @@
public static final String ACCESSIBILITY_SHORTCUT_ENABLED =
"accessibility_shortcut_enabled";
- private static final Validator ACCESSIBILITY_SHORTCUT_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Setting specifying if the accessibility shortcut is enabled.
* @hide
@@ -6466,9 +5969,6 @@
public static final String ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN =
"accessibility_shortcut_on_lock_screen";
- private static final Validator ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Setting specifying if the accessibility shortcut dialog has been shown to this user.
* @hide
@@ -6476,9 +5976,6 @@
public static final String ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN =
"accessibility_shortcut_dialog_shown";
- private static final Validator ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Setting specifying the accessibility service to be toggled via the accessibility
* shortcut. Must be its flattened {@link ComponentName}.
@@ -6488,9 +5985,6 @@
public static final String ACCESSIBILITY_SHORTCUT_TARGET_SERVICE =
"accessibility_shortcut_target_service";
- private static final Validator ACCESSIBILITY_SHORTCUT_TARGET_SERVICE_VALIDATOR =
- NULLABLE_COMPONENT_NAME_VALIDATOR;
-
/**
* Setting specifying the accessibility service or feature to be toggled via the
* accessibility button in the navigation bar. This is either a flattened
@@ -6501,32 +5995,17 @@
public static final String ACCESSIBILITY_BUTTON_TARGET_COMPONENT =
"accessibility_button_target_component";
- private static final Validator ACCESSIBILITY_BUTTON_TARGET_COMPONENT_VALIDATOR =
- new Validator() {
- @Override
- public boolean validate(@Nullable String value) {
- // technically either ComponentName or class name, but there's proper value
- // validation at callsites, so allow any non-null string
- return value != null;
- }
- };
-
/**
* If touch exploration is enabled.
*/
public static final String TOUCH_EXPLORATION_ENABLED = "touch_exploration_enabled";
- private static final Validator TOUCH_EXPLORATION_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* List of the enabled accessibility providers.
*/
public static final String ENABLED_ACCESSIBILITY_SERVICES =
"enabled_accessibility_services";
- private static final Validator ENABLED_ACCESSIBILITY_SERVICES_VALIDATOR =
- new ComponentNameListValidator(":");
-
/**
* List of the accessibility services to which the user has granted
* permission to put the device into touch exploration mode.
@@ -6536,17 +6015,12 @@
public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES =
"touch_exploration_granted_accessibility_services";
- private static final Validator TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES_VALIDATOR =
- new ComponentNameListValidator(":");
-
/**
* Whether the Global Actions Panel is enabled.
* @hide
*/
public static final String GLOBAL_ACTIONS_PANEL_ENABLED = "global_actions_panel_enabled";
- private static final Validator GLOBAL_ACTIONS_PANEL_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the Global Actions Panel can be toggled on or off in Settings.
* @hide
@@ -6568,17 +6042,12 @@
@SystemApi
public static final String HUSH_GESTURE_USED = "hush_gesture_used";
- private static final Validator HUSH_GESTURE_USED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Number of times the user has manually clicked the ringer toggle
* @hide
*/
public static final String MANUAL_RINGER_TOGGLE_COUNT = "manual_ringer_toggle_count";
- private static final Validator MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Whether to play a sound for charging events.
* @hide
@@ -6600,8 +6069,6 @@
*/
public static final String ZEN_DURATION = "zen_duration";
- private static final Validator ZEN_DURATION_VALIDATOR = ANY_INTEGER_VALIDATOR;
-
/** @hide */ public static final int ZEN_DURATION_PROMPT = -1;
/** @hide */ public static final int ZEN_DURATION_FOREVER = 0;
@@ -6637,8 +6104,6 @@
*/
public static final String IN_CALL_NOTIFICATION_ENABLED = "in_call_notification_enabled";
- private static final Validator IN_CALL_NOTIFICATION_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Uri of the slice that's presented on the keyguard.
* Defaults to a slice with the date and next alarm.
@@ -6665,9 +6130,6 @@
public static final String ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED =
"high_text_contrast_enabled";
- private static final Validator ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Setting that specifies whether the display magnification is enabled via a system-wide
* triple tap gesture. Display magnifications allows the user to zoom in the display content
@@ -6680,9 +6142,6 @@
public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED =
"accessibility_display_magnification_enabled";
- private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Setting that specifies whether the display magnification is enabled via a shortcut
* affordance within the system's navigation area. Display magnifications allows the user to
@@ -6695,9 +6154,6 @@
public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED =
"accessibility_display_magnification_navbar_enabled";
- private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED_VALIDATOR
- = BOOLEAN_VALIDATOR;
-
/**
* Setting that specifies what the display magnification scale is.
* Display magnifications allows the user to zoom in the display
@@ -6711,9 +6167,6 @@
public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE =
"accessibility_display_magnification_scale";
- private static final Validator ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE_VALIDATOR =
- new InclusiveFloatRangeValidator(1.0f, Float.MAX_VALUE);
-
/**
* Unused mangnification setting
*
@@ -6766,9 +6219,6 @@
public static final String ACCESSIBILITY_CAPTIONING_ENABLED =
"accessibility_captioning_enabled";
- private static final Validator ACCESSIBILITY_CAPTIONING_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Setting that specifies the language for captions as a locale string,
* e.g. en_US.
@@ -6779,8 +6229,6 @@
public static final String ACCESSIBILITY_CAPTIONING_LOCALE =
"accessibility_captioning_locale";
- private static final Validator ACCESSIBILITY_CAPTIONING_LOCALE_VALIDATOR = LOCALE_VALIDATOR;
-
/**
* Integer property that specifies the preset style for captions, one
* of:
@@ -6795,10 +6243,6 @@
public static final String ACCESSIBILITY_CAPTIONING_PRESET =
"accessibility_captioning_preset";
- private static final Validator ACCESSIBILITY_CAPTIONING_PRESET_VALIDATOR =
- new DiscreteValueValidator(new String[]{"-1", "0", "1", "2",
- "3", "4"});
-
/**
* Integer property that specifes the background color for captions as a
* packed 32-bit color.
@@ -6809,9 +6253,6 @@
public static final String ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR =
"accessibility_captioning_background_color";
- private static final Validator ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR_VALIDATOR =
- ANY_INTEGER_VALIDATOR;
-
/**
* Integer property that specifes the foreground color for captions as a
* packed 32-bit color.
@@ -6822,9 +6263,6 @@
public static final String ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR =
"accessibility_captioning_foreground_color";
- private static final Validator ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR_VALIDATOR =
- ANY_INTEGER_VALIDATOR;
-
/**
* Integer property that specifes the edge type for captions, one of:
* <ul>
@@ -6839,9 +6277,6 @@
public static final String ACCESSIBILITY_CAPTIONING_EDGE_TYPE =
"accessibility_captioning_edge_type";
- private static final Validator ACCESSIBILITY_CAPTIONING_EDGE_TYPE_VALIDATOR =
- new DiscreteValueValidator(new String[]{"0", "1", "2"});
-
/**
* Integer property that specifes the edge color for captions as a
* packed 32-bit color.
@@ -6853,9 +6288,6 @@
public static final String ACCESSIBILITY_CAPTIONING_EDGE_COLOR =
"accessibility_captioning_edge_color";
- private static final Validator ACCESSIBILITY_CAPTIONING_EDGE_COLOR_VALIDATOR =
- ANY_INTEGER_VALIDATOR;
-
/**
* Integer property that specifes the window color for captions as a
* packed 32-bit color.
@@ -6866,9 +6298,6 @@
public static final String ACCESSIBILITY_CAPTIONING_WINDOW_COLOR =
"accessibility_captioning_window_color";
- private static final Validator ACCESSIBILITY_CAPTIONING_WINDOW_COLOR_VALIDATOR =
- ANY_INTEGER_VALIDATOR;
-
/**
* String property that specifies the typeface for captions, one of:
* <ul>
@@ -6885,10 +6314,6 @@
public static final String ACCESSIBILITY_CAPTIONING_TYPEFACE =
"accessibility_captioning_typeface";
- private static final Validator ACCESSIBILITY_CAPTIONING_TYPEFACE_VALIDATOR =
- new DiscreteValueValidator(new String[]{"DEFAULT",
- "MONOSPACE", "SANS_SERIF", "SERIF"});
-
/**
* Floating point property that specifies font scaling for captions.
*
@@ -6897,18 +6322,12 @@
public static final String ACCESSIBILITY_CAPTIONING_FONT_SCALE =
"accessibility_captioning_font_scale";
- private static final Validator ACCESSIBILITY_CAPTIONING_FONT_SCALE_VALIDATOR =
- new InclusiveFloatRangeValidator(0.5f, 2.0f);
-
/**
* Setting that specifies whether display color inversion is enabled.
*/
public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED =
"accessibility_display_inversion_enabled";
- private static final Validator ACCESSIBILITY_DISPLAY_INVERSION_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Setting that specifies whether display color space adjustment is
* enabled.
@@ -6919,9 +6338,6 @@
public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED =
"accessibility_display_daltonizer_enabled";
- private static final Validator ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Integer property that specifies the type of color space adjustment to
* perform. Valid values are defined in AccessibilityManager and Settings arrays.xml:
@@ -6938,10 +6354,6 @@
public static final String ACCESSIBILITY_DISPLAY_DALTONIZER =
"accessibility_display_daltonizer";
- private static final Validator ACCESSIBILITY_DISPLAY_DALTONIZER_VALIDATOR =
- new DiscreteValueValidator(
- new String[] {"-1", "0", "11", "12", "13"});
-
/**
* Setting that specifies whether automatic click when the mouse pointer stops moving is
* enabled.
@@ -6952,9 +6364,6 @@
public static final String ACCESSIBILITY_AUTOCLICK_ENABLED =
"accessibility_autoclick_enabled";
- private static final Validator ACCESSIBILITY_AUTOCLICK_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Integer setting specifying amount of time in ms the mouse pointer has to stay still
* before performing click when {@link #ACCESSIBILITY_AUTOCLICK_ENABLED} is set.
@@ -6965,9 +6374,6 @@
public static final String ACCESSIBILITY_AUTOCLICK_DELAY =
"accessibility_autoclick_delay";
- private static final Validator ACCESSIBILITY_AUTOCLICK_DELAY_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Whether or not larger size icons are used for the pointer of mouse/trackpad for
* accessibility.
@@ -6978,9 +6384,6 @@
public static final String ACCESSIBILITY_LARGE_POINTER_ICON =
"accessibility_large_pointer_icon";
- private static final Validator ACCESSIBILITY_LARGE_POINTER_ICON_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* The timeout for considering a press to be a long press in milliseconds.
* @hide
@@ -6988,9 +6391,6 @@
@UnsupportedAppUsage
public static final String LONG_PRESS_TIMEOUT = "long_press_timeout";
- private static final Validator LONG_PRESS_TIMEOUT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* The duration in milliseconds between the first tap's up event and the second tap's
* down event for an interaction to be considered part of the same multi-press.
@@ -7046,8 +6446,6 @@
*/
public static final String DISPLAY_DENSITY_FORCED = "display_density_forced";
- static final Validator DISPLAY_DENSITY_FORCED_VALIDATOR = NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Setting to always use the default text-to-speech settings regardless
* of the application settings.
@@ -7065,22 +6463,16 @@
*/
public static final String TTS_DEFAULT_RATE = "tts_default_rate";
- private static final Validator TTS_DEFAULT_RATE_VALIDATOR = NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Default text-to-speech engine pitch. 100 = 1x
*/
public static final String TTS_DEFAULT_PITCH = "tts_default_pitch";
- private static final Validator TTS_DEFAULT_PITCH_VALIDATOR = NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Default text-to-speech engine.
*/
public static final String TTS_DEFAULT_SYNTH = "tts_default_synth";
- private static final Validator TTS_DEFAULT_SYNTH_VALIDATOR = PACKAGE_NAME_VALIDATOR;
-
/**
* Default text-to-speech language.
*
@@ -7128,16 +6520,11 @@
*/
public static final String TTS_DEFAULT_LOCALE = "tts_default_locale";
- private static final Validator TTS_DEFAULT_LOCALE_VALIDATOR = TTS_LIST_VALIDATOR;
-
/**
* Space delimited list of plugin packages that are enabled.
*/
public static final String TTS_ENABLED_PLUGINS = "tts_enabled_plugins";
- private static final Validator TTS_ENABLED_PLUGINS_VALIDATOR =
- new PackageNameListValidator(" ");
-
/**
* @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON}
* instead.
@@ -7146,9 +6533,6 @@
public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON;
- private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY}
* instead.
@@ -7157,9 +6541,6 @@
public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY =
Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY;
- private static final Validator WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#WIFI_NUM_OPEN_NETWORKS_KEPT}
* instead.
@@ -7168,9 +6549,6 @@
public static final String WIFI_NUM_OPEN_NETWORKS_KEPT =
Global.WIFI_NUM_OPEN_NETWORKS_KEPT;
- private static final Validator WIFI_NUM_OPEN_NETWORKS_KEPT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Global#WIFI_ON}
* instead.
@@ -7329,9 +6707,6 @@
public static final String PREFERRED_TTY_MODE =
"preferred_tty_mode";
- private static final Validator PREFERRED_TTY_MODE_VALIDATOR =
- new DiscreteValueValidator(new String[]{"0", "1", "2", "3"});
-
/**
* Whether the enhanced voice privacy mode is enabled.
* 0 = normal voice privacy
@@ -7340,8 +6715,6 @@
*/
public static final String ENHANCED_VOICE_PRIVACY_ENABLED = "enhanced_voice_privacy_enabled";
- private static final Validator ENHANCED_VOICE_PRIVACY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the TTY mode mode is enabled.
* 0 = disabled
@@ -7350,8 +6723,6 @@
*/
public static final String TTY_MODE_ENABLED = "tty_mode_enabled";
- private static final Validator TTY_MODE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* User-selected RTT mode. When on, outgoing and incoming calls will be answered as RTT
* calls when supported by the device and carrier. Boolean value.
@@ -7360,8 +6731,6 @@
*/
public static final String RTT_CALLING_MODE = "rtt_calling_mode";
- private static final Validator RTT_CALLING_MODE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
/**
* Controls whether settings backup is enabled.
@@ -7539,32 +6908,24 @@
*/
public static final String MOUNT_PLAY_NOTIFICATION_SND = "mount_play_not_snd";
- private static final Validator MOUNT_PLAY_NOTIFICATION_SND_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether or not UMS auto-starts on UMS host detection. (0 = false, 1 = true)
* @hide
*/
public static final String MOUNT_UMS_AUTOSTART = "mount_ums_autostart";
- private static final Validator MOUNT_UMS_AUTOSTART_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether or not a notification is displayed on UMS host detection. (0 = false, 1 = true)
* @hide
*/
public static final String MOUNT_UMS_PROMPT = "mount_ums_prompt";
- private static final Validator MOUNT_UMS_PROMPT_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether or not a notification is displayed while UMS is enabled. (0 = false, 1 = true)
* @hide
*/
public static final String MOUNT_UMS_NOTIFY_ENABLED = "mount_ums_notify_enabled";
- private static final Validator MOUNT_UMS_NOTIFY_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* If nonzero, ANRs in invisible background processes bring up a dialog.
* Otherwise, the process will be silently killed.
@@ -7583,9 +6944,6 @@
public static final String SHOW_FIRST_CRASH_DIALOG_DEV_OPTION =
"show_first_crash_dialog_dev_option";
- private static final Validator SHOW_FIRST_CRASH_DIALOG_DEV_OPTION_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* The {@link ComponentName} string of the service to be used as the voice recognition
* service.
@@ -7644,9 +7002,6 @@
@UnsupportedAppUsage
public static final String INCALL_POWER_BUTTON_BEHAVIOR = "incall_power_button_behavior";
- private static final Validator INCALL_POWER_BUTTON_BEHAVIOR_VALIDATOR =
- new DiscreteValueValidator(new String[]{"1", "2"});
-
/**
* INCALL_POWER_BUTTON_BEHAVIOR value for "turn off screen".
* @hide
@@ -7702,8 +7057,6 @@
*/
public static final String WAKE_GESTURE_ENABLED = "wake_gesture_enabled";
- private static final Validator WAKE_GESTURE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the device should doze if configured.
* @hide
@@ -7711,8 +7064,6 @@
@UnsupportedAppUsage
public static final String DOZE_ENABLED = "doze_enabled";
- private static final Validator DOZE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Indicates whether doze should be always on.
* <p>
@@ -7724,16 +7075,12 @@
@TestApi
public static final String DOZE_ALWAYS_ON = "doze_always_on";
- private static final Validator DOZE_ALWAYS_ON_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the device should pulse on pick up gesture.
* @hide
*/
public static final String DOZE_PICK_UP_GESTURE = "doze_pulse_on_pick_up";
- private static final Validator DOZE_PICK_UP_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the device should pulse on long press gesture.
* @hide
@@ -7746,24 +7093,18 @@
*/
public static final String DOZE_DOUBLE_TAP_GESTURE = "doze_pulse_on_double_tap";
- private static final Validator DOZE_DOUBLE_TAP_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the device should respond to the SLPI tap gesture.
* @hide
*/
public static final String DOZE_TAP_SCREEN_GESTURE = "doze_tap_gesture";
- private static final Validator DOZE_TAP_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Gesture that wakes up the display, showing some version of the lock screen.
* @hide
*/
public static final String DOZE_WAKE_LOCK_SCREEN_GESTURE = "doze_wake_screen_gesture";
- private static final Validator DOZE_WAKE_LOCK_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Gesture that wakes up the display, toggling between {@link Display.STATE_OFF} and
* {@link Display.STATE_DOZE}.
@@ -7771,16 +7112,12 @@
*/
public static final String DOZE_WAKE_DISPLAY_GESTURE = "doze_wake_display_gesture";
- private static final Validator DOZE_WAKE_DISPLAY_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Gesture that skips media.
* @hide
*/
public static final String SKIP_GESTURE = "skip_gesture";
- private static final Validator SKIP_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Count of successful gestures.
* @hide
@@ -7793,9 +7130,6 @@
*/
public static final String SKIP_TOUCH_COUNT = "skip_touch_count";
- private static final Validator SKIP_GESTURE_COUNT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Direction to advance media for skip gesture
* @hide
@@ -7803,21 +7137,11 @@
public static final String SKIP_DIRECTION = "skip_gesture_direction";
/**
- * Only used if FeatureFlag "settings_skip_direction_mutable" is enabled.
- * If feature flag is disabled, should assume SKIP_DIRECTION = 0.
- * 0 / false = right to left to advance to next
- * 1 / true = left to right to advance to next
- */
- private static final Validator SKIP_DIRECTION_VALIDATOR = BOOLEAN_VALIDATOR;
-
- /**
* Gesture that silences sound (alarms, notification, calls).
* @hide
*/
public static final String SILENCE_GESTURE = "silence_gesture";
- private static final Validator SILENCE_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Count of successful silence alarms gestures.
* @hide
@@ -7854,9 +7178,6 @@
*/
public static final String SILENCE_CALL_TOUCH_COUNT = "silence_call_touch_count";
- private static final Validator SILENCE_GESTURE_COUNT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* The current night mode that has been selected by the user. Owned
* and controlled by UiModeManagerService. Constants are as per
@@ -7865,17 +7186,12 @@
*/
public static final String UI_NIGHT_MODE = "ui_night_mode";
- private static final Validator UI_NIGHT_MODE_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 2);
-
/**
* Whether screensavers are enabled.
* @hide
*/
public static final String SCREENSAVER_ENABLED = "screensaver_enabled";
- private static final Validator SCREENSAVER_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* The user's chosen screensaver components.
*
@@ -7885,9 +7201,6 @@
*/
public static final String SCREENSAVER_COMPONENTS = "screensaver_components";
- private static final Validator SCREENSAVER_COMPONENTS_VALIDATOR =
- new ComponentNameListValidator(",");
-
/**
* If screensavers are enabled, whether the screensaver should be automatically launched
* when the device is inserted into a (desk) dock.
@@ -7895,8 +7208,6 @@
*/
public static final String SCREENSAVER_ACTIVATE_ON_DOCK = "screensaver_activate_on_dock";
- private static final Validator SCREENSAVER_ACTIVATE_ON_DOCK_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* If screensavers are enabled, whether the screensaver should be automatically launched
* when the screen times out when not on battery.
@@ -7904,8 +7215,6 @@
*/
public static final String SCREENSAVER_ACTIVATE_ON_SLEEP = "screensaver_activate_on_sleep";
- private static final Validator SCREENSAVER_ACTIVATE_ON_SLEEP_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* If screensavers are enabled, the default screensaver component.
* @hide
@@ -7919,9 +7228,6 @@
@UnsupportedAppUsage
public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
- private static final Validator NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR =
- COMPONENT_NAME_VALIDATOR;
-
/**
* Whether NFC payment is handled by the foreground application or a default.
* @hide
@@ -8037,9 +7343,6 @@
public static final String ENABLED_NOTIFICATION_ASSISTANT =
"enabled_notification_assistant";
- private static final Validator ENABLED_NOTIFICATION_ASSISTANT_VALIDATOR =
- new ComponentNameListValidator(":");
-
/**
* Read only list of the service components that the current user has explicitly allowed to
* see all of the user's notifications, separated by ':'.
@@ -8052,9 +7355,6 @@
@UnsupportedAppUsage
public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
- private static final Validator ENABLED_NOTIFICATION_LISTENERS_VALIDATOR =
- new ComponentNameListValidator(":");
-
/**
* Read only list of the packages that the current user has explicitly allowed to
* manage do not disturb, separated by ':'.
@@ -8067,9 +7367,6 @@
public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES =
"enabled_notification_policy_access_packages";
- private static final Validator ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES_VALIDATOR =
- new PackageNameListValidator(":");
-
/**
* Defines whether managed profile ringtones should be synced from it's parent profile
* <p>
@@ -8083,8 +7380,6 @@
@RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
- private static final Validator SYNC_PARENT_SOUNDS_VALIDATOR = BOOLEAN_VALIDATOR;
-
/** @hide */
@UnsupportedAppUsage
public static final String IMMERSIVE_MODE_CONFIRMATIONS = "immersive_mode_confirmations";
@@ -8218,8 +7513,6 @@
*/
public static final String DOUBLE_TAP_TO_WAKE = "double_tap_to_wake";
- private static final Validator DOUBLE_TAP_TO_WAKE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* The current assistant component. It could be a voice interaction service,
* or an activity that handles ACTION_ASSIST, or empty which means using the default
@@ -8240,8 +7533,6 @@
*/
public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled";
- private static final Validator CAMERA_GESTURE_DISABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the camera launch gesture to double tap the power button when the screen is off
* should be disabled.
@@ -8251,9 +7542,6 @@
public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED =
"camera_double_tap_power_gesture_disabled";
- private static final Validator CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether the camera double twist gesture to flip between front and back mode should be
* enabled.
@@ -8263,9 +7551,6 @@
public static final String CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED =
"camera_double_twist_to_flip_enabled";
- private static final Validator CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether or not the smart camera lift trigger that launches the camera when the user moves
* the phone into a position for taking photos should be enabled.
@@ -8302,9 +7587,6 @@
*/
public static final String FACE_UNLOCK_KEYGUARD_ENABLED = "face_unlock_keyguard_enabled";
- private static final Validator FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether or not face unlock dismisses the keyguard.
* @hide
@@ -8312,9 +7594,6 @@
public static final String FACE_UNLOCK_DISMISSES_KEYGUARD =
"face_unlock_dismisses_keyguard";
- private static final Validator FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether or not media is shown automatically when bypassing as a heads up.
* @hide
@@ -8322,9 +7601,6 @@
public static final String SHOW_MEDIA_WHEN_BYPASSING =
"show_media_when_bypassing";
- private static final Validator SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether or not face unlock requires attention. This is a cached value, the source of
* truth is obtained through the HAL.
@@ -8348,9 +7624,6 @@
*/
public static final String FACE_UNLOCK_APP_ENABLED = "face_unlock_app_enabled";
- private static final Validator FACE_UNLOCK_APP_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether or not face unlock always requires user confirmation, meaning {@link
* android.hardware.biometrics.BiometricPrompt.Builder#setConfirmationRequired(boolean)}
@@ -8361,9 +7634,6 @@
public static final String FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION =
"face_unlock_always_require_confirmation";
- private static final Validator FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether or not debugging is enabled.
* @hide
@@ -8378,9 +7648,6 @@
*/
public static final String ASSIST_GESTURE_ENABLED = "assist_gesture_enabled";
- private static final Validator ASSIST_GESTURE_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Sensitivity control for the assist gesture.
*
@@ -8396,9 +7663,6 @@
public static final String ASSIST_GESTURE_SILENCE_ALERTS_ENABLED =
"assist_gesture_silence_alerts_enabled";
- private static final Validator ASSIST_GESTURE_SILENCE_ALERTS_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Whether the assist gesture should wake the phone.
*
@@ -8407,9 +7671,6 @@
public static final String ASSIST_GESTURE_WAKE_ENABLED =
"assist_gesture_wake_enabled";
- private static final Validator ASSIST_GESTURE_WAKE_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Indicates whether the Assist Gesture Deferred Setup has been completed.
* <p>
@@ -8426,18 +7687,12 @@
*/
public static final String TRUST_AGENTS_EXTEND_UNLOCK = "trust_agents_extend_unlock";
- private static final Validator TRUST_AGENTS_EXTEND_UNLOCK_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Control whether the screen locks when trust is lost.
* @hide
*/
public static final String LOCK_SCREEN_WHEN_TRUST_LOST = "lock_screen_when_trust_lost";
- private static final Validator LOCK_SCREEN_WHEN_TRUST_LOST_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Control whether Night display is currently activated.
* @hide
@@ -8450,9 +7705,6 @@
*/
public static final String NIGHT_DISPLAY_AUTO_MODE = "night_display_auto_mode";
- private static final Validator NIGHT_DISPLAY_AUTO_MODE_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 2);
-
/**
* Control the color temperature of Night Display, represented in Kelvin.
* @hide
@@ -8460,9 +7712,6 @@
public static final String NIGHT_DISPLAY_COLOR_TEMPERATURE =
"night_display_color_temperature";
- private static final Validator NIGHT_DISPLAY_COLOR_TEMPERATURE_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Custom time when Night display is scheduled to activate.
* Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
@@ -8471,9 +7720,6 @@
public static final String NIGHT_DISPLAY_CUSTOM_START_TIME =
"night_display_custom_start_time";
- private static final Validator NIGHT_DISPLAY_CUSTOM_START_TIME_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Custom time when Night display is scheduled to deactivate.
* Represented as milliseconds from midnight (e.g. 21600000 == 6am).
@@ -8481,9 +7727,6 @@
*/
public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time";
- private static final Validator NIGHT_DISPLAY_CUSTOM_END_TIME_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* A String representing the LocalDateTime when Night display was last activated. Use to
* decide whether to apply the current activated state after a reboot or user change. In
@@ -8499,9 +7742,6 @@
*/
public static final String DISPLAY_WHITE_BALANCE_ENABLED = "display_white_balance_enabled";
- private static final Validator DISPLAY_WHITE_BALANCE_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Names of the service components that the current user has explicitly allowed to
* be a VR mode listener, separated by ':'.
@@ -8511,9 +7751,6 @@
@TestApi
public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners";
- private static final Validator ENABLED_VR_LISTENERS_VALIDATOR =
- new ComponentNameListValidator(":");
-
/**
* Behavior of the display while in VR mode.
*
@@ -8523,9 +7760,6 @@
*/
public static final String VR_DISPLAY_MODE = "vr_display_mode";
- private static final Validator VR_DISPLAY_MODE_VALIDATOR =
- new DiscreteValueValidator(new String[]{"0", "1"});
-
/**
* Lower the display persistence while the system is in VR mode.
*
@@ -8590,9 +7824,6 @@
public static final String AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN =
"automatic_storage_manager_days_to_retain";
- private static final Validator AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Default number of days of information for the automatic storage manager to retain.
*
@@ -8608,7 +7839,6 @@
public static final String AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED =
"automatic_storage_manager_bytes_cleared";
-
/**
* Last run time for the automatic storage manager.
*
@@ -8616,7 +7846,6 @@
*/
public static final String AUTOMATIC_STORAGE_MANAGER_LAST_RUN =
"automatic_storage_manager_last_run";
-
/**
* If the automatic storage manager has been disabled by policy. Note that this doesn't
* mean that the automatic storage manager is prevented from being re-enabled -- this only
@@ -8634,8 +7863,6 @@
public static final String SYSTEM_NAVIGATION_KEYS_ENABLED =
"system_navigation_keys_enabled";
- private static final Validator SYSTEM_NAVIGATION_KEYS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Holds comma separated list of ordering of QS tiles.
*
@@ -8643,8 +7870,6 @@
*/
public static final String QS_TILES = "sysui_qs_tiles";
- private static final Validator QS_TILES_VALIDATOR = TILE_LIST_VALIDATOR;
-
/**
* Specifies whether the web action API is enabled.
*
@@ -8681,8 +7906,6 @@
@TestApi
public static final String NOTIFICATION_BADGING = "notification_badging";
- private static final Validator NOTIFICATION_BADGING_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether the notification bubbles are globally enabled
* The value is boolean (1 or 0).
@@ -8691,8 +7914,6 @@
@TestApi
public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
- private static final Validator NOTIFICATION_BUBBLES_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether notifications are dismissed by a right-to-left swipe (instead of a left-to-right
* swipe).
@@ -8701,24 +7922,18 @@
*/
public static final String NOTIFICATION_DISMISS_RTL = "notification_dismiss_rtl";
- private static final Validator NOTIFICATION_DISMISS_RTL_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Comma separated list of QS tiles that have been auto-added already.
* @hide
*/
public static final String QS_AUTO_ADDED_TILES = "qs_auto_tiles";
- private static final Validator QS_AUTO_ADDED_TILES_VALIDATOR = TILE_LIST_VALIDATOR;
-
/**
* Whether the Lockdown button should be shown in the power menu.
* @hide
*/
public static final String LOCKDOWN_IN_POWER_MENU = "lockdown_in_power_menu";
- private static final Validator LOCKDOWN_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Backup manager behavioral parameters.
* This is encoded as a key=value list, separated by commas. Ex:
@@ -8790,9 +8005,6 @@
@SystemApi
public static final int VOLUME_HUSH_MUTE = 2;
- private static final Validator VOLUME_HUSH_GESTURE_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* The number of times (integer) the user has manually enabled battery saver.
* @hide
@@ -8869,9 +8081,6 @@
public static final String THEME_CUSTOMIZATION_OVERLAY_PACKAGES =
"theme_customization_overlay_packages";
- private static final Validator THEME_CUSTOMIZATION_OVERLAY_PACKAGES_VALIDATOR =
- JSON_OBJECT_VALIDATOR;
-
/**
* Navigation bar mode.
* 0 = 3 button
@@ -8881,8 +8090,6 @@
*/
public static final String NAVIGATION_MODE =
"navigation_mode";
- private static final Validator NAVIGATION_MODE_VALIDATOR =
- new DiscreteValueValidator(new String[] {"0", "1", "2"});
/**
* Controls whether aware is enabled.
@@ -8890,162 +8097,12 @@
*/
public static final String AWARE_ENABLED = "aware_enabled";
- private static final Validator AWARE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Controls whether aware_lock is enabled.
* @hide
*/
public static final String AWARE_LOCK_ENABLED = "aware_lock_enabled";
- private static final Validator AWARE_LOCK_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
- /**
- * This are the settings to be backed up.
- *
- * NOTE: Settings are backed up and restored in the order they appear
- * in this array. If you have one setting depending on another,
- * make sure that they are ordered appropriately.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static final String[] SETTINGS_TO_BACKUP = {
- BUGREPORT_IN_POWER_MENU, // moved to global
- ALLOW_MOCK_LOCATION,
- USB_MASS_STORAGE_ENABLED, // moved to global
- ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
- ACCESSIBILITY_DISPLAY_DALTONIZER,
- ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
- ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
- ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
- AUTOFILL_SERVICE,
- ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
- ENABLED_ACCESSIBILITY_SERVICES,
- ENABLED_VR_LISTENERS,
- TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
- TOUCH_EXPLORATION_ENABLED,
- ACCESSIBILITY_ENABLED,
- ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
- ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
- ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- ACCESSIBILITY_SHORTCUT_ENABLED,
- ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
- ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
- ACCESSIBILITY_CAPTIONING_PRESET,
- ACCESSIBILITY_CAPTIONING_ENABLED,
- ACCESSIBILITY_CAPTIONING_LOCALE,
- ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
- ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
- ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
- ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
- ACCESSIBILITY_CAPTIONING_TYPEFACE,
- ACCESSIBILITY_CAPTIONING_FONT_SCALE,
- ACCESSIBILITY_CAPTIONING_WINDOW_COLOR,
- TTS_DEFAULT_RATE,
- TTS_DEFAULT_PITCH,
- TTS_DEFAULT_SYNTH,
- TTS_ENABLED_PLUGINS,
- TTS_DEFAULT_LOCALE,
- SHOW_IME_WITH_HARD_KEYBOARD,
- WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, // moved to global
- WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, // moved to global
- WIFI_NUM_OPEN_NETWORKS_KEPT, // moved to global
- MOUNT_PLAY_NOTIFICATION_SND,
- MOUNT_UMS_AUTOSTART,
- MOUNT_UMS_PROMPT,
- MOUNT_UMS_NOTIFY_ENABLED,
- DOUBLE_TAP_TO_WAKE,
- WAKE_GESTURE_ENABLED,
- LONG_PRESS_TIMEOUT,
- CAMERA_GESTURE_DISABLED,
- ACCESSIBILITY_AUTOCLICK_ENABLED,
- ACCESSIBILITY_AUTOCLICK_DELAY,
- ACCESSIBILITY_LARGE_POINTER_ICON,
- PREFERRED_TTY_MODE,
- ENHANCED_VOICE_PRIVACY_ENABLED,
- TTY_MODE_ENABLED,
- RTT_CALLING_MODE,
- INCALL_POWER_BUTTON_BEHAVIOR,
- NIGHT_DISPLAY_CUSTOM_START_TIME,
- NIGHT_DISPLAY_CUSTOM_END_TIME,
- NIGHT_DISPLAY_COLOR_TEMPERATURE,
- NIGHT_DISPLAY_AUTO_MODE,
- DISPLAY_WHITE_BALANCE_ENABLED,
- SYNC_PARENT_SOUNDS,
- CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
- CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
- SYSTEM_NAVIGATION_KEYS_ENABLED,
- QS_TILES,
- DOZE_ENABLED,
- DOZE_ALWAYS_ON,
- DOZE_PICK_UP_GESTURE,
- DOZE_DOUBLE_TAP_GESTURE,
- DOZE_TAP_SCREEN_GESTURE,
- DOZE_WAKE_LOCK_SCREEN_GESTURE,
- DOZE_WAKE_DISPLAY_GESTURE,
- NFC_PAYMENT_DEFAULT_COMPONENT,
- AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
- FACE_UNLOCK_KEYGUARD_ENABLED,
- SHOW_MEDIA_WHEN_BYPASSING,
- FACE_UNLOCK_DISMISSES_KEYGUARD,
- FACE_UNLOCK_APP_ENABLED,
- FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
- ASSIST_GESTURE_ENABLED,
- ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
- ASSIST_GESTURE_WAKE_ENABLED,
- VR_DISPLAY_MODE,
- NOTIFICATION_BADGING,
- NOTIFICATION_BUBBLES,
- NOTIFICATION_DISMISS_RTL,
- QS_AUTO_ADDED_TILES,
- SCREENSAVER_ENABLED,
- SCREENSAVER_COMPONENTS,
- SCREENSAVER_ACTIVATE_ON_DOCK,
- SCREENSAVER_ACTIVATE_ON_SLEEP,
- LOCKDOWN_IN_POWER_MENU,
- SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
- VOLUME_HUSH_GESTURE,
- MANUAL_RINGER_TOGGLE_COUNT,
- HUSH_GESTURE_USED,
- IN_CALL_NOTIFICATION_ENABLED,
- LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- LOCK_SCREEN_CUSTOM_CLOCK_FACE,
- LOCK_SCREEN_SHOW_NOTIFICATIONS,
- LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
- SHOW_NOTIFICATION_SNOOZE,
- ZEN_DURATION,
- SHOW_ZEN_UPGRADE_NOTIFICATION,
- SHOW_ZEN_SETTINGS_SUGGESTION,
- ZEN_SETTINGS_UPDATED,
- ZEN_SETTINGS_SUGGESTION_VIEWED,
- CHARGING_SOUNDS_ENABLED,
- CHARGING_VIBRATION_ENABLED,
- ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS,
- ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS,
- NOTIFICATION_NEW_INTERRUPTION_MODEL,
- TRUST_AGENTS_EXTEND_UNLOCK,
- UI_NIGHT_MODE,
- LOCK_SCREEN_WHEN_TRUST_LOST,
- SKIP_GESTURE,
- SKIP_DIRECTION,
- SILENCE_GESTURE,
- THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
- NAVIGATION_MODE,
- AWARE_ENABLED,
- SKIP_GESTURE_COUNT,
- SKIP_TOUCH_COUNT,
- SILENCE_ALARMS_GESTURE_COUNT,
- SILENCE_CALL_GESTURE_COUNT,
- SILENCE_TIMER_GESTURE_COUNT,
- SILENCE_ALARMS_TOUCH_COUNT,
- SILENCE_CALL_TOUCH_COUNT,
- SILENCE_TIMER_TOUCH_COUNT,
- DARK_MODE_DIALOG_SEEN,
- GLOBAL_ACTIONS_PANEL_ENABLED,
- AWARE_LOCK_ENABLED
- };
-
/**
* The settings values which should only be restored if the target device is the
* same as the source device
@@ -9061,201 +8118,6 @@
};
/**
- * All settings in {@link SETTINGS_TO_BACKUP} and {@link DEVICE_SPECIFIC_SETTINGS_TO_BACKUP}
- * array *must* have a non-null validator, otherwise they won't be restored.
- *
- * @hide
- */
- public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
- static {
- VALIDATORS.put(BUGREPORT_IN_POWER_MENU, BUGREPORT_IN_POWER_MENU_VALIDATOR);
- VALIDATORS.put(ALLOW_MOCK_LOCATION, ALLOW_MOCK_LOCATION_VALIDATOR);
- VALIDATORS.put(USB_MASS_STORAGE_ENABLED, USB_MASS_STORAGE_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
- ACCESSIBILITY_DISPLAY_INVERSION_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_DISPLAY_DALTONIZER,
- ACCESSIBILITY_DISPLAY_DALTONIZER_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
- ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
- ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
- ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED_VALIDATOR);
- VALIDATORS.put(AUTOFILL_SERVICE, AUTOFILL_SERVICE_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
- ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE_VALIDATOR);
- VALIDATORS.put(ENABLED_ACCESSIBILITY_SERVICES,
- ENABLED_ACCESSIBILITY_SERVICES_VALIDATOR);
- VALIDATORS.put(ENABLED_VR_LISTENERS, ENABLED_VR_LISTENERS_VALIDATOR);
- VALIDATORS.put(TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
- TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES_VALIDATOR);
- VALIDATORS.put(TOUCH_EXPLORATION_ENABLED, TOUCH_EXPLORATION_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_ENABLED, ACCESSIBILITY_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
- ACCESSIBILITY_SHORTCUT_TARGET_SERVICE_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
- ACCESSIBILITY_BUTTON_TARGET_COMPONENT_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_SHORTCUT_ENABLED,
- ACCESSIBILITY_SHORTCUT_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
- ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
- ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_PRESET,
- ACCESSIBILITY_CAPTIONING_PRESET_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_ENABLED,
- ACCESSIBILITY_CAPTIONING_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_LOCALE,
- ACCESSIBILITY_CAPTIONING_LOCALE_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
- ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
- ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
- ACCESSIBILITY_CAPTIONING_EDGE_TYPE_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
- ACCESSIBILITY_CAPTIONING_EDGE_COLOR_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_TYPEFACE,
- ACCESSIBILITY_CAPTIONING_TYPEFACE_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_FONT_SCALE,
- ACCESSIBILITY_CAPTIONING_FONT_SCALE_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_CAPTIONING_WINDOW_COLOR,
- ACCESSIBILITY_CAPTIONING_WINDOW_COLOR_VALIDATOR);
- VALIDATORS.put(TTS_DEFAULT_RATE, TTS_DEFAULT_RATE_VALIDATOR);
- VALIDATORS.put(TTS_DEFAULT_PITCH, TTS_DEFAULT_PITCH_VALIDATOR);
- VALIDATORS.put(TTS_DEFAULT_SYNTH, TTS_DEFAULT_SYNTH_VALIDATOR);
- VALIDATORS.put(TTS_ENABLED_PLUGINS, TTS_ENABLED_PLUGINS_VALIDATOR);
- VALIDATORS.put(TTS_DEFAULT_LOCALE, TTS_DEFAULT_LOCALE_VALIDATOR);
- VALIDATORS.put(SHOW_IME_WITH_HARD_KEYBOARD, SHOW_IME_WITH_HARD_KEYBOARD_VALIDATOR);
- VALIDATORS.put(WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
- WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR);
- VALIDATORS.put(WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
- WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_VALIDATOR);
- VALIDATORS.put(WIFI_NUM_OPEN_NETWORKS_KEPT, WIFI_NUM_OPEN_NETWORKS_KEPT_VALIDATOR);
- VALIDATORS.put(MOUNT_PLAY_NOTIFICATION_SND, MOUNT_PLAY_NOTIFICATION_SND_VALIDATOR);
- VALIDATORS.put(MOUNT_UMS_AUTOSTART, MOUNT_UMS_AUTOSTART_VALIDATOR);
- VALIDATORS.put(MOUNT_UMS_PROMPT, MOUNT_UMS_PROMPT_VALIDATOR);
- VALIDATORS.put(MOUNT_UMS_NOTIFY_ENABLED, MOUNT_UMS_NOTIFY_ENABLED_VALIDATOR);
- VALIDATORS.put(DOUBLE_TAP_TO_WAKE, DOUBLE_TAP_TO_WAKE_VALIDATOR);
- VALIDATORS.put(WAKE_GESTURE_ENABLED, WAKE_GESTURE_ENABLED_VALIDATOR);
- VALIDATORS.put(LONG_PRESS_TIMEOUT, LONG_PRESS_TIMEOUT_VALIDATOR);
- VALIDATORS.put(CAMERA_GESTURE_DISABLED, CAMERA_GESTURE_DISABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_AUTOCLICK_ENABLED,
- ACCESSIBILITY_AUTOCLICK_ENABLED_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_AUTOCLICK_DELAY, ACCESSIBILITY_AUTOCLICK_DELAY_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_LARGE_POINTER_ICON,
- ACCESSIBILITY_LARGE_POINTER_ICON_VALIDATOR);
- VALIDATORS.put(PREFERRED_TTY_MODE, PREFERRED_TTY_MODE_VALIDATOR);
- VALIDATORS.put(ENHANCED_VOICE_PRIVACY_ENABLED,
- ENHANCED_VOICE_PRIVACY_ENABLED_VALIDATOR);
- VALIDATORS.put(TTY_MODE_ENABLED, TTY_MODE_ENABLED_VALIDATOR);
- VALIDATORS.put(RTT_CALLING_MODE, RTT_CALLING_MODE_VALIDATOR);
- VALIDATORS.put(INCALL_POWER_BUTTON_BEHAVIOR, INCALL_POWER_BUTTON_BEHAVIOR_VALIDATOR);
- VALIDATORS.put(NIGHT_DISPLAY_CUSTOM_START_TIME,
- NIGHT_DISPLAY_CUSTOM_START_TIME_VALIDATOR);
- VALIDATORS.put(NIGHT_DISPLAY_CUSTOM_END_TIME, NIGHT_DISPLAY_CUSTOM_END_TIME_VALIDATOR);
- VALIDATORS.put(NIGHT_DISPLAY_COLOR_TEMPERATURE,
- NIGHT_DISPLAY_COLOR_TEMPERATURE_VALIDATOR);
- VALIDATORS.put(NIGHT_DISPLAY_AUTO_MODE, NIGHT_DISPLAY_AUTO_MODE_VALIDATOR);
- VALIDATORS.put(DISPLAY_WHITE_BALANCE_ENABLED, DISPLAY_WHITE_BALANCE_ENABLED_VALIDATOR);
- VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR);
- VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
- CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR);
- VALIDATORS.put(CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
- CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR);
- VALIDATORS.put(SYSTEM_NAVIGATION_KEYS_ENABLED,
- SYSTEM_NAVIGATION_KEYS_ENABLED_VALIDATOR);
- VALIDATORS.put(QS_TILES, QS_TILES_VALIDATOR);
- VALIDATORS.put(DOZE_ENABLED, DOZE_ENABLED_VALIDATOR);
- VALIDATORS.put(DOZE_ALWAYS_ON, DOZE_ALWAYS_ON_VALIDATOR);
- VALIDATORS.put(DOZE_PICK_UP_GESTURE, DOZE_PICK_UP_GESTURE_VALIDATOR);
- VALIDATORS.put(DOZE_DOUBLE_TAP_GESTURE, DOZE_DOUBLE_TAP_GESTURE_VALIDATOR);
- VALIDATORS.put(DOZE_TAP_SCREEN_GESTURE, DOZE_TAP_SCREEN_GESTURE_VALIDATOR);
- VALIDATORS.put(DOZE_WAKE_LOCK_SCREEN_GESTURE, DOZE_WAKE_LOCK_SCREEN_GESTURE_VALIDATOR);
- VALIDATORS.put(DOZE_WAKE_DISPLAY_GESTURE, DOZE_WAKE_DISPLAY_GESTURE_VALIDATOR);
- VALIDATORS.put(NFC_PAYMENT_DEFAULT_COMPONENT, NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR);
- VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
- AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);
- VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR);
- VALIDATORS.put(FACE_UNLOCK_DISMISSES_KEYGUARD,
- FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR);
- VALIDATORS.put(SHOW_MEDIA_WHEN_BYPASSING, SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR);
- VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR);
- VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
- FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR);
- VALIDATORS.put(ASSIST_GESTURE_ENABLED, ASSIST_GESTURE_ENABLED_VALIDATOR);
- VALIDATORS.put(ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
- ASSIST_GESTURE_SILENCE_ALERTS_ENABLED_VALIDATOR);
- VALIDATORS.put(ASSIST_GESTURE_WAKE_ENABLED, ASSIST_GESTURE_WAKE_ENABLED_VALIDATOR);
- VALIDATORS.put(VR_DISPLAY_MODE, VR_DISPLAY_MODE_VALIDATOR);
- VALIDATORS.put(NOTIFICATION_BADGING, NOTIFICATION_BADGING_VALIDATOR);
- VALIDATORS.put(NOTIFICATION_BUBBLES, NOTIFICATION_BUBBLES_VALIDATOR);
- VALIDATORS.put(NOTIFICATION_DISMISS_RTL, NOTIFICATION_DISMISS_RTL_VALIDATOR);
- VALIDATORS.put(QS_AUTO_ADDED_TILES, QS_AUTO_ADDED_TILES_VALIDATOR);
- VALIDATORS.put(SCREENSAVER_ENABLED, SCREENSAVER_ENABLED_VALIDATOR);
- VALIDATORS.put(SCREENSAVER_COMPONENTS, SCREENSAVER_COMPONENTS_VALIDATOR);
- VALIDATORS.put(SCREENSAVER_ACTIVATE_ON_DOCK, SCREENSAVER_ACTIVATE_ON_DOCK_VALIDATOR);
- VALIDATORS.put(SCREENSAVER_ACTIVATE_ON_SLEEP, SCREENSAVER_ACTIVATE_ON_SLEEP_VALIDATOR);
- VALIDATORS.put(LOCKDOWN_IN_POWER_MENU, LOCKDOWN_IN_POWER_MENU_VALIDATOR);
- VALIDATORS.put(SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
- SHOW_FIRST_CRASH_DIALOG_DEV_OPTION_VALIDATOR);
- VALIDATORS.put(VOLUME_HUSH_GESTURE, VOLUME_HUSH_GESTURE_VALIDATOR);
- VALIDATORS.put(ENABLED_NOTIFICATION_LISTENERS,
- ENABLED_NOTIFICATION_LISTENERS_VALIDATOR); //legacy restore setting
- VALIDATORS.put(ENABLED_NOTIFICATION_ASSISTANT,
- ENABLED_NOTIFICATION_ASSISTANT_VALIDATOR); //legacy restore setting
- VALIDATORS.put(ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
- ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES_VALIDATOR); //legacy restore setting
- VALIDATORS.put(HUSH_GESTURE_USED, HUSH_GESTURE_USED_VALIDATOR);
- VALIDATORS.put(MANUAL_RINGER_TOGGLE_COUNT, MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR);
- VALIDATORS.put(IN_CALL_NOTIFICATION_ENABLED, IN_CALL_NOTIFICATION_ENABLED_VALIDATOR);
- VALIDATORS.put(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, BOOLEAN_VALIDATOR);
- VALIDATORS.put(LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR);
- VALIDATORS.put(LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, BOOLEAN_VALIDATOR);
- VALIDATORS.put(SHOW_NOTIFICATION_SNOOZE, BOOLEAN_VALIDATOR);
- VALIDATORS.put(ZEN_DURATION, ZEN_DURATION_VALIDATOR);
- VALIDATORS.put(SHOW_ZEN_UPGRADE_NOTIFICATION, BOOLEAN_VALIDATOR);
- VALIDATORS.put(SHOW_ZEN_SETTINGS_SUGGESTION, BOOLEAN_VALIDATOR);
- VALIDATORS.put(ZEN_SETTINGS_UPDATED, BOOLEAN_VALIDATOR);
- VALIDATORS.put(ZEN_SETTINGS_SUGGESTION_VIEWED, BOOLEAN_VALIDATOR);
- VALIDATORS.put(CHARGING_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
- VALIDATORS.put(CHARGING_VIBRATION_ENABLED, BOOLEAN_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS,
- NON_NEGATIVE_INTEGER_VALIDATOR);
- VALIDATORS.put(ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, NON_NEGATIVE_INTEGER_VALIDATOR);
- VALIDATORS.put(USER_SETUP_COMPLETE, BOOLEAN_VALIDATOR);
- VALIDATORS.put(ASSIST_GESTURE_SETUP_COMPLETE, BOOLEAN_VALIDATOR);
- VALIDATORS.put(NOTIFICATION_NEW_INTERRUPTION_MODEL, BOOLEAN_VALIDATOR);
- VALIDATORS.put(TRUST_AGENTS_EXTEND_UNLOCK, TRUST_AGENTS_EXTEND_UNLOCK_VALIDATOR);
- VALIDATORS.put(LOCK_SCREEN_CUSTOM_CLOCK_FACE, LOCK_SCREEN_CUSTOM_CLOCK_FACE_VALIDATOR);
- VALIDATORS.put(LOCK_SCREEN_WHEN_TRUST_LOST, LOCK_SCREEN_WHEN_TRUST_LOST_VALIDATOR);
- VALIDATORS.put(SKIP_GESTURE, SKIP_GESTURE_VALIDATOR);
- VALIDATORS.put(SKIP_DIRECTION, SKIP_DIRECTION_VALIDATOR);
- VALIDATORS.put(SKIP_DIRECTION, SKIP_DIRECTION_VALIDATOR);
- VALIDATORS.put(SILENCE_GESTURE, SILENCE_GESTURE_VALIDATOR);
- VALIDATORS.put(THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
- THEME_CUSTOMIZATION_OVERLAY_PACKAGES_VALIDATOR);
- VALIDATORS.put(NAVIGATION_MODE, NAVIGATION_MODE_VALIDATOR);
- VALIDATORS.put(AWARE_ENABLED, AWARE_ENABLED_VALIDATOR);
- VALIDATORS.put(SKIP_GESTURE_COUNT, SKIP_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(SKIP_TOUCH_COUNT, SKIP_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(SILENCE_ALARMS_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(SILENCE_TIMER_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(SILENCE_CALL_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(SILENCE_ALARMS_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(SILENCE_TIMER_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(SILENCE_CALL_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(ODI_CAPTIONS_ENABLED, ODI_CAPTIONS_ENABLED_VALIDATOR);
- VALIDATORS.put(DARK_MODE_DIALOG_SEEN, BOOLEAN_VALIDATOR);
- VALIDATORS.put(UI_NIGHT_MODE, UI_NIGHT_MODE_VALIDATOR);
- VALIDATORS.put(GLOBAL_ACTIONS_PANEL_ENABLED, GLOBAL_ACTIONS_PANEL_ENABLED_VALIDATOR);
- VALIDATORS.put(AWARE_LOCK_ENABLED, AWARE_LOCK_ENABLED_VALIDATOR);
- VALIDATORS.put(DISPLAY_DENSITY_FORCED, DISPLAY_DENSITY_FORCED_VALIDATOR);
- }
-
- /**
* Keys we no longer back up under the current schema, but want to continue to
* process when restoring historical backup datasets.
*
@@ -9387,8 +8249,6 @@
*/
public static final String APPLY_RAMPING_RINGER = "apply_ramping_ringer";
- private static final Validator APPLY_RAMPING_RINGER_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Setting whether the global gesture for enabling accessibility is enabled.
* If this gesture is enabled the user will be able to perfrom it to enable
@@ -9516,16 +8376,12 @@
*/
public static final String AUTO_TIME = "auto_time";
- private static final Validator AUTO_TIME_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Value to specify if the user prefers the time zone
* to be automatically fetched from the network (NITZ). 1=yes, 0=no
*/
public static final String AUTO_TIME_ZONE = "auto_time_zone";
- private static final Validator AUTO_TIME_ZONE_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* URI for the car dock "in" event sound.
* @hide
@@ -9556,8 +8412,6 @@
*/
public static final String DOCK_SOUNDS_ENABLED = "dock_sounds_enabled";
- private static final Validator DOCK_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether to play a sound for dock events, only when an accessibility service is on.
* @hide
@@ -9595,8 +8449,6 @@
*/
public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled";
- private static final Validator POWER_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* URI for the "wireless charging started" and "wired charging started" sound.
* @hide
@@ -9612,8 +8464,6 @@
@Deprecated
public static final String CHARGING_SOUNDS_ENABLED = "charging_sounds_enabled";
- private static final Validator CHARGING_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether to vibrate for wireless charging events.
* @deprecated Use {@link android.provider.Settings.Secure#CHARGING_VIBRATION_ENABLED}
@@ -9622,8 +8472,6 @@
@Deprecated
public static final String CHARGING_VIBRATION_ENABLED = "charging_vibration_enabled";
- private static final Validator CHARGING_VIBRATION_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether we keep the device on while the device is plugged in.
* Supported values are:
@@ -9637,30 +8485,6 @@
*/
public static final String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
- private static final Validator STAY_ON_WHILE_PLUGGED_IN_VALIDATOR = new Validator() {
- @Override
- public boolean validate(@Nullable String value) {
- try {
- int val = Integer.parseInt(value);
- return (val == 0)
- || (val == BatteryManager.BATTERY_PLUGGED_AC)
- || (val == BatteryManager.BATTERY_PLUGGED_USB)
- || (val == BatteryManager.BATTERY_PLUGGED_WIRELESS)
- || (val == (BatteryManager.BATTERY_PLUGGED_AC
- | BatteryManager.BATTERY_PLUGGED_USB))
- || (val == (BatteryManager.BATTERY_PLUGGED_AC
- | BatteryManager.BATTERY_PLUGGED_WIRELESS))
- || (val == (BatteryManager.BATTERY_PLUGGED_USB
- | BatteryManager.BATTERY_PLUGGED_WIRELESS))
- || (val == (BatteryManager.BATTERY_PLUGGED_AC
- | BatteryManager.BATTERY_PLUGGED_USB
- | BatteryManager.BATTERY_PLUGGED_WIRELESS));
- } catch (NumberFormatException e) {
- return false;
- }
- }
- };
-
/**
* When the user has enable the option to have a "bug report" command
* in the power menu.
@@ -9668,8 +8492,6 @@
*/
public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu";
- private static final Validator BUGREPORT_IN_POWER_MENU_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Whether ADB is enabled.
*/
@@ -9700,8 +8522,6 @@
*/
public static final String BLUETOOTH_ON = "bluetooth_on";
- private static final Validator BLUETOOTH_ON_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* CDMA Cell Broadcast SMS
* 0 = CDMA Cell Broadcast SMS disabled
@@ -10426,8 +9246,6 @@
*/
public static final String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
- private static final Validator USB_MASS_STORAGE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* If this setting is set (to anything), then all references
* to Gmail on the device must change to Google Mail.
@@ -10580,9 +9398,6 @@
public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON =
"wifi_networks_available_notification_on";
- private static final Validator WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* {@hide}
*/
@@ -10596,9 +9411,6 @@
public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY =
"wifi_networks_available_repeat_delay";
- private static final Validator WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* 802.11 country code in ISO 3166 format
* @hide
@@ -10628,9 +9440,6 @@
*/
public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
- private static final Validator WIFI_NUM_OPEN_NETWORKS_KEPT_VALIDATOR =
- NON_NEGATIVE_INTEGER_VALIDATOR;
-
/**
* Whether the Wi-Fi should be on. Only the Wi-Fi service should touch this.
*/
@@ -10669,8 +9478,6 @@
*/
public static final String SOFT_AP_TIMEOUT_ENABLED = "soft_ap_timeout_enabled";
- private static final Validator SOFT_AP_TIMEOUT_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Value to specify if Wi-Fi Wakeup feature is enabled.
*
@@ -10680,8 +9487,6 @@
@SystemApi
public static final String WIFI_WAKEUP_ENABLED = "wifi_wakeup_enabled";
- private static final Validator WIFI_WAKEUP_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Value to specify whether network quality scores and badging should be shown in the UI.
*
@@ -10717,8 +9522,6 @@
public static final String NETWORK_RECOMMENDATIONS_ENABLED =
"network_recommendations_enabled";
- private static final Validator NETWORK_RECOMMENDATIONS_ENABLED_VALIDATOR =
- new DiscreteValueValidator(new String[] {"-1", "0", "1"});
/**
* Which package name to use for network recommendations. If null, network recommendations
@@ -10743,13 +9546,6 @@
@TestApi
public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
- private static final Validator USE_OPEN_WIFI_PACKAGE_VALIDATOR = new Validator() {
- @Override
- public boolean validate(@Nullable String value) {
- return (value == null) || PACKAGE_NAME_VALIDATOR.validate(value);
- }
- };
-
/**
* The number of milliseconds the {@link com.android.server.NetworkScoreService}
* will give a recommendation request to complete before returning a default response.
@@ -10781,8 +9577,6 @@
*/
public static final String WIFI_SCAN_THROTTLE_ENABLED = "wifi_scan_throttle_enabled";
- private static final Validator WIFI_SCAN_THROTTLE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Settings to allow BLE scans to be enabled even when Bluetooth is turned off for
* connectivity.
@@ -10888,9 +9682,6 @@
public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED =
"wifi_watchdog_poor_network_test_enabled";
- private static final Validator WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED_VALIDATOR =
- ANY_STRING_VALIDATOR;
-
/**
* Setting to turn on suspend optimizations at screen off on Wi-Fi. Enabled by default and
* needs to be set to 0 to disable it.
@@ -10974,9 +9765,6 @@
public static final String WIFI_PNO_FREQUENCY_CULLING_ENABLED =
"wifi_pno_frequency_culling_enabled";
- private static final Validator WIFI_PNO_FREQUENCY_CULLING_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Setting to enable including recency information when determining pno network priorities.
* Disabled by default, and setting it to 1 will enable it.
@@ -10986,9 +9774,6 @@
public static final String WIFI_PNO_RECENCY_SORTING_ENABLED =
"wifi_pno_recency_sorting_enabled";
- private static final Validator WIFI_PNO_RECENCY_SORTING_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Setting to enable the Wi-Fi link probing.
* Enabled by default, and setting it to 0 will disable it.
@@ -10998,9 +9783,6 @@
public static final String WIFI_LINK_PROBING_ENABLED =
"wifi_link_probing_enabled";
- private static final Validator WIFI_LINK_PROBING_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* The maximum number of times we will retry a connection to an access
* point for which we have failed in acquiring an IP address from DHCP.
@@ -11540,15 +10322,11 @@
*/
public static final String PRIVATE_DNS_MODE = "private_dns_mode";
- private static final Validator PRIVATE_DNS_MODE_VALIDATOR = ANY_STRING_VALIDATOR;
-
/**
* @hide
*/
public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
- private static final Validator PRIVATE_DNS_SPECIFIER_VALIDATOR = ANY_STRING_VALIDATOR;
-
/**
* Forced override of the default mode (hardcoded as "automatic", nee "opportunistic").
* This allows changing the default mode without effectively disabling other modes,
@@ -12291,9 +11069,6 @@
public static final String APP_AUTO_RESTRICTION_ENABLED =
"app_auto_restriction_enabled";
- private static final Validator APP_AUTO_RESTRICTION_ENABLED_VALIDATOR =
- BOOLEAN_VALIDATOR;
-
/**
* Feature flag to enable or disable the Forced App Standby feature.
* Type: int (0 for false, 1 for true)
@@ -12568,9 +11343,6 @@
*/
public static final String EMERGENCY_TONE = "emergency_tone";
- private static final Validator EMERGENCY_TONE_VALIDATOR =
- new DiscreteValueValidator(new String[] {"0", "1", "2"});
-
/**
* CDMA only settings
* Whether the auto retry is enabled. The value is
@@ -12579,8 +11351,6 @@
*/
public static final String CALL_AUTO_RETRY = "call_auto_retry";
- private static final Validator CALL_AUTO_RETRY_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* A setting that can be read whether the emergency affordance is currently needed.
* The value is a boolean (1 or 0).
@@ -12598,9 +11368,6 @@
public static final String ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS =
"enable_automatic_system_server_heap_dumps";
- private static final Validator ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_VALIDATOR =
- new DiscreteValueValidator(new String[] {"0", "1"});
-
/**
* See RIL_PreferredNetworkType in ril.h
* @hide
@@ -12792,9 +11559,6 @@
public static final String LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL =
"low_power_sticky_auto_disable_level";
- private static final Validator LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 100);
-
/**
* Whether sticky battery saver should be deactivated once the battery level has reached the
* threshold specified by {@link #LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL}.
@@ -12804,9 +11568,6 @@
public static final String LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED =
"low_power_sticky_auto_disable_enabled";
- private static final Validator LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED_VALIDATOR =
- new DiscreteValueValidator(new String[] {"0", "1"});
-
/**
* Battery level [1-100] at which low power mode automatically turns on.
* If 0, it will not automatically turn on. For Q and newer, it will only automatically
@@ -12819,9 +11580,6 @@
*/
public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
- private static final Validator LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 100);
-
/**
* Whether battery saver is currently set to trigger based on percentage, dynamic power
* savings trigger, or none. See {@link AutoPowerSaveModeTriggers} for
@@ -12832,9 +11590,6 @@
@TestApi
public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
- private static final Validator AUTOMATIC_POWER_SAVE_MODE_VALIDATOR =
- new DiscreteValueValidator(new String[] {"0", "1"});
-
/**
* The setting that backs the disable threshold for the setPowerSavingsWarning api in
* PowerManager
@@ -12845,8 +11600,6 @@
@TestApi
public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD =
"dynamic_power_savings_disable_threshold";
- private static final Validator DYNAMIC_POWER_SAVINGS_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 100);
/**
* The setting which backs the setDynamicPowerSaveHint api in PowerManager.
@@ -12934,8 +11687,6 @@
*/
public static final String DOCK_AUDIO_MEDIA_ENABLED = "dock_audio_media_enabled";
- private static final Validator DOCK_AUDIO_MEDIA_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* The surround sound formats AC3, DTS or IEC61937 are
* available for use if they are detected.
@@ -12995,9 +11746,6 @@
*/
public static final String ENCODED_SURROUND_OUTPUT = "encoded_surround_output";
- private static final Validator ENCODED_SURROUND_OUTPUT_VALIDATOR =
- new DiscreteValueValidator(new String[] {"0", "1", "2", "3"});
-
/**
* Surround sounds formats that are enabled when ENCODED_SURROUND_OUTPUT is set to
* ENCODED_SURROUND_OUTPUT_MANUAL. Encoded as comma separated list. Allowed values
@@ -13010,32 +11758,6 @@
public static final String ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS =
"encoded_surround_output_enabled_formats";
- private static final Validator ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS_VALIDATOR =
- new Validator() {
- @Override
- public boolean validate(@Nullable String value) {
- try {
- String[] surroundFormats = TextUtils.split(value, ",");
- for (String format : surroundFormats) {
- int audioFormat = Integer.valueOf(format);
- boolean isSurroundFormat = false;
- for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
- if (sf == audioFormat) {
- isSurroundFormat = true;
- break;
- }
- }
- if (!isSurroundFormat) {
- return false;
- }
- }
- return true;
- } catch (NumberFormatException e) {
- return false;
- }
- }
- };
-
/**
* Persisted safe headphone volume management state by AudioService
* @hide
@@ -13278,8 +12000,6 @@
@Deprecated
public static final String ZEN_DURATION = "zen_duration";
- private static final Validator ZEN_DURATION_VALIDATOR = ANY_INTEGER_VALIDATOR;
-
/**
* @deprecated Use {@link android.provider.Settings.Secure#ZEN_DURATION_PROMPT} instead
* @hide
@@ -13736,8 +12456,6 @@
*/
public static final String AWARE_ALLOWED = "aware_allowed";
- private static final Validator AWARE_ALLOWED_VALIDATOR = BOOLEAN_VALIDATOR;
-
/**
* Overrides internal R.integer.config_longPressOnPowerBehavior.
* Allowable values detailed in frameworks/base/core/res/res/values/config.xml.
@@ -13746,8 +12464,6 @@
*/
public static final String POWER_BUTTON_LONG_PRESS =
"power_button_long_press";
- private static final Validator POWER_BUTTON_LONG_PRESS_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 5);
/**
* Overrides internal R.integer.config_veryLongPressOnPowerBehavior.
@@ -13757,126 +12473,6 @@
*/
public static final String POWER_BUTTON_VERY_LONG_PRESS =
"power_button_very_long_press";
- private static final Validator POWER_BUTTON_VERY_LONG_PRESS_VALIDATOR =
- new InclusiveIntegerRangeValidator(0, 1);
-
- /**
- * Settings to backup. This is here so that it's in the same place as the settings
- * keys and easy to update.
- *
- * These keys may be mentioned in the SETTINGS_TO_BACKUP arrays in System
- * and Secure as well. This is because those tables drive both backup and
- * restore, and restore needs to properly whitelist keys that used to live
- * in those namespaces. The keys will only actually be backed up / restored
- * if they are also mentioned in this table (Global.SETTINGS_TO_BACKUP).
- *
- * NOTE: Settings are backed up and restored in the order they appear
- * in this array. If you have one setting depending on another,
- * make sure that they are ordered appropriately.
- *
- * NOTE: This table should only be used for settings which should be restored
- * between different types of devices {@see #DEVICE_SPECIFIC_SETTINGS_TO_BACKUP}
- *
- * @hide
- */
- public static final String[] SETTINGS_TO_BACKUP = {
- APPLY_RAMPING_RINGER,
- BUGREPORT_IN_POWER_MENU,
- STAY_ON_WHILE_PLUGGED_IN,
- APP_AUTO_RESTRICTION_ENABLED,
- AUTO_TIME,
- AUTO_TIME_ZONE,
- POWER_SOUNDS_ENABLED,
- DOCK_SOUNDS_ENABLED,
- CHARGING_SOUNDS_ENABLED,
- USB_MASS_STORAGE_ENABLED,
- NETWORK_RECOMMENDATIONS_ENABLED,
- WIFI_WAKEUP_ENABLED,
- WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
- USE_OPEN_WIFI_PACKAGE,
- WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED,
- EMERGENCY_TONE,
- CALL_AUTO_RETRY,
- DOCK_AUDIO_MEDIA_ENABLED,
- ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS,
- ENCODED_SURROUND_OUTPUT,
- ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
- LOW_POWER_MODE_TRIGGER_LEVEL,
- LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED,
- LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL,
- BLUETOOTH_ON,
- PRIVATE_DNS_MODE,
- PRIVATE_DNS_SPECIFIER,
- SOFT_AP_TIMEOUT_ENABLED,
- ZEN_DURATION,
- CHARGING_VIBRATION_ENABLED,
- AWARE_ALLOWED,
- };
-
- /**
- * All settings in {@link SETTINGS_TO_BACKUP} array *must* have a non-null validator,
- * otherwise they won't be restored.
- *
- * @hide
- */
- public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
-
- static {
- VALIDATORS.put(APPLY_RAMPING_RINGER, APPLY_RAMPING_RINGER_VALIDATOR);
- VALIDATORS.put(BUGREPORT_IN_POWER_MENU, BUGREPORT_IN_POWER_MENU_VALIDATOR);
- VALIDATORS.put(STAY_ON_WHILE_PLUGGED_IN, STAY_ON_WHILE_PLUGGED_IN_VALIDATOR);
- VALIDATORS.put(AUTO_TIME, AUTO_TIME_VALIDATOR);
- VALIDATORS.put(AUTO_TIME_ZONE, AUTO_TIME_ZONE_VALIDATOR);
- VALIDATORS.put(POWER_SOUNDS_ENABLED, POWER_SOUNDS_ENABLED_VALIDATOR);
- VALIDATORS.put(DOCK_SOUNDS_ENABLED, DOCK_SOUNDS_ENABLED_VALIDATOR);
- VALIDATORS.put(CHARGING_SOUNDS_ENABLED, CHARGING_SOUNDS_ENABLED_VALIDATOR);
- VALIDATORS.put(USB_MASS_STORAGE_ENABLED, USB_MASS_STORAGE_ENABLED_VALIDATOR);
- VALIDATORS.put(NETWORK_RECOMMENDATIONS_ENABLED,
- NETWORK_RECOMMENDATIONS_ENABLED_VALIDATOR);
- VALIDATORS.put(WIFI_WAKEUP_ENABLED, WIFI_WAKEUP_ENABLED_VALIDATOR);
- VALIDATORS.put(WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
- WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR);
- VALIDATORS.put(USE_OPEN_WIFI_PACKAGE, USE_OPEN_WIFI_PACKAGE_VALIDATOR);
- VALIDATORS.put(WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED,
- WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED_VALIDATOR);
- VALIDATORS.put(EMERGENCY_TONE, EMERGENCY_TONE_VALIDATOR);
- VALIDATORS.put(CALL_AUTO_RETRY, CALL_AUTO_RETRY_VALIDATOR);
- VALIDATORS.put(DOCK_AUDIO_MEDIA_ENABLED, DOCK_AUDIO_MEDIA_ENABLED_VALIDATOR);
- VALIDATORS.put(ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS,
- ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_VALIDATOR);
- VALIDATORS.put(ENCODED_SURROUND_OUTPUT, ENCODED_SURROUND_OUTPUT_VALIDATOR);
- VALIDATORS.put(ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
- ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS_VALIDATOR);
- VALIDATORS.put(LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL,
- LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL_VALIDATOR);
- VALIDATORS.put(LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED,
- LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED_VALIDATOR);
- VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR);
- VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL_MAX,
- LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR);
- VALIDATORS.put(AUTOMATIC_POWER_SAVE_MODE, AUTOMATIC_POWER_SAVE_MODE_VALIDATOR);
- VALIDATORS.put(DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
- DYNAMIC_POWER_SAVINGS_VALIDATOR);
- VALIDATORS.put(BLUETOOTH_ON, BLUETOOTH_ON_VALIDATOR);
- VALIDATORS.put(PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_VALIDATOR);
- VALIDATORS.put(PRIVATE_DNS_SPECIFIER, PRIVATE_DNS_SPECIFIER_VALIDATOR);
- VALIDATORS.put(SOFT_AP_TIMEOUT_ENABLED, SOFT_AP_TIMEOUT_ENABLED_VALIDATOR);
- VALIDATORS.put(WIFI_SCAN_THROTTLE_ENABLED, WIFI_SCAN_THROTTLE_ENABLED_VALIDATOR);
- VALIDATORS.put(APP_AUTO_RESTRICTION_ENABLED, APP_AUTO_RESTRICTION_ENABLED_VALIDATOR);
- VALIDATORS.put(ZEN_DURATION, ZEN_DURATION_VALIDATOR);
- VALIDATORS.put(CHARGING_VIBRATION_ENABLED, CHARGING_VIBRATION_ENABLED_VALIDATOR);
- VALIDATORS.put(DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, BOOLEAN_VALIDATOR);
- VALIDATORS.put(REQUIRE_PASSWORD_TO_DECRYPT, BOOLEAN_VALIDATOR);
- VALIDATORS.put(DEVICE_DEMO_MODE, BOOLEAN_VALIDATOR);
- VALIDATORS.put(WIFI_PNO_FREQUENCY_CULLING_ENABLED,
- WIFI_PNO_FREQUENCY_CULLING_ENABLED_VALIDATOR);
- VALIDATORS.put(WIFI_PNO_RECENCY_SORTING_ENABLED,
- WIFI_PNO_RECENCY_SORTING_ENABLED_VALIDATOR);
- VALIDATORS.put(WIFI_LINK_PROBING_ENABLED, WIFI_LINK_PROBING_ENABLED_VALIDATOR);
- VALIDATORS.put(AWARE_ALLOWED, AWARE_ALLOWED_VALIDATOR);
- VALIDATORS.put(POWER_BUTTON_LONG_PRESS, POWER_BUTTON_LONG_PRESS_VALIDATOR);
- VALIDATORS.put(POWER_BUTTON_VERY_LONG_PRESS, POWER_BUTTON_VERY_LONG_PRESS_VALIDATOR);
- }
/**
* Global settings that shouldn't be persisted.
diff --git a/core/java/android/provider/TEST_MAPPING b/core/java/android/provider/TEST_MAPPING
index 52a6a45..773be80 100644
--- a/core/java/android/provider/TEST_MAPPING
+++ b/core/java/android/provider/TEST_MAPPING
@@ -7,6 +7,14 @@
"include-annotation": "android.platform.test.annotations.Presubmit"
}
]
+ },
+ {
+ "name": "SettingsProviderTest",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ }
+ ]
}
]
}
diff --git a/core/java/android/service/autofill/augmented/FillRequest.java b/core/java/android/service/autofill/augmented/FillRequest.java
index 9a97bb2..0b44470 100644
--- a/core/java/android/service/autofill/augmented/FillRequest.java
+++ b/core/java/android/service/autofill/augmented/FillRequest.java
@@ -81,6 +81,7 @@
return mProxy.getSmartSuggestionParams();
}
+ @NonNull
@Override
public String toString() {
return "FillRequest[act=" + getActivityComponent().flattenToShortString()
diff --git a/core/java/android/service/autofill/augmented/PresentationParams.java b/core/java/android/service/autofill/augmented/PresentationParams.java
index 334487d..8b3a001 100644
--- a/core/java/android/service/autofill/augmented/PresentationParams.java
+++ b/core/java/android/service/autofill/augmented/PresentationParams.java
@@ -82,6 +82,7 @@
return mBounds;
}
+ @NonNull
@Override
public String toString() {
return mBounds.toString();
diff --git a/core/java/android/service/contentcapture/ActivityEvent.java b/core/java/android/service/contentcapture/ActivityEvent.java
index fc781c2..b741cff 100644
--- a/core/java/android/service/contentcapture/ActivityEvent.java
+++ b/core/java/android/service/contentcapture/ActivityEvent.java
@@ -111,6 +111,7 @@
}
}
+ @NonNull
@Override
public String toString() {
return new StringBuilder("ActivityEvent[").append(mComponentName.toShortString())
diff --git a/core/java/android/service/euicc/EuiccProfileInfo.java b/core/java/android/service/euicc/EuiccProfileInfo.java
index 702837b..6c357cc 100644
--- a/core/java/android/service/euicc/EuiccProfileInfo.java
+++ b/core/java/android/service/euicc/EuiccProfileInfo.java
@@ -16,6 +16,7 @@
package android.service.euicc;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
@@ -395,7 +396,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -430,6 +431,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
return "EuiccProfileInfo (nickname="
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index aa114450..8ab687f 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -257,6 +257,7 @@
dest.writeString(mIssuer);
}
+ @NonNull
@Override
public String toString() {
return "Adjustment{"
diff --git a/core/java/android/service/notification/NotificationStats.java b/core/java/android/service/notification/NotificationStats.java
index 2b4c24c..8be114c 100644
--- a/core/java/android/service/notification/NotificationStats.java
+++ b/core/java/android/service/notification/NotificationStats.java
@@ -16,6 +16,8 @@
package android.service.notification;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.RemoteInput;
@@ -266,7 +268,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -293,6 +295,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("NotificationStats{");
diff --git a/core/java/android/service/notification/SnoozeCriterion.java b/core/java/android/service/notification/SnoozeCriterion.java
index 938cc10..eb624c9 100644
--- a/core/java/android/service/notification/SnoozeCriterion.java
+++ b/core/java/android/service/notification/SnoozeCriterion.java
@@ -15,6 +15,7 @@
*/
package android.service.notification;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -118,7 +119,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
diff --git a/core/java/android/service/resolver/ResolverTarget.java b/core/java/android/service/resolver/ResolverTarget.java
index 33b3283..b3657c4 100644
--- a/core/java/android/service/resolver/ResolverTarget.java
+++ b/core/java/android/service/resolver/ResolverTarget.java
@@ -16,13 +16,10 @@
package android.service.resolver;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.ArrayMap;
-
-import java.util.Map;
/**
* A ResolverTarget contains features by which an app or option will be ranked, in
@@ -173,6 +170,7 @@
}
// serialize the class to a string.
+ @NonNull
@Override
public String toString() {
return "ResolverTarget{"
diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
index dc9c858..619c507 100644
--- a/core/java/android/service/watchdog/ExplicitHealthCheckService.java
+++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -229,13 +229,14 @@
return mHealthCheckTimeoutMillis;
}
+ @NonNull
@Override
public String toString() {
return "PackageConfig{" + mPackageName + ", " + mHealthCheckTimeoutMillis + "}";
}
@Override
- public boolean equals(Object other) {
+ public boolean equals(@Nullable Object other) {
if (other == this) {
return true;
}
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index bab4bc36..3b6ec0b 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -937,9 +937,12 @@
}
/**
- * Returns true if the day of the given time is the epoch on the Julian Calendar
- * (January 1, 1970 on the Gregorian calendar).
- *
+ * Returns true if the instant of the supplied time would be for the
+ * Gregorian calendar date January 1, 1970 <em>for a user observing UTC
+ * </em>, i.e. the timezone of the time object is ignored.
+ * <p>
+ * See {@link #getJulianDay(long, long)} for how to determine the Julian day
+ * for the timezone of the time object.
* <p>
* This method can return an incorrect answer when the date / time fields have
* been set to a local time that contradicts the available timezone information.
@@ -949,31 +952,39 @@
*/
public static boolean isEpoch(Time time) {
long millis = time.toMillis(true);
- return getJulianDay(millis, 0) == EPOCH_JULIAN_DAY;
+ return getJulianDay(millis, 0 /* UTC offset */) == EPOCH_JULIAN_DAY;
}
/**
* Computes the Julian day number for a point in time in a particular
- * timezone. The Julian day for a given date is the same for every
- * timezone. For example, the Julian day for July 1, 2008 is 2454649.
+ * timezone. The Julian day for a given calendar date is the same for
+ * every timezone. For example, the Julian day for July 1, 2008 is
+ * 2454649.
*
* <p>Callers must pass the time in UTC millisecond (as can be returned
* by {@link #toMillis(boolean)} or {@link #normalize(boolean)})
- * and the offset from UTC of the timezone in seconds (as might be in
- * {@link #gmtoff}).
+ * and the offset from UTC of the timezone in seconds at that time (as
+ * might be in {@link #gmtoff}).
*
* <p>The Julian day is useful for testing if two events occur on the
* same calendar date and for determining the relative time of an event
* from the present ("yesterday", "3 days ago", etc.).
*
* @param millis the time in UTC milliseconds
- * @param gmtoff the offset from UTC in seconds
+ * @param gmtoffSeconds the offset from UTC in seconds
* @return the Julian day
+ * @deprecated Use {@link java.time.temporal.JulianFields#JULIAN_DAY} instead.
*/
- public static int getJulianDay(long millis, long gmtoff) {
- long offsetMillis = gmtoff * 1000;
- long julianDay = (millis + offsetMillis) / DateUtils.DAY_IN_MILLIS;
- return (int) julianDay + EPOCH_JULIAN_DAY;
+ @Deprecated
+ public static int getJulianDay(long millis, long gmtoffSeconds) {
+ long offsetMillis = gmtoffSeconds * 1000;
+ long adjustedMillis = millis + offsetMillis;
+ long julianDay = adjustedMillis / DateUtils.DAY_IN_MILLIS;
+ // Negative adjustedMillis values must round towards Integer.MIN_VALUE.
+ if (adjustedMillis < 0 && adjustedMillis % DateUtils.DAY_IN_MILLIS != 0) {
+ julianDay--;
+ }
+ return (int) (julianDay + EPOCH_JULIAN_DAY);
}
/**
diff --git a/core/java/android/view/GestureExclusionTracker.java b/core/java/android/view/GestureExclusionTracker.java
index 6fcdd71..fcc14c1 100644
--- a/core/java/android/view/GestureExclusionTracker.java
+++ b/core/java/android/view/GestureExclusionTracker.java
@@ -44,7 +44,7 @@
while (i.hasNext()) {
final GestureExclusionViewInfo info = i.next();
final View v = info.getView();
- if (v == null || !v.isAttachedToWindow()) {
+ if (v == null || !v.isAttachedToWindow() || !v.isShown()) {
mGestureExclusionViewsChanged = true;
i.remove();
continue;
@@ -122,7 +122,8 @@
public int update() {
final View excludedView = getView();
- if (excludedView == null || !excludedView.isAttachedToWindow()) return GONE;
+ if (excludedView == null || !excludedView.isAttachedToWindow()
+ || !excludedView.isShown()) return GONE;
final List<Rect> localRects = excludedView.getSystemGestureExclusionRects();
final List<Rect> newRects = new ArrayList<>(localRects.size());
for (Rect src : localRects) {
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 83abf1a..3bf44ac 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -42,7 +42,6 @@
* editor {@link #mFocusedEditor} if {@link #isServedEditorRendered} is {@code true}.
*/
private boolean mShowOnNextImeRender;
- private boolean mHasWindowFocus;
public ImeInsetsSourceConsumer(
InsetsState state, Supplier<Transaction> transactionSupplier,
@@ -68,23 +67,18 @@
}
public void applyImeVisibility(boolean setVisible) {
- if (!mHasWindowFocus) {
- // App window doesn't have focus, any visibility changes would be no-op.
- return;
- }
-
mController.applyImeVisibility(setVisible);
}
@Override
public void onWindowFocusGained() {
- mHasWindowFocus = true;
+ super.onWindowFocusGained();
getImm().registerImeConsumer(this);
}
@Override
public void onWindowFocusLost() {
- mHasWindowFocus = false;
+ super.onWindowFocusLost();
getImm().unregisterImeConsumer(this);
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index bf16e3d..d0ecae9 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -296,7 +296,8 @@
final ArraySet<Integer> internalTypes = mState.toInternalType(types);
final SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();
- Pair<Integer, Boolean> typesReadyPair = collectConsumers(fromIme, internalTypes, consumers);
+ Pair<Integer, Boolean> typesReadyPair = collectConsumers(
+ fromIme, internalTypes, consumers, listener);
int typesReady = typesReadyPair.first;
boolean isReady = typesReadyPair.second;
if (!isReady) {
@@ -324,13 +325,16 @@
* @return Pair of (types ready to animate, is ready to animate).
*/
private Pair<Integer, Boolean> collectConsumers(boolean fromIme,
- ArraySet<Integer> internalTypes, SparseArray<InsetsSourceConsumer> consumers) {
+ ArraySet<Integer> internalTypes, SparseArray<InsetsSourceConsumer> consumers,
+ WindowInsetsAnimationControlListener listener) {
int typesReady = 0;
boolean isReady = true;
for (int i = internalTypes.size() - 1; i >= 0; i--) {
InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
- if (consumer.getControl() != null) {
- if (!consumer.isVisible()) {
+ // Double check for IME that IME target window has focus.
+ if (consumer.getType() != TYPE_IME || consumer.hasWindowFocus()) {
+ boolean setVisible = !consumer.isVisible();
+ if (setVisible) {
// Show request
switch(consumer.requestShow(fromIme)) {
case ShowResult.SHOW_IMMEDIATELY:
@@ -357,8 +361,11 @@
}
consumers.put(consumer.getType(), consumer);
} else {
- // TODO: Let calling app know it's not possible, or wait
- // TODO: Remove it from types
+ // window doesnt have focus, no-op.
+ isReady = false;
+ // TODO: Let the calling app know that window has lost focus and
+ // show()/hide()/controlWindowInsetsAnimation requests will be ignored.
+ typesReady &= ~InsetsState.toPublicType(consumer.getType());
}
}
return new Pair<>(typesReady, isReady);
@@ -533,7 +540,10 @@
@Override
public void onCancelled() {
- mAnimator.cancel();
+ // Animator can be null when it is cancelled before onReady() completes.
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
}
private void onAnimationFinish() {
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index a780158..9edccb3 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -58,6 +58,7 @@
private final @InternalInsetType int mType;
private final InsetsState mState;
private @Nullable InsetsSourceControl mSourceControl;
+ private boolean mHasWindowFocus;
public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state,
Supplier<Transaction> transactionSupplier, InsetsController controller) {
@@ -104,12 +105,20 @@
/**
* Called when current window gains focus
*/
- public void onWindowFocusGained() {}
+ public void onWindowFocusGained() {
+ mHasWindowFocus = true;
+ }
/**
* Called when current window loses focus.
*/
- public void onWindowFocusLost() {}
+ public void onWindowFocusLost() {
+ mHasWindowFocus = false;
+ }
+
+ boolean hasWindowFocus() {
+ return mHasWindowFocus;
+ }
boolean applyLocalVisibilityOverride() {
@@ -153,7 +162,6 @@
return;
}
mVisible = visible;
- applyHiddenToControl();
applyLocalVisibilityOverride();
mController.notifyVisibilityChanged();
}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index b76f2a1..a04c39b 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -17,6 +17,7 @@
package android.view;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.SIZE;
@@ -161,13 +162,15 @@
continue;
}
+ boolean skipNonImeInImeMode = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_IME
+ && source.getType() != TYPE_IME;
boolean skipSystemBars = ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
&& (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR);
boolean skipIme = source.getType() == TYPE_IME
&& (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0;
boolean skipLegacyTypes = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
&& (toPublicType(type) & Type.compatSystemInsets()) != 0;
- if (skipSystemBars || skipIme || skipLegacyTypes) {
+ if (skipSystemBars || skipIme || skipLegacyTypes || skipNonImeInImeMode) {
typeVisibilityMap[indexOf(toPublicType(type))] = source.isVisible();
continue;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1779a80..6ce7120 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14403,6 +14403,7 @@
}
notifyAppearedOrDisappearedForContentCaptureIfNeeded(isVisible);
+ updateSystemGestureExclusionRects();
}
/**
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index d474b4d..61debc8 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -4745,8 +4745,8 @@
/**
* Obtains a pooled instance.
*
- * @param rowCount The number of rows.
- * @param columnCount The number of columns.
+ * @param rowCount The number of rows, or -1 if count is unknown.
+ * @param columnCount The number of columns, or -1 if count is unknown.
* @param hierarchical Whether the collection is hierarchical.
*/
public static CollectionInfo obtain(int rowCount, int columnCount,
@@ -4800,7 +4800,7 @@
/**
* Gets the number of rows.
*
- * @return The row count.
+ * @return The row count, or -1 if count is unknown.
*/
public int getRowCount() {
return mRowCount;
@@ -4809,7 +4809,7 @@
/**
* Gets the number of columns.
*
- * @return The column count.
+ * @return The column count, or -1 if count is unknown.
*/
public int getColumnCount() {
return mColumnCount;
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index bd38629..c29d251 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -373,6 +373,7 @@
}
}
+ @NonNull
@Override
public String toString() {
final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=")
diff --git a/core/java/android/view/textclassifier/OWNERS b/core/java/android/view/textclassifier/OWNERS
new file mode 100644
index 0000000..893a083
--- /dev/null
+++ b/core/java/android/view/textclassifier/OWNERS
@@ -0,0 +1,10 @@
+# Bug component: 709498
+
+toki@google.com
+tonymak@google.com
+zilka@google.com
+jalt@google.com
+joannechung@google.com
+svetoslavganov@google.com
+eugeniom@google.com
+samsellem@google.com
\ No newline at end of file
diff --git a/core/java/android/view/textclassifier/TextClassificationSessionId.java b/core/java/android/view/textclassifier/TextClassificationSessionId.java
index 5e62a11..8b68e17 100644
--- a/core/java/android/view/textclassifier/TextClassificationSessionId.java
+++ b/core/java/android/view/textclassifier/TextClassificationSessionId.java
@@ -96,8 +96,6 @@
* Flattens this id to a string.
*
* @return The flattened id.
- *
- * @hide
*/
public @NonNull String flattenToString() {
return mValue;
diff --git a/core/java/android/view/textclassifier/TextClassifierEvent.java b/core/java/android/view/textclassifier/TextClassifierEvent.java
index a041296..eb6aec0 100644
--- a/core/java/android/view/textclassifier/TextClassifierEvent.java
+++ b/core/java/android/view/textclassifier/TextClassifierEvent.java
@@ -86,11 +86,13 @@
TYPE_ACTIONS_SHOWN, TYPE_LINK_CLICKED, TYPE_OVERTYPE, TYPE_COPY_ACTION,
TYPE_PASTE_ACTION, TYPE_CUT_ACTION, TYPE_SHARE_ACTION, TYPE_SMART_ACTION,
TYPE_SELECTION_DRAG, TYPE_SELECTION_DESTROYED, TYPE_OTHER_ACTION, TYPE_SELECT_ALL,
- TYPE_SELECTION_RESET, TYPE_MANUAL_REPLY, TYPE_ACTIONS_GENERATED})
+ TYPE_SELECTION_RESET, TYPE_MANUAL_REPLY, TYPE_ACTIONS_GENERATED, TYPE_LINKS_GENERATED})
public @interface Type {
// For custom event types, use range 1,000,000+.
}
+ // All these event type constants are required to match with those defined in
+ // textclassifier_enums.proto.
/** User started a new selection. */
public static final int TYPE_SELECTION_STARTED = 1;
/** User modified an existing selection. */
@@ -131,6 +133,8 @@
public static final int TYPE_MANUAL_REPLY = 19;
/** TextClassifier generated some actions */
public static final int TYPE_ACTIONS_GENERATED = 20;
+ /** Some text links were generated.*/
+ public static final int TYPE_LINKS_GENERATED = 21;
@Category
private final int mEventCategory;
@@ -365,7 +369,8 @@
out.append(this.getClass().getSimpleName());
out.append("{");
out.append("mEventCategory=").append(mEventCategory);
- out.append(", mEventTypes=").append(Arrays.toString(mEntityTypes));
+ out.append(", mEventType=").append(mEventType);
+ out.append(", mEntityTypes=").append(Arrays.toString(mEntityTypes));
out.append(", mEventContext=").append(mEventContext);
out.append(", mResultId=").append(mResultId);
out.append(", mEventIndex=").append(mEventIndex);
@@ -373,11 +378,19 @@
out.append(", mScores=").append(Arrays.toString(mScores));
out.append(", mModelName=").append(mModelName);
out.append(", mActionIndices=").append(Arrays.toString(mActionIndices));
+ toString(out);
out.append("}");
return out.toString();
}
/**
+ * Overrides this to append extra fields to the output of {@link #toString()}.
+ * <p>
+ * Extra fields should be formatted like this: ", {field_name}={field_value}".
+ */
+ void toString(StringBuilder out) {}
+
+ /**
* Returns a {@link SelectionEvent} equivalent of this event; or {@code null} if it can not be
* converted to a {@link SelectionEvent}.
* @hide
@@ -811,6 +824,16 @@
return mRelativeSuggestedWordEndIndex;
}
+ @Override
+ void toString(StringBuilder out) {
+ out.append(", getRelativeWordStartIndex=").append(mRelativeWordStartIndex);
+ out.append(", getRelativeWordEndIndex=").append(mRelativeWordEndIndex);
+ out.append(", getRelativeSuggestedWordStartIndex=")
+ .append(mRelativeSuggestedWordStartIndex);
+ out.append(", getRelativeSuggestedWordEndIndex=")
+ .append(mRelativeSuggestedWordEndIndex);
+ }
+
/**
* Builder class for {@link TextSelectionEvent}.
*/
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index e4b5eaa..2af7ac7 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1843,8 +1843,8 @@
/**
* Injects the supplied Java object into this WebView. The object is
- * injected into the JavaScript context of the main frame, using the
- * supplied name. This allows the Java object's methods to be
+ * injected into all frames of the web page, including all the iframes,
+ * using the supplied name. This allows the Java object's methods to be
* accessed from JavaScript. For applications targeted to API
* level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
* and above, only public methods that are annotated with
@@ -1883,6 +1883,11 @@
* thread of this WebView. Care is therefore required to maintain thread
* safety.
* </li>
+ * <li> Because the object is exposed to all the frames, any frame could
+ * obtain the object name and call methods on it. There is no way to tell the
+ * calling frame's origin from the app side, so the app must not assume that
+ * the caller is trustworthy unless the app can guarantee that no third party
+ * content is ever loaded into the WebView even inside an iframe.</li>
* <li> The Java object's fields are not accessible.</li>
* <li> For applications targeted to API level {@link android.os.Build.VERSION_CODES#LOLLIPOP}
* and above, methods of injected Java objects are enumerable from
@@ -2807,7 +2812,7 @@
}
@Override
- public void onProvideContentCaptureStructure(ViewStructure structure, int flags) {
+ public void onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) {
mProvider.getViewDelegate().onProvideContentCaptureStructure(structure, flags);
}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 5b129f4..1de2e72 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -20,7 +20,6 @@
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ApplicationErrorReport;
-import android.content.type.MimeMapImpl;
import android.os.Build;
import android.os.DeadObjectException;
import android.os.Debug;
@@ -34,9 +33,6 @@
import com.android.server.NetworkManagementSocketTagger;
import dalvik.system.RuntimeHooks;
import dalvik.system.VMRuntime;
-
-import libcore.net.MimeMap;
-
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -214,14 +210,6 @@
RuntimeHooks.setTimeZoneIdSupplier(() -> SystemProperties.get("persist.sys.timezone"));
/*
- * Replace libcore's minimal default mapping between MIME types and file
- * extensions with a mapping that's suitable for Android. Android's mapping
- * contains many more entries that are derived from IANA registrations but
- * with several customizations (extensions, overrides).
- */
- MimeMap.setDefault(MimeMapImpl.createDefaultInstance());
-
- /*
* Sets handler for java.util.logging to use Android log facilities.
* The odd "new instance-and-then-throw-away" is a mirror of how
* the "java.util.logging.config.class" system property works. We
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 9ea9b06..b5d4945 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -92,11 +92,6 @@
private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
- /**
- * when preloading, GC after allocating this many bytes
- */
- private static final int PRELOAD_GC_THRESHOLD = 50000;
-
private static final String ABI_LIST_ARG = "--abi-list=";
// TODO (chriswailes): Re-name this --zygote-socket-name= and then add a
@@ -281,11 +276,6 @@
droppedPriviliges = true;
}
- // Alter the target heap utilization. With explicit GCs this
- // is not likely to have any effect.
- float defaultUtilization = runtime.getTargetHeapUtilization();
- runtime.setTargetHeapUtilization(0.8f);
-
try {
BufferedReader br =
new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);
@@ -301,9 +291,6 @@
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
try {
- if (false) {
- Log.v(TAG, "Preloading " + line + "...");
- }
// Load and explicitly initialize the given class. Use
// Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
// (to derive the caller's class-loader). Use true to force initialization, and
@@ -334,8 +321,6 @@
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally {
IoUtils.closeQuietly(is);
- // Restore default.
- runtime.setTargetHeapUtilization(defaultUtilization);
// Fill in dex caches with classes, fields, and methods brought in by preloading.
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java
index d459bfb..aab2f4b 100644
--- a/core/java/com/android/internal/widget/LockSettingsInternal.java
+++ b/core/java/com/android/internal/widget/LockSettingsInternal.java
@@ -16,6 +16,8 @@
package com.android.internal.widget;
+import android.annotation.Nullable;
+import android.app.admin.PasswordMetrics;
/**
* LockSettingsService local system service interface.
@@ -61,4 +63,18 @@
long tokenHandle, byte[] token, int requestedQuality, int userId);
public abstract boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId);
+
+ /**
+ * Returns PasswordMetrics object corresponding to the given user's lockscreen password.
+ * If the user has a password but its metrics isn't known yet (for example if the device
+ * has not been unlocked since boot), this method will return {@code null}.
+ * If the user has no password, a default PasswordMetrics (PASSWORD_QUALITY_UNSPECIFIED)
+ * will be returned.
+ *
+ * Calling this method on a managed profile user with unified challenge is undefined.
+ *
+ * @param userHandle the user for whom to provide metrics.
+ * @return the user password metrics.
+ */
+ public abstract @Nullable PasswordMetrics getUserPasswordMetrics(int userHandle);
}
diff --git a/core/java/com/package.html b/core/java/com/package.html
new file mode 100644
index 0000000..8f35da9
--- /dev/null
+++ b/core/java/com/package.html
@@ -0,0 +1,8 @@
+<!--
+ This file is to hide classes in com.* packages from SDK
+-->
+<html>
+<body>
+ {@hide}
+</body>
+</html>
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 2987c5e..11d321f 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -220,10 +220,10 @@
{
ALOG_ASSERT(env->IsInstanceOf(obj, gRect_class));
- ir->set(env->GetIntField(obj, gRect_leftFieldID),
- env->GetIntField(obj, gRect_topFieldID),
- env->GetIntField(obj, gRect_rightFieldID),
- env->GetIntField(obj, gRect_bottomFieldID));
+ ir->setLTRB(env->GetIntField(obj, gRect_leftFieldID),
+ env->GetIntField(obj, gRect_topFieldID),
+ env->GetIntField(obj, gRect_rightFieldID),
+ env->GetIntField(obj, gRect_bottomFieldID));
return ir;
}
@@ -241,10 +241,10 @@
{
ALOG_ASSERT(env->IsInstanceOf(obj, gRectF_class));
- r->set(env->GetFloatField(obj, gRectF_leftFieldID),
- env->GetFloatField(obj, gRectF_topFieldID),
- env->GetFloatField(obj, gRectF_rightFieldID),
- env->GetFloatField(obj, gRectF_bottomFieldID));
+ r->setLTRB(env->GetFloatField(obj, gRectF_leftFieldID),
+ env->GetFloatField(obj, gRectF_topFieldID),
+ env->GetFloatField(obj, gRectF_rightFieldID),
+ env->GetFloatField(obj, gRectF_bottomFieldID));
return r;
}
@@ -252,10 +252,10 @@
{
ALOG_ASSERT(env->IsInstanceOf(obj, gRect_class));
- r->set(SkIntToScalar(env->GetIntField(obj, gRect_leftFieldID)),
- SkIntToScalar(env->GetIntField(obj, gRect_topFieldID)),
- SkIntToScalar(env->GetIntField(obj, gRect_rightFieldID)),
- SkIntToScalar(env->GetIntField(obj, gRect_bottomFieldID)));
+ r->setLTRB(SkIntToScalar(env->GetIntField(obj, gRect_leftFieldID)),
+ SkIntToScalar(env->GetIntField(obj, gRect_topFieldID)),
+ SkIntToScalar(env->GetIntField(obj, gRect_rightFieldID)),
+ SkIntToScalar(env->GetIntField(obj, gRect_bottomFieldID)));
return r;
}
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index 1fb5fe3..87662f7 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -61,7 +61,7 @@
static jboolean Region_setRect(JNIEnv* env, jobject, jlong dstHandle, jint left, jint top, jint right, jint bottom) {
SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
- bool result = dst->setRect(left, top, right, bottom);
+ bool result = dst->setRect({left, top, right, bottom});
return boolTojboolean(result);
}
@@ -92,10 +92,7 @@
static jboolean Region_op0(JNIEnv* env, jobject, jlong dstHandle, jint left, jint top, jint right, jint bottom, jint op) {
SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
- SkIRect ir;
-
- ir.set(left, top, right, bottom);
- bool result = dst->op(ir, (SkRegion::Op)op);
+ bool result = dst->op({left, top, right, bottom}, (SkRegion::Op)op);
return boolTojboolean(result);
}
@@ -139,13 +136,13 @@
}
static jboolean Region_quickContains(JNIEnv* env, jobject region, jint left, jint top, jint right, jint bottom) {
- bool result = GetSkRegion(env, region)->quickContains(left, top, right, bottom);
+ bool result = GetSkRegion(env, region)->quickContains({left, top, right, bottom});
return boolTojboolean(result);
}
static jboolean Region_quickRejectIIII(JNIEnv* env, jobject region, jint left, jint top, jint right, jint bottom) {
SkIRect ir;
- ir.set(left, top, right, bottom);
+ ir.setLTRB(left, top, right, bottom);
bool result = GetSkRegion(env, region)->quickReject(ir);
return boolTojboolean(result);
}
@@ -224,7 +221,7 @@
SkRegion* region = new SkRegion;
for (size_t x = 0; x + 4 <= rects.size(); x += 4) {
- region->op(rects[x], rects[x+1], rects[x+2], rects[x+3], SkRegion::kUnion_Op);
+ region->op({rects[x], rects[x+1], rects[x+2], rects[x+3]}, SkRegion::kUnion_Op);
}
return reinterpret_cast<jlong>(region);
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index 64caf33..2265268 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -29,6 +29,7 @@
#include "android_hardware_input_InputWindowHandle.h"
#include "android_hardware_input_InputApplicationHandle.h"
#include "android_util_Binder.h"
+#include <binder/IPCThreadState.h>
namespace android {
@@ -80,6 +81,12 @@
NativeInputWindowHandle::~NativeInputWindowHandle() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->DeleteWeakGlobalRef(mObjWeak);
+
+ // Clear the weak reference to the layer handle and flush any binder ref count operations so we
+ // do not hold on to any binder references.
+ // TODO(b/139697085) remove this after it can be flushed automatically
+ mInfo.touchableRegionCropHandle.clear();
+ IPCThreadState::self()->flushCommands();
}
jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) {
diff --git a/core/proto/android/stats/textclassifier/textclassifier_enums.proto b/core/proto/android/stats/textclassifier/textclassifier_enums.proto
index 1885f19..4be7b7c 100644
--- a/core/proto/android/stats/textclassifier/textclassifier_enums.proto
+++ b/core/proto/android/stats/textclassifier/textclassifier_enums.proto
@@ -60,6 +60,8 @@
MANUAL_REPLY = 19;
// TextClassifier generated some actions
ACTIONS_GENERATED = 20;
+ // Some text links were generated
+ LINKS_GENERATED = 21;
}
enum WidgetType {
diff --git a/core/res/TEST_MAPPING b/core/res/TEST_MAPPING
index 1d22d782..ccd91a4 100644
--- a/core/res/TEST_MAPPING
+++ b/core/res/TEST_MAPPING
@@ -4,7 +4,7 @@
"name": "CtsPermission2TestCases",
"options": [
{
- "include-filter": "android.permission2.cts.PermissionPolicyTest#testPlatformPermissionPolicyUnaltered"
+ "include-filter": "android.permission2.cts.PermissionPolicyTest#platformPermissionPolicyIsUnaltered"
}
]
}
diff --git a/core/res/res/values-mcc450-mnc08/config.xml b/core/res/res/values-mcc450-mnc08/config.xml
index ca26ec1..5edbaed 100644
--- a/core/res/res/values-mcc450-mnc08/config.xml
+++ b/core/res/res/values-mcc450-mnc08/config.xml
@@ -28,4 +28,14 @@
<!-- Do not set the system language as value of EF LI/EF PL -->
<bool name="config_use_sim_language_file">false</bool>
+ <!-- Configures encoding type to parse the User Data of an SMS for reserved TP-DCS value.
+ Refer to SmsConstants.java
+ ENCODING_UNKNOWN = 0;
+ ENCODING_7BIT = 1;
+ ENCODING_8BIT = 2;
+ ENCODING_16BIT = 3;
+ ENCODING_KSC5601 = 4;
+ -->
+ <integer name="default_reserved_data_coding_scheme">4</integer>
+
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0a60d71..2cd39cb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3038,6 +3038,16 @@
string that's stored in 8-bit unpacked format) characters.-->
<bool translatable="false" name="config_sms_decode_gsm_8bit_data">false</bool>
+ <!-- Configures encoding type to parse the User Data of an SMS for reserved TP-DCS value.
+ Refer to SmsConstants.java
+ ENCODING_UNKNOWN = 0;
+ ENCODING_7BIT = 1;
+ ENCODING_8BIT = 2;
+ ENCODING_16BIT = 3;
+ ENCODING_KSC5601 = 4;
+ -->
+ <integer name="default_reserved_data_coding_scheme">2</integer>
+
<!-- If EMS is not supported, framework breaks down EMS into single segment SMS
and adds page info " x/y". This config is used to set which carrier doesn't
support EMS and whether page info should be added at the beginning or the end.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 58fc585..eaebd91 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2657,6 +2657,7 @@
<java-symbol type="attr" name="ambientShadowAlpha" />
<java-symbol type="attr" name="spotShadowAlpha" />
<java-symbol type="bool" name="config_sms_decode_gsm_8bit_data" />
+ <java-symbol type="integer" name="default_reserved_data_coding_scheme" />
<java-symbol type="dimen" name="text_size_small_material" />
<java-symbol type="attr" name="checkMarkGravity" />
<java-symbol type="layout" name="select_dialog_singlechoice_material" />
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 9955c51..2417209 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1270,10 +1270,8 @@
<action android:name="com.android.frameworks.coretests.activity.BROADCAST_REMOTE_DENIED" />
</intent-filter>
</receiver>
- <service android:name="android.app.activity.LocalService">
- <intent-filter>
- <action android:name="com.android.frameworks.coretests.activity.SERVICE_LOCAL" />
- </intent-filter>
+ <service android:name="android.app.activity.ServiceTest$RemoteService"
+ android:process=":RemoteService">
<meta-data android:name="com.android.frameworks.coretests.string" android:value="foo" />
<meta-data android:name="com.android.frameworks.coretests.boolean" android:value="true" />
<meta-data android:name="com.android.frameworks.coretests.integer" android:value="100" />
@@ -1281,18 +1279,6 @@
<meta-data android:name="com.android.frameworks.coretests.float" android:value="100.1" />
<meta-data android:name="com.android.frameworks.coretests.reference" android:resource="@xml/metadata" />
</service>
- <service android:name="android.app.activity.LocalDeniedService"
- android:permission="com.android.frameworks.coretests.permission.TEST_DENIED">
- <intent-filter>
- <action android:name="com.android.frameworks.coretests.activity.SERVICE_LOCAL_DENIED" />
- </intent-filter>
- </service>
- <service android:name="android.app.activity.LocalGrantedService"
- android:permission="com.android.frameworks.coretests.permission.TEST_GRANTED">
- <intent-filter>
- <action android:name="com.android.frameworks.coretests.activity.SERVICE_LOCAL_GRANTED" />
- </intent-filter>
- </service>
<service
android:name="android.service.settings.suggestions.MockSuggestionService"
diff --git a/core/tests/coretests/src/android/app/activity/LocalDeniedService.java b/core/tests/coretests/src/android/app/activity/LocalDeniedService.java
deleted file mode 100644
index 3bdac22..0000000
--- a/core/tests/coretests/src/android/app/activity/LocalDeniedService.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.activity;
-
-public class LocalDeniedService extends LocalService
-{
-}
-
diff --git a/core/tests/coretests/src/android/app/activity/LocalGrantedService.java b/core/tests/coretests/src/android/app/activity/LocalGrantedService.java
deleted file mode 100644
index 7ab0fb4..0000000
--- a/core/tests/coretests/src/android/app/activity/LocalGrantedService.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.activity;
-
-public class LocalGrantedService extends LocalService
-{
-}
-
diff --git a/core/tests/coretests/src/android/app/activity/LocalReceiver.java b/core/tests/coretests/src/android/app/activity/LocalReceiver.java
index bfd543f..7f81339 100644
--- a/core/tests/coretests/src/android/app/activity/LocalReceiver.java
+++ b/core/tests/coretests/src/android/app/activity/LocalReceiver.java
@@ -23,9 +23,9 @@
import android.content.IntentFilter;
import android.content.ReceiverCallNotAllowedException;
import android.content.ServiceConnection;
-import android.os.RemoteException;
import android.os.IBinder;
import android.os.Parcel;
+import android.os.RemoteException;
public class LocalReceiver extends BroadcastReceiver {
public LocalReceiver() {
@@ -52,7 +52,7 @@
public void onServiceDisconnected(ComponentName name) {
}
};
- context.bindService(new Intent(context, LocalService.class), sc, 0);
+ context.bindService(new Intent(context, ServiceTest.RemoteService.class), sc, 0);
context.unbindService(sc);
} catch (ReceiverCallNotAllowedException e) {
//resultString = "This is the correct behavior but not yet implemented";
diff --git a/core/tests/coretests/src/android/app/activity/LocalService.java b/core/tests/coretests/src/android/app/activity/LocalService.java
deleted file mode 100644
index c31ca4b..0000000
--- a/core/tests/coretests/src/android/app/activity/LocalService.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.activity;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.util.Log;
-
-public class LocalService extends Service {
- private final IBinder mBinder = new Binder() {
-
- @Override
- protected boolean onTransact(int code, Parcel data, Parcel reply,
- int flags) throws RemoteException {
- if (code == ServiceTest.SET_REPORTER_CODE) {
- data.enforceInterface(ServiceTest.SERVICE_LOCAL);
- mReportObject = data.readStrongBinder();
- return true;
- } else {
- return super.onTransact(code, data, reply, flags);
- }
- }
-
- };
-
- private IBinder mReportObject;
- private int mStartCount = 1;
-
- public LocalService() {
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- //Log.i("LocalService", "onStart: " + intent);
- if (intent.getExtras() != null) {
- mReportObject = intent.getExtras().getIBinder(ServiceTest.REPORT_OBJ_NAME);
- if (mReportObject != null) {
- try {
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken(ServiceTest.SERVICE_LOCAL);
- data.writeInt(mStartCount);
- mStartCount++;
- mReportObject.transact(
- ServiceTest.STARTED_CODE, data, null, 0);
- data.recycle();
- } catch (RemoteException e) {
- }
- }
- }
- }
-
- @Override
- public void onDestroy() {
- Log.i("LocalService", "onDestroy: mReportObject=" + mReportObject);
- if (mReportObject != null) {
- try {
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken(ServiceTest.SERVICE_LOCAL);
- mReportObject.transact(
- ServiceTest.DESTROYED_CODE, data, null, 0);
- data.recycle();
- } catch (RemoteException e) {
- }
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- Log.i("LocalService", "onBind: " + intent);
- return mBinder;
- }
-
- @Override
- public boolean onUnbind(Intent intent) {
- Log.i("LocalService", "onUnbind: " + intent);
- if (mReportObject != null) {
- try {
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken(ServiceTest.SERVICE_LOCAL);
- mReportObject.transact(
- ServiceTest.UNBIND_CODE, data, null, 0);
- data.recycle();
- } catch (RemoteException e) {
- }
- }
- return true;
- }
-
- @Override
- public void onRebind(Intent intent) {
- Log.i("LocalService", "onUnbind: " + intent);
- if (mReportObject != null) {
- try {
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken(ServiceTest.SERVICE_LOCAL);
- mReportObject.transact(
- ServiceTest.REBIND_CODE, data, null, 0);
- data.recycle();
- } catch (RemoteException e) {
- }
- }
- }
-}
diff --git a/core/tests/coretests/src/android/app/activity/MetaDataTest.java b/core/tests/coretests/src/android/app/activity/MetaDataTest.java
index cf27878..be6e276 100644
--- a/core/tests/coretests/src/android/app/activity/MetaDataTest.java
+++ b/core/tests/coretests/src/android/app/activity/MetaDataTest.java
@@ -125,7 +125,7 @@
@SmallTest
public void testServiceWithData() throws Exception {
- ComponentName cn = new ComponentName(mContext, LocalService.class);
+ ComponentName cn = new ComponentName(mContext, ServiceTest.RemoteService.class);
ServiceInfo si = mContext.getPackageManager().getServiceInfo(
cn, PackageManager.GET_META_DATA);
diff --git a/core/tests/coretests/src/android/app/activity/ServiceTest.java b/core/tests/coretests/src/android/app/activity/ServiceTest.java
index 9d2aebd..c89f37d 100644
--- a/core/tests/coretests/src/android/app/activity/ServiceTest.java
+++ b/core/tests/coretests/src/android/app/activity/ServiceTest.java
@@ -16,453 +16,250 @@
package android.app.activity;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.app.Service;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Binder;
-import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
+import android.os.Process;
import android.os.RemoteException;
import androidx.test.filters.MediumTest;
-import androidx.test.filters.Suppress;
-// These test binders purport to support an interface whose canonical
-// interface name is ServiceTest.SERVICE_LOCAL
-// Temporarily suppress, this test is causing unit test suite run to fail
-// TODO: remove this suppress
-@Suppress
-public class ServiceTest extends ActivityTestsBase {
+import junit.framework.TestCase;
- public static final String SERVICE_LOCAL =
- "com.android.frameworks.coretests.activity.SERVICE_LOCAL";
- public static final String SERVICE_LOCAL_GRANTED =
- "com.android.frameworks.coretests.activity.SERVICE_LOCAL_GRANTED";
- public static final String SERVICE_LOCAL_DENIED =
- "com.android.frameworks.coretests.activity.SERVICE_LOCAL_DENIED";
+import org.junit.Test;
- public static final String REPORT_OBJ_NAME = "report";
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Supplier;
- public static final int STARTED_CODE = 1;
- public static final int DESTROYED_CODE = 2;
- public static final int SET_REPORTER_CODE = 3;
- public static final int UNBIND_CODE = 4;
- public static final int REBIND_CODE = 5;
+/**
+ * Test for verifying the behavior of {@link Service}.
+ * <p>
+ * Tests related to internal behavior are usually placed here, e.g. the restart delay may be
+ * different depending on the current amount of restarting services.
+ * <p>
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ServiceTest
+ */
+@MediumTest
+public class ServiceTest extends TestCase {
+ private static final String ACTION_SERVICE_STARTED = RemoteService.class.getName() + "_STARTED";
+ private static final String EXTRA_START_CODE = "start_code";
+ private static final String EXTRA_PID = "pid";
- public static final int STATE_START_1 = 0;
- public static final int STATE_START_2 = 1;
- public static final int STATE_UNBIND = 2;
- public static final int STATE_DESTROY = 3;
- public static final int STATE_REBIND = 4;
- public static final int STATE_UNBIND_ONLY = 5;
- public int mStartState;
+ private static final long TIMEOUT_SEC = 5;
+ private static final int NOT_STARTED = -1;
- public IBinder mStartReceiver = new Binder() {
+ private final Context mContext = getInstrumentation().getContext();
+ private final Intent mServiceIntent = new Intent(mContext, RemoteService.class);
+ private TestConnection mCurrentConnection;
+
+ @Override
+ public void tearDown() {
+ mContext.stopService(mServiceIntent);
+ if (mCurrentConnection != null) {
+ mContext.unbindService(mCurrentConnection);
+ mCurrentConnection = null;
+ }
+ }
+
+ @Test
+ public void testRestart_stickyStartedService_restarted() {
+ testRestartStartedService(Service.START_STICKY, true /* shouldRestart */);
+ }
+
+ @Test
+ public void testRestart_redeliveryStartedService_restarted() {
+ testRestartStartedService(Service.START_FLAG_REDELIVERY, true /* shouldRestart */);
+ }
+
+ @Test
+ public void testRestart_notStickyStartedService_notRestarted() {
+ testRestartStartedService(Service.START_NOT_STICKY, false /* shouldRestart */);
+ }
+
+ private void testRestartStartedService(int startFlag, boolean shouldRestart) {
+ final int servicePid = startService(startFlag);
+ assertThat(servicePid, not(NOT_STARTED));
+
+ final int restartedServicePid = waitForServiceStarted(
+ () -> Process.killProcess(servicePid));
+ assertThat(restartedServicePid, shouldRestart ? not(NOT_STARTED) : is(NOT_STARTED));
+ }
+
+ @Test
+ public void testRestart_boundService_restarted() {
+ final int servicePid = bindService(Context.BIND_AUTO_CREATE);
+ assertThat(servicePid, not(NOT_STARTED));
+
+ Process.killProcess(servicePid);
+ // The service should be restarted and the connection will receive onServiceConnected again.
+ assertThat(mCurrentConnection.takePid(), not(NOT_STARTED));
+ }
+
+ @Test
+ public void testRestart_boundNotStickyStartedService_restarted() {
+ final ActivityManager am = mContext.getSystemService(ActivityManager.class);
+ final Supplier<RunningServiceInfo> serviceInfoGetter = () -> {
+ for (RunningServiceInfo rs : am.getRunningServices(Integer.MAX_VALUE)) {
+ if (mServiceIntent.getComponent().equals(rs.service)) {
+ return rs;
+ }
+ }
+ return null;
+ };
+
+ final int servicePid = bindService(Context.BIND_AUTO_CREATE);
+ assertThat(servicePid, not(NOT_STARTED));
+ assertThat(startService(Service.START_NOT_STICKY), is(servicePid));
+
+ RunningServiceInfo info = serviceInfoGetter.get();
+ assertThat(info, notNullValue());
+ assertThat(info.started, is(true));
+
+ Process.killProcess(servicePid);
+ // The service will be restarted for connection but the started state should be gone.
+ final int restartedServicePid = mCurrentConnection.takePid();
+ assertThat(restartedServicePid, not(NOT_STARTED));
+
+ info = serviceInfoGetter.get();
+ assertThat(info, notNullValue());
+ assertThat(info.started, is(false));
+ assertThat(info.clientCount, is(1));
+ }
+
+ @Test
+ public void testRestart_notStickyStartedNoAutoCreateBoundService_notRestarted() {
+ final int servicePid = startService(Service.START_NOT_STICKY);
+ assertThat(servicePid, not(NOT_STARTED));
+ assertThat(bindService(0 /* flags */), is(servicePid));
+
+ Process.killProcess(servicePid);
+ assertThat(mCurrentConnection.takePid(), is(NOT_STARTED));
+ }
+
+ /** @return The pid of the started service. */
+ private int startService(int code) {
+ return waitForServiceStarted(
+ () -> mContext.startService(mServiceIntent.putExtra(EXTRA_START_CODE, code)));
+ }
+
+ /** @return The pid of the started service. */
+ private int waitForServiceStarted(Runnable serviceTrigger) {
+ final CompletableFuture<Integer> pidResult = new CompletableFuture<>();
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ pidResult.complete(intent.getIntExtra(EXTRA_PID, NOT_STARTED));
+ mContext.unregisterReceiver(this);
+ }
+ }, new IntentFilter(ACTION_SERVICE_STARTED));
+
+ serviceTrigger.run();
+ try {
+ return pidResult.get(TIMEOUT_SEC, TimeUnit.SECONDS);
+ } catch (ExecutionException | InterruptedException | TimeoutException ignored) {
+ }
+ return NOT_STARTED;
+ }
+
+ /** @return The pid of the bound service. */
+ private int bindService(int flags) {
+ mCurrentConnection = new TestConnection();
+ assertThat(mContext.bindService(mServiceIntent, mCurrentConnection, flags), is(true));
+ return mCurrentConnection.takePid();
+ }
+
+ private static class TestConnection implements ServiceConnection {
+ private CompletableFuture<Integer> mServicePid = new CompletableFuture<>();
+
+ /**
+ * @return The pid of the connected service. It is only valid once after
+ * {@link #onServiceConnected} is called.
+ */
+ int takePid() {
+ try {
+ return mServicePid.get(TIMEOUT_SEC, TimeUnit.SECONDS);
+ } catch (ExecutionException | InterruptedException | TimeoutException ignored) {
+ } finally {
+ mServicePid = new CompletableFuture<>();
+ }
+ return NOT_STARTED;
+ }
+
@Override
- protected boolean onTransact(int code, Parcel data, Parcel reply,
- int flags) throws RemoteException {
- //Log.i("ServiceTest", "Received code " + code + " in state " + mStartState);
- if (code == STARTED_CODE) {
- data.enforceInterface(SERVICE_LOCAL);
- int count = data.readInt();
- if (mStartState == STATE_START_1) {
- if (count == 1) {
- finishGood();
- } else {
- finishBad("onStart() again on an object when it should have been the first time");
- }
- } else if (mStartState == STATE_START_2) {
- if (count == 2) {
- finishGood();
- } else {
- finishBad("onStart() the first time on an object when it should have been the second time");
- }
- } else {
- finishBad("onStart() was called when not expected (state="+mStartState+")");
- }
- return true;
- } else if (code == DESTROYED_CODE) {
- data.enforceInterface(SERVICE_LOCAL);
- if (mStartState == STATE_DESTROY) {
- finishGood();
- } else {
- finishBad("onDestroy() was called when not expected (state="+mStartState+")");
- }
- return true;
- } else if (code == UNBIND_CODE) {
- data.enforceInterface(SERVICE_LOCAL);
- if (mStartState == STATE_UNBIND) {
- mStartState = STATE_DESTROY;
- } else if (mStartState == STATE_UNBIND_ONLY) {
- finishGood();
- } else {
- finishBad("onUnbind() was called when not expected (state="+mStartState+")");
- }
- return true;
- } else if (code == REBIND_CODE) {
- data.enforceInterface(SERVICE_LOCAL);
- if (mStartState == STATE_REBIND) {
- finishGood();
- } else {
- finishBad("onRebind() was called when not expected (state="+mStartState+")");
- }
- return true;
- } else {
- return super.onTransact(code, data, reply, flags);
- }
- }
- };
-
- public class EmptyConnection implements ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service) {
- }
-
- public void onServiceDisconnected(ComponentName name) {
- }
- }
-
- public class TestConnection implements ServiceConnection {
- private final boolean mExpectDisconnect;
- private final boolean mSetReporter;
- private boolean mMonitor;
- private int mCount;
-
- public TestConnection(boolean expectDisconnect, boolean setReporter) {
- mExpectDisconnect = expectDisconnect;
- mSetReporter = setReporter;
- mMonitor = !setReporter;
- }
-
- void setMonitor(boolean v) {
- mMonitor = v;
- }
-
- public void onServiceConnected(ComponentName name, IBinder service) {
- if (mSetReporter) {
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken(SERVICE_LOCAL);
- data.writeStrongBinder(mStartReceiver);
- try {
- service.transact(SET_REPORTER_CODE, data, null, 0);
- } catch (RemoteException e) {
- finishBad("DeadObjectException when sending reporting object");
- }
+ final Parcel data = Parcel.obtain();
+ final Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(RemoteService.DESCRIPTOR);
+ try {
+ service.transact(RemoteService.TRANSACTION_GET_PID, data, reply, 0 /* flags */);
+ reply.readException();
+ mServicePid.complete(reply.readInt());
+ } catch (RemoteException e) {
+ mServicePid.complete(NOT_STARTED);
+ } finally {
data.recycle();
- }
-
- if (mMonitor) {
- mCount++;
- if (mStartState == STATE_START_1) {
- if (mCount == 1) {
- finishGood();
- } else {
- finishBad("onServiceConnected() again on an object when it should have been the first time");
- }
- } else if (mStartState == STATE_START_2) {
- if (mCount == 2) {
- finishGood();
- } else {
- finishBad("onServiceConnected() the first time on an object when it should have been the second time");
- }
- } else {
- finishBad("onServiceConnected() called unexpectedly");
- }
+ reply.recycle();
}
}
+ @Override
public void onServiceDisconnected(ComponentName name) {
- if (mMonitor) {
- if (mStartState == STATE_DESTROY) {
- if (mExpectDisconnect) {
- finishGood();
- } else {
- finishBad("onServiceDisconnected() when it shouldn't have been");
+ }
+ }
+
+ public static class RemoteService extends Service {
+ static final String DESCRIPTOR = RemoteService.class.getName();
+ static final int TRANSACTION_GET_PID = Binder.FIRST_CALL_TRANSACTION;
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ new Handler().post(() -> {
+ final Intent responseIntent = new Intent(ACTION_SERVICE_STARTED);
+ responseIntent.putExtra(EXTRA_PID, Process.myPid());
+ sendBroadcast(responseIntent);
+ });
+ if (intent != null && intent.hasExtra(EXTRA_START_CODE)) {
+ return intent.getIntExtra(EXTRA_START_CODE, Service.START_NOT_STICKY);
+ }
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new Binder() {
+ @Override
+ protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ if (code == TRANSACTION_GET_PID) {
+ data.enforceInterface(DESCRIPTOR);
+ reply.writeNoException();
+ reply.writeInt(Process.myPid());
+ return true;
}
- } else {
- finishBad("onServiceDisconnected() called unexpectedly");
+ return super.onTransact(code, data, reply, flags);
}
- }
- }
- }
-
- void startExpectResult(Intent service) {
- startExpectResult(service, new Bundle());
- }
-
- void startExpectResult(Intent service, Bundle bundle) {
- bundle.putIBinder(REPORT_OBJ_NAME, mStartReceiver);
- boolean success = false;
- try {
- //Log.i("foo", "STATE_START_1");
- mStartState = STATE_START_1;
- getContext().startService(new Intent(service).putExtras(bundle));
- waitForResultOrThrow(5 * 1000, "service to start first time");
- //Log.i("foo", "STATE_START_2");
- mStartState = STATE_START_2;
- getContext().startService(new Intent(service).putExtras(bundle));
- waitForResultOrThrow(5 * 1000, "service to start second time");
- success = true;
- } finally {
- if (!success) {
- try {
- getContext().stopService(service);
- } catch (Exception e) {
- // eat
- }
- }
- }
- //Log.i("foo", "STATE_DESTROY");
- mStartState = STATE_DESTROY;
- getContext().stopService(service);
- waitForResultOrThrow(5 * 1000, "service to be destroyed");
- }
-
- void startExpectNoPermission(Intent service) {
- try {
- getContext().startService(service);
- fail("Expected security exception when starting " + service);
- } catch (SecurityException e) {
- // expected
- }
- }
-
- void bindExpectResult(Intent service) {
- TestConnection conn = new TestConnection(true, false);
- TestConnection conn2 = new TestConnection(false, false);
- boolean success = false;
- try {
- // Expect to see the TestConnection connected.
- mStartState = STATE_START_1;
- getContext().bindService(service, conn, 0);
- getContext().startService(service);
- waitForResultOrThrow(5 * 1000, "existing connection to receive service");
-
- // Expect to see the second TestConnection connected.
- getContext().bindService(service, conn2, 0);
- waitForResultOrThrow(5 * 1000, "new connection to receive service");
-
- getContext().unbindService(conn2);
- success = true;
- } finally {
- if (!success) {
- try {
- getContext().stopService(service);
- getContext().unbindService(conn);
- getContext().unbindService(conn2);
- } catch (Exception e) {
- // eat
- }
- }
- }
-
- // Expect to see the TestConnection disconnected.
- mStartState = STATE_DESTROY;
- getContext().stopService(service);
- waitForResultOrThrow(5 * 1000, "existing connection to lose service");
-
- getContext().unbindService(conn);
-
- conn = new TestConnection(true, true);
- success = false;
- try {
- // Expect to see the TestConnection connected.
- conn.setMonitor(true);
- mStartState = STATE_START_1;
- getContext().bindService(service, conn, 0);
- getContext().startService(service);
- waitForResultOrThrow(5 * 1000, "existing connection to receive service");
-
- success = true;
- } finally {
- if (!success) {
- try {
- getContext().stopService(service);
- getContext().unbindService(conn);
- } catch (Exception e) {
- // eat
- }
- }
- }
-
- // Expect to see the service unbind and then destroyed.
- conn.setMonitor(false);
- mStartState = STATE_UNBIND;
- getContext().stopService(service);
- waitForResultOrThrow(5 * 1000, "existing connection to lose service");
-
- getContext().unbindService(conn);
-
- conn = new TestConnection(true, true);
- success = false;
- try {
- // Expect to see the TestConnection connected.
- conn.setMonitor(true);
- mStartState = STATE_START_1;
- getContext().bindService(service, conn, 0);
- getContext().startService(service);
- waitForResultOrThrow(5 * 1000, "existing connection to receive service");
-
- success = true;
- } finally {
- if (!success) {
- try {
- getContext().stopService(service);
- getContext().unbindService(conn);
- } catch (Exception e) {
- // eat
- }
- }
- }
-
- // Expect to see the service unbind but not destroyed.
- conn.setMonitor(false);
- mStartState = STATE_UNBIND_ONLY;
- getContext().unbindService(conn);
- waitForResultOrThrow(5 * 1000, "existing connection to unbind service");
-
- // Expect to see the service rebound.
- mStartState = STATE_REBIND;
- getContext().bindService(service, conn, 0);
- waitForResultOrThrow(5 * 1000, "existing connection to rebind service");
-
- // Expect to see the service unbind and then destroyed.
- mStartState = STATE_UNBIND;
- getContext().stopService(service);
- waitForResultOrThrow(5 * 1000, "existing connection to lose service");
-
- getContext().unbindService(conn);
- }
-
- void bindAutoExpectResult(Intent service) {
- TestConnection conn = new TestConnection(false, true);
- boolean success = false;
- try {
- conn.setMonitor(true);
- mStartState = STATE_START_1;
- getContext().bindService(
- service, conn, Context.BIND_AUTO_CREATE);
- waitForResultOrThrow(5 * 1000, "connection to start and receive service");
- success = true;
- } finally {
- if (!success) {
- try {
- getContext().unbindService(conn);
- } catch (Exception e) {
- // eat
- }
- }
- }
- mStartState = STATE_UNBIND;
- getContext().unbindService(conn);
- waitForResultOrThrow(5 * 1000, "disconnecting from service");
- }
-
- void bindExpectNoPermission(Intent service) {
- TestConnection conn = new TestConnection(false, false);
- try {
- getContext().bindService(service, conn, Context.BIND_AUTO_CREATE);
- fail("Expected security exception when binding " + service);
- } catch (SecurityException e) {
- // expected
- } finally {
- getContext().unbindService(conn);
- }
- }
-
-
- @MediumTest
- public void testLocalStartClass() throws Exception {
- startExpectResult(new Intent(getContext(), LocalService.class));
- }
-
- @MediumTest
- public void testLocalStartAction() throws Exception {
- startExpectResult(new Intent(SERVICE_LOCAL));
- }
-
- @MediumTest
- public void testLocalBindClass() throws Exception {
- bindExpectResult(new Intent(getContext(), LocalService.class));
- }
-
- @MediumTest
- public void testLocalBindAction() throws Exception {
- bindExpectResult(new Intent(SERVICE_LOCAL));
- }
-
- @MediumTest
- public void testLocalBindAutoClass() throws Exception {
- bindAutoExpectResult(new Intent(getContext(), LocalService.class));
- }
-
- @MediumTest
- public void testLocalBindAutoAction() throws Exception {
- bindAutoExpectResult(new Intent(SERVICE_LOCAL));
- }
-
- @MediumTest
- public void testLocalStartClassPermissionGranted() throws Exception {
- startExpectResult(new Intent(getContext(), LocalGrantedService.class));
- }
-
- @MediumTest
- public void testLocalStartActionPermissionGranted() throws Exception {
- startExpectResult(new Intent(SERVICE_LOCAL_GRANTED));
- }
-
- @MediumTest
- public void testLocalBindClassPermissionGranted() throws Exception {
- bindExpectResult(new Intent(getContext(), LocalGrantedService.class));
- }
-
- @MediumTest
- public void testLocalBindActionPermissionGranted() throws Exception {
- bindExpectResult(new Intent(SERVICE_LOCAL_GRANTED));
- }
-
- @MediumTest
- public void testLocalBindAutoClassPermissionGranted() throws Exception {
- bindAutoExpectResult(new Intent(getContext(), LocalGrantedService.class));
- }
-
- @MediumTest
- public void testLocalBindAutoActionPermissionGranted() throws Exception {
- bindAutoExpectResult(new Intent(SERVICE_LOCAL_GRANTED));
- }
-
- @MediumTest
- public void testLocalStartClassPermissionDenied() throws Exception {
- startExpectNoPermission(new Intent(getContext(), LocalDeniedService.class));
- }
-
- @MediumTest
- public void testLocalStartActionPermissionDenied() throws Exception {
- startExpectNoPermission(new Intent(SERVICE_LOCAL_DENIED));
- }
-
- @MediumTest
- public void testLocalBindClassPermissionDenied() throws Exception {
- bindExpectNoPermission(new Intent(getContext(), LocalDeniedService.class));
- }
-
- @MediumTest
- public void testLocalBindActionPermissionDenied() throws Exception {
- bindExpectNoPermission(new Intent(SERVICE_LOCAL_DENIED));
- }
-
- @MediumTest
- public void testLocalUnbindTwice() throws Exception {
- EmptyConnection conn = new EmptyConnection();
- getContext().bindService(
- new Intent(SERVICE_LOCAL_GRANTED), conn, 0);
- getContext().unbindService(conn);
- try {
- getContext().unbindService(conn);
- fail("No exception thrown on second unbind");
- } catch (IllegalArgumentException e) {
- //Log.i("foo", "Unbind exception", e);
+ };
}
}
}
diff --git a/core/tests/coretests/src/android/os/ProcessTest.java b/core/tests/coretests/src/android/os/ProcessTest.java
index b749e71..9de4501 100644
--- a/core/tests/coretests/src/android/os/ProcessTest.java
+++ b/core/tests/coretests/src/android/os/ProcessTest.java
@@ -29,8 +29,10 @@
assertEquals(Process.BLUETOOTH_UID, Process.getUidForName("bluetooth"));
assertEquals(Process.FIRST_APPLICATION_UID, Process.getUidForName("u0_a0"));
assertEquals(UserHandle.getUid(1, Process.SYSTEM_UID), Process.getUidForName("u1_system"));
- assertEquals(UserHandle.getUid(2, Process.FIRST_ISOLATED_UID),
+ assertEquals(UserHandle.getUid(2, Process.FIRST_APP_ZYGOTE_ISOLATED_UID),
Process.getUidForName("u2_i0"));
+ assertEquals(UserHandle.getUid(2, Process.FIRST_ISOLATED_UID),
+ Process.getUidForName("u2_i9000"));
assertEquals(UserHandle.getUid(3, Process.FIRST_APPLICATION_UID + 100),
Process.getUidForName("u3_a100"));
}
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 1e55828..337663e 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -145,6 +145,7 @@
InsetsSourceControl ime = controls[2];
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mController.getSourceConsumer(TYPE_IME).onWindowFocusGained();
// since there is no focused view, forcefully make IME visible.
mController.applyImeVisibility(true /* setVisible */);
mController.show(Type.all());
@@ -160,6 +161,7 @@
assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ mController.getSourceConsumer(TYPE_IME).onWindowFocusLost();
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
@@ -172,12 +174,14 @@
controls[0] = ime;
mController.onControlsChanged(controls);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mController.getSourceConsumer(TYPE_IME).onWindowFocusGained();
mController.applyImeVisibility(true);
mController.cancelExistingAnimation();
assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
mController.applyImeVisibility(false);
mController.cancelExistingAnimation();
assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ mController.getSourceConsumer(TYPE_IME).onWindowFocusLost();
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 971e143..e5fe2d0 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -18,8 +18,10 @@
import static android.view.InsetsState.TYPE_TOP_BAR;
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
@@ -40,6 +42,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
/**
@@ -60,6 +63,7 @@
private SurfaceSession mSession = new SurfaceSession();
private SurfaceControl mLeash;
@Mock Transaction mMockTransaction;
+ private InsetsSource mSpyInsetsSource;
@Before
public void setup() {
@@ -77,7 +81,11 @@
} catch (BadTokenException e) {
// activity isn't running, lets ignore BadTokenException.
}
- mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(),
+ InsetsState state = new InsetsState();
+ mSpyInsetsSource = Mockito.spy(new InsetsSource(TYPE_TOP_BAR));
+ state.addSource(mSpyInsetsSource);
+
+ mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, state,
() -> mMockTransaction, new InsetsController(viewRootImpl));
});
instrumentation.waitForIdleSync();
@@ -88,14 +96,15 @@
@Test
public void testHide() {
mConsumer.hide();
- verify(mMockTransaction).hide(eq(mLeash));
+ assertFalse("Consumer should not be visible", mConsumer.isVisible());
+ verify(mSpyInsetsSource).setVisible(eq(false));
}
@Test
public void testShow() {
- mConsumer.hide();
mConsumer.show();
- verify(mMockTransaction, atLeastOnce()).show(eq(mLeash));
+ assertTrue("Consumer should be visible", mConsumer.isVisible());
+ verify(mSpyInsetsSource).setVisible(eq(true));
}
@Test
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 9f4a619..cf2ef30 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -116,6 +116,7 @@
if (result != 0) {
LOG(ERROR) << "Failed to open APK '" << path << "' " << ::ErrorCodeString(result);
+ ::CloseArchive(unmanaged_handle);
return {};
}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 8a035db..5353869 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -7402,12 +7402,12 @@
print_complex(value.data, true);
printf("\n");
} else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT
- || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) {
+ && value.dataType <= Res_value::TYPE_LAST_COLOR_INT) {
printf("(color) #%08x\n", value.data);
} else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) {
printf("(boolean) %s\n", value.data ? "true" : "false");
} else if (value.dataType >= Res_value::TYPE_FIRST_INT
- || value.dataType <= Res_value::TYPE_LAST_INT) {
+ && value.dataType <= Res_value::TYPE_LAST_INT) {
printf("(int) 0x%08x or %d\n", value.data, value.data);
} else {
printf("(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\n",
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index 2d2df52..b39f4f2 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -130,7 +130,7 @@
// calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX
temp.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
}
- out->join(RECT_ARGS(temp));
+ out->join({RECT_ARGS(temp)});
}
void DamageAccumulator::applyMatrix4Transform(DirtyStack* frame) {
@@ -145,7 +145,7 @@
// Don't attempt to calculate damage for a perspective transform
// as the numbers this works with can break the perspective
// calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX
- rect->set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
+ rect->setLTRB(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
}
}
}
@@ -209,7 +209,7 @@
// Perform clipping
if (props.getClipDamageToBounds() && !frame->pendingDirty.isEmpty()) {
- if (!frame->pendingDirty.intersect(0, 0, props.getWidth(), props.getHeight())) {
+ if (!frame->pendingDirty.intersect(SkRect::MakeIWH(props.getWidth(), props.getHeight()))) {
frame->pendingDirty.setEmpty();
}
}
@@ -233,7 +233,7 @@
}
void DamageAccumulator::dirty(float left, float top, float right, float bottom) {
- mHead->pendingDirty.join(left, top, right, bottom);
+ mHead->pendingDirty.join({left, top, right, bottom});
}
void DamageAccumulator::peekAtDirty(SkRect* dest) const {
diff --git a/libs/hwui/DisplayListOps.in b/libs/hwui/DisplayListOps.in
index 2deb565..4a252af 100644
--- a/libs/hwui/DisplayListOps.in
+++ b/libs/hwui/DisplayListOps.in
@@ -49,3 +49,4 @@
X(DrawAtlas)
X(DrawShadowRec)
X(DrawVectorDrawable)
+X(DrawWebView)
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index c8eb1ca..c0df2fa 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -16,6 +16,7 @@
#include "RecordingCanvas.h"
+#include "pipeline/skia/FunctorDrawable.h"
#include "VectorDrawable.h"
#include "SkAndroidFrameworkUtils.h"
@@ -496,6 +497,16 @@
SkPaint paint;
BitmapPalette palette;
};
+struct DrawWebView final : Op {
+ static const auto kType = Type::DrawWebView;
+ DrawWebView(skiapipeline::FunctorDrawable* drawable) : drawable(sk_ref_sp(drawable)) {}
+ sk_sp<skiapipeline::FunctorDrawable> drawable;
+ // We can't invoke SkDrawable::draw directly, because VkFunctorDrawable expects
+ // SkDrawable::onSnapGpuDrawHandler callback instead of SkDrawable::onDraw.
+ // SkCanvas::drawDrawable/SkGpuDevice::drawDrawable has the logic to invoke
+ // onSnapGpuDrawHandler.
+ void draw(SkCanvas* c, const SkMatrix&) const { c->drawDrawable(drawable.get()); }
+};
}
template <typename T, typename... Args>
@@ -680,6 +691,9 @@
void DisplayListData::drawVectorDrawable(VectorDrawableRoot* tree) {
this->push<DrawVectorDrawable>(0, tree);
}
+void DisplayListData::drawWebView(skiapipeline::FunctorDrawable* drawable) {
+ this->push<DrawWebView>(0, drawable);
+}
typedef void (*draw_fn)(const void*, SkCanvas*, const SkMatrix&);
typedef void (*void_fn)(const void*);
@@ -986,5 +1000,9 @@
fDL->drawVectorDrawable(tree);
}
+void RecordingCanvas::drawWebView(skiapipeline::FunctorDrawable* drawable) {
+ fDL->drawWebView(drawable);
+}
+
} // namespace uirenderer
} // namespace android
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 16ec877..a79b7c0 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -36,6 +36,10 @@
namespace android {
namespace uirenderer {
+namespace skiapipeline {
+class FunctorDrawable;
+}
+
enum class DisplayListOpType : uint8_t {
#define X(T) T,
#include "DisplayListOps.in"
@@ -119,6 +123,7 @@
SkBlendMode, const SkRect*, const SkPaint*);
void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
void drawVectorDrawable(VectorDrawableRoot* tree);
+ void drawWebView(skiapipeline::FunctorDrawable*);
template <typename T, typename... Args>
void* push(size_t, Args&&...);
@@ -203,6 +208,7 @@
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
void drawVectorDrawable(VectorDrawableRoot* tree);
+ void drawWebView(skiapipeline::FunctorDrawable*);
/**
* If "isClipMayBeComplex" returns false, it is guaranteed the current clip is a rectangle.
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index a1be5b7..2ba6fbe 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -361,7 +361,7 @@
void Bitmap::getBounds(SkRect* bounds) const {
SkASSERT(bounds);
- bounds->set(0, 0, SkIntToScalar(width()), SkIntToScalar(height()));
+ bounds->setIWH(width(), height());
}
#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 0db5133..d67cf8c 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -158,7 +158,7 @@
functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas());
}
mDisplayList->mChildFunctors.push_back(functorDrawable);
- drawDrawable(functorDrawable);
+ mRecorder.drawWebView(functorDrawable);
#endif
}
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 88a0c6e..aad15ab 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -726,7 +726,7 @@
// New surface needs a full draw
dirty->setEmpty();
} else {
- if (!dirty->isEmpty() && !dirty->intersect(0, 0, frame.width(), frame.height())) {
+ if (!dirty->isEmpty() && !dirty->intersect(SkRect::MakeIWH(frame.width(), frame.height()))) {
ALOGW("Dirty " RECT_STRING " doesn't intersect with 0 0 %d %d ?", SK_RECT_ARGS(*dirty),
frame.width(), frame.height());
dirty->setEmpty();
@@ -735,7 +735,7 @@
}
if (dirty->isEmpty()) {
- dirty->set(0, 0, frame.width(), frame.height());
+ dirty->setIWH(frame.width(), frame.height());
}
// At this point dirty is the area of the window to update. However,
@@ -751,7 +751,7 @@
if (frame.bufferAge() > (int)mSwapHistory.size()) {
// We don't have enough history to handle this old of a buffer
// Just do a full-draw
- dirty->set(0, 0, frame.width(), frame.height());
+ dirty->setIWH(frame.width(), frame.height());
} else {
// At this point we haven't yet added the latest frame
// to the damage history (happens below)
diff --git a/libs/hwui/tests/common/scenes/RectGridAnimation.cpp b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
index d5ecfaf..80b5cc1 100644
--- a/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
@@ -37,7 +37,7 @@
SkRegion region;
for (int xOffset = 0; xOffset < 200; xOffset += 2) {
for (int yOffset = 0; yOffset < 200; yOffset += 2) {
- region.op(xOffset, yOffset, xOffset + 1, yOffset + 1, SkRegion::kUnion_Op);
+ region.op({xOffset, yOffset, xOffset + 1, yOffset + 1}, SkRegion::kUnion_Op);
}
}
diff --git a/location/java/android/location/GnssCapabilities.java b/location/java/android/location/GnssCapabilities.java
index 36fe8da..2e2f984 100644
--- a/location/java/android/location/GnssCapabilities.java
+++ b/location/java/android/location/GnssCapabilities.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
/**
@@ -164,6 +165,7 @@
return hasCapability(MEASUREMENT_CORRECTIONS_REFLECTING_PLANE);
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder("GnssCapabilities: ( ");
diff --git a/location/java/android/location/GnssMeasurementCorrections.java b/location/java/android/location/GnssMeasurementCorrections.java
index 3e32c21..a23213f 100644
--- a/location/java/android/location/GnssMeasurementCorrections.java
+++ b/location/java/android/location/GnssMeasurementCorrections.java
@@ -176,6 +176,7 @@
}
};
+ @NonNull
@Override
public String toString() {
final String format = " %-29s = %s\n";
diff --git a/location/java/android/location/GnssReflectingPlane.java b/location/java/android/location/GnssReflectingPlane.java
index 9d05287..1acdd1e 100644
--- a/location/java/android/location/GnssReflectingPlane.java
+++ b/location/java/android/location/GnssReflectingPlane.java
@@ -107,6 +107,7 @@
}
};
+ @NonNull
@Override
public String toString() {
final String format = " %-29s = %s\n";
diff --git a/location/java/android/location/GnssSingleSatCorrection.java b/location/java/android/location/GnssSingleSatCorrection.java
index e901909..aeca562 100644
--- a/location/java/android/location/GnssSingleSatCorrection.java
+++ b/location/java/android/location/GnssSingleSatCorrection.java
@@ -268,6 +268,7 @@
}
};
+ @NonNull
@Override
public String toString() {
final String format = " %-29s = %s\n";
diff --git a/location/java/android/location/GpsClock.java b/location/java/android/location/GpsClock.java
index 52ba60e..f123766 100644
--- a/location/java/android/location/GpsClock.java
+++ b/location/java/android/location/GpsClock.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -437,6 +438,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
final String format = " %-15s = %s\n";
diff --git a/location/java/android/location/GpsMeasurement.java b/location/java/android/location/GpsMeasurement.java
index 51718b8..27a8189 100644
--- a/location/java/android/location/GpsMeasurement.java
+++ b/location/java/android/location/GpsMeasurement.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -1244,6 +1245,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
final String format = " %-29s = %s\n";
diff --git a/location/java/android/location/GpsMeasurementsEvent.java b/location/java/android/location/GpsMeasurementsEvent.java
index 1cd1fb4..d69158d 100644
--- a/location/java/android/location/GpsMeasurementsEvent.java
+++ b/location/java/android/location/GpsMeasurementsEvent.java
@@ -140,6 +140,7 @@
parcel.writeTypedArray(measurementsArray, flags);
}
+ @NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder("[ GpsMeasurementsEvent:\n\n");
diff --git a/location/java/android/location/GpsNavigationMessage.java b/location/java/android/location/GpsNavigationMessage.java
index 77f0113..6eeea26 100644
--- a/location/java/android/location/GpsNavigationMessage.java
+++ b/location/java/android/location/GpsNavigationMessage.java
@@ -290,6 +290,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
final String format = " %-15s = %s\n";
diff --git a/location/java/android/location/GpsNavigationMessageEvent.java b/location/java/android/location/GpsNavigationMessageEvent.java
index 2aa685c..f60e5c7 100644
--- a/location/java/android/location/GpsNavigationMessageEvent.java
+++ b/location/java/android/location/GpsNavigationMessageEvent.java
@@ -109,6 +109,7 @@
parcel.writeParcelable(mNavigationMessage, flags);
}
+ @NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder("[ GpsNavigationMessageEvent:\n\n");
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index a05d850..0902acf 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -734,6 +734,7 @@
}
}
+ @NonNull
@Override
public String toString() {
StringBuilder s = new StringBuilder();
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index b15cc5c..ff6921d 100644
--- a/location/lib/Android.bp
+++ b/location/lib/Android.bp
@@ -16,13 +16,12 @@
java_sdk_library {
name: "com.android.location.provider",
- srcs: ["java/**/*.java"],
+ srcs: [
+ "java/**/*.java",
+ ":framework-srcs",
+ ],
libs: [
"androidx.annotation_annotation",
],
api_packages: ["com.android.location.provider"],
- srcs_lib: "framework-minus-apex",
- // TODO(b/70046217): remove core/java and android below. It was added to provide definitions for
- // types like android.os.Bundle
- srcs_lib_whitelist_pkgs: ["android", "com.android.internal.location"],
}
diff --git a/media/Android.bp b/media/Android.bp
index ef32239..a59b3e7 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -45,13 +45,6 @@
}
filegroup {
- name: "updatable-media-srcs-without-aidls",
- srcs : [
- ":mediasession2-srcs-without-aidls",
- ],
-}
-
-filegroup {
name: "mediasession2-srcs",
srcs: [
"apex/java/android/media/Controller2Link.java",
@@ -71,19 +64,6 @@
}
filegroup {
- name: "mediasession2-srcs-without-aidls",
- srcs: [
- ":mediasession2-srcs",
- ],
- exclude_srcs: [
- "apex/java/android/media/IMediaController2.aidl",
- "apex/java/android/media/IMediaSession2.aidl",
- "apex/java/android/media/IMediaSession2Service.aidl",
- ],
- path: "apex/java",
-}
-
-filegroup {
name: "mediaplayer2-srcs",
srcs: [
"apex/java/android/media/CloseGuard.java",
@@ -113,21 +93,21 @@
droidstubs {
name: "updatable-media-stubs",
srcs: [
- ":updatable-media-srcs-without-aidls",
+ ":updatable-media-srcs",
":framework-media-annotation-srcs",
],
args: metalava_updatable_media_args,
- // Ideally, sdk_version here should be "current_system", but "current - 1" is used
- // to avoid dependency cycle with framework.
- sdk_version: "28",
+ aidl: {
+ // TODO(b/135922046) remove this
+ include_dirs: ["frameworks/base/core/java"],
+ },
+ sdk_version: "system_current",
}
java_library {
name: "updatable_media_stubs",
srcs: [":updatable-media-stubs"],
- // Ideally, sdk_version here should be "current_system", but "current - 1" is used
- // to avoid dependency cycle with framework.
- sdk_version: "28",
+ sdk_version: "system_current",
}
java_library {
diff --git a/media/java/android/media/AudioFocusInfo.java b/media/java/android/media/AudioFocusInfo.java
index ee89509..675cf73 100644
--- a/media/java/android/media/AudioFocusInfo.java
+++ b/media/java/android/media/AudioFocusInfo.java
@@ -17,6 +17,7 @@
package android.media;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -155,7 +156,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (obj == null)
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategy.java b/media/java/android/media/audiopolicy/AudioProductStrategy.java
index e456dad..2799d46 100644
--- a/media/java/android/media/audiopolicy/AudioProductStrategy.java
+++ b/media/java/android/media/audiopolicy/AudioProductStrategy.java
@@ -299,6 +299,7 @@
}
};
+ @NonNull
@Override
public String toString() {
StringBuilder s = new StringBuilder();
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 6fd3342..92fb31b 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -1006,7 +1006,7 @@
* @return {@code true} if equals, {@code false} otherwise
*/
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (!(obj instanceof RemoteUserInfo)) {
return false;
}
diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java
index 6197c70..9e671b1 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -179,6 +179,10 @@
* <td>TV content rating system for Canada (French)</td>
* </tr>
* <tr>
+ * <td>DTMB</td>
+ * <td>DTMB content rating system</td>
+ * </tr>
+ * <tr>
* <td>DVB</td>
* <td>DVB content rating system</td>
* </tr>
@@ -199,10 +203,18 @@
* <td>TV content rating system for South Korea</td>
* </tr>
* <tr>
+ * <td>NZ_TV</td>
+ * <td>TV content rating system for New Zealand</td>
+ * </tr>
+ * <tr>
* <td>SG_TV</td>
* <td>TV content rating system for Singapore</td>
* </tr>
* <tr>
+ * <td>TH_TV</td>
+ * <td>TV content rating system for Thailand</td>
+ * </tr>
+ * <tr>
* <td>US_MV</td>
* <td>Movie content rating system for the United States</td>
* </tr>
@@ -356,6 +368,67 @@
* <td>Only to be viewed by adults</td>
* </tr>
* <tr>
+ * <td valign="top" rowspan="15">DTMB</td>
+ * <td>DTMB_4</td>
+ * <td>Recommended for ages 4 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_5</td>
+ * <td>Recommended for ages 5 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_6</td>
+ * <td>Recommended for ages 6 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_7</td>
+ * <td>Recommended for ages 7 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_8</td>
+ * <td>Recommended for ages 8 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_9</td>
+ * <td>Recommended for ages 9 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_10</td>
+ * <td>Recommended for ages 10 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_11</td>
+ * <td>Recommended for ages 11 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_12</td>
+ * <td>Recommended for ages 12 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_13</td>
+ * <td>Recommended for ages 13 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_14</td>
+ * <td>Recommended for ages 14 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_15</td>
+ * <td>Recommended for ages 15 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_16</td>
+ * <td>Recommended for ages 16 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_17</td>
+ * <td>Recommended for ages 17 and over</td>
+ * </tr>
+ * <tr>
+ * <td>DTMB_18</td>
+ * <td>Recommended for ages 18 and over</td>
+ * </tr>
+ * <tr>
* <td valign="top" rowspan="15">DVB</td>
* <td>DVB_4</td>
* <td>Recommended for ages 4 and over</td>
@@ -648,6 +721,22 @@
* <td>For adults only</td>
* </tr>
* <tr>
+ * <td valign="top" rowspan="3">NZ_TV</td>
+ * <td>NZ_TV_G</td>
+ * <td>Programmes which exclude material likely to be unsuitable for children. Programmes
+ * may not necessarily be designed for child viewers but should not contain material likely
+ * to alarm or distress them.</td>
+ * </tr>
+ * <tr>
+ * <td>NZ_TV_PGR</td>
+ * <td>Programmes containing material more suited for mature audiences but not necessarily
+ * unsuitable for child viewers when subject to the guidance of a parent or an adult.</td>
+ * </tr>
+ * <tr>
+ * <td>NZ_TV_AO</td>
+ * <td>Programmes containing adult themes and directed primarily at mature audiences.</td>
+ * </tr>
+ * <tr>
* <td valign="top" rowspan="6">SG_TV</td>
* <td>SG_TV_G</td>
* <td>Suitable for all ages</td>
@@ -674,6 +763,31 @@
* <td>Suitable for adults aged 21 and above</td>
* </tr>
* <tr>
+ * <td valign="top" rowspan="6">TH_TV</td>
+ * <td>TH_TV_4</td>
+ * <td>Suitable for audiences 3 to 5 years of age</td>
+ * </tr>
+ * <tr>
+ * <td>TH_TV_6</td>
+ * <td>Suitable for audiences 6 to 12 years of age</td>
+ * </tr>
+ * <tr>
+ * <td>TH_TV_10</td>
+ * <td>Suitable for all audiences</td>
+ * </tr>
+ * <tr>
+ * <td>TH_TV_13</td>
+ * <td>Parental guidance suggested for viewers age below 13</td>
+ * </tr>
+ * <tr>
+ * <td>TH_TV_18</td>
+ * <td>Parental guidance suggested for viewers age below 18</td>
+ * </tr>
+ * <tr>
+ * <td>TH_TV_19</td>
+ * <td>Not suitable for children and teenagers</td>
+ * </tr>
+ * <tr>
* <td valign="top" rowspan="5">US_MV</td>
* <td>US_MV_G</td>
* <td>General audiences</td>
diff --git a/media/java/android/media/tv/TvInputHardwareInfo.java b/media/java/android/media/tv/TvInputHardwareInfo.java
index 5b316be..b12f7c5 100644
--- a/media/java/android/media/tv/TvInputHardwareInfo.java
+++ b/media/java/android/media/tv/TvInputHardwareInfo.java
@@ -19,12 +19,14 @@
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.hardware.tv.input.V1_0.Constants;
import android.media.AudioManager;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
+
import java.lang.annotation.Retention;
/**
@@ -141,6 +143,7 @@
return mCableConnectionStatus;
}
+ @NonNull
@Override
public String toString() {
StringBuilder b = new StringBuilder(128);
diff --git a/media/java/android/media/tv/TvStreamConfig.java b/media/java/android/media/tv/TvStreamConfig.java
index f012b46..7ea93b4 100644
--- a/media/java/android/media/tv/TvStreamConfig.java
+++ b/media/java/android/media/tv/TvStreamConfig.java
@@ -16,6 +16,8 @@
package android.media.tv;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -87,6 +89,7 @@
return mGeneration;
}
+ @NonNull
@Override
public String toString() {
return "TvStreamConfig {mStreamId=" + mStreamId + ";" + "mType=" + mType + ";mGeneration="
@@ -163,7 +166,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null) return false;
if (!(obj instanceof TvStreamConfig)) return false;
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index e09eeb8..ea00d6e 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -394,6 +394,7 @@
*
* @param encrypted The encryption status of the track.
*/
+ @NonNull
public Builder setEncrypted(boolean encrypted) {
mEncrypted = encrypted;
return this;
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 8d420e2..cbc820b 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -743,8 +743,8 @@
}
status_t JMediaCodec::getMetrics(JNIEnv *, MediaAnalyticsItem * &reply) const {
-
- status_t status = mCodec->getMetrics(reply);
+ mediametrics_handle_t reply2 = MediaAnalyticsItem::convert(reply);
+ status_t status = mCodec->getMetrics(reply2);
return status;
}
@@ -1848,7 +1848,7 @@
}
// get what we have for the metrics from the codec
- MediaAnalyticsItem *item = NULL;
+ MediaAnalyticsItem *item = 0;
status_t err = codec->getMetrics(env, item);
if (err != OK) {
@@ -1860,7 +1860,7 @@
// housekeeping
delete item;
- item = NULL;
+ item = 0;
return mybundle;
}
diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp
index 923d1d2..307d80d 100644
--- a/media/jni/android_media_MediaCodecList.cpp
+++ b/media/jni/android_media_MediaCodecList.cpp
@@ -26,6 +26,7 @@
#include <utils/Vector.h>
+#include <mutex>
#include <vector>
#include "android_runtime/AndroidRuntime.h"
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
index 338ec12..85a007f 100644
--- a/media/lib/signer/Android.bp
+++ b/media/lib/signer/Android.bp
@@ -16,8 +16,9 @@
java_sdk_library {
name: "com.android.mediadrm.signer",
- srcs: ["java/**/*.java"],
+ srcs: [
+ "java/**/*.java",
+ ":framework-srcs",
+ ],
api_packages: ["com.android.mediadrm.signer"],
- srcs_lib: "framework-minus-apex",
- srcs_lib_whitelist_pkgs: ["android.media"],
}
diff --git a/mime/Android.bp b/mime/Android.bp
deleted file mode 100644
index 9303755..0000000
--- a/mime/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library {
- name: "mimemap",
- visibility: [
- "//cts/tests/tests/mimemap:__subpackages__",
- "//frameworks/base:__subpackages__",
- ],
-
- srcs: [
- "java/android/content/type/MimeMapImpl.java",
- ],
-
- java_resources: [
- ":debian.mime.types",
- ":android.mime.types",
- ],
-
- sdk_version: "core_platform",
-}
-
-filegroup {
- name: "android.mime.types",
- visibility: [
- "//visibility:private",
- ],
- path: "java-res/",
- srcs: [
- "java-res/android.mime.types",
- ],
-}
diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types
deleted file mode 100644
index 1ca912e..0000000
--- a/mime/java-res/android.mime.types
+++ /dev/null
@@ -1,146 +0,0 @@
-
-###############################################################################
-#
-# Android-specific MIME type <-> extension mappings
-#
-# Each line below defines an mapping from one MIME type to the first of the
-# listed extensions, and from listed extension back to the MIME type.
-# A mapping overrides any previous mapping _from_ that same MIME type or
-# extension (put() semantics), unless that MIME type / extension is prefixed with '?'
-# (putIfAbsent() semantics).
-#
-#
-###############################################################################
-#
-# EXAMPLES
-#
-# A line of the form:
-#
-# ?mime ext1 ?ext2 ext3
-#
-# affects the current mappings along the lines of the following pseudo code:
-#
-# mimeToExt.putIfAbsent("mime", "ext1");
-# extToMime.put("ext1", "mime");
-# extToMime.putIfAbsent("ext2", "mime");
-# extToMime.put("ext3", "mime");
-#
-# The line:
-#
-# ?text/plain txt
-#
-# leaves any earlier mapping for "text/plain" untouched, or maps that MIME type
-# to the file extension ".txt" if there is no earlier mapping. The line also
-# sets the mapping from file extension ".txt" to be the MIME type "text/plain",
-# regardless of whether a previous mapping existed.
-#
-###############################################################################
-
-
-# File extensions that Android wants to override to point to the given MIME type.
-#
-# After processing a line of the form:
-# ?<mimeType> <extension1> <extension2>
-# If <mimeType> was not already mapped to an extension then it will be
-# mapped to <extension1>.
-# <extension1> and <extension2> are mapped (or remapped) to <mimeType>.
-
-?application/epub+zip epub
-?application/pkix-cert cer
-?application/rss+xml rss
-?application/vnd.android.ota ota
-?application/vnd.apple.mpegurl m3u8
-?application/vnd.ms-pki.stl stl
-?application/vnd.ms-powerpoint pot
-?application/vnd.ms-wpl wpl
-?application/vnd.stardivision.impress sdp
-?application/vnd.stardivision.writer vor
-?application/vnd.youtube.yt yt
-?application/x-android-drm-fl fl
-?application/x-flac flac
-?application/x-font pcf
-?application/x-mpegurl m3u m3u8
-?application/x-pem-file pem
-?application/x-pkcs12 p12 pfx
-?application/x-webarchive webarchive
-?application/x-webarchive-xml webarchivexml
-?application/x-x509-server-cert crt
-?application/x-x509-user-cert crt
-
-?audio/3gpp 3gpp
-?audio/aac-adts aac
-?audio/imelody imy
-?audio/midi rtttl xmf
-?audio/mobile-xmf mxmf
-?audio/mp4 m4a
-?audio/mpegurl m3u
-?audio/sp-midi smf
-?audio/x-matroska mka
-?audio/x-pn-realaudio ra
-
-?image/bmp bmp
-?image/heic heic
-?image/heic-sequence heics
-?image/heif heif hif
-?image/heif-sequence heifs
-?image/ico cur
-?image/webp webp
-?image/x-adobe-dng dng
-?image/x-fuji-raf raf
-?image/x-icon ico
-?image/x-nikon-nrw nrw
-?image/x-panasonic-rw2 rw2
-?image/x-pentax-pef pef
-?image/x-samsung-srw srw
-?image/x-sony-arw arw
-
-?text/comma-separated-values csv
-?text/plain diff po
-?text/rtf rtf
-?text/text phps
-?text/xml xml
-?text/x-vcard vcf
-
-?video/3gpp2 3gpp2 3g2
-?video/3gpp 3gpp
-?video/avi avi
-?video/m4v m4v
-?video/mp2p mpeg
-?video/mp2t m2ts mts
-?video/mp2ts ts
-?video/vnd.youtube.yt yt
-?video/x-webex wrf
-
-# Optional additions that should not override any previous mapping.
-
-?application/x-wifi-config ?xml
-
-# Special cases where Android has a strong opinion about mappings, so we
-# define them very last and make them override in both directions (no "?").
-#
-# Lines here are of the form:
-# <mimeType> <extension1> <extension2> ...
-#
-# After processing each line,
-# <mimeType> is mapped to <extension1>
-# <extension1>, <extension2>, ... are all mapped to <mimeType>
-# This overrides any mappings for this <mimeType> / for these extensions
-# that may have been defined earlier.
-
-application/pgp-signature pgp
-application/x-x509-ca-cert crt
-audio/aac aac
-audio/basic snd
-audio/flac flac
-audio/midi rtx
-audio/mpeg mp3 m4a m4r
-audio/x-mpegurl m3u m3u8
-image/jpeg jpg
-image/x-ms-bmp bmp
-text/plain txt
-text/x-c++hdr hpp
-text/x-c++src cpp
-video/3gpp 3gpp
-video/mpeg mpeg
-video/quicktime mov
-video/x-matroska mkv
diff --git a/mime/java/android/content/type/MimeMapImpl.java b/mime/java/android/content/type/MimeMapImpl.java
deleted file mode 100644
index c904ea3..0000000
--- a/mime/java/android/content/type/MimeMapImpl.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.type;
-
-import libcore.net.MimeMap;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * Default implementation of {@link MimeMap}, a bidirectional mapping between
- * MIME types and file extensions.
- *
- * This default mapping is loaded from data files that start with some mappings
- * recognized by IANA plus some custom extensions and overrides.
- *
- * @hide
- */
-public class MimeMapImpl extends MimeMap {
-
- /**
- * Creates and returns a new {@link MimeMapImpl} instance that implements.
- * Android's default mapping between MIME types and extensions.
- */
- public static MimeMapImpl createDefaultInstance() {
- return parseFromResources("/mime.types", "/android.mime.types");
- }
-
- private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+");
-
- /**
- * Note: These maps only contain lowercase keys/values, regarded as the
- * {@link #toLowerCase(String) canonical form}.
- *
- * <p>This is the case for both extensions and MIME types. The mime.types
- * data file contains examples of mixed-case MIME types, but some applications
- * use the lowercase version of these same types. RFC 2045 section 2 states
- * that MIME types are case insensitive.
- */
- private final Map<String, String> mMimeTypeToExtension;
- private final Map<String, String> mExtensionToMimeType;
-
- public MimeMapImpl(Map<String, String> mimeTypeToExtension,
- Map<String, String> extensionToMimeType) {
- this.mMimeTypeToExtension = new HashMap<>(mimeTypeToExtension);
- for (Map.Entry<String, String> entry : mimeTypeToExtension.entrySet()) {
- checkValidMimeType(entry.getKey());
- checkValidExtension(entry.getValue());
- }
- this.mExtensionToMimeType = new HashMap<>(extensionToMimeType);
- for (Map.Entry<String, String> entry : extensionToMimeType.entrySet()) {
- checkValidExtension(entry.getKey());
- checkValidMimeType(entry.getValue());
- }
- }
-
- private static void checkValidMimeType(String s) {
- if (MimeMap.isNullOrEmpty(s) || !s.equals(MimeMap.toLowerCase(s))) {
- throw new IllegalArgumentException("Invalid MIME type: " + s);
- }
- }
-
- private static void checkValidExtension(String s) {
- if (MimeMap.isNullOrEmpty(s) || !s.equals(MimeMap.toLowerCase(s))) {
- throw new IllegalArgumentException("Invalid extension: " + s);
- }
- }
-
- static MimeMapImpl parseFromResources(String... resourceNames) {
- Map<String, String> mimeTypeToExtension = new HashMap<>();
- Map<String, String> extensionToMimeType = new HashMap<>();
- for (String resourceName : resourceNames) {
- parseTypes(mimeTypeToExtension, extensionToMimeType, resourceName);
- }
- return new MimeMapImpl(mimeTypeToExtension, extensionToMimeType);
- }
-
- /**
- * An element of a *mime.types file: A MIME type or an extension, with an optional
- * prefix of "?" (if not overriding an earlier value).
- */
- private static class Element {
- public final boolean keepExisting;
- public final String s;
-
- Element(boolean keepExisting, String value) {
- this.keepExisting = keepExisting;
- this.s = toLowerCase(value);
- if (value.isEmpty()) {
- throw new IllegalArgumentException();
- }
- }
-
- public String toString() {
- return keepExisting ? ("?" + s) : s;
- }
- }
-
- private static String maybePut(Map<String, String> map, Element keyElement, String value) {
- if (keyElement.keepExisting) {
- return map.putIfAbsent(keyElement.s, value);
- } else {
- return map.put(keyElement.s, value);
- }
- }
-
- private static void parseTypes(Map<String, String> mimeTypeToExtension,
- Map<String, String> extensionToMimeType, String resource) {
- try (BufferedReader r = new BufferedReader(
- new InputStreamReader(MimeMapImpl.class.getResourceAsStream(resource)))) {
- String line;
- while ((line = r.readLine()) != null) {
- int commentPos = line.indexOf('#');
- if (commentPos >= 0) {
- line = line.substring(0, commentPos);
- }
- line = line.trim();
- // The first time a MIME type is encountered it is mapped to the first extension
- // listed in its line. The first time an extension is encountered it is mapped
- // to the MIME type.
- //
- // When encountering a previously seen MIME type or extension, then by default
- // the later ones override earlier mappings (put() semantics); however if a MIME
- // type or extension is prefixed with '?' then any earlier mapping _from_ that
- // MIME type / extension is kept (putIfAbsent() semantics).
- final String[] split = SPLIT_PATTERN.split(line);
- if (split.length <= 1) {
- // Need mimeType + at least one extension to make a mapping.
- // "mime.types" files may also contain lines with just a mimeType without
- // an extension but we skip them as they provide no mapping info.
- continue;
- }
- List<Element> lineElements = new ArrayList<>(split.length);
- for (String s : split) {
- boolean keepExisting = s.startsWith("?");
- if (keepExisting) {
- s = s.substring(1);
- }
- if (s.isEmpty()) {
- throw new IllegalArgumentException("Invalid entry in '" + line + "'");
- }
- lineElements.add(new Element(keepExisting, s));
- }
-
- // MIME type -> first extension (one mapping)
- // This will override any earlier mapping from this MIME type to another
- // extension, unless this MIME type was prefixed with '?'.
- Element mimeElement = lineElements.get(0);
- List<Element> extensionElements = lineElements.subList(1, lineElements.size());
- String firstExtension = extensionElements.get(0).s;
- maybePut(mimeTypeToExtension, mimeElement, firstExtension);
-
- // extension -> MIME type (one or more mappings).
- // This will override any earlier mapping from this extension to another
- // MIME type, unless this extension was prefixed with '?'.
- for (Element extensionElement : extensionElements) {
- maybePut(extensionToMimeType, extensionElement, mimeElement.s);
- }
- }
- } catch (IOException | RuntimeException e) {
- throw new RuntimeException("Failed to parse " + resource, e);
- }
- }
-
- @Override
- protected String guessExtensionFromLowerCaseMimeType(String mimeType) {
- return mMimeTypeToExtension.get(mimeType);
- }
-
- @Override
- protected String guessMimeTypeFromLowerCaseExtension(String extension) {
- return mExtensionToMimeType.get(extension);
- }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java
index 78bb1bc..013c63b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java
@@ -192,23 +192,28 @@
}
}
- // Set button text based on security lock type
+ // Set button text based on screen lock type
private void setButtonText() {
LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
int passwordQuality = lockPatternUtils.getActivePasswordQuality(mUid);
switch (passwordQuality) {
// PIN
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
+ mButton.setText(R.string.unlock_dialog_button_text_pin);
+ break;
// Pattern
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
mButton.setText(R.string.unlock_dialog_button_text_pattern);
break;
// Password
- case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
mButton.setText(R.string.unlock_dialog_button_text_password);
break;
default:
- Log.e(TAG, "Encountered unexpected security type when attempting to set "
+ Log.e(TAG, "Encountered unexpected screen lock type when attempting to set "
+ "button text:" + passwordQuality);
}
}
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 7760e0e..9c8345da 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -24,6 +24,8 @@
"SettingsLibProgressBar",
"SettingsLibAdaptiveIcon",
"SettingsLibRadioButtonPreference",
+ "WifiTrackerLib",
+ "SettingsLibDisplayDensityUtils",
],
// ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
diff --git a/packages/SettingsLib/DisplayDensityUtils/Android.bp b/packages/SettingsLib/DisplayDensityUtils/Android.bp
new file mode 100644
index 0000000..27d0cb5
--- /dev/null
+++ b/packages/SettingsLib/DisplayDensityUtils/Android.bp
@@ -0,0 +1,7 @@
+android_library {
+ name: "SettingsLibDisplayDensityUtils",
+
+ srcs: ["src/**/*.java"],
+
+ min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/DisplayDensityUtils/AndroidManifest.xml b/packages/SettingsLib/DisplayDensityUtils/AndroidManifest.xml
new file mode 100644
index 0000000..0a4e2bb
--- /dev/null
+++ b/packages/SettingsLib/DisplayDensityUtils/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.settingslib.display">
+
+</manifest>
diff --git a/packages/SettingsLib/DisplayDensityUtils/src/com/android/settingslib/display/DisplayDensityConfiguration.java b/packages/SettingsLib/DisplayDensityUtils/src/com/android/settingslib/display/DisplayDensityConfiguration.java
new file mode 100644
index 0000000..284a902
--- /dev/null
+++ b/packages/SettingsLib/DisplayDensityUtils/src/com/android/settingslib/display/DisplayDensityConfiguration.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.display;
+
+import android.os.AsyncTask;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
+
+/** Utility methods for controlling the display density. */
+public class DisplayDensityConfiguration {
+ private static final String LOG_TAG = "DisplayDensityConfig";
+
+ /**
+ * Returns the default density for the specified display.
+ *
+ * @param displayId the identifier of the display
+ * @return the default density of the specified display, or {@code -1} if the display does not
+ * exist or the density could not be obtained
+ */
+ static int getDefaultDisplayDensity(int displayId) {
+ try {
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ return wm.getInitialDisplayDensity(displayId);
+ } catch (RemoteException exc) {
+ return -1;
+ }
+ }
+
+ /**
+ * Asynchronously applies display density changes to the specified display.
+ *
+ * <p>The change will be applied to the user specified by the value of {@link
+ * UserHandle#myUserId()} at the time the method is called.
+ *
+ * @param displayId the identifier of the display to modify
+ */
+ public static void clearForcedDisplayDensity(final int displayId) {
+ final int userId = UserHandle.myUserId();
+ AsyncTask.execute(
+ () -> {
+ try {
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ wm.clearForcedDisplayDensityForUser(displayId, userId);
+ } catch (RemoteException exc) {
+ Log.w(LOG_TAG, "Unable to clear forced display density setting");
+ }
+ });
+ }
+
+ /**
+ * Asynchronously applies display density changes to the specified display.
+ *
+ * <p>The change will be applied to the user specified by the value of {@link
+ * UserHandle#myUserId()} at the time the method is called.
+ *
+ * @param displayId the identifier of the display to modify
+ * @param density the density to force for the specified display
+ */
+ public static void setForcedDisplayDensity(final int displayId, final int density) {
+ final int userId = UserHandle.myUserId();
+ AsyncTask.execute(
+ () -> {
+ try {
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ wm.setForcedDisplayDensityForUser(displayId, density, userId);
+ } catch (RemoteException exc) {
+ Log.w(LOG_TAG, "Unable to save forced display density setting");
+ }
+ });
+ }
+}
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index eb6160a..75344c4 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -376,7 +376,7 @@
<string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"ప్రొటానోమలీ (ఎరుపు-ఆకుపచ్చ రంగు)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"ట్రైటనోమలీ (నీలం-పసుపు రంగు)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"రంగు సవరణ"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ ఫీచర్ ప్రయోగాత్మకమైనది, పనితీరుపై ప్రభావం చూపవచ్చు."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
<string name="power_remaining_settings_home_page" msgid="4845022416859002011">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="6123167166221295462">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
index 99d48d3..aac7fc3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -34,11 +34,14 @@
import com.android.settingslib.R;
+import libcore.timezone.CountryTimeZones;
+import libcore.timezone.CountryTimeZones.TimeZoneMapping;
import libcore.timezone.TimeZoneFinder;
import org.xmlpull.v1.XmlPullParserException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -387,7 +390,21 @@
@VisibleForTesting
public List<String> lookupTimeZoneIdsByCountry(String country) {
- return TimeZoneFinder.getInstance().lookupTimeZoneIdsByCountry(country);
+ final CountryTimeZones countryTimeZones =
+ TimeZoneFinder.getInstance().lookupCountryTimeZones(country);
+ if (countryTimeZones == null) {
+ return null;
+ }
+ final List<TimeZoneMapping> mappings = countryTimeZones.getTimeZoneMappings();
+ return extractTimeZoneIds(mappings);
+ }
+
+ private static List<String> extractTimeZoneIds(List<TimeZoneMapping> timeZoneMappings) {
+ final List<String> zoneIds = new ArrayList<>(timeZoneMappings.size());
+ for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
+ zoneIds.add(timeZoneMapping.timeZoneId);
+ }
+ return Collections.unmodifiableList(zoneIds);
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java
index 008943c..12d054e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java
@@ -126,10 +126,13 @@
return;
}
- final List<Long> devicesHiSyncIds = new ArrayList<>();
final List<BluetoothDevice> devices = hapProfile.getConnectableDevices();
-
for (BluetoothDevice device : devices) {
+ // Only add master HearingAid device, ignore sub
+ if (mCachedBluetoothDeviceManager.isSubDevice(device)) {
+ Log.w(TAG, "Sub hearingAid device: " + device.getName());
+ continue;
+ }
final CachedBluetoothDevice cachedDevice =
mCachedBluetoothDeviceManager.findDevice(device);
@@ -142,13 +145,8 @@
+ ", is connected : " + cachedDevice.isConnected()
+ ", is preferred : " + hapProfile.isPreferred(device));
- final long hiSyncId = hapProfile.getHiSyncId(device);
-
- // device with same hiSyncId should not be shown in the UI.
- // So do not add it into connectedDevices.
- if (!devicesHiSyncIds.contains(hiSyncId) && hapProfile.isPreferred(device)
+ if (hapProfile.isPreferred(device)
&& BluetoothDevice.BOND_BONDED == cachedDevice.getBondState()) {
- devicesHiSyncIds.add(hiSyncId);
addMediaDevice(cachedDevice);
}
}
@@ -284,9 +282,8 @@
+ activeDevice + ", profile : " + bluetoothProfile);
if (BluetoothProfile.HEARING_AID == bluetoothProfile) {
- if (activeDevice != null) {
- dispatchConnectedDeviceChanged(MediaDeviceUtils.getId(activeDevice));
- }
+ dispatchConnectedDeviceChanged(activeDevice == null
+ ? PhoneMediaDevice.ID : MediaDeviceUtils.getId(activeDevice));
} else if (BluetoothProfile.A2DP == bluetoothProfile) {
// When active device change to Hearing Aid,
// BluetoothEventManager also send onActiveDeviceChanged() to notify that active device
@@ -304,12 +301,16 @@
private MediaDevice findActiveHearingAidDevice() {
final HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
- if (hearingAidProfile != null) {
- final List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices();
- for (BluetoothDevice btDevice : activeDevices) {
- if (btDevice != null) {
- return findMediaDevice(MediaDeviceUtils.getId(btDevice));
- }
+ if (hearingAidProfile == null) {
+ Log.e(TAG, "findActiveHearingAidDevice: hearingAidProfile == null");
+ return null;
+ }
+ final List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices();
+ for (BluetoothDevice btDevice : activeDevices) {
+ final MediaDevice mediaDevice =
+ findMediaDevice(Long.toString(hearingAidProfile.getHiSyncId(btDevice)));
+ if (mediaDevice != null) {
+ return mediaDevice;
}
}
return null;
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java
index f181150..4b8e706 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java
@@ -32,6 +32,9 @@
* @return CachedBluetoothDevice address
*/
public static String getId(CachedBluetoothDevice cachedDevice) {
+ if (cachedDevice.isHearingAidDevice()) {
+ return Long.toString(cachedDevice.getHiSyncId());
+ }
return cachedDevice.getAddress();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/LongPressWifiEntryPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/LongPressWifiEntryPreference.java
new file mode 100644
index 0000000..503d60c
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/LongPressWifiEntryPreference.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.wifi;
+
+import android.content.Context;
+
+import androidx.fragment.app.Fragment;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.wifitrackerlib.WifiEntry;
+
+/**
+ * WifiEntryPreference that can be long pressed.
+ */
+public class LongPressWifiEntryPreference extends WifiEntryPreference {
+
+ private final Fragment mFragment;
+
+ public LongPressWifiEntryPreference(Context context, WifiEntry wifiEntry, Fragment fragment) {
+ super(context, wifiEntry);
+ mFragment = fragment;
+ }
+
+ @Override
+ public void onBindViewHolder(final PreferenceViewHolder view) {
+ super.onBindViewHolder(view);
+ if (mFragment != null) {
+ view.itemView.setOnCreateContextMenuListener(mFragment);
+ view.itemView.setTag(this);
+ view.itemView.setLongClickable(true);
+ }
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java
new file mode 100644
index 0000000..22f47f1
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.wifi;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ImageView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settingslib.R;
+import com.android.settingslib.Utils;
+import com.android.wifitrackerlib.WifiEntry;
+
+/**
+ * Preference to display a WifiEntry in a wifi picker.
+ */
+public class WifiEntryPreference extends Preference implements WifiEntry.WifiEntryCallback {
+
+ private static final int[] STATE_SECURED = {
+ R.attr.state_encrypted
+ };
+
+ private static final int[] STATE_METERED = {
+ R.attr.state_metered
+ };
+
+ private static final int[] FRICTION_ATTRS = {
+ R.attr.wifi_friction
+ };
+
+ // These values must be kept within [WifiEntry.WIFI_LEVEL_MIN, WifiEntry.WIFI_LEVEL_MAX]
+ private static final int[] WIFI_CONNECTION_STRENGTH = {
+ R.string.accessibility_no_wifi,
+ R.string.accessibility_wifi_one_bar,
+ R.string.accessibility_wifi_two_bars,
+ R.string.accessibility_wifi_three_bars,
+ R.string.accessibility_wifi_signal_full
+ };
+
+ // StateListDrawable to display secured lock / metered "$" icon
+ @Nullable private final StateListDrawable mFrictionSld;
+ private final IconInjector mIconInjector;
+ private WifiEntry mWifiEntry;
+ private int mLevel = -1;
+ private CharSequence mContentDescription;
+
+ public WifiEntryPreference(@NonNull Context context, @NonNull WifiEntry wifiEntry) {
+ this(context, wifiEntry, new IconInjector(context));
+ }
+
+ @VisibleForTesting
+ WifiEntryPreference(@NonNull Context context, @NonNull WifiEntry wifiEntry,
+ @NonNull IconInjector iconInjector) {
+ super(context);
+
+ setLayoutResource(R.layout.preference_access_point);
+ setWidgetLayoutResource(R.layout.access_point_friction_widget);
+ mFrictionSld = getFrictionStateListDrawable();
+ mWifiEntry = wifiEntry;
+ mWifiEntry.setListener(this);
+ mIconInjector = iconInjector;
+ refresh();
+ }
+
+ public WifiEntry getWifiEntry() {
+ return mWifiEntry;
+ }
+
+ @Override
+ public void onBindViewHolder(final PreferenceViewHolder view) {
+ super.onBindViewHolder(view);
+ final Drawable drawable = getIcon();
+ if (drawable != null) {
+ drawable.setLevel(mLevel);
+ }
+
+ view.itemView.setContentDescription(mContentDescription);
+
+ final ImageView frictionImageView = (ImageView) view.findViewById(R.id.friction_icon);
+ bindFrictionImage(frictionImageView);
+
+ // Turn off divider
+ view.findViewById(R.id.two_target_divider).setVisibility(View.INVISIBLE);
+ }
+
+ /**
+ * Updates the title and summary; may indirectly call notifyChanged().
+ */
+ public void refresh() {
+ setTitle(mWifiEntry.getTitle());
+ final int level = mWifiEntry.getLevel();
+ if (level != mLevel) {
+ mLevel = level;
+ updateIcon(mLevel);
+ notifyChanged();
+ }
+
+ setSummary(mWifiEntry.getSummary());
+ mContentDescription = buildContentDescription();
+ }
+
+ /**
+ * Indicates the state of the WifiEntry has changed and clients may retrieve updates through
+ * the WifiEntry getter methods.
+ */
+ public void onUpdated() {
+ // TODO(b/70983952): Fill this method in
+ refresh();
+ }
+
+ /**
+ * Result of the connect request indicated by the WifiEntry.CONNECT_STATUS constants.
+ */
+ public void onConnectResult(int status) {
+ // TODO(b/70983952): Fill this method in
+ }
+
+ /**
+ * Result of the disconnect request indicated by the WifiEntry.DISCONNECT_STATUS constants.
+ */
+ public void onDisconnectResult(int status) {
+ // TODO(b/70983952): Fill this method in
+ }
+
+ /**
+ * Result of the forget request indicated by the WifiEntry.FORGET_STATUS constants.
+ */
+ public void onForgetResult(int status) {
+ // TODO(b/70983952): Fill this method in
+ }
+
+ private void updateIcon(int level) {
+ if (level == -1) {
+ setIcon(null);
+ return;
+ }
+
+ final Drawable drawable = mIconInjector.getIcon(level);
+ if (drawable != null) {
+ drawable.setTintList(Utils.getColorAttr(getContext(),
+ android.R.attr.colorControlNormal));
+ setIcon(drawable);
+ } else {
+ setIcon(null);
+ }
+ }
+
+ @Nullable
+ private StateListDrawable getFrictionStateListDrawable() {
+ TypedArray frictionSld;
+ try {
+ frictionSld = getContext().getTheme().obtainStyledAttributes(FRICTION_ATTRS);
+ } catch (Resources.NotFoundException e) {
+ // Fallback for platforms that do not need friction icon resources.
+ frictionSld = null;
+ }
+ return frictionSld != null ? (StateListDrawable) frictionSld.getDrawable(0) : null;
+ }
+
+ /**
+ * Binds the friction icon drawable using a StateListDrawable.
+ *
+ * <p>Friction icons will be rebound when notifyChange() is called, and therefore
+ * do not need to be managed in refresh()</p>.
+ */
+ private void bindFrictionImage(ImageView frictionImageView) {
+ if (frictionImageView == null || mFrictionSld == null) {
+ return;
+ }
+ if ((mWifiEntry.getSecurity() != WifiEntry.SECURITY_NONE)
+ && (mWifiEntry.getSecurity() != WifiEntry.SECURITY_OWE)
+ && (mWifiEntry.getSecurity() != WifiEntry.SECURITY_OWE_TRANSITION)) {
+ mFrictionSld.setState(STATE_SECURED);
+ } else if (mWifiEntry.isMetered()) {
+ mFrictionSld.setState(STATE_METERED);
+ }
+ frictionImageView.setImageDrawable(mFrictionSld.getCurrent());
+ }
+
+ /**
+ * Helper method to generate content description string.
+ */
+ @VisibleForTesting
+ CharSequence buildContentDescription() {
+ final Context context = getContext();
+
+ CharSequence contentDescription = getTitle();
+ final CharSequence summary = getSummary();
+ if (!TextUtils.isEmpty(summary)) {
+ contentDescription = TextUtils.concat(contentDescription, ",", summary);
+ }
+ int level = mWifiEntry.getLevel();
+ if (level >= 0 && level < WIFI_CONNECTION_STRENGTH.length) {
+ contentDescription = TextUtils.concat(contentDescription, ",",
+ context.getString(WIFI_CONNECTION_STRENGTH[level]));
+ }
+ return TextUtils.concat(contentDescription, ",",
+ mWifiEntry.getSecurity() == WifiEntry.SECURITY_NONE
+ ? context.getString(R.string.accessibility_wifi_security_type_none)
+ : context.getString(R.string.accessibility_wifi_security_type_secured));
+ }
+
+
+ static class IconInjector {
+ private final Context mContext;
+
+ IconInjector(Context context) {
+ mContext = context;
+ }
+
+ public Drawable getIcon(int level) {
+ return mContext.getDrawable(Utils.getWifiIconResource(level));
+ }
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java
index 030bab6..f27cef9 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/BluetoothMediaManagerTest.java
@@ -428,20 +428,21 @@
@Test
public void onActiveDeviceChanged_hearingAidDeviceIsActive_returnHearingAidDeviceId() {
+ final Long hiSyncId = Integer.toUnsignedLong(12345);
final BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
final List<BluetoothDevice> devices = new ArrayList<>();
devices.add(bluetoothDevice);
final BluetoothMediaDevice bluetoothMediaDevice = mock(BluetoothMediaDevice.class);
mMediaManager.mMediaDevices.add(bluetoothMediaDevice);
- when(bluetoothDevice.getAddress()).thenReturn(TEST_ADDRESS);
+ when(mHapProfile.getHiSyncId(bluetoothDevice)).thenReturn(hiSyncId);
when(mHapProfile.getActiveDevices()).thenReturn(devices);
- when(bluetoothMediaDevice.getId()).thenReturn(TEST_ADDRESS);
+ when(bluetoothMediaDevice.getId()).thenReturn(Long.toString(hiSyncId));
mMediaManager.registerCallback(mCallback);
mMediaManager.onActiveDeviceChanged(null, BluetoothProfile.A2DP);
- verify(mCallback).onConnectedDeviceChanged(TEST_ADDRESS);
+ verify(mCallback).onConnectedDeviceChanged(Long.toString(hiSyncId));
}
@Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java
new file mode 100644
index 0000000..752a549
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import com.android.wifitrackerlib.WifiEntry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiEntryPreferenceTest {
+
+ private Context mContext;
+
+ @Mock
+ private WifiEntry mMockWifiEntry;
+ @Mock
+ private WifiEntryPreference.IconInjector mMockIconInjector;
+
+ @Mock
+ private Drawable mMockDrawable0;
+ @Mock
+ private Drawable mMockDrawable1;
+ @Mock
+ private Drawable mMockDrawable2;
+ @Mock
+ private Drawable mMockDrawable3;
+ @Mock
+ private Drawable mMockDrawable4;
+
+ private static final String MOCK_TITLE = "title";
+ private static final String MOCK_SUMMARY = "summary";
+
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+
+ MockitoAnnotations.initMocks(this);
+
+ when(mMockWifiEntry.getTitle()).thenReturn(MOCK_TITLE);
+ when(mMockWifiEntry.getSummary()).thenReturn(MOCK_SUMMARY);
+
+ when(mMockIconInjector.getIcon(0)).thenReturn(mMockDrawable0);
+ when(mMockIconInjector.getIcon(1)).thenReturn(mMockDrawable1);
+ when(mMockIconInjector.getIcon(2)).thenReturn(mMockDrawable2);
+ when(mMockIconInjector.getIcon(3)).thenReturn(mMockDrawable3);
+ when(mMockIconInjector.getIcon(4)).thenReturn(mMockDrawable4);
+ }
+
+ @Test
+ public void constructor_shouldSetWifiEntryTitleAndSummary() {
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ assertThat(pref.getTitle()).isEqualTo(MOCK_TITLE);
+ assertThat(pref.getSummary()).isEqualTo(MOCK_SUMMARY);
+ }
+
+ @Test
+ public void constructor_shouldSetIcon() {
+ when(mMockWifiEntry.getLevel()).thenReturn(0);
+
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ assertThat(pref.getIcon()).isEqualTo(mMockDrawable0);
+ }
+
+ @Test
+ public void titleChanged_refresh_shouldUpdateTitle() {
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+ final String updatedTitle = "updated title";
+ when(mMockWifiEntry.getTitle()).thenReturn(updatedTitle);
+
+ pref.refresh();
+
+ assertThat(pref.getTitle()).isEqualTo(updatedTitle);
+ }
+
+ @Test
+ public void summaryChanged_refresh_shouldUpdateSummary() {
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+ final String updatedSummary = "updated summary";
+ when(mMockWifiEntry.getSummary()).thenReturn(updatedSummary);
+
+ pref.refresh();
+
+ assertThat(pref.getSummary()).isEqualTo(updatedSummary);
+ }
+
+ @Test
+ public void levelChanged_refresh_shouldUpdateLevelIcon() {
+ final List<Drawable> iconList = new ArrayList<>();
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ when(mMockWifiEntry.getLevel()).thenReturn(0);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(2);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(3);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(4);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(-1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+
+ assertThat(iconList).containsExactly(mMockDrawable0, mMockDrawable1,
+ mMockDrawable2, mMockDrawable3, mMockDrawable4, null);
+ }
+}
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index e54b847..681b494 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -11,7 +11,7 @@
],
static_libs: [
"junit",
- "SettingsLib",
+ "SettingsLibDisplayDensityUtils",
],
platform_apis: true,
certificate: "platform",
@@ -24,13 +24,17 @@
// because this test is not an instrumentation test. (because the target runs in the system process.)
srcs: [
"test/**/*.java",
+ "src/android/provider/settings/backup/*",
+ "src/android/provider/settings/validators/*",
"src/com/android/providers/settings/SettingsBackupAgent.java",
"src/com/android/providers/settings/SettingsState.java",
"src/com/android/providers/settings/SettingsHelper.java",
],
static_libs: [
"androidx.test.rules",
- "SettingsLib",
+ "SettingsLibDisplayDensityUtils",
+ "platform-test-annotations",
+ "truth-prebuilt",
],
libs: [
"android.test.base",
diff --git a/packages/SettingsProvider/TEST_MAPPING b/packages/SettingsProvider/TEST_MAPPING
new file mode 100644
index 0000000..890510f
--- /dev/null
+++ b/packages/SettingsProvider/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+ "presubmit": [
+ {
+ "name": "SettingsProviderTest"
+ },
+ {
+ "name": "CtsProviderTestCases",
+ "options": [
+ {
+ "include-filter": "android.provider.cts.settings."
+ }
+ ]
+ }
+ ]
+}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
new file mode 100644
index 0000000..0c49f63
--- /dev/null
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.settings.backup;
+
+import android.provider.Settings;
+
+/** Information related to the backup of Global settings */
+public class GlobalSettings {
+
+ /**
+ * These keys may be mentioned in the SETTINGS_TO_BACKUP arrays in SystemSettings
+ * and SecureSettings as well. This is because those tables drive both backup and
+ * restore, and restore needs to properly whitelist keys that used to live
+ * in those namespaces.
+ *
+ * NOTE: Settings are backed up and restored in the order they appear
+ * in this array. If you have one setting depending on another,
+ * make sure that they are ordered appropriately.
+ *
+ * NOTE: This table should only be used for settings which should be restored
+ * between different types of devices
+ * {@see #Settings.Secure.DEVICE_SPECIFIC_SETTINGS_TO_BACKUP}
+ *
+ * NOTE: All settings which are backed up should have a corresponding validator.
+ */
+ public static final String[] SETTINGS_TO_BACKUP = {
+ Settings.Global.APPLY_RAMPING_RINGER,
+ Settings.Global.BUGREPORT_IN_POWER_MENU,
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
+ Settings.Global.APP_AUTO_RESTRICTION_ENABLED,
+ Settings.Global.AUTO_TIME,
+ Settings.Global.AUTO_TIME_ZONE,
+ Settings.Global.POWER_SOUNDS_ENABLED,
+ Settings.Global.DOCK_SOUNDS_ENABLED,
+ Settings.Global.CHARGING_SOUNDS_ENABLED,
+ Settings.Global.USB_MASS_STORAGE_ENABLED,
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED,
+ Settings.Global.WIFI_WAKEUP_ENABLED,
+ Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
+ Settings.Global.USE_OPEN_WIFI_PACKAGE,
+ Settings.Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED,
+ Settings.Global.EMERGENCY_TONE,
+ Settings.Global.CALL_AUTO_RETRY,
+ Settings.Global.DOCK_AUDIO_MEDIA_ENABLED,
+ Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS,
+ Settings.Global.ENCODED_SURROUND_OUTPUT,
+ Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL,
+ Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED,
+ Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL,
+ Settings.Global.BLUETOOTH_ON,
+ Settings.Global.PRIVATE_DNS_MODE,
+ Settings.Global.PRIVATE_DNS_SPECIFIER,
+ Settings.Global.SOFT_AP_TIMEOUT_ENABLED,
+ Settings.Global.ZEN_DURATION,
+ Settings.Global.CHARGING_VIBRATION_ENABLED,
+ Settings.Global.AWARE_ALLOWED,
+ };
+}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
new file mode 100644
index 0000000..8c2e431
--- /dev/null
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.settings.backup;
+
+import android.annotation.UnsupportedAppUsage;
+import android.provider.Settings;
+
+/** Information relating to the Secure settings which should be backed up */
+public class SecureSettings {
+
+ /**
+ * NOTE: Settings are backed up and restored in the order they appear
+ * in this array. If you have one setting depending on another,
+ * make sure that they are ordered appropriately.
+ */
+ @UnsupportedAppUsage
+ public static final String[] SETTINGS_TO_BACKUP = {
+ Settings.Secure.BUGREPORT_IN_POWER_MENU, // moved to global
+ Settings.Secure.ALLOW_MOCK_LOCATION,
+ Settings.Secure.USB_MASS_STORAGE_ENABLED, // moved to global
+ Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
+ Settings.Secure.AUTOFILL_SERVICE,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ Settings.Secure.ENABLED_VR_LISTENERS,
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED,
+ Settings.Secure.ACCESSIBILITY_ENABLED,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
+ Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR,
+ Settings.Secure.TTS_DEFAULT_RATE,
+ Settings.Secure.TTS_DEFAULT_PITCH,
+ Settings.Secure.TTS_DEFAULT_SYNTH,
+ Settings.Secure.TTS_ENABLED_PLUGINS,
+ Settings.Secure.TTS_DEFAULT_LOCALE,
+ Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
+ Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, // moved to global
+ Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, // moved to global
+ Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT, // moved to global
+ Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
+ Settings.Secure.MOUNT_UMS_AUTOSTART,
+ Settings.Secure.MOUNT_UMS_PROMPT,
+ Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
+ Settings.Secure.DOUBLE_TAP_TO_WAKE,
+ Settings.Secure.WAKE_GESTURE_ENABLED,
+ Settings.Secure.LONG_PRESS_TIMEOUT,
+ Settings.Secure.CAMERA_GESTURE_DISABLED,
+ Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED,
+ Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
+ Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
+ Settings.Secure.PREFERRED_TTY_MODE,
+ Settings.Secure.ENHANCED_VOICE_PRIVACY_ENABLED,
+ Settings.Secure.TTY_MODE_ENABLED,
+ Settings.Secure.RTT_CALLING_MODE,
+ Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
+ Settings.Secure.NIGHT_DISPLAY_CUSTOM_START_TIME,
+ Settings.Secure.NIGHT_DISPLAY_CUSTOM_END_TIME,
+ Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
+ Settings.Secure.NIGHT_DISPLAY_AUTO_MODE,
+ Settings.Secure.DISPLAY_WHITE_BALANCE_ENABLED,
+ Settings.Secure.SYNC_PARENT_SOUNDS,
+ Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
+ Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
+ Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
+ Settings.Secure.QS_TILES,
+ Settings.Secure.DOZE_ENABLED,
+ Settings.Secure.DOZE_ALWAYS_ON,
+ Settings.Secure.DOZE_PICK_UP_GESTURE,
+ Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
+ Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
+ Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
+ Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
+ Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
+ Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
+ Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED,
+ Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING,
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
+ Settings.Secure.FACE_UNLOCK_APP_ENABLED,
+ Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
+ Settings.Secure.ASSIST_GESTURE_ENABLED,
+ Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
+ Settings.Secure.ASSIST_GESTURE_WAKE_ENABLED,
+ Settings.Secure.VR_DISPLAY_MODE,
+ Settings.Secure.NOTIFICATION_BADGING,
+ Settings.Secure.NOTIFICATION_BUBBLES,
+ Settings.Secure.NOTIFICATION_DISMISS_RTL,
+ Settings.Secure.QS_AUTO_ADDED_TILES,
+ Settings.Secure.SCREENSAVER_ENABLED,
+ Settings.Secure.SCREENSAVER_COMPONENTS,
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
+ Settings.Secure.LOCKDOWN_IN_POWER_MENU,
+ Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
+ Settings.Secure.VOLUME_HUSH_GESTURE,
+ Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT,
+ Settings.Secure.HUSH_GESTURE_USED,
+ Settings.Secure.IN_CALL_NOTIFICATION_ENABLED,
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+ Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
+ Settings.Secure.SHOW_NOTIFICATION_SNOOZE,
+ Settings.Secure.ZEN_DURATION,
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION,
+ Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION,
+ Settings.Secure.ZEN_SETTINGS_UPDATED,
+ Settings.Secure.ZEN_SETTINGS_SUGGESTION_VIEWED,
+ Settings.Secure.CHARGING_SOUNDS_ENABLED,
+ Settings.Secure.CHARGING_VIBRATION_ENABLED,
+ Settings.Secure.ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS,
+ Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS,
+ Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL,
+ Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
+ Settings.Secure.UI_NIGHT_MODE,
+ Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST,
+ Settings.Secure.SKIP_GESTURE,
+ Settings.Secure.SKIP_DIRECTION,
+ Settings.Secure.SILENCE_GESTURE,
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
+ Settings.Secure.NAVIGATION_MODE,
+ Settings.Secure.AWARE_ENABLED,
+ Settings.Secure.SKIP_GESTURE_COUNT,
+ Settings.Secure.SKIP_TOUCH_COUNT,
+ Settings.Secure.SILENCE_ALARMS_GESTURE_COUNT,
+ Settings.Secure.SILENCE_CALL_GESTURE_COUNT,
+ Settings.Secure.SILENCE_TIMER_GESTURE_COUNT,
+ Settings.Secure.SILENCE_ALARMS_TOUCH_COUNT,
+ Settings.Secure.SILENCE_CALL_TOUCH_COUNT,
+ Settings.Secure.SILENCE_TIMER_TOUCH_COUNT,
+ Settings.Secure.DARK_MODE_DIALOG_SEEN,
+ Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED,
+ Settings.Secure.AWARE_LOCK_ENABLED
+ };
+}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
new file mode 100644
index 0000000..89b19de
--- /dev/null
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.settings.backup;
+
+import android.annotation.UnsupportedAppUsage;
+import android.provider.Settings;
+
+/** Information about the system settings to back up */
+public class SystemSettings {
+
+ /**
+ * Settings to backup.
+ *
+ * NOTE: Settings are backed up and restored in the order they appear
+ * in this array. If you have one setting depending on another,
+ * make sure that they are ordered appropriately.
+ */
+ @UnsupportedAppUsage
+ public static final String[] SETTINGS_TO_BACKUP = {
+ Settings.System.STAY_ON_WHILE_PLUGGED_IN, // moved to global
+ Settings.System.WIFI_USE_STATIC_IP,
+ Settings.System.WIFI_STATIC_IP,
+ Settings.System.WIFI_STATIC_GATEWAY,
+ Settings.System.WIFI_STATIC_NETMASK,
+ Settings.System.WIFI_STATIC_DNS1,
+ Settings.System.WIFI_STATIC_DNS2,
+ Settings.System.BLUETOOTH_DISCOVERABILITY,
+ Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT,
+ Settings.System.FONT_SCALE,
+ Settings.System.DIM_SCREEN,
+ Settings.System.SCREEN_OFF_TIMEOUT,
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
+ Settings.System.SCREEN_BRIGHTNESS_FOR_VR,
+ Settings.System.ADAPTIVE_SLEEP,
+ Settings.System.VIBRATE_INPUT_DEVICES,
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ Settings.System.TEXT_AUTO_REPLACE,
+ Settings.System.TEXT_AUTO_CAPS,
+ Settings.System.TEXT_AUTO_PUNCTUATE,
+ Settings.System.TEXT_SHOW_PASSWORD,
+ Settings.System.AUTO_TIME, // moved to global
+ Settings.System.AUTO_TIME_ZONE, // moved to global
+ Settings.System.TIME_12_24,
+ Settings.System.DATE_FORMAT,
+ Settings.System.DTMF_TONE_WHEN_DIALING,
+ Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
+ Settings.System.HEARING_AID,
+ Settings.System.TTY_MODE,
+ Settings.System.MASTER_MONO,
+ Settings.System.MASTER_BALANCE,
+ Settings.System.SOUND_EFFECTS_ENABLED,
+ Settings.System.HAPTIC_FEEDBACK_ENABLED,
+ Settings.System.POWER_SOUNDS_ENABLED, // moved to global
+ Settings.System.DOCK_SOUNDS_ENABLED, // moved to global
+ Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
+ Settings.System.SHOW_WEB_SUGGESTIONS,
+ Settings.System.SIP_CALL_OPTIONS,
+ Settings.System.SIP_RECEIVE_CALLS,
+ Settings.System.POINTER_SPEED,
+ Settings.System.VIBRATE_WHEN_RINGING,
+ Settings.System.RINGTONE,
+ Settings.System.LOCK_TO_APP_ENABLED,
+ Settings.System.NOTIFICATION_SOUND,
+ Settings.System.ACCELEROMETER_ROTATION,
+ Settings.System.SHOW_BATTERY_PERCENT,
+ Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Settings.System.RING_VIBRATION_INTENSITY,
+ Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+ Settings.System.DISPLAY_COLOR_MODE,
+ Settings.System.ALARM_ALERT,
+ Settings.System.NOTIFICATION_LIGHT_PULSE,
+ };
+}
diff --git a/core/java/android/provider/settings/validators/ComponentNameListValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/ComponentNameListValidator.java
similarity index 100%
rename from core/java/android/provider/settings/validators/ComponentNameListValidator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/ComponentNameListValidator.java
diff --git a/core/java/android/provider/settings/validators/DiscreteValueValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueValidator.java
similarity index 100%
rename from core/java/android/provider/settings/validators/DiscreteValueValidator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueValidator.java
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
new file mode 100644
index 0000000..9be636d
--- /dev/null
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.settings.validators;
+
+import static android.provider.settings.validators.SettingsValidators.ANY_INTEGER_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.ANY_STRING_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.BOOLEAN_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.PERCENTAGE_INTEGER_VALIDATOR;
+
+import android.media.AudioFormat;
+import android.os.BatteryManager;
+import android.provider.Settings.Global;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+import java.util.Map;
+
+/**
+ * Validators for Global settings
+ */
+public class GlobalSettingsValidators {
+ /**
+ * All settings in {@link Global.SETTINGS_TO_BACKUP} array *must* have a non-null validator,
+ * otherwise they won't be restored.
+ */
+ public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
+
+ static {
+ VALIDATORS.put(Global.APPLY_RAMPING_RINGER, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.BUGREPORT_IN_POWER_MENU, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Global.STAY_ON_WHILE_PLUGGED_IN,
+ value -> {
+ try {
+ int val = Integer.parseInt(value);
+ return (val == 0)
+ || (val == BatteryManager.BATTERY_PLUGGED_AC)
+ || (val == BatteryManager.BATTERY_PLUGGED_USB)
+ || (val == BatteryManager.BATTERY_PLUGGED_WIRELESS)
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_USB))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS));
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ });
+ VALIDATORS.put(Global.AUTO_TIME, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.AUTO_TIME_ZONE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.POWER_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.DOCK_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.CHARGING_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.USB_MASS_STORAGE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Global.NETWORK_RECOMMENDATIONS_ENABLED,
+ new DiscreteValueValidator(new String[] {"-1", "0", "1"}));
+ VALIDATORS.put(Global.WIFI_WAKEUP_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Global.USE_OPEN_WIFI_PACKAGE,
+ value -> (value == null) || PACKAGE_NAME_VALIDATOR.validate(value));
+ VALIDATORS.put(Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED, ANY_STRING_VALIDATOR);
+ VALIDATORS.put(
+ Global.EMERGENCY_TONE, new DiscreteValueValidator(new String[] {"0", "1", "2"}));
+ VALIDATORS.put(Global.CALL_AUTO_RETRY, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.DOCK_AUDIO_MEDIA_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS,
+ new DiscreteValueValidator(new String[] {"0", "1"}));
+ VALIDATORS.put(
+ Global.ENCODED_SURROUND_OUTPUT,
+ new DiscreteValueValidator(new String[] {"0", "1", "2", "3"}));
+ VALIDATORS.put(
+ Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
+ value -> {
+ try {
+ String[] surroundFormats = TextUtils.split(value, ",");
+ for (String format : surroundFormats) {
+ int audioFormat = Integer.valueOf(format);
+ boolean isSurroundFormat = false;
+ for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
+ if (sf == audioFormat) {
+ isSurroundFormat = true;
+ break;
+ }
+ }
+ if (!isSurroundFormat) {
+ return false;
+ }
+ }
+ return true;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ });
+ VALIDATORS.put(
+ Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL,
+ new InclusiveIntegerRangeValidator(0, 100));
+ VALIDATORS.put(
+ Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED,
+ new DiscreteValueValidator(new String[] {"0", "1"}));
+ VALIDATORS.put(Global.LOW_POWER_MODE_TRIGGER_LEVEL, PERCENTAGE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Global.LOW_POWER_MODE_TRIGGER_LEVEL_MAX, PERCENTAGE_INTEGER_VALIDATOR);
+ VALIDATORS.put(
+ Global.AUTOMATIC_POWER_SAVE_MODE,
+ new DiscreteValueValidator(new String[] {"0", "1"}));
+ VALIDATORS.put(
+ Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, PERCENTAGE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Global.BLUETOOTH_ON, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.PRIVATE_DNS_MODE, ANY_STRING_VALIDATOR);
+ VALIDATORS.put(Global.PRIVATE_DNS_SPECIFIER, ANY_STRING_VALIDATOR);
+ VALIDATORS.put(Global.SOFT_AP_TIMEOUT_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.WIFI_SCAN_THROTTLE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.APP_AUTO_RESTRICTION_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.ZEN_DURATION, ANY_INTEGER_VALIDATOR);
+ VALIDATORS.put(Global.CHARGING_VIBRATION_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.REQUIRE_PASSWORD_TO_DECRYPT, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.DEVICE_DEMO_MODE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.WIFI_PNO_FREQUENCY_CULLING_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.WIFI_PNO_RECENCY_SORTING_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.WIFI_LINK_PROBING_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.AWARE_ALLOWED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.POWER_BUTTON_LONG_PRESS, new InclusiveIntegerRangeValidator(0, 5));
+ VALIDATORS.put(
+ Global.POWER_BUTTON_VERY_LONG_PRESS, new InclusiveIntegerRangeValidator(0, 1));
+ }
+}
diff --git a/core/java/android/provider/settings/validators/InclusiveFloatRangeValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveFloatRangeValidator.java
similarity index 89%
rename from core/java/android/provider/settings/validators/InclusiveFloatRangeValidator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/InclusiveFloatRangeValidator.java
index 38400ac..1a0b88c 100644
--- a/core/java/android/provider/settings/validators/InclusiveFloatRangeValidator.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveFloatRangeValidator.java
@@ -23,11 +23,11 @@
*
* @hide
*/
-public final class InclusiveFloatRangeValidator implements Validator {
+final class InclusiveFloatRangeValidator implements Validator {
private final float mMin;
private final float mMax;
- public InclusiveFloatRangeValidator(float min, float max) {
+ InclusiveFloatRangeValidator(float min, float max) {
mMin = min;
mMax = max;
}
diff --git a/core/java/android/provider/settings/validators/InclusiveIntegerRangeValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveIntegerRangeValidator.java
similarity index 89%
rename from core/java/android/provider/settings/validators/InclusiveIntegerRangeValidator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/InclusiveIntegerRangeValidator.java
index e53c252..f9f8ce8 100644
--- a/core/java/android/provider/settings/validators/InclusiveIntegerRangeValidator.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveIntegerRangeValidator.java
@@ -23,11 +23,11 @@
*
* @hide
*/
-public final class InclusiveIntegerRangeValidator implements Validator {
+final class InclusiveIntegerRangeValidator implements Validator {
private final int mMin;
private final int mMax;
- public InclusiveIntegerRangeValidator(int min, int max) {
+ InclusiveIntegerRangeValidator(int min, int max) {
mMin = min;
mMax = max;
}
diff --git a/core/java/android/provider/settings/validators/ListValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/ListValidator.java
similarity index 100%
rename from core/java/android/provider/settings/validators/ListValidator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/ListValidator.java
diff --git a/core/java/android/provider/settings/validators/PackageNameListValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/PackageNameListValidator.java
similarity index 89%
rename from core/java/android/provider/settings/validators/PackageNameListValidator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/PackageNameListValidator.java
index bc7fc13..a883223 100644
--- a/core/java/android/provider/settings/validators/PackageNameListValidator.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/PackageNameListValidator.java
@@ -23,8 +23,8 @@
*
* @hide
*/
-public final class PackageNameListValidator extends ListValidator {
- public PackageNameListValidator(String separator) {
+final class PackageNameListValidator extends ListValidator {
+ PackageNameListValidator(String separator) {
super(separator);
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
new file mode 100644
index 0000000..f160edc6
--- /dev/null
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.settings.validators;
+
+import static android.provider.settings.validators.SettingsValidators.ANY_INTEGER_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.BOOLEAN_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.COLON_SEPARATED_COMPONENT_LIST_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.COLON_SEPARATED_PACKAGE_LIST_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.COMMA_SEPARATED_COMPONENT_LIST_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.COMPONENT_NAME_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.JSON_OBJECT_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.LOCALE_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.NULLABLE_COMPONENT_NAME_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.TILE_LIST_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.TTS_LIST_VALIDATOR;
+
+import android.provider.Settings.Secure;
+import android.util.ArrayMap;
+
+import java.util.Map;
+
+/**
+ * Validators for the Secure Settings.
+ */
+public class SecureSettingsValidators {
+ /**
+ * All settings in {@link Secure.SETTINGS_TO_BACKUP} and {@link
+ * Secure.DEVICE_SPECIFIC_SETTINGS_TO_BACKUP} array *must* have a non-null validator, otherwise
+ * they won't be restored.
+ */
+ public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
+
+ static {
+ VALIDATORS.put(Secure.BUGREPORT_IN_POWER_MENU, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ALLOW_MOCK_LOCATION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.USB_MASS_STORAGE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
+ new DiscreteValueValidator(new String[] {"-1", "0", "11", "12", "13"}));
+ VALIDATORS.put(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.AUTOFILL_SERVICE, NULLABLE_COMPONENT_NAME_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ new InclusiveFloatRangeValidator(1.0f, Float.MAX_VALUE));
+ VALIDATORS.put(
+ Secure.ENABLED_ACCESSIBILITY_SERVICES, COLON_SEPARATED_COMPONENT_LIST_VALIDATOR);
+ VALIDATORS.put(Secure.ENABLED_VR_LISTENERS, COLON_SEPARATED_COMPONENT_LIST_VALIDATOR);
+ VALIDATORS.put(
+ Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ COLON_SEPARATED_COMPONENT_LIST_VALIDATOR);
+ VALIDATORS.put(Secure.TOUCH_EXPLORATION_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, NULLABLE_COMPONENT_NAME_VALIDATOR);
+ // technically either ComponentName or class name, but there's proper value
+ // validation at callsites, so allow any non-null string
+ VALIDATORS.put(Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT, value -> value != null);
+ VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_CAPTIONING_PRESET,
+ new DiscreteValueValidator(new String[] {"-1", "0", "1", "2", "3", "4"}));
+ VALIDATORS.put(Secure.ACCESSIBILITY_CAPTIONING_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_CAPTIONING_LOCALE, LOCALE_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, ANY_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, ANY_INTEGER_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
+ new DiscreteValueValidator(new String[] {"0", "1", "2"}));
+ VALIDATORS.put(Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, ANY_INTEGER_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE,
+ new DiscreteValueValidator(
+ new String[] {"DEFAULT", "MONOSPACE", "SANS_SERIF", "SERIF"}));
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE,
+ new InclusiveFloatRangeValidator(0.5f, 2.0f));
+ VALIDATORS.put(Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, ANY_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.TTS_DEFAULT_RATE, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.TTS_DEFAULT_PITCH, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.TTS_DEFAULT_SYNTH, PACKAGE_NAME_VALIDATOR);
+ VALIDATORS.put(Secure.TTS_ENABLED_PLUGINS, new PackageNameListValidator(" "));
+ VALIDATORS.put(Secure.TTS_DEFAULT_LOCALE, TTS_LIST_VALIDATOR);
+ VALIDATORS.put(Secure.SHOW_IME_WITH_HARD_KEYBOARD, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.WIFI_NUM_OPEN_NETWORKS_KEPT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.MOUNT_PLAY_NOTIFICATION_SND, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.MOUNT_UMS_AUTOSTART, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.MOUNT_UMS_PROMPT, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.MOUNT_UMS_NOTIFY_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOUBLE_TAP_TO_WAKE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.WAKE_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.LONG_PRESS_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.CAMERA_GESTURE_DISABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_AUTOCLICK_DELAY, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_LARGE_POINTER_ICON, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Secure.PREFERRED_TTY_MODE,
+ new DiscreteValueValidator(new String[] {"0", "1", "2", "3"}));
+ VALIDATORS.put(Secure.ENHANCED_VOICE_PRIVACY_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.TTY_MODE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.RTT_CALLING_MODE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Secure.INCALL_POWER_BUTTON_BEHAVIOR,
+ new DiscreteValueValidator(new String[] {"1", "2"}));
+ VALIDATORS.put(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.NIGHT_DISPLAY_AUTO_MODE, new InclusiveIntegerRangeValidator(0, 2));
+ VALIDATORS.put(Secure.DISPLAY_WHITE_BALANCE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SYNC_PARENT_SOUNDS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.QS_TILES, TILE_LIST_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_ALWAYS_ON, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_PICK_UP_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_DOUBLE_TAP_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_TAP_SCREEN_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_WAKE_DISPLAY_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.NFC_PAYMENT_DEFAULT_COMPONENT, COMPONENT_NAME_VALIDATOR);
+ VALIDATORS.put(
+ Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.FACE_UNLOCK_KEYGUARD_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SHOW_MEDIA_WHEN_BYPASSING, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.FACE_UNLOCK_APP_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ASSIST_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.VR_DISPLAY_MODE, new DiscreteValueValidator(new String[] {"0", "1"}));
+ VALIDATORS.put(Secure.NOTIFICATION_BADGING, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.NOTIFICATION_BUBBLES, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.NOTIFICATION_DISMISS_RTL, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.QS_AUTO_ADDED_TILES, TILE_LIST_VALIDATOR);
+ VALIDATORS.put(Secure.SCREENSAVER_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SCREENSAVER_COMPONENTS, COMMA_SEPARATED_COMPONENT_LIST_VALIDATOR);
+ VALIDATORS.put(Secure.SCREENSAVER_ACTIVATE_ON_DOCK, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.LOCKDOWN_IN_POWER_MENU, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.VOLUME_HUSH_GESTURE, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ENABLED_NOTIFICATION_LISTENERS,
+ COLON_SEPARATED_COMPONENT_LIST_VALIDATOR); // legacy restore setting
+ VALIDATORS.put(
+ Secure.ENABLED_NOTIFICATION_ASSISTANT,
+ COLON_SEPARATED_COMPONENT_LIST_VALIDATOR); // legacy restore setting
+ VALIDATORS.put(
+ Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
+ COLON_SEPARATED_PACKAGE_LIST_VALIDATOR); // legacy restore setting
+ VALIDATORS.put(Secure.HUSH_GESTURE_USED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.MANUAL_RINGER_TOGGLE_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.IN_CALL_NOTIFICATION_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SHOW_NOTIFICATION_SNOOZE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ZEN_DURATION, ANY_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SHOW_ZEN_SETTINGS_SUGGESTION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ZEN_SETTINGS_UPDATED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ZEN_SETTINGS_SUGGESTION_VIEWED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.CHARGING_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.CHARGING_VIBRATION_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(
+ Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.USER_SETUP_COMPLETE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ASSIST_GESTURE_SETUP_COMPLETE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.TRUST_AGENTS_EXTEND_UNLOCK, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE, JSON_OBJECT_VALIDATOR);
+ VALIDATORS.put(Secure.LOCK_SCREEN_WHEN_TRUST_LOST, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SKIP_GESTURE, BOOLEAN_VALIDATOR);
+ /*
+ * Only used if FeatureFlag "settings_skip_direction_mutable" is enabled.
+ * If feature flag is disabled, should assume SKIP_DIRECTION = 0.
+ * 0 / false = right to left to advance to next
+ * 1 / true = left to right to advance to next
+ */
+ VALIDATORS.put(Secure.SKIP_DIRECTION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SILENCE_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, JSON_OBJECT_VALIDATOR);
+ VALIDATORS.put(
+ Secure.NAVIGATION_MODE, new DiscreteValueValidator(new String[] {"0", "1", "2"}));
+ VALIDATORS.put(Secure.AWARE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SKIP_GESTURE_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.SKIP_TOUCH_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.SILENCE_ALARMS_GESTURE_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.SILENCE_TIMER_GESTURE_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.SILENCE_CALL_GESTURE_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.SILENCE_ALARMS_TOUCH_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.SILENCE_TIMER_TOUCH_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.SILENCE_CALL_TOUCH_COUNT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.ODI_CAPTIONS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DARK_MODE_DIALOG_SEEN, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.UI_NIGHT_MODE, new InclusiveIntegerRangeValidator(0, 2));
+ VALIDATORS.put(Secure.GLOBAL_ACTIONS_PANEL_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.AWARE_LOCK_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DISPLAY_DENSITY_FORCED, NON_NEGATIVE_INTEGER_VALIDATOR);
+ }
+}
diff --git a/core/java/android/provider/settings/validators/SettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
similarity index 87%
rename from core/java/android/provider/settings/validators/SettingsValidators.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
index 562c638..224042c 100644
--- a/core/java/android/provider/settings/validators/SettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
@@ -24,6 +24,7 @@
import org.json.JSONException;
import org.json.JSONObject;
+import java.text.SimpleDateFormat;
import java.util.Locale;
/**
@@ -180,4 +181,27 @@
public static final Validator TTS_LIST_VALIDATOR = new TTSListValidator();
public static final Validator TILE_LIST_VALIDATOR = new TileListValidator();
+
+ static final Validator DATE_FORMAT_VALIDATOR = value -> {
+ try {
+ new SimpleDateFormat(value);
+ return true;
+ } catch (IllegalArgumentException | NullPointerException e) {
+ return false;
+ }
+ };
+
+ static final Validator COLON_SEPARATED_COMPONENT_LIST_VALIDATOR =
+ new ComponentNameListValidator(":");
+
+ static final Validator COLON_SEPARATED_PACKAGE_LIST_VALIDATOR =
+ new PackageNameListValidator(":");
+
+ static final Validator COMMA_SEPARATED_COMPONENT_LIST_VALIDATOR =
+ new ComponentNameListValidator(",");
+
+ static final Validator PERCENTAGE_INTEGER_VALIDATOR =
+ new InclusiveIntegerRangeValidator(0, 100);
+
+ static final Validator VIBRATION_INTENSITY_VALIDATOR = new InclusiveIntegerRangeValidator(0, 3);
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
new file mode 100644
index 0000000..94ab0f1
--- /dev/null
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.settings.validators;
+
+import static android.provider.settings.validators.SettingsValidators.BOOLEAN_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.COMPONENT_NAME_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.DATE_FORMAT_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.URI_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.VIBRATION_INTENSITY_VALIDATOR;
+
+import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.hardware.display.ColorDisplayManager;
+import android.os.BatteryManager;
+import android.provider.Settings.System;
+import android.util.ArrayMap;
+
+import java.util.Map;
+
+/**
+ * Validators for System settings
+ */
+public class SystemSettingsValidators {
+ /**
+ * These are all public system settings
+ *
+ * <p>All settings in {@link System.SETTINGS_TO_BACKUP} array *must* have a non-null validator,
+ * otherwise they won't be restored.
+ */
+ @UnsupportedAppUsage
+ public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
+
+ static {
+ VALIDATORS.put(
+ System.STAY_ON_WHILE_PLUGGED_IN,
+ value -> {
+ try {
+ int val = Integer.parseInt(value);
+ return (val == 0)
+ || (val == BatteryManager.BATTERY_PLUGGED_AC)
+ || (val == BatteryManager.BATTERY_PLUGGED_USB)
+ || (val == BatteryManager.BATTERY_PLUGGED_WIRELESS)
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_USB))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS));
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ });
+ VALIDATORS.put(System.END_BUTTON_BEHAVIOR, new InclusiveIntegerRangeValidator(0, 3));
+ VALIDATORS.put(System.WIFI_USE_STATIC_IP, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.BLUETOOTH_DISCOVERABILITY, new InclusiveIntegerRangeValidator(0, 2));
+ VALIDATORS.put(System.BLUETOOTH_DISCOVERABILITY_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(
+ System.NEXT_ALARM_FORMATTED,
+ new Validator() {
+ private static final int MAX_LENGTH = 1000;
+
+ @Override
+ public boolean validate(String value) {
+ // TODO: No idea what the correct format is.
+ return value == null || value.length() < MAX_LENGTH;
+ }
+ });
+ VALIDATORS.put(
+ System.FONT_SCALE,
+ value -> {
+ try {
+ return Float.parseFloat(value) >= 0;
+ } catch (NumberFormatException | NullPointerException e) {
+ return false;
+ }
+ });
+ VALIDATORS.put(System.DIM_SCREEN, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ System.DISPLAY_COLOR_MODE,
+ new Validator() {
+ @Override
+ public boolean validate(@Nullable String value) {
+ // Assume the actual validation that this device can properly handle this
+ // kind of
+ // color mode further down in ColorDisplayManager / ColorDisplayService.
+ try {
+ final int setting = Integer.parseInt(value);
+ final boolean isInFrameworkRange =
+ setting >= ColorDisplayManager.COLOR_MODE_NATURAL
+ && setting <= ColorDisplayManager.COLOR_MODE_AUTOMATIC;
+ final boolean isInVendorRange =
+ setting >= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MIN
+ && setting
+ <= ColorDisplayManager
+ .VENDOR_COLOR_MODE_RANGE_MAX;
+ return isInFrameworkRange || isInVendorRange;
+ } catch (NumberFormatException | NullPointerException e) {
+ return false;
+ }
+ }
+ });
+ VALIDATORS.put(System.SCREEN_OFF_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(System.SCREEN_BRIGHTNESS_FOR_VR, new InclusiveIntegerRangeValidator(0, 255));
+ VALIDATORS.put(System.SCREEN_BRIGHTNESS_MODE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.ADAPTIVE_SLEEP, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.MODE_RINGER_STREAMS_AFFECTED, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(System.MUTE_STREAMS_AFFECTED, NON_NEGATIVE_INTEGER_VALIDATOR);
+ VALIDATORS.put(System.VIBRATE_ON, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.NOTIFICATION_VIBRATION_INTENSITY, VIBRATION_INTENSITY_VALIDATOR);
+ VALIDATORS.put(System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_VALIDATOR);
+ VALIDATORS.put(System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_VALIDATOR);
+ VALIDATORS.put(System.RINGTONE, URI_VALIDATOR);
+ VALIDATORS.put(System.NOTIFICATION_SOUND, URI_VALIDATOR);
+ VALIDATORS.put(System.ALARM_ALERT, URI_VALIDATOR);
+ VALIDATORS.put(System.TEXT_AUTO_REPLACE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.TEXT_AUTO_CAPS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.TEXT_AUTO_PUNCTUATE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.TEXT_SHOW_PASSWORD, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.AUTO_TIME, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.AUTO_TIME_ZONE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.SHOW_GTALK_SERVICE_STATUS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ System.WALLPAPER_ACTIVITY,
+ new Validator() {
+ private static final int MAX_LENGTH = 1000;
+
+ @Override
+ public boolean validate(String value) {
+ if (value != null && value.length() > MAX_LENGTH) {
+ return false;
+ }
+ return ComponentName.unflattenFromString(value) != null;
+ }
+ });
+ VALIDATORS.put(
+ System.TIME_12_24, new DiscreteValueValidator(new String[] {"12", "24", null}));
+ VALIDATORS.put(System.DATE_FORMAT, DATE_FORMAT_VALIDATOR);
+ VALIDATORS.put(System.SETUP_WIZARD_HAS_RUN, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.ACCELEROMETER_ROTATION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.USER_ROTATION, new InclusiveIntegerRangeValidator(0, 3));
+ VALIDATORS.put(System.DTMF_TONE_WHEN_DIALING, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.SOUND_EFFECTS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.HAPTIC_FEEDBACK_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.POWER_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.DOCK_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.SHOW_WEB_SUGGESTIONS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.WIFI_USE_STATIC_IP, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.ADVANCED_SETTINGS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.SCREEN_AUTO_BRIGHTNESS_ADJ, new InclusiveFloatRangeValidator(-1, 1));
+ VALIDATORS.put(System.VIBRATE_INPUT_DEVICES, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.MASTER_MONO, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.MASTER_BALANCE, new InclusiveFloatRangeValidator(-1.f, 1.f));
+ VALIDATORS.put(System.NOTIFICATIONS_USE_RING_VOLUME, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.VIBRATE_IN_SILENT, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.MEDIA_BUTTON_RECEIVER, COMPONENT_NAME_VALIDATOR);
+ VALIDATORS.put(System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.VIBRATE_WHEN_RINGING, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.DTMF_TONE_TYPE_WHEN_DIALING, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.HEARING_AID, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.TTY_MODE, new InclusiveIntegerRangeValidator(0, 3));
+ VALIDATORS.put(System.NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.POINTER_LOCATION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.SHOW_TOUCHES, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.WINDOW_ORIENTATION_LISTENER_LOG, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.LOCKSCREEN_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.LOCKSCREEN_DISABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.SIP_RECEIVE_CALLS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ System.SIP_CALL_OPTIONS,
+ new DiscreteValueValidator(new String[] {"SIP_ALWAYS", "SIP_ADDRESS_ONLY"}));
+ VALIDATORS.put(System.SIP_ALWAYS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.SIP_ADDRESS_ONLY, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.SIP_ASK_ME_EACH_TIME, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.POINTER_SPEED, new InclusiveFloatRangeValidator(-7, 7));
+ VALIDATORS.put(System.LOCK_TO_APP_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ System.EGG_MODE,
+ new Validator() {
+ @Override
+ public boolean validate(@Nullable String value) {
+ try {
+ return Long.parseLong(value) >= 0;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+ });
+ VALIDATORS.put(System.WIFI_STATIC_IP, LENIENT_IP_ADDRESS_VALIDATOR);
+ VALIDATORS.put(System.WIFI_STATIC_GATEWAY, LENIENT_IP_ADDRESS_VALIDATOR);
+ VALIDATORS.put(System.WIFI_STATIC_NETMASK, LENIENT_IP_ADDRESS_VALIDATOR);
+ VALIDATORS.put(System.WIFI_STATIC_DNS1, LENIENT_IP_ADDRESS_VALIDATOR);
+ VALIDATORS.put(System.WIFI_STATIC_DNS2, LENIENT_IP_ADDRESS_VALIDATOR);
+ VALIDATORS.put(System.SHOW_BATTERY_PERCENT, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR);
+ }
+}
diff --git a/core/java/android/provider/settings/validators/TTSListValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/TTSListValidator.java
similarity index 100%
rename from core/java/android/provider/settings/validators/TTSListValidator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/TTSListValidator.java
diff --git a/core/java/android/provider/settings/validators/TileListValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/TileListValidator.java
similarity index 100%
rename from core/java/android/provider/settings/validators/TileListValidator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/TileListValidator.java
diff --git a/core/java/android/provider/settings/validators/Validator.java b/packages/SettingsProvider/src/android/provider/settings/validators/Validator.java
similarity index 100%
rename from core/java/android/provider/settings/validators/Validator.java
rename to packages/SettingsProvider/src/android/provider/settings/validators/Validator.java
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 36e945f..f545fa6 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -34,6 +34,12 @@
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.provider.Settings;
+import android.provider.settings.backup.GlobalSettings;
+import android.provider.settings.backup.SecureSettings;
+import android.provider.settings.backup.SystemSettings;
+import android.provider.settings.validators.GlobalSettingsValidators;
+import android.provider.settings.validators.SecureSettingsValidators;
+import android.provider.settings.validators.SystemSettingsValidators;
import android.provider.settings.validators.Validator;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -45,7 +51,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
-import com.android.settingslib.display.DisplayDensityUtils;
+import com.android.settingslib.display.DisplayDensityConfiguration;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
@@ -542,7 +548,7 @@
Cursor cursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION, null,
null, null);
try {
- return extractRelevantValues(cursor, Settings.System.SETTINGS_TO_BACKUP);
+ return extractRelevantValues(cursor, SystemSettings.SETTINGS_TO_BACKUP);
} finally {
cursor.close();
}
@@ -552,7 +558,7 @@
Cursor cursor = getContentResolver().query(Settings.Secure.CONTENT_URI, PROJECTION, null,
null, null);
try {
- return extractRelevantValues(cursor, Settings.Secure.SETTINGS_TO_BACKUP);
+ return extractRelevantValues(cursor, SecureSettings.SETTINGS_TO_BACKUP);
} finally {
cursor.close();
}
@@ -562,7 +568,7 @@
Cursor cursor = getContentResolver().query(Settings.Global.CONTENT_URI, PROJECTION, null,
null, null);
try {
- return extractRelevantValues(cursor, Settings.Global.SETTINGS_TO_BACKUP);
+ return extractRelevantValues(cursor, GlobalSettings.SETTINGS_TO_BACKUP);
} finally {
cursor.close();
}
@@ -633,18 +639,18 @@
final String[] whitelist;
Map<String, Validator> validators = null;
if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
- whitelist = ArrayUtils.concatElements(String.class, Settings.Secure.SETTINGS_TO_BACKUP,
+ whitelist = ArrayUtils.concatElements(String.class, SecureSettings.SETTINGS_TO_BACKUP,
Settings.Secure.LEGACY_RESTORE_SETTINGS,
Settings.Secure.DEVICE_SPECIFIC_SETTINGS_TO_BACKUP);
- validators = Settings.Secure.VALIDATORS;
+ validators = SecureSettingsValidators.VALIDATORS;
} else if (contentUri.equals(Settings.System.CONTENT_URI)) {
- whitelist = ArrayUtils.concatElements(String.class, Settings.System.SETTINGS_TO_BACKUP,
+ whitelist = ArrayUtils.concatElements(String.class, SystemSettings.SETTINGS_TO_BACKUP,
Settings.System.LEGACY_RESTORE_SETTINGS);
- validators = Settings.System.VALIDATORS;
+ validators = SystemSettingsValidators.VALIDATORS;
} else if (contentUri.equals(Settings.Global.CONTENT_URI)) {
- whitelist = ArrayUtils.concatElements(String.class, Settings.Global.SETTINGS_TO_BACKUP,
+ whitelist = ArrayUtils.concatElements(String.class, GlobalSettings.SETTINGS_TO_BACKUP,
Settings.Global.LEGACY_RESTORE_SETTINGS);
- validators = Settings.Global.VALIDATORS;
+ validators = GlobalSettingsValidators.VALIDATORS;
} else {
throw new IllegalArgumentException("Unknown URI: " + contentUri);
}
@@ -1035,7 +1041,8 @@
if (previousDensity == null || previousDensity != newDensity) {
// From nothing to something is a change.
- DisplayDensityUtils.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, newDensity);
+ DisplayDensityConfiguration.setForcedDisplayDensity(
+ Display.DEFAULT_DISPLAY, newDensity);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index e492e28..4d71e72b5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -70,6 +70,7 @@
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
+import android.provider.settings.validators.SystemSettingsValidators;
import android.provider.settings.validators.Validator;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -1717,7 +1718,7 @@
}
private void validateSystemSettingValue(String name, String value) {
- Validator validator = Settings.System.VALIDATORS.get(name);
+ Validator validator = SystemSettingsValidators.VALIDATORS.get(name);
if (validator != null && !validator.validate(value)) {
throw new IllegalArgumentException("Invalid value: " + value
+ " for setting: " + name);
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
similarity index 97%
rename from core/tests/coretests/src/android/provider/SettingsBackupTest.java
rename to packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index eef780a..d7eb7e95 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -18,15 +18,16 @@
import static com.google.android.collect.Sets.newHashSet;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.empty;
-import static org.hamcrest.Matchers.is;
+import static junit.framework.Assert.assertTrue;
import static java.lang.reflect.Modifier.isFinal;
import static java.lang.reflect.Modifier.isPublic;
import static java.lang.reflect.Modifier.isStatic;
import android.platform.test.annotations.Presubmit;
+import android.provider.settings.backup.GlobalSettings;
+import android.provider.settings.backup.SecureSettings;
+import android.provider.settings.backup.SystemSettings;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -727,45 +728,43 @@
public void systemSettingsBackedUpOrBlacklisted() {
checkSettingsBackedUpOrBlacklisted(
getCandidateSettings(Settings.System.class),
- newHashSet(Settings.System.SETTINGS_TO_BACKUP),
+ newHashSet(SystemSettings.SETTINGS_TO_BACKUP),
BACKUP_BLACKLISTED_SYSTEM_SETTINGS);
}
@Test
public void globalSettingsBackedUpOrBlacklisted() {
checkSettingsBackedUpOrBlacklisted(
- getCandidateSettings(Settings.Global.class),
- newHashSet(Settings.Global.SETTINGS_TO_BACKUP),
- BACKUP_BLACKLISTED_GLOBAL_SETTINGS);
+ getCandidateSettings(Settings.Global.class),
+ newHashSet(GlobalSettings.SETTINGS_TO_BACKUP),
+ BACKUP_BLACKLISTED_GLOBAL_SETTINGS);
}
@Test
public void secureSettingsBackedUpOrBlacklisted() {
HashSet<String> keys = new HashSet<String>();
- Collections.addAll(keys, Settings.Secure.SETTINGS_TO_BACKUP);
+ Collections.addAll(keys, SecureSettings.SETTINGS_TO_BACKUP);
Collections.addAll(keys, Settings.Secure.DEVICE_SPECIFIC_SETTINGS_TO_BACKUP);
checkSettingsBackedUpOrBlacklisted(
getCandidateSettings(Settings.Secure.class),
keys,
- BACKUP_BLACKLISTED_SECURE_SETTINGS);
+ BACKUP_BLACKLISTED_SECURE_SETTINGS);
}
private static void checkSettingsBackedUpOrBlacklisted(
Set<String> settings, Set<String> settingsToBackup, Set<String> blacklist) {
Set<String> settingsNotBackedUp = difference(settings, settingsToBackup);
Set<String> settingsNotBackedUpOrBlacklisted = difference(settingsNotBackedUp, blacklist);
- assertThat(
+ assertTrue(
"Settings not backed up or blacklisted",
- settingsNotBackedUpOrBlacklisted,
- is(empty()));
+ settingsNotBackedUpOrBlacklisted.isEmpty());
- assertThat(
- "blacklisted settings backed up",
- intersect(settingsToBackup, blacklist),
- is(empty()));
+ assertTrue(
+ "blacklisted settings backed up", intersect(settingsToBackup, blacklist).isEmpty());
}
- private static Set<String> getCandidateSettings(Class<? extends Settings.NameValueTable> clazz) {
+ private static Set<String> getCandidateSettings(
+ Class<? extends Settings.NameValueTable> clazz) {
HashSet<String> result = new HashSet<String>();
for (Field field : clazz.getDeclaredFields()) {
if (looksLikeValidSetting(field)) {
diff --git a/core/tests/coretests/src/android/provider/settings/validators/SettingsValidatorsTest.java b/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
similarity index 92%
rename from core/tests/coretests/src/android/provider/settings/validators/SettingsValidatorsTest.java
rename to packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
index 5f042d3..a3b0835 100644
--- a/core/tests/coretests/src/android/provider/settings/validators/SettingsValidatorsTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
@@ -24,6 +24,9 @@
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
+import android.provider.settings.backup.GlobalSettings;
+import android.provider.settings.backup.SecureSettings;
+import android.provider.settings.backup.SystemSettings;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -218,7 +221,7 @@
@Test
public void dateFormatValidator_onNullValue_returnsFalse() {
- assertFalse(Settings.System.DATE_FORMAT_VALIDATOR.validate(null));
+ assertFalse(SettingsValidators.DATE_FORMAT_VALIDATOR.validate(null));
}
@Test
@@ -238,18 +241,18 @@
@Test
public void testJSONObjectValidator_onNullValue_returnsFalse() {
- assertThat(SettingsValidators.JSON_OBJECT_VALIDATOR.validate(null)).isFalse();
+ assertFalse(SettingsValidators.JSON_OBJECT_VALIDATOR.validate(null));
}
@Test
public void testJSONObjectValidator_onEmptyString_returnsFalse() {
- assertThat(SettingsValidators.JSON_OBJECT_VALIDATOR.validate("")).isFalse();
+ assertFalse(SettingsValidators.JSON_OBJECT_VALIDATOR.validate(""));
}
@Test
public void ensureAllBackedUpSystemSettingsHaveValidators() {
- String offenders = getOffenders(concat(Settings.System.SETTINGS_TO_BACKUP,
- Settings.System.LEGACY_RESTORE_SETTINGS), Settings.System.VALIDATORS);
+ String offenders = getOffenders(concat(SystemSettings.SETTINGS_TO_BACKUP,
+ Settings.System.LEGACY_RESTORE_SETTINGS), SystemSettingsValidators.VALIDATORS);
failIfOffendersPresent(offenders, "Settings.System");
}
@@ -295,16 +298,16 @@
@Test
public void ensureAllBackedUpGlobalSettingsHaveValidators() {
- String offenders = getOffenders(concat(Settings.Global.SETTINGS_TO_BACKUP,
- Settings.Global.LEGACY_RESTORE_SETTINGS), Settings.Global.VALIDATORS);
+ String offenders = getOffenders(concat(GlobalSettings.SETTINGS_TO_BACKUP,
+ Settings.Global.LEGACY_RESTORE_SETTINGS), GlobalSettingsValidators.VALIDATORS);
failIfOffendersPresent(offenders, "Settings.Global");
}
@Test
public void ensureAllBackedUpSecureSettingsHaveValidators() {
- String offenders = getOffenders(concat(Settings.Secure.SETTINGS_TO_BACKUP,
- Settings.Secure.LEGACY_RESTORE_SETTINGS), Settings.Secure.VALIDATORS);
+ String offenders = getOffenders(concat(SecureSettings.SETTINGS_TO_BACKUP,
+ Settings.Secure.LEGACY_RESTORE_SETTINGS), SecureSettingsValidators.VALIDATORS);
failIfOffendersPresent(offenders, "Settings.Secure");
}
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
index 68efa67..ce1da4a 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
@@ -31,6 +31,8 @@
import libcore.io.Streams;
+import org.junit.After;
+import org.junit.Before;
import org.junit.runner.RunWith;
import java.io.FileInputStream;
@@ -60,6 +62,20 @@
private int mSecondaryUserId = Integer.MIN_VALUE;
+ @Before
+ public void setUp() {
+ Settings.Global.clearProviderForTest();
+ Settings.Secure.clearProviderForTest();
+ Settings.System.clearProviderForTest();
+ }
+
+ @After
+ public void tearDown() {
+ Settings.Global.clearProviderForTest();
+ Settings.Secure.clearProviderForTest();
+ Settings.System.clearProviderForTest();
+ }
+
protected void setStringViaFrontEndApiSetting(int type, String name, String value, int userId) {
ContentResolver contentResolver = getContext().getContentResolver();
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java
index 863b035..ff11f70 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java
@@ -84,8 +84,10 @@
return line.trim();
}
+ @Override
@Before
public void setUp() {
+ super.setUp();
mUm = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
mHasUserRestriction = mUm.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
mSystemSetUserRestriction = mUm.getUserRestrictionSource(
@@ -145,8 +147,10 @@
assertTrue("Invalid value", value.equals("1") || value.equals("0"));
}
+ @Override
@After
public void tearDown() {
+ super.tearDown();
if (!mHasUserRestriction || mSystemSetUserRestriction) {
// The test may have modified the user restriction state. Restore it.
mUm.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index cf8e1a5..12ca92f 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -64,8 +64,10 @@
private TestFriendlySettingsBackupAgent mAgentUnderTest;
private Context mContext;
+ @Override
@Before
public void setUp() {
+ super.setUp();
mContext = new ContextWithMockContentResolver(getContext());
mAgentUnderTest = new TestFriendlySettingsBackupAgent();
diff --git a/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml b/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml
index fe1bb26..7c7c8c1 100644
--- a/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml
+++ b/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml
@@ -16,16 +16,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="22"
android:viewportHeight="17"
- android:width="22dp"
- android:height="17dp">
+ android:width="19.41dp"
+ android:height="15dp">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M1.22,8.49l0.43-4.96h4.33v1.17H2.67L2.44,7.41c0.41-0.29,0.85-0.43,1.33-0.43c0.77,0,1.38,0.3,1.83,0.9 s0.66,1.41,0.66,2.43c0,1.03-0.24,1.84-0.72,2.43s-1.14,0.88-1.98,0.88c-0.75,0-1.36-0.24-1.83-0.73s-0.74-1.16-0.81-2.02h1.13 c0.07,0.57,0.23,1,0.49,1.29c0.26,0.29,0.59,0.43,1.01,0.43c0.47,0,0.84-0.2,1.1-0.61c0.26-0.41,0.4-0.96,0.4-1.65 c0-0.65-0.14-1.18-0.43-1.59S3.96,8.11,3.47,8.11c-0.4,0-0.72,0.1-0.96,0.31L2.19,8.75L1.22,8.49z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M14.14,12.24l-0.22,0.27c-0.63,0.73-1.55,1.1-2.76,1.1c-1.08,0-1.92-0.36-2.53-1.07c-0.61-0.71-0.93-1.72-0.94-3.02V7.56 c0-1.39,0.28-2.44,0.84-3.13c0.56-0.7,1.39-1.04,2.51-1.04c0.95,0,1.69,0.26,2.23,0.79c0.54,0.53,0.83,1.28,0.89,2.26h-1.25 c-0.05-0.62-0.22-1.1-0.52-1.45c-0.29-0.35-0.74-0.52-1.34-0.52c-0.72,0-1.24,0.23-1.57,0.7C9.14,5.63,8.96,6.37,8.95,7.4v2.03 c0,1,0.19,1.77,0.57,2.31c0.38,0.54,0.93,0.8,1.65,0.8c0.67,0,1.19-0.16,1.54-0.49l0.18-0.17V9.59h-1.82V8.52h3.07V12.24z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M20.96,8.88h-3.52v3.53h4.1v1.07h-5.35V3.52h5.28V4.6h-4.03V7.8h3.52V8.88z" />
-
+ android:pathData="M 6.72 3.52 L 6.54 4.69 L 3.34 4.69 L 2.63 7.41 C 3.011 7.143 3.465 7 3.93 7 C 4.5 6.986 5.041 7.251 5.38 7.71 C 5.756 8.249 5.952 8.893 5.94 9.55 C 5.98 10.276 5.864 11.002 5.6 11.68 C 5.385 12.267 5.007 12.78 4.51 13.16 C 4.043 13.499 3.476 13.671 2.9 13.65 C 2.271 13.653 1.675 13.369 1.28 12.88 C 0.854 12.302 0.636 11.597 0.66 10.88 L 1.76 10.88 C 1.81 12 2.21 12.57 3 12.58 C 3.592 12.589 4.132 12.243 4.37 11.7 C 4.708 11.044 4.85 10.305 4.78 9.57 C 4.767 9.209 4.645 8.86 4.43 8.57 C 4.239 8.309 3.934 8.156 3.61 8.16 C 3.404 8.138 3.196 8.162 3 8.23 C 2.748 8.358 2.518 8.527 2.32 8.73 L 1.31 8.46 L 2.51 3.52 L 6.72 3.52 Z M 11.7 3.39 C 12.459 3.353 13.195 3.662 13.7 4.23 C 14.185 4.864 14.42 5.654 14.36 6.45 L 13.1 6.45 C 13.131 5.938 12.998 5.43 12.72 5 C 12.455 4.679 12.056 4.498 11.64 4.51 C 11.025 4.456 10.42 4.688 10 5.14 C 9.491 5.811 9.179 6.611 9.1 7.45 L 8.75 9.54 L 8.75 10.57 C 8.82 11.86 9.36 12.52 10.36 12.57 C 10.701 12.593 11.043 12.538 11.36 12.41 C 11.661 12.281 11.943 12.113 12.2 11.91 L 12.62 9.62 L 10.77 9.62 L 11 8.52 L 14 8.52 L 13.36 12.23 C 13.176 12.483 12.953 12.706 12.7 12.89 C 11.995 13.398 11.138 13.652 10.27 13.61 C 9.507 13.634 8.773 13.315 8.27 12.74 C 7.748 12.085 7.475 11.267 7.5 10.43 C 7.47 10.097 7.47 9.763 7.5 9.43 L 7.8 7.43 C 7.927 6.332 8.36 5.293 9.05 4.43 C 9.725 3.692 10.703 3.308 11.7 3.39 Z M 20.81 7.21 L 20.62 8.29 L 18.32 8.29 L 18.06 9.8 L 20.06 9.8 L 19.83 10.84 L 17.88 10.84 L 17.59 12.54 L 19.9 12.54 L 19.71 13.61 L 16.14 13.61 L 17.25 7.21 L 20.81 7.21 Z" />
+ <path android:pathData="M 0 0 H 14 V 17 H 0 V 0 Z"/>
</vector>
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 45126f3..107d5cc 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -19,6 +19,8 @@
import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
import static android.telephony.PhoneStateListener.LISTEN_NONE;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -33,6 +35,8 @@
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.settingslib.WirelessUtils;
@@ -42,8 +46,6 @@
import java.util.List;
import java.util.Objects;
-import androidx.annotation.VisibleForTesting;
-
/**
* Controller that generates text including the carrier names and/or the status of all the SIM
* interfaces in the device. Through a callback, the updates can be retrieved either as a list or
@@ -220,8 +222,9 @@
.getSystemService(Context.TELEPHONY_SERVICE));
if (callback != null) {
mCarrierTextCallback = callback;
- if (ConnectivityManager.from(mContext).isNetworkSupported(
- ConnectivityManager.TYPE_MOBILE)) {
+ // TODO(b/140034799)
+ if (whitelistIpcs(() -> ConnectivityManager.from(mContext).isNetworkSupported(
+ ConnectivityManager.TYPE_MOBILE))) {
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
mKeyguardUpdateMonitor.registerCallback(mCallback);
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index 210b82d..979f3dc 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -16,6 +16,8 @@
package com.android.keyguard;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.content.Context;
@@ -132,7 +134,7 @@
return false;
}
});
- updateEmergencyCallButton();
+ whitelistIpcs(this::updateEmergencyCallButton);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 169c97b..454f446 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -15,6 +15,8 @@
*/
package com.android.keyguard;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.app.admin.DevicePolicyManager;
@@ -467,8 +469,8 @@
* @param turningOff true if the device is being turned off
*/
void showPrimarySecurityScreen(boolean turningOff) {
- SecurityMode securityMode = mSecurityModel.getSecurityMode(
- KeyguardUpdateMonitor.getCurrentUser());
+ SecurityMode securityMode = whitelistIpcs(() -> mSecurityModel.getSecurityMode(
+ KeyguardUpdateMonitor.getCurrentUser()));
if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
showSecurityScreen(securityMode);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
index 0cb6423..16e9ffc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -15,6 +15,8 @@
*/
package com.android.keyguard;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.telephony.SubscriptionManager;
@@ -67,7 +69,9 @@
return SecurityMode.SimPin;
}
- final int security = mLockPatternUtils.getActivePasswordQuality(userId);
+ // TODO(b/140034863)
+ final int security = whitelistIpcs(() ->
+ mLockPatternUtils.getActivePasswordQuality(userId));
switch (security) {
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 6da2a42..aa1d8b4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -18,6 +18,8 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.Intent.ACTION_USER_REMOVED;
+import static android.content.Intent.ACTION_USER_STOPPED;
import static android.content.Intent.ACTION_USER_UNLOCKED;
import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
@@ -36,6 +38,7 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.annotation.AnyThread;
import android.annotation.MainThread;
@@ -161,6 +164,8 @@
private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
private static final int MSG_TELEPHONY_CAPABLE = 338;
private static final int MSG_TIMEZONE_UPDATE = 339;
+ private static final int MSG_USER_STOPPED = 340;
+ private static final int MSG_USER_REMOVED = 341;
/** Biometric authentication state: Not listening. */
private static final int BIOMETRIC_STATE_STOPPED = 0;
@@ -374,7 +379,13 @@
handleDreamingStateChanged(msg.arg1);
break;
case MSG_USER_UNLOCKED:
- handleUserUnlocked();
+ handleUserUnlocked(msg.arg1);
+ break;
+ case MSG_USER_STOPPED:
+ handleUserStopped(msg.arg1);
+ break;
+ case MSG_USER_REMOVED:
+ handleUserRemoved(msg.arg1);
break;
case MSG_ASSISTANT_STACK_CHANGED:
setAssistantVisible((boolean) msg.obj);
@@ -426,6 +437,7 @@
}
};
+ private SparseBooleanArray mUserIsUnlocked = new SparseBooleanArray();
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
@@ -997,9 +1009,10 @@
private boolean isFaceDisabled(int userId) {
final DevicePolicyManager dpm =
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
+ // TODO(b/140035044)
+ return whitelistIpcs(() -> dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
& DevicePolicyManager.KEYGUARD_DISABLE_FACE) != 0
- || isSimPinSecure();
+ || isSimPinSecure());
}
@@ -1205,7 +1218,14 @@
.equals(action)) {
mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
} else if (ACTION_USER_UNLOCKED.equals(action)) {
- mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_UNLOCKED,
+ getSendingUserId(), 0));
+ } else if (ACTION_USER_STOPPED.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_STOPPED,
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1), 0));
+ } else if (ACTION_USER_REMOVED.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED,
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1), 0));
}
}
};
@@ -1556,8 +1576,9 @@
}
}
- private void handleUserUnlocked() {
+ private void handleUserUnlocked(int userId) {
checkIsHandlerThread();
+ mUserIsUnlocked.put(userId, true);
mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1567,6 +1588,16 @@
}
}
+ private void handleUserStopped(int userId) {
+ checkIsHandlerThread();
+ mUserIsUnlocked.put(userId, mUserManager.isUserUnlocked(userId));
+ }
+
+ private void handleUserRemoved(int userId) {
+ checkIsHandlerThread();
+ mUserIsUnlocked.delete(userId);
+ }
+
@VisibleForTesting
protected KeyguardUpdateMonitor(Context context) {
mContext = context;
@@ -1610,6 +1641,8 @@
allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
allUserFilter.addAction(ACTION_USER_UNLOCKED);
+ allUserFilter.addAction(ACTION_USER_STOPPED);
+ allUserFilter.addAction(ACTION_USER_REMOVED);
context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
null, mHandler);
@@ -1664,6 +1697,8 @@
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
mUserManager = context.getSystemService(UserManager.class);
mIsPrimaryUser = mUserManager.isPrimaryUser();
+ int user = ActivityManager.getCurrentUser();
+ mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user));
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
updateAirplaneModeState();
@@ -1707,6 +1742,19 @@
}
/**
+ * If a user is encrypted or not.
+ * This is NOT related to the lock screen being visible or not.
+ *
+ * @param userId The user.
+ * @return {@code true} when encrypted.
+ * @see UserManager#isUserUnlocked()
+ * @see Intent#ACTION_USER_UNLOCKED
+ */
+ public boolean isUserUnlocked(int userId) {
+ return mUserIsUnlocked.get(userId);
+ }
+
+ /**
* Called whenever passive authentication is requested or aborted by a sensor.
*
* @param active If the interrupt started or ended.
@@ -1884,9 +1932,10 @@
* If face hardware is available, user has enrolled and enabled auth via setting.
*/
public boolean isFaceAuthEnabledForUser(int userId) {
- return mFaceManager != null && mFaceManager.isHardwareDetected()
+ // TODO(b/140034352)
+ return whitelistIpcs(() -> mFaceManager != null && mFaceManager.isHardwareDetected()
&& mFaceManager.hasEnrolledTemplates(userId)
- && mFaceSettingEnabledForUser.get(userId);
+ && mFaceSettingEnabledForUser.get(userId));
}
private void stopListeningForFingerprint() {
@@ -2294,7 +2343,7 @@
}
private boolean resolveNeedsSlowUnlockTransition() {
- if (mUserManager.isUserUnlocked(getCurrentUser())) {
+ if (isUserUnlocked(getCurrentUser())) {
return false;
}
Intent homeIntent = new Intent(Intent.ACTION_MAIN)
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 08691ec..1edb57e 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -34,13 +34,14 @@
// list of "ABC", etc per digit, starting with '0'
static String sKlondike[];
+ private final TextView mDigitText;
+ private final TextView mKlondikeText;
+ private final LockPatternUtils mLockPatternUtils;
+ private final PowerManager mPM;
+
private int mDigit = -1;
private int mTextViewResId;
private PasswordTextView mTextView;
- private TextView mDigitText;
- private TextView mKlondikeText;
- private boolean mEnableHaptics;
- private PowerManager mPM;
private View.OnClickListener mListener = new View.OnClickListener() {
@Override
@@ -90,8 +91,7 @@
setOnClickListener(mListener);
setOnHoverListener(new LiftToActivateListener(context));
- mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
-
+ mLockPatternUtils = new LockPatternUtils(context);
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
@@ -162,7 +162,7 @@
// Cause a VIRTUAL_KEY vibration
public void doHapticKeyClick() {
- if (mEnableHaptics) {
+ if (mLockPatternUtils.isTactileFeedbackEnabled()) {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
| HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index ffa69fa..ce61a00 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -19,6 +19,7 @@
import static android.app.StatusBarManager.DISABLE_NONE;
import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.util.SysuiLifecycle.viewAttachLifecycle;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -382,9 +383,10 @@
private void updateShowPercent() {
final boolean showing = mBatteryPercentView != null;
- final boolean systemSetting = 0 != Settings.System
+ // TODO(b/140051051)
+ final boolean systemSetting = 0 != whitelistIpcs(() -> Settings.System
.getIntForUser(getContext().getContentResolver(),
- SHOW_BATTERY_PERCENT, 0, mUser);
+ SHOW_BATTERY_PERCENT, 0, mUser));
if ((mShowPercentAvailable && systemSetting && mShowPercentMode != MODE_OFF)
|| mShowPercentMode == MODE_ON || mShowPercentMode == MODE_ESTIMATE) {
diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
index 8fabe7a..62826d8 100644
--- a/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
@@ -16,10 +16,12 @@
package com.android.systemui;
+import android.app.Service;
+
/**
* Interface necessary to make Dagger happy. See {@link ContextComponentResolver}.
*/
public interface ContextComponentHelper {
/** Turns a classname into an instance of the class or returns null. */
- <T> T resolve(String className);
+ Service resolveService(String className);
}
diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
index 09bccd9..e8f0196 100644
--- a/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
+++ b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
@@ -16,6 +16,8 @@
package com.android.systemui;
+import android.app.Service;
+
import java.util.Map;
import javax.inject.Inject;
@@ -25,21 +27,26 @@
* Used during Service and Activity instantiation to make them injectable.
*/
public class ContextComponentResolver implements ContextComponentHelper {
- private final Map<Class<?>, Provider<Object>> mCreators;
+ private final Map<Class<?>, Provider<Service>> mServiceCreators;
@Inject
- ContextComponentResolver(Map<Class<?>, Provider<Object>> creators) {
- mCreators = creators;
+ ContextComponentResolver(
+ Map<Class<?>, Provider<Service>> serviceCreators) {
+ mServiceCreators = serviceCreators;
}
/**
- * Looks up the class name to see if Dagger has an instance of it.
+ * Looks up the Service class name to see if Dagger has an instance of it.
*/
@Override
- public <T> T resolve(String className) {
- for (Map.Entry<Class<?>, Provider<Object>> p : mCreators.entrySet()) {
+ public Service resolveService(String className) {
+ return resolve(className, mServiceCreators);
+ }
+
+ private <T> T resolve(String className, Map<Class<?>, Provider<T>> creators) {
+ for (Map.Entry<Class<?>, Provider<T>> p : creators.entrySet()) {
if (p.getKey().getName().equals(className)) {
- return (T) p.getValue().get();
+ return p.getValue().get();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/DejankUtils.java b/packages/SystemUI/src/com/android/systemui/DejankUtils.java
index bec8820..97578e1 100644
--- a/packages/SystemUI/src/com/android/systemui/DejankUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/DejankUtils.java
@@ -16,39 +16,200 @@
package com.android.systemui;
+import static android.os.IBinder.FLAG_ONEWAY;
+
+import static com.android.settingslib.utils.ThreadUtils.isMainThread;
+
+import android.annotation.MainThread;
+import android.os.Binder;
+import android.os.Binder.ProxyTransactListener;
+import android.os.Build;
import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.StrictMode;
+import android.os.SystemProperties;
import android.view.Choreographer;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.util.Assert;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Stack;
+import java.util.function.Supplier;
/**
* Utility class for methods used to dejank the UI.
*/
public class DejankUtils {
+ public static final boolean STRICT_MODE_ENABLED = Build.IS_ENG
+ || SystemProperties.getBoolean("persist.sysui.strictmode", false);
private static final Choreographer sChoreographer = Choreographer.getInstance();
private static final Handler sHandler = new Handler();
private static final ArrayList<Runnable> sPendingRunnables = new ArrayList<>();
+ private static Stack<String> sBlockingIpcs = new Stack<>();
+ private static boolean sTemporarilyIgnoreStrictMode;
+ private static final HashSet<String> sWhitelistedFrameworkClasses = new HashSet<>();
+ private static final Object sLock = new Object();
+ private static final ProxyTransactListener sProxy = new ProxyTransactListener() {
+ @Override
+ public Object onTransactStarted(IBinder binder, int transactionCode, int flags) {
+ synchronized (sLock) {
+ if ((flags & FLAG_ONEWAY) == FLAG_ONEWAY || sBlockingIpcs.empty()
+ || !isMainThread() || sTemporarilyIgnoreStrictMode) {
+ return null;
+ }
+
+ try {
+ String description = binder.getInterfaceDescriptor();
+ if (sWhitelistedFrameworkClasses.contains(description)) {
+ return null;
+ }
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+
+ StrictMode.noteSlowCall("IPC detected on critical path: " + sBlockingIpcs.peek());
+ return null;
+ }
+ }
+
+ @Override
+ public Object onTransactStarted(IBinder binder, int transactionCode) {
+ return null;
+ }
+
+ @Override
+ public void onTransactEnded(Object o) {
+
+ }
+ };
/**
* Only for testing.
*/
private static boolean sImmediate;
- private static final Runnable sAnimationCallbackRunnable = new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < sPendingRunnables.size(); i++) {
- sHandler.post(sPendingRunnables.get(i));
- }
- sPendingRunnables.clear();
+ static {
+ if (STRICT_MODE_ENABLED) {
+ // Common IPCs that are ok to block the main thread.
+ sWhitelistedFrameworkClasses.add("android.view.IWindowSession");
+ sWhitelistedFrameworkClasses.add("com.android.internal.policy.IKeyguardStateCallback");
+ sWhitelistedFrameworkClasses.add("android.os.IPowerManager");
+ sWhitelistedFrameworkClasses.add("com.android.internal.statusbar.IStatusBarService");
+
+ Binder.setProxyTransactListener(sProxy);
+ StrictMode.ThreadPolicy.Builder builder = new StrictMode.ThreadPolicy.Builder()
+ .detectCustomSlowCalls()
+ .penaltyFlashScreen()
+ .penaltyLog();
+ StrictMode.setThreadPolicy(builder.build());
}
+ }
+
+ private static final Runnable sAnimationCallbackRunnable = () -> {
+ for (int i = 0; i < sPendingRunnables.size(); i++) {
+ sHandler.post(sPendingRunnables.get(i));
+ }
+ sPendingRunnables.clear();
};
/**
+ * Enable blocking-binder-call {@link StrictMode} for a {@link Runnable}.
+ *
+ * @param runnable Target.
+ */
+ @MainThread
+ public static void detectBlockingIpcs(Runnable runnable) {
+ if (STRICT_MODE_ENABLED && sBlockingIpcs.empty()) {
+ synchronized (sLock) {
+ sBlockingIpcs.push("detectBlockingIpcs");
+ try {
+ runnable.run();
+ } finally {
+ sBlockingIpcs.pop();
+ }
+ }
+ } else {
+ runnable.run();
+ }
+ }
+
+ /**
+ * Enable blocking-binder-call {@link StrictMode}.
+ *
+ * @param tag A key.
+ * @see #detectBlockingIpcs(Runnable)
+ */
+ @MainThread
+ public static void startDetectingBlockingIpcs(String tag) {
+ if (STRICT_MODE_ENABLED) {
+ synchronized (sLock) {
+ sBlockingIpcs.push(tag);
+ }
+ }
+ }
+
+ /**
+ * Stop IPC detection for a specific tag.
+ *
+ * @param tag The key.
+ * @see #startDetectingBlockingIpcs(String)
+ */
+ @MainThread
+ public static void stopDetectingBlockingIpcs(String tag) {
+ if (STRICT_MODE_ENABLED) {
+ synchronized (sLock) {
+ sBlockingIpcs.remove(tag);
+ }
+ }
+ }
+
+ /**
+ * Temporarily ignore blocking binder calls for contents of this {@link Runnable}.
+ *
+ * @param runnable Target.
+ */
+ @MainThread
+ public static void whitelistIpcs(Runnable runnable) {
+ if (STRICT_MODE_ENABLED && !sTemporarilyIgnoreStrictMode) {
+ synchronized (sLock) {
+ sTemporarilyIgnoreStrictMode = true;
+ try {
+ runnable.run();
+ } finally {
+ sTemporarilyIgnoreStrictMode = false;
+ }
+ }
+ } else {
+ runnable.run();
+ }
+ }
+
+ /**
+ * @see #whitelistIpcs(Runnable)
+ */
+ @MainThread
+ public static <T> T whitelistIpcs(Supplier<T> supplier) {
+ if (STRICT_MODE_ENABLED && !sTemporarilyIgnoreStrictMode) {
+ synchronized (sLock) {
+ sTemporarilyIgnoreStrictMode = true;
+ final T val;
+ try {
+ val = supplier.get();
+ } finally {
+ sTemporarilyIgnoreStrictMode = false;
+ }
+ return val;
+ }
+ } else {
+ return supplier.get();
+ }
+ }
+
+ /**
* Executes {@code r} after performTraversals. Use this do to CPU heavy work for which the
* timing is not critical for animation. The work is then scheduled at the same time
* RenderThread is doing its thing, leading to better parallelization.
diff --git a/packages/SystemUI/src/com/android/systemui/ServiceBinder.java b/packages/SystemUI/src/com/android/systemui/ServiceBinder.java
index 6282c6e..131a0f8 100644
--- a/packages/SystemUI/src/com/android/systemui/ServiceBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/ServiceBinder.java
@@ -16,6 +16,8 @@
package com.android.systemui;
+import android.app.Service;
+
import com.android.systemui.doze.DozeService;
import dagger.Binds;
@@ -36,6 +38,5 @@
@Binds
@IntoMap
@ClassKey(DozeService.class)
- public abstract Object bindDozeService(DozeService service);
-
+ public abstract Service bindDozeService(DozeService service);
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
index 00ae992..6a59fa1 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
@@ -18,16 +18,25 @@
import android.app.Application;
import android.app.Service;
+import android.content.ContentProvider;
+import android.content.Context;
import android.content.Intent;
-import androidx.core.app.CoreComponentFactory;
+import androidx.annotation.NonNull;
+import androidx.core.app.AppComponentFactory;
import javax.inject.Inject;
/**
* Implementation of AppComponentFactory that injects into constructors.
+ *
+ * This class sets up dependency injection when creating our application.
+ *
+ * Services support dependency injection into their constructors.
+ *
+ * ContentProviders support injection into member variables - _not_ constructors.
*/
-public class SystemUIAppComponentFactory extends CoreComponentFactory {
+public class SystemUIAppComponentFactory extends AppComponentFactory {
@Inject
public ContextComponentHelper mComponentHelper;
@@ -36,12 +45,14 @@
super();
}
+ @NonNull
@Override
- public Application instantiateApplication(ClassLoader cl, String className)
+ public Application instantiateApplicationCompat(
+ @NonNull ClassLoader cl, @NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- Application app = super.instantiateApplication(cl, className);
- if (app instanceof SystemUIApplication) {
- ((SystemUIApplication) app).setContextAvailableCallback(
+ Application app = super.instantiateApplicationCompat(cl, className);
+ if (app instanceof ContextProvider) {
+ ((ContextProvider) app).setContextAvailableCallback(
context -> {
SystemUIFactory.createFromConfig(context);
SystemUIFactory.getInstance().getRootComponent().inject(
@@ -53,24 +64,43 @@
return app;
}
+ @NonNull
@Override
- public Service instantiateService(ClassLoader cl, String className, Intent intent)
+ public ContentProvider instantiateProviderCompat(
+ @NonNull ClassLoader cl, @NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- Service service = mComponentHelper.resolve(className);
- if (service != null) {
- return checkCompatWrapper(service);
+
+ ContentProvider contentProvider = super.instantiateProviderCompat(cl, className);
+ if (contentProvider instanceof ContextProvider) {
+ ((ContextProvider) contentProvider).setContextAvailableCallback(
+ context -> {
+ SystemUIFactory.createFromConfig(context);
+ SystemUIFactory.getInstance().getRootComponent().inject(
+ contentProvider);
+ }
+ );
}
- return super.instantiateService(cl, className, intent);
+
+ return contentProvider;
}
- static <T> T checkCompatWrapper(T obj) {
- if (obj instanceof CompatWrapped) {
- T wrapper = (T) ((CompatWrapped) obj).getWrapper();
- if (wrapper != null) {
- return wrapper;
- }
+ @NonNull
+ @Override
+ public Service instantiateServiceCompat(
+ @NonNull ClassLoader cl, @NonNull String className, Intent intent)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+ Service service = mComponentHelper.resolveService(className);
+ if (service != null) {
+ return service;
}
+ return super.instantiateServiceCompat(cl, className, intent);
+ }
- return obj;
+ interface ContextAvailableCallback {
+ void onContextAvailable(Context context);
+ }
+
+ interface ContextProvider {
+ void setContextAvailableCallback(ContextAvailableCallback callback);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index f8449ad..aafc67e 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -48,7 +48,8 @@
/**
* Application class for SystemUI.
*/
-public class SystemUIApplication extends Application implements SysUiServiceProvider {
+public class SystemUIApplication extends Application implements SysUiServiceProvider,
+ SystemUIAppComponentFactory.ContextProvider {
public static final String TAG = "SystemUIService";
private static final boolean DEBUG = false;
@@ -60,7 +61,7 @@
private boolean mServicesStarted;
private boolean mBootCompleted;
private final Map<Class<?>, Object> mComponents = new HashMap<>();
- private ContextAvailableCallback mContextAvailableCallback;
+ private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
@Override
public void onCreate() {
@@ -74,7 +75,6 @@
// the theme set there.
setTheme(R.style.Theme_SystemUI);
-
if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
@@ -291,11 +291,10 @@
return mServices;
}
- void setContextAvailableCallback(ContextAvailableCallback callback) {
+ @Override
+ public void setContextAvailableCallback(
+ SystemUIAppComponentFactory.ContextAvailableCallback callback) {
mContextAvailableCallback = callback;
}
- interface ContextAvailableCallback {
- void onContextAvailable(Context context);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index b67d7df..39617ec 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -24,13 +24,13 @@
import android.util.Log;
import android.view.ViewGroup;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.keyguard.DismissCallbackRegistry;
-import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -70,6 +70,10 @@
}
public static void createFromConfig(Context context) {
+ if (mFactory != null) {
+ return;
+ }
+
final String clsName = context.getString(R.string.config_systemUIFactoryComponent);
if (clsName == null || clsName.length() == 0) {
throw new RuntimeException("No SystemUIFactory component configured");
@@ -86,6 +90,11 @@
}
}
+ @VisibleForTesting
+ static void cleanup() {
+ mFactory = null;
+ }
+
public SystemUIFactory() {}
private void init(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
index f18c8b2..ad04f18 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
@@ -16,6 +16,8 @@
package com.android.systemui;
+import android.content.ContentProvider;
+
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import com.android.systemui.fragments.FragmentService;
@@ -76,7 +78,12 @@
boolean allowNotificationLongPressName();
/**
- * Injects into the supplied argument.
+ * Member injection into the supplied argument.
*/
void inject(SystemUIAppComponentFactory factory);
+
+ /**
+ * Member injection into the supplied argument.
+ */
+ void inject(ContentProvider contentProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
index 1e20b99..7a9feb7 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
@@ -16,6 +16,8 @@
package com.android.systemui.assist;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -368,8 +370,9 @@
long currentTimestamp = SystemClock.uptimeMillis();
mLearningTimeElapsed += currentTimestamp - mLastLearningTimestamp;
mLastLearningTimestamp = currentTimestamp;
- Settings.Secure.putLong(
- mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed);
+ // TODO(b/140034473)
+ whitelistIpcs(() -> Settings.Secure.putLong(
+ mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed));
mIsLearned =
mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index ac32d4d..c4feac1 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -1,5 +1,7 @@
package com.android.systemui.assist;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -374,7 +376,8 @@
}
public boolean canVoiceAssistBeLaunchedFromKeyguard() {
- return mAssistUtils.activeServiceSupportsLaunchFromKeyguard();
+ // TODO(b/140051519)
+ return whitelistIpcs(() -> mAssistUtils.activeServiceSupportsLaunchFromKeyguard());
}
public ComponentName getVoiceInteractorComponentName() {
@@ -442,7 +445,8 @@
}
public void onLockscreenShown() {
- mAssistUtils.onLockscreenShown();
+ // TODO(b/140052478)
+ whitelistIpcs(mAssistUtils::onLockscreenShown);
}
public long getAssistHandleShowAndGoRemainingDurationMs() {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
index b3f57af..c21a717 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
@@ -16,6 +16,8 @@
package com.android.systemui.assist;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.provider.DeviceConfig;
import androidx.annotation.Nullable;
@@ -27,20 +29,24 @@
public PhenotypeHelper() {}
public long getLong(String name, long defaultValue) {
- return DeviceConfig.getLong(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+ return whitelistIpcs(() ->
+ DeviceConfig.getLong(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue));
}
public int getInt(String name, int defaultValue) {
- return DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+ return whitelistIpcs(() ->
+ DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue));
}
@Nullable
public String getString(String name, @Nullable String defaultValue) {
- return DeviceConfig.getString(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+ return whitelistIpcs(() ->
+ DeviceConfig.getString(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue));
}
public boolean getBoolean(String name, boolean defaultValue) {
- return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+ return whitelistIpcs(() ->
+ DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue));
}
public void addOnPropertiesChangedListener(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricDialogView.java
index 2b4dde5..2904755 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricDialogView.java
@@ -18,8 +18,14 @@
import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.annotation.IntDef;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
@@ -38,6 +44,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -71,6 +78,7 @@
public static final String KEY_ERROR_TEXT_STRING = "key_error_text_string";
public static final String KEY_ERROR_TEXT_IS_TEMPORARY = "key_error_text_is_temporary";
public static final String KEY_ERROR_TEXT_COLOR = "key_error_text_color";
+ public static final String KEY_DIALOG_SIZE = "key_dialog_size";
private static final int ANIMATION_DURATION_SHOW = 250; // ms
private static final int ANIMATION_DURATION_AWAY = 350; // ms
@@ -83,8 +91,18 @@
protected static final int STATE_PENDING_CONFIRMATION = 3;
protected static final int STATE_AUTHENTICATED = 4;
- @VisibleForTesting
- final WakefulnessLifecycle mWakefulnessLifecycle;
+ // Dialog layout/animation
+ private static final int IMPLICIT_Y_PADDING = 16; // dp
+ private static final int GROW_DURATION = 150; // ms
+ private static final int TEXT_ANIMATE_DISTANCE = 32; // dp
+ @VisibleForTesting static final int SIZE_UNKNOWN = 0;
+ @VisibleForTesting static final int SIZE_SMALL = 1;
+ @VisibleForTesting static final int SIZE_GROWING = 2;
+ @VisibleForTesting static final int SIZE_BIG = 3;
+ @IntDef({SIZE_UNKNOWN, SIZE_SMALL, SIZE_GROWING, SIZE_BIG})
+ @interface DialogSize {}
+
+ @VisibleForTesting final WakefulnessLifecycle mWakefulnessLifecycle;
private final AccessibilityManager mAccessibilityManager;
private final IBinder mWindowToken = new Binder();
private final Interpolator mLinearOutSlowIn;
@@ -95,25 +113,18 @@
private final int mErrorColor;
private final float mDialogWidth;
protected final DialogViewCallback mCallback;
+ private final DialogOutlineProvider mOutlineProvider = new DialogOutlineProvider();
protected final ViewGroup mLayout;
protected final LinearLayout mDialog;
- @VisibleForTesting
- final TextView mTitleText;
- @VisibleForTesting
- final TextView mSubtitleText;
- @VisibleForTesting
- final TextView mDescriptionText;
- @VisibleForTesting
- final ImageView mBiometricIcon;
- @VisibleForTesting
- final TextView mErrorText;
- @VisibleForTesting
- final Button mPositiveButton;
- @VisibleForTesting
- final Button mNegativeButton;
- @VisibleForTesting
- final Button mTryAgainButton;
+ @VisibleForTesting final TextView mTitleText;
+ @VisibleForTesting final TextView mSubtitleText;
+ @VisibleForTesting final TextView mDescriptionText;
+ @VisibleForTesting final ImageView mBiometricIcon;
+ @VisibleForTesting final TextView mErrorText;
+ @VisibleForTesting final Button mPositiveButton;
+ @VisibleForTesting final Button mNegativeButton;
+ @VisibleForTesting final Button mTryAgainButton;
protected final int mTextColor;
@@ -126,6 +137,8 @@
private boolean mSkipIntro;
protected boolean mRequireConfirmation;
private int mUserId; // used to determine if we should show work background
+ private @DialogSize int mSize;
+ private float mIconOriginalY;
private boolean mCompletedAnimatingIn;
private boolean mPendingDismissDialog;
@@ -137,6 +150,7 @@
protected abstract boolean shouldGrayAreaDismissDialog();
protected abstract void handleResetMessage();
protected abstract void updateIcon(int oldState, int newState);
+ protected abstract boolean supportsSmallDialog();
private final Runnable mShowAnimationRunnable = new Runnable() {
@Override
@@ -166,6 +180,30 @@
}
};
+ private final class DialogOutlineProvider extends ViewOutlineProvider {
+
+ float mY;
+
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(
+ 0 /* left */,
+ (int) mY, /* top */
+ mDialog.getWidth() /* right */,
+ mDialog.getBottom(), /* bottom */
+ getResources().getDimension(R.dimen.biometric_dialog_corner_size));
+ }
+
+ int calculateSmall() {
+ final float padding = Utils.dpToPixels(mContext, IMPLICIT_Y_PADDING);
+ return mDialog.getHeight() - mBiometricIcon.getHeight() - 2 * (int) padding;
+ }
+
+ void setOutlineY(float y) {
+ mY = y;
+ }
+ }
+
protected Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -346,7 +384,6 @@
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
final ImageView backgroundView = mLayout.findViewById(R.id.background);
-
if (mUserManager.isManagedProfile(mUserId)) {
final Drawable image = getResources().getDrawable(R.drawable.work_challenge_background,
mContext.getTheme());
@@ -428,6 +465,42 @@
mSkipIntro = false;
}
+ /**
+ * Do small/big layout here instead of onAttachedToWindow, since:
+ * 1) We need the big layout to be measured, etc for small -> big animation
+ * 2) We need the dialog measurements to know where to move the biometric icon to
+ *
+ * BiometricDialogView already sets the views to their default big state, so here we only
+ * need to hide the ones that are unnecessary.
+ */
+ @Override
+ public void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ if (mIconOriginalY == 0) {
+ mIconOriginalY = mBiometricIcon.getY();
+ }
+
+ // UNKNOWN means size hasn't been set yet. First time we create the dialog.
+ // onLayout can happen when visibility of views change (during animation, etc).
+ if (getSize() != SIZE_UNKNOWN) {
+ // Probably not the cleanest way to do this, but since dialog is big by default,
+ // and small dialogs can persist across orientation changes, we need to set it to
+ // small size here again.
+ if (getSize() == SIZE_SMALL) {
+ updateSize(SIZE_SMALL);
+ }
+ return;
+ }
+
+ // If we don't require confirmation, show the small dialog first (until errors occur).
+ if (!requiresConfirmation() && supportsSmallDialog()) {
+ updateSize(SIZE_SMALL);
+ } else {
+ updateSize(SIZE_BIG);
+ }
+ }
+
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
@@ -435,6 +508,133 @@
mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
}
+ @VisibleForTesting
+ void updateSize(@DialogSize int newSize) {
+ final float padding = Utils.dpToPixels(mContext, IMPLICIT_Y_PADDING);
+ final float iconSmallPositionY = mDialog.getHeight() - mBiometricIcon.getHeight() - padding;
+
+ if (newSize == SIZE_SMALL) {
+ if (!supportsSmallDialog()) {
+ Log.e(TAG, "Small dialog unsupported");
+ return;
+ }
+
+ // These fields are required and/or always hold a spot on the UI, so should be set to
+ // INVISIBLE so they keep their position
+ mTitleText.setVisibility(View.INVISIBLE);
+ mErrorText.setVisibility(View.INVISIBLE);
+ mNegativeButton.setVisibility(View.INVISIBLE);
+
+ // These fields are optional, so set them to gone or invisible depending on their
+ // usage. If they're empty, they're already set to GONE in BiometricDialogView.
+ if (!TextUtils.isEmpty(mSubtitleText.getText())) {
+ mSubtitleText.setVisibility(View.INVISIBLE);
+ }
+ if (!TextUtils.isEmpty(mDescriptionText.getText())) {
+ mDescriptionText.setVisibility(View.INVISIBLE);
+ }
+
+ // Move the biometric icon to the small spot
+ mBiometricIcon.setY(iconSmallPositionY);
+
+ // Clip the dialog to the small size
+ mDialog.setOutlineProvider(mOutlineProvider);
+ mOutlineProvider.setOutlineY(mOutlineProvider.calculateSmall());
+
+ mDialog.setClipToOutline(true);
+ mDialog.invalidateOutline();
+
+ mSize = newSize;
+ announceAccessibilityEvent();
+ } else if (mSize == SIZE_SMALL && newSize == SIZE_BIG) {
+ mSize = SIZE_GROWING;
+
+ // Animate the outline
+ final ValueAnimator outlineAnimator =
+ ValueAnimator.ofFloat(mOutlineProvider.calculateSmall(), 0);
+ outlineAnimator.addUpdateListener((animation) -> {
+ final float y = (float) animation.getAnimatedValue();
+ mOutlineProvider.setOutlineY(y);
+ mDialog.invalidateOutline();
+ });
+
+ // Animate the icon back to original big position
+ final ValueAnimator iconAnimator =
+ ValueAnimator.ofFloat(iconSmallPositionY, mIconOriginalY);
+ iconAnimator.addUpdateListener((animation) -> {
+ final float y = (float) animation.getAnimatedValue();
+ mBiometricIcon.setY(y);
+ });
+
+ // Animate the error text so it slides up with the icon
+ final ValueAnimator textSlideAnimator =
+ ValueAnimator.ofFloat(Utils.dpToPixels(mContext, TEXT_ANIMATE_DISTANCE), 0);
+ textSlideAnimator.addUpdateListener((animation) -> {
+ final float y = (float) animation.getAnimatedValue();
+ mErrorText.setTranslationY(y);
+ });
+
+ // Opacity animator for things that should fade in (title, subtitle, details, negative
+ // button)
+ final ValueAnimator opacityAnimator = ValueAnimator.ofFloat(0, 1);
+ opacityAnimator.addUpdateListener((animation) -> {
+ final float opacity = (float) animation.getAnimatedValue();
+
+ // These fields are required and/or always hold a spot on the UI
+ mTitleText.setAlpha(opacity);
+ mErrorText.setAlpha(opacity);
+ mNegativeButton.setAlpha(opacity);
+ mTryAgainButton.setAlpha(opacity);
+
+ // These fields are optional, so only animate them if they're supposed to be showing
+ if (!TextUtils.isEmpty(mSubtitleText.getText())) {
+ mSubtitleText.setAlpha(opacity);
+ }
+ if (!TextUtils.isEmpty(mDescriptionText.getText())) {
+ mDescriptionText.setAlpha(opacity);
+ }
+ });
+
+ // Choreograph together
+ final AnimatorSet as = new AnimatorSet();
+ as.setDuration(GROW_DURATION);
+ as.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ // Set the visibility of opacity-animating views back to VISIBLE
+ mTitleText.setVisibility(View.VISIBLE);
+ mErrorText.setVisibility(View.VISIBLE);
+ mNegativeButton.setVisibility(View.VISIBLE);
+ mTryAgainButton.setVisibility(View.VISIBLE);
+
+ if (!TextUtils.isEmpty(mSubtitleText.getText())) {
+ mSubtitleText.setVisibility(View.VISIBLE);
+ }
+ if (!TextUtils.isEmpty(mDescriptionText.getText())) {
+ mDescriptionText.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ mSize = SIZE_BIG;
+ }
+ });
+ as.play(outlineAnimator).with(iconAnimator).with(opacityAnimator)
+ .with(textSlideAnimator);
+ as.start();
+ } else if (mSize == SIZE_BIG) {
+ mDialog.setClipToOutline(false);
+ mDialog.invalidateOutline();
+
+ mBiometricIcon.setY(mIconOriginalY);
+
+ mSize = newSize;
+ }
+ }
+
private void setDismissesDialog(View v) {
v.setClickable(true);
v.setOnClickListener(v1 -> {
@@ -599,6 +799,12 @@
*/
@Override
public void onError(String error) {
+ // All error messages will cause the dialog to go from small -> big. Error messages
+ // are messages such as lockout, auth failed, etc.
+ if (mSize == SIZE_SMALL) {
+ updateSize(SIZE_BIG);
+ }
+
updateState(STATE_ERROR);
showTemporaryMessage(error);
showTryAgainButton(false /* show */);
@@ -619,11 +825,16 @@
bundle.putCharSequence(KEY_ERROR_TEXT_STRING, mErrorText.getText());
bundle.putBoolean(KEY_ERROR_TEXT_IS_TEMPORARY, mHandler.hasMessages(MSG_RESET_MESSAGE));
bundle.putInt(KEY_ERROR_TEXT_COLOR, mErrorText.getCurrentTextColor());
+ bundle.putInt(KEY_DIALOG_SIZE, mSize);
}
@Override
public void restoreState(Bundle bundle) {
mRestoredState = bundle;
+
+ // Keep in mind that this happens before onAttachedToWindow()
+ mSize = bundle.getInt(KEY_DIALOG_SIZE);
+
final int tryAgainVisibility = bundle.getInt(KEY_TRY_AGAIN_VISIBILITY);
mTryAgainButton.setVisibility(tryAgainVisibility);
final int confirmVisibility = bundle.getInt(KEY_CONFIRM_VISIBILITY);
@@ -678,7 +889,28 @@
mState = newState;
}
+ protected @DialogSize int getSize() {
+ return mSize;
+ }
+
protected void showTryAgainButton(boolean show) {
+ if (show && getSize() == SIZE_SMALL) {
+ // Do not call super, we will nicely animate the alpha together with the rest
+ // of the elements in here.
+ updateSize(SIZE_BIG);
+ } else {
+ if (show) {
+ mTryAgainButton.setVisibility(View.VISIBLE);
+ } else {
+ mTryAgainButton.setVisibility(View.GONE);
+ announceAccessibilityEvent();
+ }
+ }
+
+ if (show) {
+ mPositiveButton.setVisibility(View.GONE);
+ announceAccessibilityEvent();
+ }
}
protected void onDialogAnimatedIn() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/ui/FaceDialogView.java
index bd87148..9e4fe24 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/FaceDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/FaceDialogView.java
@@ -16,24 +16,15 @@
package com.android.systemui.biometrics.ui;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
import android.content.Context;
-import android.graphics.Outline;
import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricPrompt;
import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
-import android.view.ViewOutlineProvider;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.biometrics.DialogViewCallback;
@@ -45,23 +36,11 @@
public class FaceDialogView extends BiometricDialogView {
private static final String TAG = "FaceDialogView";
- private static final String KEY_DIALOG_SIZE = "key_dialog_size";
+
private static final String KEY_DIALOG_ANIMATED_IN = "key_dialog_animated_in";
private static final int HIDE_DIALOG_DELAY = 500; // ms
- private static final int IMPLICIT_Y_PADDING = 16; // dp
- private static final int GROW_DURATION = 150; // ms
- private static final int TEXT_ANIMATE_DISTANCE = 32; // dp
- private static final int SIZE_UNKNOWN = 0;
- @VisibleForTesting
- static final int SIZE_SMALL = 1;
- private static final int SIZE_GROWING = 2;
- private static final int SIZE_BIG = 3;
-
- private int mSize;
- private float mIconOriginalY;
- private DialogOutlineProvider mOutlineProvider = new DialogOutlineProvider();
private IconController mIconController;
private boolean mDialogAnimatedIn;
@@ -125,30 +104,6 @@
}
}
- private final class DialogOutlineProvider extends ViewOutlineProvider {
-
- float mY;
-
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRoundRect(
- 0 /* left */,
- (int) mY, /* top */
- mDialog.getWidth() /* right */,
- mDialog.getBottom(), /* bottom */
- getResources().getDimension(R.dimen.biometric_dialog_corner_size));
- }
-
- int calculateSmall() {
- final float padding = dpToPixels(IMPLICIT_Y_PADDING);
- return mDialog.getHeight() - mBiometricIcon.getHeight() - 2 * (int) padding;
- }
-
- void setOutlineY(float y) {
- mY = y;
- }
- }
-
private final Runnable mErrorToIdleAnimationRunnable = () -> {
updateState(STATE_IDLE);
mErrorText.setVisibility(View.INVISIBLE);
@@ -160,132 +115,9 @@
mIconController = new IconController();
}
- @VisibleForTesting
- void updateSize(int newSize) {
- final float padding = dpToPixels(IMPLICIT_Y_PADDING);
- final float iconSmallPositionY = mDialog.getHeight() - mBiometricIcon.getHeight() - padding;
-
- if (newSize == SIZE_SMALL) {
- // These fields are required and/or always hold a spot on the UI, so should be set to
- // INVISIBLE so they keep their position
- mTitleText.setVisibility(View.INVISIBLE);
- mErrorText.setVisibility(View.INVISIBLE);
- mNegativeButton.setVisibility(View.INVISIBLE);
-
- // These fields are optional, so set them to gone or invisible depending on their
- // usage. If they're empty, they're already set to GONE in BiometricDialogView.
- if (!TextUtils.isEmpty(mSubtitleText.getText())) {
- mSubtitleText.setVisibility(View.INVISIBLE);
- }
- if (!TextUtils.isEmpty(mDescriptionText.getText())) {
- mDescriptionText.setVisibility(View.INVISIBLE);
- }
-
- // Move the biometric icon to the small spot
- mBiometricIcon.setY(iconSmallPositionY);
-
- // Clip the dialog to the small size
- mDialog.setOutlineProvider(mOutlineProvider);
- mOutlineProvider.setOutlineY(mOutlineProvider.calculateSmall());
-
- mDialog.setClipToOutline(true);
- mDialog.invalidateOutline();
-
- mSize = newSize;
- announceAccessibilityEvent();
- } else if (mSize == SIZE_SMALL && newSize == SIZE_BIG) {
- mSize = SIZE_GROWING;
-
- // Animate the outline
- final ValueAnimator outlineAnimator =
- ValueAnimator.ofFloat(mOutlineProvider.calculateSmall(), 0);
- outlineAnimator.addUpdateListener((animation) -> {
- final float y = (float) animation.getAnimatedValue();
- mOutlineProvider.setOutlineY(y);
- mDialog.invalidateOutline();
- });
-
- // Animate the icon back to original big position
- final ValueAnimator iconAnimator =
- ValueAnimator.ofFloat(iconSmallPositionY, mIconOriginalY);
- iconAnimator.addUpdateListener((animation) -> {
- final float y = (float) animation.getAnimatedValue();
- mBiometricIcon.setY(y);
- });
-
- // Animate the error text so it slides up with the icon
- final ValueAnimator textSlideAnimator =
- ValueAnimator.ofFloat(dpToPixels(TEXT_ANIMATE_DISTANCE), 0);
- textSlideAnimator.addUpdateListener((animation) -> {
- final float y = (float) animation.getAnimatedValue();
- mErrorText.setTranslationY(y);
- });
-
- // Opacity animator for things that should fade in (title, subtitle, details, negative
- // button)
- final ValueAnimator opacityAnimator = ValueAnimator.ofFloat(0, 1);
- opacityAnimator.addUpdateListener((animation) -> {
- final float opacity = (float) animation.getAnimatedValue();
-
- // These fields are required and/or always hold a spot on the UI
- mTitleText.setAlpha(opacity);
- mErrorText.setAlpha(opacity);
- mNegativeButton.setAlpha(opacity);
- mTryAgainButton.setAlpha(opacity);
-
- // These fields are optional, so only animate them if they're supposed to be showing
- if (!TextUtils.isEmpty(mSubtitleText.getText())) {
- mSubtitleText.setAlpha(opacity);
- }
- if (!TextUtils.isEmpty(mDescriptionText.getText())) {
- mDescriptionText.setAlpha(opacity);
- }
- });
-
- // Choreograph together
- final AnimatorSet as = new AnimatorSet();
- as.setDuration(GROW_DURATION);
- as.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- // Set the visibility of opacity-animating views back to VISIBLE
- mTitleText.setVisibility(View.VISIBLE);
- mErrorText.setVisibility(View.VISIBLE);
- mNegativeButton.setVisibility(View.VISIBLE);
- mTryAgainButton.setVisibility(View.VISIBLE);
-
- if (!TextUtils.isEmpty(mSubtitleText.getText())) {
- mSubtitleText.setVisibility(View.VISIBLE);
- }
- if (!TextUtils.isEmpty(mDescriptionText.getText())) {
- mDescriptionText.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mSize = SIZE_BIG;
- }
- });
- as.play(outlineAnimator).with(iconAnimator).with(opacityAnimator)
- .with(textSlideAnimator);
- as.start();
- } else if (mSize == SIZE_BIG) {
- mDialog.setClipToOutline(false);
- mDialog.invalidateOutline();
-
- mBiometricIcon.setY(mIconOriginalY);
-
- mSize = newSize;
- }
- }
-
@Override
public void onSaveState(Bundle bundle) {
super.onSaveState(bundle);
- bundle.putInt(KEY_DIALOG_SIZE, mSize);
bundle.putBoolean(KEY_DIALOG_ANIMATED_IN, mDialogAnimatedIn);
}
@@ -300,57 +132,9 @@
@Override
public void restoreState(Bundle bundle) {
super.restoreState(bundle);
- // Keep in mind that this happens before onAttachedToWindow()
- mSize = bundle.getInt(KEY_DIALOG_SIZE);
mDialogAnimatedIn = bundle.getBoolean(KEY_DIALOG_ANIMATED_IN);
}
- /**
- * Do small/big layout here instead of onAttachedToWindow, since:
- * 1) We need the big layout to be measured, etc for small -> big animation
- * 2) We need the dialog measurements to know where to move the biometric icon to
- *
- * BiometricDialogView already sets the views to their default big state, so here we only
- * need to hide the ones that are unnecessary.
- */
- @Override
- public void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
-
- if (mIconOriginalY == 0) {
- mIconOriginalY = mBiometricIcon.getY();
- }
-
- // UNKNOWN means size hasn't been set yet. First time we create the dialog.
- // onLayout can happen when visibility of views change (during animation, etc).
- if (mSize != SIZE_UNKNOWN) {
- // Probably not the cleanest way to do this, but since dialog is big by default,
- // and small dialogs can persist across orientation changes, we need to set it to
- // small size here again.
- if (mSize == SIZE_SMALL) {
- updateSize(SIZE_SMALL);
- }
- return;
- }
-
- // If we don't require confirmation, show the small dialog first (until errors occur).
- if (!requiresConfirmation()) {
- updateSize(SIZE_SMALL);
- } else {
- updateSize(SIZE_BIG);
- }
- }
-
- @Override
- public void onError(String error) {
- super.onError(error);
- // All error messages will cause the dialog to go from small -> big. Error messages
- // are messages such as lockout, auth failed, etc.
- if (mSize == SIZE_SMALL) {
- updateSize(SIZE_BIG);
- }
- }
-
@Override
public void onAuthenticationFailed(String message) {
super.onAuthenticationFailed(message);
@@ -358,27 +142,6 @@
}
@Override
- public void showTryAgainButton(boolean show) {
- if (show && mSize == SIZE_SMALL) {
- // Do not call super, we will nicely animate the alpha together with the rest
- // of the elements in here.
- updateSize(SIZE_BIG);
- } else {
- if (show) {
- mTryAgainButton.setVisibility(View.VISIBLE);
- } else {
- mTryAgainButton.setVisibility(View.GONE);
- announceAccessibilityEvent();
- }
- }
-
- if (show) {
- mPositiveButton.setVisibility(View.GONE);
- announceAccessibilityEvent();
- }
- }
-
- @Override
protected int getHintStringResourceId() {
return 0;
}
@@ -462,6 +225,11 @@
}
@Override
+ protected boolean supportsSmallDialog() {
+ return true;
+ }
+
+ @Override
public void onDialogAnimatedIn() {
super.onDialogAnimatedIn();
mDialogAnimatedIn = true;
@@ -475,19 +243,11 @@
@Override
protected boolean shouldGrayAreaDismissDialog() {
- if (mSize == SIZE_SMALL) {
+ if (getSize() == SIZE_SMALL) {
return false;
}
return true;
}
- private float dpToPixels(float dp) {
- return dp * ((float) mContext.getResources().getDisplayMetrics().densityDpi
- / DisplayMetrics.DENSITY_DEFAULT);
- }
- private float pixelsToDp(float pixels) {
- return pixels / ((float) mContext.getResources().getDisplayMetrics().densityDpi
- / DisplayMetrics.DENSITY_DEFAULT);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/ui/FingerprintDialogView.java
index e597080..2925880 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/FingerprintDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/FingerprintDialogView.java
@@ -80,6 +80,11 @@
}
}
+ @Override
+ protected boolean supportsSmallDialog() {
+ return false;
+ }
+
protected boolean shouldAnimateForTransition(int oldState, int newState) {
if (newState == STATE_ERROR) {
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/Utils.java b/packages/SystemUI/src/com/android/systemui/biometrics/ui/Utils.java
new file mode 100644
index 0000000..028b1aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/Utils.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui;
+
+import android.content.Context;
+import android.util.DisplayMetrics;
+
+public class Utils {
+ static float dpToPixels(Context context, float dp) {
+ return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
+ / DisplayMetrics.DENSITY_DEFAULT);
+ }
+
+ static float pixelsToDp(Context context, float pixels) {
+ return pixels / ((float) context.getResources().getDisplayMetrics().densityDpi
+ / DisplayMetrics.DENSITY_DEFAULT);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 4120334..efac147 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -35,6 +35,7 @@
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.util.AsyncSensorManager;
+import com.android.systemui.util.DeviceConfigProxy;
import java.io.PrintWriter;
@@ -51,18 +52,23 @@
public class FalsingManagerProxy implements FalsingManager {
private FalsingManager mInternalFalsingManager;
- private final Handler mMainHandler;
+ private DeviceConfig.OnPropertiesChangedListener mDeviceConfigListener;
+ private final DeviceConfigProxy mDeviceConfig;
private boolean mBrightlineEnabled;
@Inject
FalsingManagerProxy(Context context, PluginManager pluginManager,
- @Named(MAIN_HANDLER_NAME) Handler handler) {
- mMainHandler = handler;
+ @Named(MAIN_HANDLER_NAME) Handler handler, DeviceConfigProxy deviceConfig) {
+ mDeviceConfig = deviceConfig;
+ mDeviceConfigListener =
+ properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace());
setupFalsingManager(context);
- DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
- command -> mMainHandler.post(command),
- properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace())
+ mDeviceConfig.addOnPropertiesChangedListener(
+ DeviceConfig.NAMESPACE_SYSTEMUI,
+ handler::post,
+ mDeviceConfigListener
);
+
final PluginListener<FalsingPlugin> mPluginListener = new PluginListener<FalsingPlugin>() {
public void onPluginConnected(FalsingPlugin plugin, Context context) {
FalsingManager pluginFalsingManager = plugin.getFalsingManager(context);
@@ -91,9 +97,8 @@
/**
* Chooses the FalsingManager implementation.
*/
- @VisibleForTesting
- public void setupFalsingManager(Context context) {
- boolean brightlineEnabled = DeviceConfig.getBoolean(
+ private void setupFalsingManager(Context context) {
+ boolean brightlineEnabled = mDeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, true);
if (brightlineEnabled == mBrightlineEnabled && mInternalFalsingManager != null) {
return;
@@ -109,10 +114,10 @@
mInternalFalsingManager = new BrightLineFalsingManager(
new FalsingDataProvider(context.getResources().getDisplayMetrics()),
Dependency.get(AsyncSensorManager.class),
- KeyguardUpdateMonitor.getInstance(context)
+ KeyguardUpdateMonitor.getInstance(context),
+ mDeviceConfig
);
}
-
}
/**
@@ -305,6 +310,7 @@
@Override
public void cleanup() {
+ mDeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigListener);
mInternalFalsingManager.cleanup();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index 9e0b702..9e646b62 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -33,6 +33,7 @@
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.util.DeviceConfigProxy;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -88,7 +89,8 @@
public BrightLineFalsingManager(
FalsingDataProvider falsingDataProvider,
SensorManager sensorManager,
- KeyguardUpdateMonitor keyguardUpdateMonitor) {
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ DeviceConfigProxy deviceConfigProxy) {
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mDataProvider = falsingDataProvider;
mSensorManager = sensorManager;
@@ -96,15 +98,16 @@
mMetricsLogger = new MetricsLogger();
mClassifiers = new ArrayList<>();
- DistanceClassifier distanceClassifier = new DistanceClassifier(mDataProvider);
- ProximityClassifier proximityClassifier = new ProximityClassifier(distanceClassifier,
- mDataProvider);
+ DistanceClassifier distanceClassifier =
+ new DistanceClassifier(mDataProvider, deviceConfigProxy);
+ ProximityClassifier proximityClassifier =
+ new ProximityClassifier(distanceClassifier, mDataProvider, deviceConfigProxy);
mClassifiers.add(new PointerCountClassifier(mDataProvider));
mClassifiers.add(new TypeClassifier(mDataProvider));
- mClassifiers.add(new DiagonalClassifier(mDataProvider));
+ mClassifiers.add(new DiagonalClassifier(mDataProvider, deviceConfigProxy));
mClassifiers.add(distanceClassifier);
mClassifiers.add(proximityClassifier);
- mClassifiers.add(new ZigZagClassifier(mDataProvider));
+ mClassifiers.add(new ZigZagClassifier(mDataProvider, deviceConfigProxy));
}
private void registerSensors() {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
index cc66454..9c03b91 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
@@ -23,6 +23,8 @@
import android.provider.DeviceConfig;
+import com.android.systemui.util.DeviceConfigProxy;
+
/**
* False on swipes that are too close to 45 degrees.
*
@@ -42,14 +44,14 @@
private final float mHorizontalAngleRange;
private final float mVerticalAngleRange;
- DiagonalClassifier(FalsingDataProvider dataProvider) {
+ DiagonalClassifier(FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
super(dataProvider);
- mHorizontalAngleRange = DeviceConfig.getFloat(
+ mHorizontalAngleRange = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_DIAGONAL_HORIZONTAL_ANGLE_RANGE,
HORIZONTAL_ANGLE_RANGE);
- mVerticalAngleRange = DeviceConfig.getFloat(
+ mVerticalAngleRange = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_DIAGONAL_VERTICAL_ANGLE_RANGE,
VERTICAL_ANGLE_RANGE);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
index a6a617d..0954f9e 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
@@ -27,6 +27,8 @@
import android.view.MotionEvent;
import android.view.VelocityTracker;
+import com.android.systemui.util.DeviceConfigProxy;
+
import java.util.List;
/**
@@ -50,35 +52,35 @@
private boolean mDistanceDirty;
private DistanceVectors mCachedDistance;
- DistanceClassifier(FalsingDataProvider dataProvider) {
+ DistanceClassifier(FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
super(dataProvider);
- mVelocityToDistanceMultiplier = DeviceConfig.getFloat(
+ mVelocityToDistanceMultiplier = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_DISTANCE_VELOCITY_TO_DISTANCE,
VELOCITY_TO_DISTANCE);
- float horizontalFlingThresholdIn = DeviceConfig.getFloat(
+ float horizontalFlingThresholdIn = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_FLING_THRESHOLD_IN,
HORIZONTAL_FLING_THRESHOLD_DISTANCE_IN);
- float verticalFlingThresholdIn = DeviceConfig.getFloat(
+ float verticalFlingThresholdIn = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_DISTANCE_VERTICAL_FLING_THRESHOLD_IN,
VERTICAL_FLING_THRESHOLD_DISTANCE_IN);
- float horizontalSwipeThresholdIn = DeviceConfig.getFloat(
+ float horizontalSwipeThresholdIn = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_SWIPE_THRESHOLD_IN,
HORIZONTAL_SWIPE_THRESHOLD_DISTANCE_IN);
- float verticalSwipeThresholdIn = DeviceConfig.getFloat(
+ float verticalSwipeThresholdIn = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN,
VERTICAL_SWIPE_THRESHOLD_DISTANCE_IN);
- float screenFractionMaxDistance = DeviceConfig.getFloat(
+ float screenFractionMaxDistance = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_DISTANCE_SCREEN_FRACTION_MAX_DISTANCE,
SCREEN_FRACTION_MAX_DISTANCE);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
index 2644bf9..1827047 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
@@ -24,6 +24,8 @@
import android.provider.DeviceConfig;
import android.view.MotionEvent;
+import com.android.systemui.util.DeviceConfigProxy;
+
/**
* False touch if proximity sensor is covered for more than a certain percentage of the gesture.
@@ -44,11 +46,11 @@
private float mPercentNear;
ProximityClassifier(DistanceClassifier distanceClassifier,
- FalsingDataProvider dataProvider) {
+ FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
super(dataProvider);
this.mDistanceClassifier = distanceClassifier;
- mPercentCoveredThreshold = DeviceConfig.getFloat(
+ mPercentCoveredThreshold = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD,
PERCENT_COVERED_THRESHOLD);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
index 82ae30a..a0da988 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
@@ -25,6 +25,8 @@
import android.provider.DeviceConfig;
import android.view.MotionEvent;
+import com.android.systemui.util.DeviceConfigProxy;
+
import java.util.ArrayList;
import java.util.List;
@@ -48,25 +50,25 @@
private final float mMaxXSecondaryDeviance;
private final float mMaxYSecondaryDeviance;
- ZigZagClassifier(FalsingDataProvider dataProvider) {
+ ZigZagClassifier(FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
super(dataProvider);
- mMaxXPrimaryDeviance = DeviceConfig.getFloat(
+ mMaxXPrimaryDeviance = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_ZIGZAG_X_PRIMARY_DEVIANCE,
MAX_X_PRIMARY_DEVIANCE);
- mMaxYPrimaryDeviance = DeviceConfig.getFloat(
+ mMaxYPrimaryDeviance = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_ZIGZAG_Y_PRIMARY_DEVIANCE,
MAX_Y_PRIMARY_DEVIANCE);
- mMaxXSecondaryDeviance = DeviceConfig.getFloat(
+ mMaxXSecondaryDeviance = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE,
MAX_X_SECONDARY_DEVIANCE);
- mMaxYSecondaryDeviance = DeviceConfig.getFloat(
+ mMaxYSecondaryDeviance = deviceConfigProxy.getFloat(
DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE,
MAX_Y_SECONDARY_DEVIANCE);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 36c3cc6..4016b59 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -25,6 +25,7 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
@@ -643,26 +644,29 @@
@Override
public int getBouncerPromptReason() {
- int currentUser = ActivityManager.getCurrentUser();
- boolean trust = mTrustManager.isTrustUsuallyManaged(currentUser);
- boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser);
- boolean any = trust || biometrics;
- KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
- mUpdateMonitor.getStrongAuthTracker();
- int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
+ // TODO(b/140053364)
+ return whitelistIpcs(() -> {
+ int currentUser = ActivityManager.getCurrentUser();
+ boolean trust = mTrustManager.isTrustUsuallyManaged(currentUser);
+ boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser);
+ boolean any = trust || biometrics;
+ KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
+ mUpdateMonitor.getStrongAuthTracker();
+ int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
- if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
- return KeyguardSecurityView.PROMPT_REASON_RESTART;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
- } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
- }
- return KeyguardSecurityView.PROMPT_REASON_NONE;
+ if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
+ return KeyguardSecurityView.PROMPT_REASON_RESTART;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
+ } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
+ }
+ return KeyguardSecurityView.PROMPT_REASON_NONE;
+ });
}
@Override
@@ -2172,18 +2176,21 @@
}
private void notifyDefaultDisplayCallbacks(boolean showing) {
- int size = mKeyguardStateCallbacks.size();
- for (int i = size - 1; i >= 0; i--) {
- IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
- try {
- callback.onShowingStateChanged(showing);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to call onShowingStateChanged", e);
- if (e instanceof DeadObjectException) {
- mKeyguardStateCallbacks.remove(callback);
+ // TODO(b/140053364)
+ whitelistIpcs(() -> {
+ int size = mKeyguardStateCallbacks.size();
+ for (int i = size - 1; i >= 0; i--) {
+ IKeyguardStateCallback callback = mKeyguardStateCallbacks.get(i);
+ try {
+ callback.onShowingStateChanged(showing);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onShowingStateChanged", e);
+ if (e instanceof DeadObjectException) {
+ mKeyguardStateCallbacks.remove(callback);
+ }
}
}
- }
+ });
updateInputRestrictedLocked();
mUiOffloadThread.submit(() -> {
mTrustManager.reportKeyguardShowingChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
index 4571ef3..8c21dde 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
@@ -16,6 +16,7 @@
package com.android.systemui.qs;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
import android.content.Context;
@@ -109,7 +110,8 @@
return;
}
mListening = listening;
- updateListeners();
+ // TODO(b/140053526)
+ whitelistIpcs(this::updateListeners);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index f1e9c87..37113cf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -16,6 +16,7 @@
package com.android.systemui.qs;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
import android.content.Context;
@@ -164,7 +165,9 @@
};
public static int getNumQuickTiles(Context context) {
- return Dependency.get(TunerService.class).getValue(NUM_QUICK_TILES, mDefaultMaxTiles);
+ // TODO(b/140052679)
+ return whitelistIpcs(() ->
+ Dependency.get(TunerService.class).getValue(NUM_QUICK_TILES, mDefaultMaxTiles));
}
void setDisabledByPolicy(boolean disabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index bba64d9..9178fda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.admin.DevicePolicyManager;
@@ -234,7 +236,8 @@
return;
}
- if (!mDozing && mDevicePolicyManager.isDeviceManaged()) {
+ // TODO(b/140053632)
+ if (!mDozing && whitelistIpcs(mDevicePolicyManager::isDeviceManaged)) {
final CharSequence organizationName =
mDevicePolicyManager.getDeviceOwnerOrganizationName();
if (organizationName != null) {
@@ -381,7 +384,7 @@
int userId = KeyguardUpdateMonitor.getCurrentUser();
String trustGrantedIndication = getTrustGrantedIndication();
String trustManagedIndication = getTrustManagedIndication();
- if (!mUserManager.isUserUnlocked(userId)) {
+ if (!mKeyguardUpdateMonitor.isUserUnlocked(userId)) {
mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
mTextView.setTextColor(mInitialTextColorState);
} else if (!TextUtils.isEmpty(mTransientIndication)) {
@@ -753,6 +756,13 @@
}
@Override
+ public void onUserSwitchComplete(int userId) {
+ if (mVisible) {
+ updateIndication(false);
+ }
+ }
+
+ @Override
public void onUserUnlocked() {
if (mVisible) {
updateIndication(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 802a7d29..107b24c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -17,6 +17,8 @@
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.app.Notification;
@@ -323,8 +325,9 @@
}
private boolean hideSilentNotificationsOnLockscreen() {
- return Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0;
+ // TODO(b/140058091)
+ return whitelistIpcs(() -> Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0);
}
private void setShowLockscreenNotifications(boolean show) {
@@ -515,8 +518,9 @@
for (int i = currentProfiles.size() - 1; i >= 0; i--) {
final int userId = currentProfiles.valueAt(i).id;
boolean isProfilePublic = devicePublic;
- boolean needsSeparateChallenge = mLockPatternUtils.isSeparateProfileChallengeEnabled(
- userId);
+ // TODO(b/140058091)
+ boolean needsSeparateChallenge = whitelistIpcs(() ->
+ mLockPatternUtils.isSeparateProfileChallengeEnabled(userId));
if (!devicePublic && userId != getCurrentUserId()
&& needsSeparateChallenge && isSecure(userId)) {
// Keyguard.isDeviceLocked is updated asynchronously, assume that all profiles
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index f0eeb04..4422a81 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -24,6 +24,7 @@
import android.view.animation.Interpolator;
import com.android.internal.annotations.GuardedBy;
+import com.android.systemui.DejankUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.Interpolators;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
@@ -137,6 +138,8 @@
recordHistoricalState(state, mState);
synchronized (mListeners) {
+ String tag = getClass().getSimpleName() + "#setState(" + state + ")";
+ DejankUtils.startDetectingBlockingIpcs(tag);
for (RankedListener rl : new ArrayList<>(mListeners)) {
rl.mListener.onStatePreChange(mState, state);
}
@@ -149,6 +152,7 @@
for (RankedListener rl : new ArrayList<>(mListeners)) {
rl.mListener.onStatePostChange();
}
+ DejankUtils.stopDetectingBlockingIpcs(tag);
}
return true;
@@ -178,9 +182,12 @@
mIsDozing = isDozing;
synchronized (mListeners) {
+ String tag = getClass().getSimpleName() + "#setIsDozing";
+ DejankUtils.startDetectingBlockingIpcs(tag);
for (RankedListener rl : new ArrayList<>(mListeners)) {
rl.mListener.onDozingChanged(isDozing);
}
+ DejankUtils.stopDetectingBlockingIpcs(tag);
}
return true;
@@ -220,9 +227,12 @@
mDozeAmount = dozeAmount;
float interpolatedAmount = mDozeInterpolator.getInterpolation(dozeAmount);
synchronized (mListeners) {
+ String tag = getClass().getSimpleName() + "#setDozeAmount";
+ DejankUtils.startDetectingBlockingIpcs(tag);
for (RankedListener rl : new ArrayList<>(mListeners)) {
rl.mListener.onDozeAmountChanged(mDozeAmount, interpolatedAmount);
}
+ DejankUtils.stopDetectingBlockingIpcs(tag);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index f8fef7d..0032174 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -499,10 +499,10 @@
if (rankingMap == null) {
return;
}
- NotificationListenerService.Ranking tmpRanking = new NotificationListenerService.Ranking();
+ NotificationListenerService.Ranking ranking = new NotificationListenerService.Ranking();
for (NotificationEntry pendingNotification : mPendingNotifications.values()) {
- rankingMap.getRanking(pendingNotification.key, tmpRanking);
- pendingNotification.populateFromRanking(tmpRanking);
+ rankingMap.getRanking(pendingNotification.key, ranking);
+ pendingNotification.setRanking(ranking);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
index 0009292..727e245 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
@@ -213,7 +213,7 @@
StatusBarNotification notification) {
updateRanking(ranking);
final StatusBarNotification oldNotification = entry.notification;
- entry.notification = notification;
+ entry.setNotification(notification);
mGroupManager.onEntryUpdated(entry, oldNotification);
}
@@ -325,14 +325,6 @@
return NotificationManager.IMPORTANCE_UNSPECIFIED;
}
- public String getOverrideGroupKey(String key) {
- if (mRankingMap != null) {
- getRanking(key, mTmpRanking);
- return mTmpRanking.getOverrideGroupKey();
- }
- return null;
- }
-
public List<SnoozeCriterion> getSnoozeCriteria(String key) {
if (mRankingMap != null) {
getRanking(key, mTmpRanking);
@@ -365,23 +357,25 @@
return false;
}
- private void updateRankingAndSort(RankingMap ranking) {
- if (ranking != null) {
- mRankingMap = ranking;
+ private void updateRankingAndSort(RankingMap rankingMap) {
+ if (rankingMap != null) {
+ mRankingMap = rankingMap;
synchronized (mEntries) {
final int len = mEntries.size();
for (int i = 0; i < len; i++) {
NotificationEntry entry = mEntries.valueAt(i);
- if (!getRanking(entry.key, mTmpRanking)) {
+ Ranking newRanking = new Ranking();
+ if (!getRanking(entry.key, newRanking)) {
continue;
}
+ entry.setRanking(newRanking);
+
final StatusBarNotification oldSbn = entry.notification.cloneLight();
- final String overrideGroupKey = getOverrideGroupKey(entry.key);
+ final String overrideGroupKey = newRanking.getOverrideGroupKey();
if (!Objects.equals(oldSbn.getOverrideGroupKey(), overrideGroupKey)) {
entry.notification.setOverrideGroupKey(overrideGroupKey);
mGroupManager.onEntryUpdated(entry, oldSbn);
}
- entry.populateFromRanking(mTmpRanking);
entry.setIsHighPriority(isHighPriority(entry.notification));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index fe88541..6178488 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -38,7 +38,7 @@
import android.os.Bundle;
import android.os.Parcelable;
import android.os.SystemClock;
-import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
@@ -88,6 +88,8 @@
private static final int COLOR_INVALID = 1;
public final String key;
public StatusBarNotification notification;
+ private Ranking mRanking;
+
public NotificationChannel channel;
public long lastAudiblyAlertedMs;
public boolean noisy;
@@ -103,7 +105,7 @@
private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
public CharSequence remoteInputText;
public List<SnoozeCriterion> snoozeCriteria;
- public int userSentiment = NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
+ public int userSentiment = Ranking.USER_SENTIMENT_NEUTRAL;
/** Smart Actions provided by the NotificationAssistantService. */
@NonNull
public List<Notification.Action> systemGeneratedSmartActions = Collections.emptyList();
@@ -181,21 +183,80 @@
private boolean mAutoHeadsUp;
private boolean mPulseSupressed;
- public NotificationEntry(StatusBarNotification n) {
- this(n, null);
+ public NotificationEntry(
+ StatusBarNotification sbn,
+ @NonNull Ranking ranking) {
+ this(sbn, ranking, false);
}
- public NotificationEntry(
- StatusBarNotification n,
- @Nullable NotificationListenerService.Ranking ranking) {
- this.key = n.getKey();
- this.notification = n;
+ private NotificationEntry(
+ StatusBarNotification sbn,
+ Ranking ranking,
+ boolean isTest) {
+ this.key = sbn.getKey();
+ this.notification = sbn;
+
+ // TODO: Update tests to no longer need to pass null ranking
if (ranking != null) {
- populateFromRanking(ranking);
+ setRanking(ranking);
+ } else if (!isTest) {
+ throw new IllegalArgumentException("Ranking cannot be null");
}
}
- public void populateFromRanking(@NonNull NotificationListenerService.Ranking ranking) {
+ /**
+ * Method for old tests that build NotificationEntries with a ranking.
+ *
+ * @deprecated New tests should pass a ranking object as well.
+ */
+ @VisibleForTesting
+ @Deprecated
+ public static NotificationEntry buildForTest(StatusBarNotification sbn) {
+ // TODO START here this will NPE on all tests
+ return new NotificationEntry(sbn, null, true);
+ }
+
+ /** The key for this notification. Guaranteed to be immutable and unique */
+ public String key() {
+ return key;
+ }
+
+ /**
+ * The StatusBarNotification that represents one half of a NotificationEntry (the other half
+ * being the Ranking). This object is swapped out whenever a notification is updated.
+ */
+ public StatusBarNotification sbn() {
+ return notification;
+ }
+
+ /**
+ * Should only be called by NotificationEntryManager and friends.
+ * TODO: Make this package-private
+ */
+ public void setNotification(StatusBarNotification sbn) {
+ if (!sbn.getKey().equals(key)) {
+ throw new IllegalArgumentException("New key " + sbn.getKey()
+ + " doesn't match existing key " + key);
+ }
+ notification = sbn;
+ }
+
+ /**
+ * The Ranking that represents one half of a NotificationEntry (the other half being the
+ * StatusBarNotification). This object is swapped out whenever a the ranking is updated (which
+ * generally occurs whenever anything changes in the notification list).
+ */
+ public Ranking ranking() {
+ return mRanking;
+ }
+
+ /**
+ * Should only be called by NotificationEntryManager and friends.
+ * TODO: Make this package-private
+ */
+ public void setRanking(@NonNull Ranking ranking) {
+ mRanking = ranking;
+
channel = ranking.getChannel();
lastAudiblyAlertedMs = ranking.getLastAudiblyAlertedMillis();
importance = ranking.getImportance();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 80d36a1..ab9162a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -76,7 +76,6 @@
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
import com.android.systemui.statusbar.KeyguardAffordanceView;
-import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.ExtensionController.Extension;
@@ -117,6 +116,7 @@
private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
+ private final UnlockMethodCache mUnlockMethodCache;
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
private ViewGroup mIndicationArea;
@@ -129,7 +129,6 @@
private View mCameraPreview;
private ActivityStarter mActivityStarter;
- private UnlockMethodCache mUnlockMethodCache;
private LockPatternUtils mLockPatternUtils;
private FlashlightController mFlashlightController;
private PreviewInflater mPreviewInflater;
@@ -185,6 +184,7 @@
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
}
private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
@@ -242,8 +242,6 @@
mBurnInYOffset = getResources().getDimensionPixelSize(
R.dimen.default_burn_in_prevention_offset);
updateCameraVisibility();
- mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
- mUnlockMethodCache.addListener(this);
setClipChildren(false);
setClipToPadding(false);
inflateCameraPreview();
@@ -281,11 +279,13 @@
getContext().registerReceiverAsUser(mDevicePolicyReceiver,
UserHandle.ALL, filter, null, null);
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
+ mUnlockMethodCache.addListener(this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
+ mUnlockMethodCache.removeListener(this);
mAccessibilityController.removeStateChangedCallback(this);
mRightExtension.destroy();
mLeftExtension.destroy();
@@ -804,11 +804,11 @@
@Override
public IconState getIcon() {
- ResolveInfo resolved = resolveCameraIntent();
boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
- mIconState.isVisible = !isCameraDisabled && resolved != null
+ mIconState.isVisible = !isCameraDisabled
&& getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
- && mUserSetupComplete;
+ && mUserSetupComplete
+ && resolveCameraIntent() != null;
mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
mIconState.contentDescription =
mContext.getString(R.string.accessibility_camera_button);
@@ -820,7 +820,7 @@
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer(
KeyguardUpdateMonitor.getCurrentUser());
- boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
+ boolean secure = mUnlockMethodCache.isMethodSecure();
return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index dc9b373..2e7ba045c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import android.content.Context;
@@ -468,12 +469,15 @@
* notifications on Keyguard, like SIM PIN/PUK.
*/
public boolean needsFullscreenBouncer() {
- ensureView();
- if (mKeyguardView != null) {
- SecurityMode mode = mKeyguardView.getSecurityMode();
- return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
- }
- return false;
+ // TODO(b/140059518)
+ return whitelistIpcs(() -> {
+ ensureView();
+ if (mKeyguardView != null) {
+ SecurityMode mode = mKeyguardView.getSecurityMode();
+ return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
+ }
+ return false;
+ });
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 1d4d0bd..dcc3107 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserManager;
@@ -98,25 +100,30 @@
// Short-circuiting from UserManager. Needs to be extracted because of SystemUI boolean flag
// qs_show_user_switcher_for_single_user
- // The default in UserManager is to show the switcher. We want to not show it unless the
- // user explicitly requests it in Settings
- final boolean userSwitcherEnabled = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.USER_SWITCHER_ENABLED, 0) != 0;
-
// TODO(b/138661450) Move IPC calls to background
- if (!userSwitcherEnabled
- || !UserManager.supportsMultipleUsers()
- || UserManager.isDeviceInDemoMode(mContext)
- || mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)) {
- return false;
- }
+ return whitelistIpcs(() -> {
+ // The default in UserManager is to show the switcher. We want to not show it unless the
+ // user explicitly requests it in Settings
+ final boolean userSwitcherEnabled = Settings.Global.getInt(
+ mContext.getContentResolver(),
+ Settings.Global.USER_SWITCHER_ENABLED, 0) != 0;
- final boolean guestEnabled = !mContext.getSystemService(DevicePolicyManager.class)
- .getGuestUserDisabled(null);
- return mUserSwitcherController.getSwitchableUserCount() > 1
- // If we cannot add guests even if they are enabled, do not show
- || (guestEnabled && !mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER))
- || mContext.getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user);
+ if (!userSwitcherEnabled
+ || !UserManager.supportsMultipleUsers()
+ || UserManager.isDeviceInDemoMode(mContext)
+ || mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)) {
+ return false;
+ }
+
+ final boolean guestEnabled = !mContext.getSystemService(DevicePolicyManager.class)
+ .getGuestUserDisabled(null);
+ return mUserSwitcherController.getSwitchableUserCount() > 1
+ // If we cannot add guests even if they are enabled, do not show
+ || (guestEnabled && !mUserManager.hasUserRestriction(
+ UserManager.DISALLOW_ADD_USER))
+ || mContext.getResources().getBoolean(
+ R.bool.qs_show_user_switcher_for_single_user);
+ });
}
private void registerListener() {
@@ -167,7 +174,8 @@
private void refreshContentDescription() {
String currentUser = null;
- if (mUserManager.isUserSwitcherEnabled()
+ // TODO(b/138661450)
+ if (whitelistIpcs(mUserManager::isUserSwitcherEnabled)
&& mUserSwitcherController != null) {
currentUser = mUserSwitcherController.getCurrentUserName(mContext);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index c76cdcb..248bc75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -666,6 +666,7 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ DejankUtils.startDetectingBlockingIpcs("NVP#onLayout");
super.onLayout(changed, left, top, right, bottom);
setIsFullWidth(mNotificationStackScroller.getWidth() == getWidth());
@@ -712,6 +713,7 @@
mExpandAfterLayoutRunnable.run();
mExpandAfterLayoutRunnable = null;
}
+ DejankUtils.stopDetectingBlockingIpcs("NVP#onLayout");
}
private void updateGestureExclusionRect() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 4c5b464..9fc3e47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -25,6 +25,7 @@
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.Dependency.BG_HANDLER;
import static com.android.systemui.Dependency.MAIN_HANDLER;
@@ -131,6 +132,7 @@
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.ActivityStarterDelegate;
import com.android.systemui.AutoReinflateContainer;
+import com.android.systemui.DejankUtils;
import com.android.systemui.DemoMode;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
@@ -3680,16 +3682,21 @@
@Override
public void onStartedGoingToSleep() {
+ String tag = "StatusBar#onStartedGoingToSleep";
+ DejankUtils.startDetectingBlockingIpcs(tag);
updateNotificationPanelTouchState();
notifyHeadsUpGoingToSleep();
dismissVolumeDialog();
mWakeUpCoordinator.setFullyAwake(false);
mBypassHeadsUpNotifier.setFullyAwake(false);
mKeyguardBypassController.onStartedGoingToSleep();
+ DejankUtils.stopDetectingBlockingIpcs(tag);
}
@Override
public void onStartedWakingUp() {
+ String tag = "StatusBar#onStartedWakingUp";
+ DejankUtils.startDetectingBlockingIpcs(tag);
mDeviceInteractive = true;
mWakeUpCoordinator.setWakingUp(true);
if (!mKeyguardBypassController.getBypassEnabled()) {
@@ -3704,6 +3711,7 @@
// once we fully woke up.
updateNotificationPanelTouchState();
mPulseExpansionHandler.onStartedWakingUp();
+ DejankUtils.stopDetectingBlockingIpcs(tag);
}
@Override
@@ -3854,18 +3862,20 @@
}
boolean isCameraAllowedByAdmin() {
- if (mDevicePolicyManager.getCameraDisabled(null,
- mLockscreenUserManager.getCurrentUserId())) {
- return false;
- } else if (mStatusBarKeyguardViewManager == null ||
- (isKeyguardShowing() && isKeyguardSecure())) {
- // Check if the admin has disabled the camera specifically for the keyguard
- return (mDevicePolicyManager.
- getKeyguardDisabledFeatures(null, mLockscreenUserManager.getCurrentUserId())
- & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
- }
-
- return true;
+ // TODO(b/140060745)
+ return whitelistIpcs(() -> {
+ if (mDevicePolicyManager.getCameraDisabled(null,
+ mLockscreenUserManager.getCurrentUserId())) {
+ return false;
+ } else if (mStatusBarKeyguardViewManager == null
+ || (isKeyguardShowing() && isKeyguardSecure())) {
+ // Check if the admin has disabled the camera specifically for the keyguard
+ return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
+ mLockscreenUserManager.getCurrentUserId())
+ & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
+ }
+ return true;
+ });
}
private boolean isGoingToSleep() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index 0ef981b..e85b147 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -18,6 +18,7 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
import android.app.ActivityManager;
@@ -370,12 +371,14 @@
mWindowManager.updateViewLayout(mStatusBarView, mLp);
}
if (mHasTopUi != mHasTopUiChanged) {
- try {
- mActivityManager.setHasTopUi(mHasTopUiChanged);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to call setHasTopUi", e);
- }
- mHasTopUi = mHasTopUiChanged;
+ whitelistIpcs(() -> {
+ try {
+ mActivityManager.setHasTopUi(mHasTopUiChanged);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to call setHasTopUi", e);
+ }
+ mHasTopUi = mHasTopUiChanged;
+ });
}
notifyStateChangedCallbacks();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 6789930..7a81ed4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -65,8 +65,6 @@
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.DragDownHelper;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.phone.ScrimController.ScrimVisibility;
import com.android.systemui.tuner.TunerService;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index b1d6ca6..24ecd14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -27,6 +27,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.DejankUtils;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -133,15 +134,20 @@
mTrusted = trusted;
mTrustManaged = trustManaged;
mFaceAuthEnabled = faceAuthEnabled;
+ Trace.endSection();
notifyListeners();
+ } else {
+ Trace.endSection();
}
- Trace.endSection();
}
private void notifyListeners() {
+ String tag = "UnlockMethodCache#notifyListeners";
+ DejankUtils.startDetectingBlockingIpcs(tag);
for (OnUnlockMethodChangedListener listener : mListeners) {
listener.onUnlockMethodStateChanged();
}
+ DejankUtils.stopDetectingBlockingIpcs(tag);
}
public void dump(PrintWriter pw) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
index abe3f2c..fc6e5e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
@@ -18,12 +18,12 @@
import static com.android.systemui.statusbar.policy.NetworkControllerImpl.TAG;
import android.content.Context;
-import android.text.format.DateFormat;
import android.util.Log;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
import java.util.BitSet;
@@ -254,6 +254,8 @@
}
static class State {
+ // No locale as it's only used for logging purposes
+ private static SimpleDateFormat sSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
boolean connected;
boolean enabled;
boolean activityIn;
@@ -301,7 +303,7 @@
.append("activityOut=").append(activityOut).append(',')
.append("activityDormant=").append(activityDormant).append(',')
.append("rssi=").append(rssi).append(',')
- .append("lastModified=").append(DateFormat.format("MM-dd HH:mm:ss", time));
+ .append("lastModified=").append(sSDF.format(time));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 395add7..2e1e520 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.policy;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.Dependency.MAIN_HANDLER_NAME;
import android.app.ActivityManager;
@@ -313,9 +314,10 @@
// adb shell settings put system enable_fullscreen_user_switcher 1 # Turn it on.
// Restart SystemUI or adb reboot.
final int DEFAULT = -1;
+ // TODO(b/140061064)
final int overrideUseFullscreenUserSwitcher =
- Settings.System.getInt(mContext.getContentResolver(),
- "enable_fullscreen_user_switcher", DEFAULT);
+ whitelistIpcs(() -> Settings.System.getInt(mContext.getContentResolver(),
+ "enable_fullscreen_user_switcher", DEFAULT));
if (overrideUseFullscreenUserSwitcher != DEFAULT) {
return overrideUseFullscreenUserSwitcher != 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index aa4dcc0..a55e2cf 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -34,6 +34,7 @@
import android.util.ArraySet;
import com.android.internal.util.ArrayUtils;
+import com.android.systemui.DejankUtils;
import com.android.systemui.DemoMode;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.settings.CurrentUserTracker;
@@ -189,7 +190,8 @@
mContentResolver.registerContentObserver(uri, false, mObserver, mCurrentUser);
}
// Send the first state.
- String value = Settings.Secure.getStringForUser(mContentResolver, key, mCurrentUser);
+ String value = DejankUtils.whitelistIpcs(() -> Settings.Secure
+ .getStringForUser(mContentResolver, key, mCurrentUser));
tunable.onTuningChanged(key, value);
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/DeviceConfigProxy.java b/packages/SystemUI/src/com/android/systemui/util/DeviceConfigProxy.java
new file mode 100644
index 0000000..3a2172a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/DeviceConfigProxy.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+
+/**
+ * Wrapper around DeviceConfig useful for testing.
+ */
+public class DeviceConfigProxy {
+ @Inject
+ public DeviceConfigProxy() {
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#addOnPropertiesChangedListener}.
+ */
+ public void addOnPropertiesChangedListener(
+ @NonNull String namespace,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) {
+ DeviceConfig.addOnPropertiesChangedListener(
+ namespace, executor, onPropertiesChangedListener);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#enforceReadPermission}.
+ */
+ public void enforceReadPermission(Context context, String namespace) {
+ DeviceConfig.enforceReadPermission(context, namespace);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#getBoolean}.
+ */
+ public boolean getBoolean(
+ @NonNull String namespace, @NonNull String name, boolean defaultValue) {
+ return DeviceConfig.getBoolean(namespace, name, defaultValue);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#getFloat}.
+ */
+ public float getFloat(
+ @NonNull String namespace, @NonNull String name, float defaultValue) {
+ return DeviceConfig.getFloat(namespace, name, defaultValue);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#getInt}.
+ */
+ public int getInt(@NonNull String namespace, @NonNull String name, int defaultValue) {
+ return DeviceConfig.getInt(namespace, name, defaultValue);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#getLong}.
+ */
+ public long getLong(@NonNull String namespace, @NonNull String name, long defaultValue) {
+ return DeviceConfig.getLong(namespace, name, defaultValue);
+
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#getProperty}.
+ */
+ public String getProperty(@NonNull String namespace, @NonNull String name) {
+ return DeviceConfig.getProperty(namespace, name);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#getString}.
+ */
+ public String getString(
+ @NonNull String namespace, @NonNull String name, @Nullable String defaultValue) {
+ return DeviceConfig.getString(namespace, name, defaultValue);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#removeOnPropertiesChangedListener}.
+ *
+ * Like {@link #addOnPropertiesChangedListener}, this operates on a callback type that
+ * wraps the original callback type provided by {@link DeviceConfig}.
+ */
+ public void removeOnPropertiesChangedListener(
+ @NonNull DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) {
+ DeviceConfig.removeOnPropertiesChangedListener(onPropertiesChangedListener);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#resetToDefaults}.
+ */
+ public void resetToDefaults(@Settings.ResetMode int resetMode,
+ @Nullable String namespace) {
+ DeviceConfig.resetToDefaults(resetMode, namespace);
+ }
+
+ /**
+ * Wrapped version of {@link DeviceConfig#setProperty}.
+ */
+ public boolean setProperty(
+ @NonNull String namespace,
+ @NonNull String name,
+ @Nullable String value,
+ boolean makeDefault) {
+ return DeviceConfig.setProperty(namespace, name, value, makeDefault);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index a3cb6c0..fce79c3 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -477,6 +477,16 @@
assertThat(listToVerify.get(0)).isEqualTo(TEST_SUBSCRIPTION_2);
}
+ @Test
+ public void testIsUserUnlocked() {
+ // mUserManager will report the user as unlocked on @Before
+ assertThat(mKeyguardUpdateMonitor.isUserUnlocked(KeyguardUpdateMonitor.getCurrentUser()))
+ .isTrue();
+ // Invalid user should not be unlocked.
+ int randomUser = 99;
+ assertThat(mKeyguardUpdateMonitor.isUserUnlocked(randomUser)).isFalse();
+ }
+
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
int subscription = simInited
? 1/* mock subid=1 */ : SubscriptionManager.DUMMY_SUBSCRIPTION_ID_BASE;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 8a6ee12..ccd2138 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -392,18 +392,18 @@
}
private void entryRemoved(StatusBarNotification notification) {
- mEntryListener.onEntryRemoved(new NotificationEntry(notification),
+ mEntryListener.onEntryRemoved(NotificationEntry.buildForTest(notification),
null, false);
}
private void entryAdded(StatusBarNotification notification, int importance) {
- NotificationEntry entry = new NotificationEntry(notification);
+ NotificationEntry entry = NotificationEntry.buildForTest(notification);
entry.importance = importance;
mEntryListener.onPendingEntryAdded(entry);
}
private void entryUpdated(StatusBarNotification notification, int importance) {
- NotificationEntry entry = new NotificationEntry(notification);
+ NotificationEntry entry = NotificationEntry.buildForTest(notification);
entry.importance = importance;
mEntryListener.onPostEntryUpdated(entry);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
index 256cfb2..a245d41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
@@ -42,7 +42,7 @@
public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
new DexmakerShareClassLoaderRule();
- protected final TestableDependency mDependency = new TestableDependency(mContext);
+ protected TestableDependency mDependency;
protected SysuiTestableContext mSysuiContext;
private Instrumentation mRealInstrumentation;
@@ -53,6 +53,7 @@
@Before
public void SysuiSetup() {
SystemUIFactory.createFromConfig(mContext);
+ mDependency = new TestableDependency(mContext);
// TODO: Figure out another way to give reference to a SysuiTestableContext.
mSysuiContext = (SysuiTestableContext) mContext;
@@ -69,6 +70,7 @@
public void SysuiTeardown() {
InstrumentationRegistry.registerInstance(mRealInstrumentation,
InstrumentationRegistry.getArguments());
+ SystemUIFactory.cleanup();
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 8d93f96..e4f33e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -55,12 +55,13 @@
@Rule
public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
new DexmakerShareClassLoaderRule();
- public TestableDependency mDependency = new TestableDependency(mContext);
+ public TestableDependency mDependency;
private Instrumentation mRealInstrumentation;
@Before
public void SysuiSetup() throws Exception {
SystemUIFactory.createFromConfig(mContext);
+ mDependency = new TestableDependency(mContext);
mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
Instrumentation inst = spy(mRealInstrumentation);
@@ -82,6 +83,7 @@
InstrumentationRegistry.getArguments());
// Reset the assert's main looper.
Assert.sMainLooper = Looper.getMainLooper();
+ SystemUIFactory.cleanup();
}
protected LeakCheck getLeakCheck() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
index 815a70a..3eea853 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
@@ -878,7 +878,7 @@
when(sbn.getNotification()).thenReturn(notification);
// NotificationEntry -> StatusBarNotification -> Notification -> BubbleMetadata
- return new NotificationEntry(sbn);
+ return NotificationEntry.buildForTest(sbn);
}
private void setCurrentTime(long time) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
index 7ea6493..2073ae1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
@@ -31,6 +31,8 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.util.DeviceConfigProxy;
+import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.After;
import org.junit.Before;
@@ -45,8 +47,9 @@
public class FalsingManagerProxyTest extends SysuiTestCase {
@Mock
PluginManager mPluginManager;
- private boolean mDefaultConfigValue;
private Handler mHandler;
+ private FalsingManagerProxy mProxy;
+ private DeviceConfigProxy mDeviceConfig;
private TestableLooper mTestableLooper;
@Before
@@ -54,50 +57,47 @@
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
mHandler = new Handler(mTestableLooper.getLooper());
- mDefaultConfigValue = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
- BRIGHTLINE_FALSING_MANAGER_ENABLED, false);
- // In case it runs on a device where it's been set to true, set it to false by hand.
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+ mDeviceConfig = new DeviceConfigProxyFake();
+ mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false);
}
@After
public void tearDown() {
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
- BRIGHTLINE_FALSING_MANAGER_ENABLED, mDefaultConfigValue ? "true" : "false", false);
+ if (mProxy != null) {
+ mProxy.cleanup();
+ }
}
@Test
public void test_brightLineFalsingManagerDisabled() {
- FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
-
- assertThat(proxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
+ mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler, mDeviceConfig);
+ assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
}
@Test
- public void test_brightLineFalsingManagerEnabled() {
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
- BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false);
- FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
-
- assertThat(proxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class));
- }
-
- @Test
- public void test_brightLineFalsingManagerToggled() {
- FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
- assertThat(proxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
-
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+ public void test_brightLineFalsingManagerEnabled() throws InterruptedException {
+ mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false);
mTestableLooper.processAllMessages();
- proxy.setupFalsingManager(getContext());
- assertThat(proxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class));
+ mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler, mDeviceConfig);
+ assertThat(mProxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class));
+ }
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+ @Test
+ public void test_brightLineFalsingManagerToggled() throws InterruptedException {
+ mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler, mDeviceConfig);
+ assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
+
+ mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+ BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false);
+ mTestableLooper.processAllMessages();
+ assertThat(mProxy.getInternalFalsingManager(),
+ instanceOf(BrightLineFalsingManager.class));
+
+ mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false);
mTestableLooper.processAllMessages();
- proxy.setupFalsingManager(getContext());
- assertThat(proxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
+ assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java
index b45d3f2..afe4200 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java
@@ -28,6 +28,8 @@
import androidx.test.filters.SmallTest;
+import com.android.systemui.util.DeviceConfigProxyFake;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -58,7 +60,7 @@
public void setup() {
super.setup();
MockitoAnnotations.initMocks(this);
- mClassifier = new DiagonalClassifier(mDataProvider);
+ mClassifier = new DiagonalClassifier(mDataProvider, new DeviceConfigProxyFake());
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java
index 805bb91..f0f5fc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java
@@ -24,6 +24,8 @@
import androidx.test.filters.SmallTest;
+import com.android.systemui.util.DeviceConfigProxyFake;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -41,7 +43,7 @@
public void setup() {
super.setup();
mDataProvider = getDataProvider();
- mClassifier = new DistanceClassifier(mDataProvider);
+ mClassifier = new DistanceClassifier(mDataProvider, new DeviceConfigProxyFake());
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
index a6cabbf..c76fe74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
@@ -31,6 +31,8 @@
import androidx.test.filters.SmallTest;
+import com.android.systemui.util.DeviceConfigProxyFake;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -60,7 +62,8 @@
MockitoAnnotations.initMocks(this);
when(mDataProvider.getInteractionType()).thenReturn(GENERIC);
when(mDistanceClassifier.isLongSwipe()).thenReturn(false);
- mClassifier = new ProximityClassifier(mDistanceClassifier, mDataProvider);
+ mClassifier = new ProximityClassifier(
+ mDistanceClassifier, mDataProvider, new DeviceConfigProxyFake());
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java
index fb4c1ec..387c0da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java
@@ -24,6 +24,8 @@
import androidx.test.filters.SmallTest;
+import com.android.systemui.util.DeviceConfigProxyFake;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -41,7 +43,7 @@
@Before
public void setup() {
super.setup();
- mClassifier = new ZigZagClassifier(getDataProvider());
+ mClassifier = new ZigZagClassifier(getDataProvider(), new DeviceConfigProxyFake());
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java
index d35fc30..7fa1dbe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/DismissCallbackRegistryTest.java
@@ -38,12 +38,13 @@
@RunWith(AndroidJUnit4.class)
public class DismissCallbackRegistryTest extends SysuiTestCase {
- private final DismissCallbackRegistry mDismissCallbackRegistry = new DismissCallbackRegistry();
+ private DismissCallbackRegistry mDismissCallbackRegistry;
private @Mock IKeyguardDismissCallback mMockCallback;
private @Mock IKeyguardDismissCallback mMockCallback2;
@Before
public void setUp() throws Exception {
+ mDismissCallbackRegistry = new DismissCallbackRegistry();
MockitoAnnotations.initMocks(this);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index 881cc39..e6f36e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -129,7 +129,7 @@
public void setUp() {
mTestHandler = Handler.createAsync(Looper.myLooper());
mSbn = createNewNotification(0 /* id */);
- mEntry = new NotificationEntry(mSbn);
+ mEntry = NotificationEntry.buildForTest(mSbn);
mEntry.setRow(mRow);
mAlertingNotificationManager = createAlertingNotificationManager();
@@ -180,7 +180,7 @@
public void testReleaseAllImmediately() {
for (int i = 0; i < TEST_NUM_NOTIFICATIONS; i++) {
StatusBarNotification sbn = createNewNotification(i);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.setRow(mRow);
mAlertingNotificationManager.showNotification(entry);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index daee55b..2427cfc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -268,12 +268,18 @@
public void unlockMethodCache_listenerUpdatesIndication() {
createController();
String restingIndication = "Resting indication";
- when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
- mController.setRestingIndication(restingIndication);
+
mController.setVisible(true);
+ assertThat(mTextView.getText()).isEqualTo(
+ mContext.getString(com.android.internal.R.string.lockscreen_storage_locked));
+
+ when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
+ mController.setRestingIndication(restingIndication);
assertThat(mTextView.getText()).isEqualTo(mController.getTrustGrantedIndication());
reset(mKeyguardUpdateMonitor);
+ when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
mController.onUnlockMethodStateChanged();
assertThat(mTextView.getText()).isEqualTo(restingIndication);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
index 0800cb9..55ce8d60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
@@ -91,7 +91,7 @@
@Test
public void testNotificationUpdateCallsUpdateNotification() {
- when(mNotificationData.get(mSbn.getKey())).thenReturn(new NotificationEntry(mSbn));
+ when(mNotificationData.get(mSbn.getKey())).thenReturn(NotificationEntry.buildForTest(mSbn));
mListener.onNotificationPosted(mSbn, mRanking);
TestableLooper.get(this).processAllMessages();
verify(mEntryManager).updateNotification(mSbn, mRanking);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index da25eed..99d09f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -30,7 +30,6 @@
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.google.android.collect.Sets;
@@ -81,7 +80,7 @@
Handler.createAsync(Looper.myLooper()));
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
0, new Notification(), UserHandle.CURRENT, null, 0);
- mEntry = new NotificationEntry(mSbn);
+ mEntry = NotificationEntry.buildForTest(mSbn);
mEntry.setRow(mRow);
mRemoteInputManager.setUpWithPresenterForTest(mCallback,
@@ -176,7 +175,7 @@
// Setup a notification entry with 1 remote input.
StatusBarNotification newSbn =
mRemoteInputManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false);
- NotificationEntry entry = new NotificationEntry(newSbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(newSbn);
// Try rebuilding to add another reply.
newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInput(entry, "Reply 2", true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 7063ddf..99428ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -50,7 +50,6 @@
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
/**
* A helper class to create {@link ExpandableNotificationRow} (for both individual and group
@@ -307,7 +306,7 @@
userHandle,
null /* overrideGroupKey */,
System.currentTimeMillis());
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.setRow(row);
entry.createIcons(mContext, sbn);
entry.channel = new NotificationChannel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 58fb53a..54d8688 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -119,7 +119,7 @@
private NotificationEntry createEntry() throws Exception {
ExpandableNotificationRow row = mHelper.createRow();
- NotificationEntry entry = new NotificationEntry(row.getStatusBarNotification());
+ NotificationEntry entry = NotificationEntry.buildForTest(row.getStatusBarNotification());
entry.setRow(row);
return entry;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index 185723f..e54ea6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -97,7 +97,7 @@
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
0, mNotification, new UserHandle(ActivityManager.getCurrentUser()), null, 0);
- mEntry = new NotificationEntry(mSbn);
+ mEntry = NotificationEntry.buildForTest(mSbn);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 2ca1b06..36b143b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -239,7 +239,7 @@
.setContentText("Text");
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
0, n.build(), new UserHandle(ActivityManager.getCurrentUser()), null, 0);
- mEntry = new NotificationEntry(mSbn);
+ mEntry = NotificationEntry.buildForTest(mSbn);
mEntry.expandedIcon = mock(StatusBarIconView.class);
mEntryManager = new TestableNotificationEntryManager(mContext);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
index 6f7751b..b522316 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
@@ -195,12 +195,12 @@
// test should filter out hidden notifications:
// hidden
- NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
+ NotificationEntry entry = NotificationEntry.buildForTest(mMockStatusBarNotification);
entry.suspended = true;
assertTrue(mNotificationFilter.shouldFilterOut(entry));
// not hidden
- entry = new NotificationEntry(mMockStatusBarNotification);
+ entry = NotificationEntry.buildForTest(mMockStatusBarNotification);
entry.suspended = false;
assertFalse(mNotificationFilter.shouldFilterOut(entry));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
index 311b81c..e42d155 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
@@ -234,7 +234,7 @@
new UserHandle(ActivityManager.getCurrentUser()),
null,
0);
- return new NotificationEntry(notification);
+ return NotificationEntry.buildForTest(notification);
}
private static final String TEST_PACKAGE_NAME = "test";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
index dd2630b..49229ca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
@@ -62,7 +62,7 @@
mVisualStabilityManager.setUpWithPresenter(mock(NotificationPresenter.class));
mVisualStabilityManager.setVisibilityLocationProvider(mLocationProvider);
- mEntry = new NotificationEntry(mock(StatusBarNotification.class));
+ mEntry = NotificationEntry.buildForTest(mock(StatusBarNotification.class));
mEntry.setRow(mRow);
when(mRow.getEntry()).thenReturn(mEntry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index e2d8e56..ed719d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -233,7 +233,7 @@
Notification n = mMockStatusBarNotification.getNotification();
n.flags = Notification.FLAG_FOREGROUND_SERVICE;
- NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
+ NotificationEntry entry = NotificationEntry.buildForTest(mMockStatusBarNotification);
entry.setRow(mRow);
mNotificationData.add(entry);
Bundle override = new Bundle();
@@ -252,7 +252,7 @@
nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
n = nb.build();
when(mMockStatusBarNotification.getNotification()).thenReturn(n);
- NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
+ NotificationEntry entry = NotificationEntry.buildForTest(mMockStatusBarNotification);
entry.setRow(mRow);
mNotificationData.add(entry);
Bundle override = new Bundle();
@@ -266,7 +266,7 @@
@Test
public void testIsExemptFromDndVisualSuppression_system() {
initStatusBarNotification(false);
- NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
+ NotificationEntry entry = NotificationEntry.buildForTest(mMockStatusBarNotification);
entry.setRow(mRow);
entry.mIsSystemNotification = true;
mNotificationData.add(entry);
@@ -281,7 +281,7 @@
@Test
public void testIsNotExemptFromDndVisualSuppression_hiddenCategories() {
initStatusBarNotification(false);
- NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
+ NotificationEntry entry = NotificationEntry.buildForTest(mMockStatusBarNotification);
entry.setRow(mRow);
entry.mIsSystemNotification = true;
Bundle override = new Bundle();
@@ -369,7 +369,7 @@
StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
notification, mContext.getUser(), "", 0);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.setHasSentReply();
assertTrue(entry.isLastMessageFromReply());
@@ -474,7 +474,7 @@
.build();
StatusBarNotification aSbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
aN, mContext.getUser(), "", 0);
- NotificationEntry a = new NotificationEntry(aSbn);
+ NotificationEntry a = NotificationEntry.buildForTest(aSbn);
a.setRow(mock(ExpandableNotificationRow.class));
a.setIsHighPriority(false);
@@ -488,7 +488,7 @@
.build();
StatusBarNotification bSbn = new StatusBarNotification("pkg2", "pkg2", 0, "tag", 0, 0,
bN, mContext.getUser(), "", 0);
- NotificationEntry b = new NotificationEntry(bSbn);
+ NotificationEntry b = NotificationEntry.buildForTest(bSbn);
b.setIsHighPriority(true);
b.setRow(mock(ExpandableNotificationRow.class));
@@ -509,7 +509,7 @@
.build();
StatusBarNotification aSbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
aN, mContext.getUser(), "", 0);
- NotificationEntry a = new NotificationEntry(aSbn);
+ NotificationEntry a = NotificationEntry.buildForTest(aSbn);
a.setRow(mock(ExpandableNotificationRow.class));
a.setIsHighPriority(false);
@@ -523,7 +523,7 @@
.build();
StatusBarNotification bSbn = new StatusBarNotification("pkg2", "pkg2", 0, "tag", 0, 0,
bN, mContext.getUser(), "", 0);
- NotificationEntry b = new NotificationEntry(bSbn);
+ NotificationEntry b = NotificationEntry.buildForTest(bSbn);
b.setRow(mock(ExpandableNotificationRow.class));
b.setIsHighPriority(false);
@@ -556,7 +556,7 @@
override.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_DEFAULT);
mNotificationData.rankingOverrides.put(sbn.getKey(), override);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.setRow(mRow);
mNotificationData.add(entry);
@@ -583,7 +583,7 @@
override.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_LOW);
mNotificationData.rankingOverrides.put(sbn.getKey(), override);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.setRow(mRow);
mNotificationData.add(entry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index cca9f28..57a6aae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -23,6 +23,7 @@
import android.app.Notification;
import android.os.Bundle;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -59,7 +60,18 @@
mExtras = new Bundle();
mNotif.extras = mExtras;
- mEntry = new NotificationEntry(mStatusBarNotification);
+ mEntry = NotificationEntry.buildForTest(mStatusBarNotification);
+ }
+
+ @Test
+ public void testInitialization() {
+ final Ranking ranking = new Ranking();
+
+ final NotificationEntry entry = new NotificationEntry(mStatusBarNotification, ranking);
+
+ assertEquals("key", entry.key());
+ assertEquals(mStatusBarNotification, entry.sbn());
+ assertEquals(ranking, entry.ranking());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index 5e587f8..ff3a2e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -96,7 +96,7 @@
StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
0, null, TEST_UID,
0, new Notification(), UserHandle.CURRENT, null, 0);
- mEntry = new NotificationEntry(sbn);
+ mEntry = NotificationEntry.buildForTest(sbn);
mEntry.setRow(mRow);
mLogger = new TestableNotificationLogger(mListener, Dependency.get(UiOffloadThread.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index 13b9d56..98e1692 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -60,7 +60,7 @@
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
mRow = mock(ExpandableNotificationRow.class);
- NotificationEntry entry = new NotificationEntry(
+ NotificationEntry entry = NotificationEntry.buildForTest(
mock(StatusBarNotification.class));
entry.channel = mock(NotificationChannel.class);
when(mRow.getEntry()).thenReturn(entry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 48934da..de3623f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -121,7 +121,7 @@
@Test
public void testCanRemoveImmediately_notTopEntry() {
- NotificationEntry laterEntry = new NotificationEntry(createNewNotification(1));
+ NotificationEntry laterEntry = NotificationEntry.buildForTest(createNewNotification(1));
laterEntry.setRow(mRow);
mHeadsUpManager.showNotification(mEntry);
mHeadsUpManager.showNotification(laterEntry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 75aae01..33d3ac8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -82,8 +82,7 @@
private FragmentController mControllerExternalDisplay;
private SysuiTestableContext mSysuiTestableContextExternal;
- private OverviewProxyService mOverviewProxyService =
- mDependency.injectMockDependency(OverviewProxyService.class);
+ private OverviewProxyService mOverviewProxyService;
private CommandQueue mCommandQueue;
private SysUiState mMockSysUiState;
@@ -115,6 +114,8 @@
public void setupFragment() throws Exception {
setupSysuiDependency();
createRootView();
+ mOverviewProxyService =
+ mDependency.injectMockDependency(OverviewProxyService.class);
TestableLooper.get(this).runWithLooper(() -> {
mHandler = new Handler();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
index cf08428..d6b38ff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
@@ -30,7 +30,6 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
-import com.android.systemui.TestableDependency;
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
import com.android.systemui.statusbar.policy.RotationLockController;
@@ -50,7 +49,6 @@
@Rule
public final SysuiTestableContext mContext = new SysuiTestableContext(
InstrumentationRegistry.getContext(), getLeakCheck());
- private final TestableDependency mDependency = new TestableDependency(mContext);
private RotationButtonController mRotationButtonController;
private RotationButton mRotationButton;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
index b1c3c83..a0d264d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
@@ -256,7 +256,7 @@
StatusBarNotification oldNotification = childEntry.notification;
StatusBarNotification newSbn = spy(childEntry.notification.clone());
doReturn("other_group").when(newSbn).getGroupKey();
- childEntry.notification = newSbn;
+ childEntry.setNotification(newSbn);
mGroupManager.onEntryUpdated(childEntry, oldNotification);
assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
@@ -267,7 +267,7 @@
NotificationEntry summaryEntry =
mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
NotificationEntry childEntry =
- mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
+ mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY, 47);
when(childEntry.getRow().isInflationFlagSet(mHeadsUpManager.getContentFlag()))
.thenReturn(false);
mHeadsUpManager.showNotification(summaryEntry);
@@ -277,8 +277,9 @@
// Update that child to a summary.
StatusBarNotification oldNotification = childEntry.notification;
- childEntry.notification = mGroupTestHelper.createSummaryNotification(
- Notification.GROUP_ALERT_SUMMARY).notification;
+ childEntry.setNotification(
+ mGroupTestHelper.createSummaryNotification(
+ Notification.GROUP_ALERT_SUMMARY, 47).notification);
mGroupManager.onEntryUpdated(childEntry, oldNotification);
assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
index e6b9778..e33545b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
@@ -45,11 +45,15 @@
}
public NotificationEntry createSummaryNotification() {
- return createSummaryNotification(Notification.GROUP_ALERT_ALL);
+ return createSummaryNotification(Notification.GROUP_ALERT_ALL, mId++);
}
public NotificationEntry createSummaryNotification(int groupAlertBehavior) {
- return createEntry(true, groupAlertBehavior);
+ return createSummaryNotification(groupAlertBehavior, mId++);
+ }
+
+ public NotificationEntry createSummaryNotification(int groupAlertBehavior, int id) {
+ return createEntry(id, true, groupAlertBehavior);
}
public NotificationEntry createChildNotification() {
@@ -57,10 +61,14 @@
}
public NotificationEntry createChildNotification(int groupAlertBehavior) {
- return createEntry(false, groupAlertBehavior);
+ return createEntry(mId++, false, groupAlertBehavior);
}
- public NotificationEntry createEntry(boolean isSummary, int groupAlertBehavior) {
+ public NotificationEntry createChildNotification(int groupAlertBehavior, int id) {
+ return createEntry(id, false, groupAlertBehavior);
+ }
+
+ public NotificationEntry createEntry(int id, boolean isSummary, int groupAlertBehavior) {
Notification notif = new Notification.Builder(mContext, TEST_CHANNEL_ID)
.setContentTitle("Title")
.setSmallIcon(R.drawable.ic_person)
@@ -71,7 +79,7 @@
StatusBarNotification sbn = new StatusBarNotification(
TEST_PACKAGE_NAME /* pkg */,
TEST_PACKAGE_NAME,
- mId++,
+ id,
null /* tag */,
0, /* uid */
0 /* initialPid */,
@@ -79,7 +87,7 @@
new UserHandle(ActivityManager.getCurrentUser()),
null /* overrideGroupKey */,
0 /* postTime */);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
entry.setRow(row);
when(row.getEntry()).thenReturn(entry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 186a8c7..45cd1e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -86,7 +86,7 @@
Notification n = new Notification.Builder(getContext(), "a").build();
StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
UserHandle.of(0), null, 0);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
mCommandQueue.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_EXPAND, 0,
false /* animate */);
TestableLooper.get(this).processAllMessages();
@@ -100,7 +100,7 @@
Notification n = new Notification.Builder(getContext(), "a").build();
StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
UserHandle.of(0), null, 0);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
mCommandQueue.disable(DEFAULT_DISPLAY, 0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE,
false /* animate */);
TestableLooper.get(this).processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index fa235bd..7fbf183 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -418,7 +418,7 @@
.build();
StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
UserHandle.of(0), null, 0);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.importance = IMPORTANCE_HIGH;
assertTrue(mNotificationInterruptionStateProvider.shouldHeadsUp(entry));
@@ -439,7 +439,7 @@
.build();
StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
UserHandle.of(0), null, 0);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.importance = IMPORTANCE_HIGH;
assertFalse(mNotificationInterruptionStateProvider.shouldHeadsUp(entry));
@@ -456,7 +456,7 @@
Notification n = new Notification.Builder(getContext(), "a").build();
StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
UserHandle.of(0), null, 0);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.suppressedVisualEffects = SUPPRESSED_EFFECT_PEEK;
entry.importance = IMPORTANCE_HIGH;
@@ -474,7 +474,7 @@
Notification n = new Notification.Builder(getContext(), "a").build();
StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
UserHandle.of(0), null, 0);
- NotificationEntry entry = new NotificationEntry(sbn);
+ NotificationEntry entry = NotificationEntry.buildForTest(sbn);
entry.importance = IMPORTANCE_HIGH;
assertTrue(mNotificationInterruptionStateProvider.shouldHeadsUp(entry));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java
index 2462fb3..bda0e39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java
@@ -88,7 +88,7 @@
when(mNotification.getAllowSystemGeneratedContextualActions()).thenReturn(true);
when(mStatusBarNotification.getNotification()).thenReturn(mNotification);
- mEntry = new NotificationEntry(mStatusBarNotification);
+ mEntry = NotificationEntry.buildForTest(mStatusBarNotification);
when(mSmartReplyConstants.isEnabled()).thenReturn(true);
mActionIcon = Icon.createWithResource(mContext, R.drawable.ic_person);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 0cb5754..b59bac1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -140,7 +140,7 @@
StatusBarNotification sbn = mock(StatusBarNotification.class);
when(sbn.getNotification()).thenReturn(mNotification);
when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
- mEntry = new NotificationEntry(sbn);
+ mEntry = NotificationEntry.buildForTest(sbn);
mActionIcon = Icon.createWithResource(mContext, R.drawable.ic_person);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/DeviceConfigProxyFake.java b/packages/SystemUI/tests/src/com/android/systemui/util/DeviceConfigProxyFake.java
new file mode 100644
index 0000000..426aba0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/DeviceConfigProxyFake.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util;
+
+import android.content.Context;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.OnPropertiesChangedListener;
+import android.provider.DeviceConfig.Properties;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * A Fake of {@link DeviceConfigProxy} useful for testing.
+ *
+ * No properties are set by default. No calls to {@link DeviceConfig} are made. Be sure to set any
+ * properties you rely on ahead of time in your test.
+ */
+public class DeviceConfigProxyFake extends DeviceConfigProxy {
+
+ private List<Pair<Executor, OnPropertiesChangedListener>> mListeners = new ArrayList<>();
+ private Map<String, Map<String, String>> mDefaultProperties = new HashMap<>();
+ private Map<String, Map<String, String>> mProperties = new HashMap<>();
+
+ public DeviceConfigProxyFake() {
+ }
+
+ @Override
+ public void addOnPropertiesChangedListener(
+ String namespace, Executor executor,
+ OnPropertiesChangedListener onPropertiesChangedListener) {
+ mListeners.add(Pair.create(executor, onPropertiesChangedListener));
+ }
+
+ @Override
+ public void removeOnPropertiesChangedListener(
+ OnPropertiesChangedListener onPropertiesChangedListener) {
+ mListeners.removeIf(listener -> {
+ if (listener == null) {
+ return false;
+ }
+ return listener.second.equals(onPropertiesChangedListener);
+ });
+ }
+
+ @Override
+ public boolean setProperty(String namespace, String name, String value, boolean makeDefault) {
+ setPropertyInternal(namespace, name, value, mProperties);
+ if (makeDefault) {
+ setPropertyInternal(namespace, name, value, mDefaultProperties);
+ }
+
+ for (Pair<Executor, OnPropertiesChangedListener> listener : mListeners) {
+ listener.first.execute(() -> listener.second.onPropertiesChanged(
+ new Properties(namespace, mProperties.get(namespace))));
+ }
+ return true;
+ }
+
+ private void setPropertyInternal(String namespace, String name, String value,
+ Map<String, Map<String, String>> properties) {
+ properties.putIfAbsent(namespace, new HashMap<>());
+ properties.get(namespace).put(name, value);
+ }
+
+ @Override
+ public void enforceReadPermission(Context context, String namespace) {
+ // no-op
+ }
+
+ private Properties propsForNamespaceAndName(String namespace, String name) {
+ if (mProperties.containsKey(namespace) && mProperties.get(namespace).containsKey(name)) {
+ return new Properties(namespace, mProperties.get(namespace));
+ }
+ if (mDefaultProperties.containsKey(namespace)) {
+ return new Properties(namespace, mDefaultProperties.get(namespace));
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean getBoolean(String namespace, String name, boolean defaultValue) {
+ Properties props = propsForNamespaceAndName(namespace, name);
+ if (props != null) {
+ return props.getBoolean(name, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getInt(String namespace, String name, int defaultValue) {
+ Properties props = propsForNamespaceAndName(namespace, name);
+ if (props != null) {
+ return props.getInt(name, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public long getLong(String namespace, String name, long defaultValue) {
+ Properties props = propsForNamespaceAndName(namespace, name);
+ if (props != null) {
+ return props.getLong(name, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public String getProperty(String namespace, String name) {
+ return getString(namespace, name, null);
+ }
+
+ @Override
+ public String getString(String namespace, String name, String defaultValue) {
+ Properties props = propsForNamespaceAndName(namespace, name);
+ if (props != null) {
+ return props.getString(name, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public void resetToDefaults(int resetMode, String namespace) {
+ if (mProperties.containsKey(namespace)) {
+ mProperties.get(namespace).clear();
+ }
+ }
+}
diff --git a/services/Android.bp b/services/Android.bp
index 27f8d36..6953e86 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -63,6 +63,5 @@
platform_compat_config {
name: "services-platform-compat-config",
- prefix: "services",
src: ":services",
}
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index d8b7e3a..a338b90 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -66,12 +66,6 @@
// Tag for logging received events.
private static final String LOG_TAG = "TouchExplorer";
- // States this explorer can be in.
- private static final int STATE_TOUCH_EXPLORING = 0x00000001;
- private static final int STATE_DRAGGING = 0x00000002;
- private static final int STATE_DELEGATING = 0x00000004;
- private static final int STATE_GESTURE_DETECTING = 0x00000005;
-
// The maximum of the cosine between the vectors of two moving
// pointers so they can be considered moving in the same direction.
private static final float MAX_DRAGGING_ANGLE_COS = 0.525321989f; // cos(pi/4)
@@ -248,7 +242,13 @@
return;
}
- if (mState.isTouchExploring()) {
+ // TODO: extract the below functions into separate handlers for each state.
+ // Right now the number of functions and number of states make the code messy.
+ if (mState.isClear()) {
+ handleMotionEventStateClear(event, rawEvent, policyFlags);
+ } else if (mState.isTouchInteracting()) {
+ handleMotionEventStateTouchInteracting(event, rawEvent, policyFlags);
+ } else if (mState.isTouchExploring()) {
handleMotionEventStateTouchExploring(event, rawEvent, policyFlags);
} else if (mState.isDragging()) {
handleMotionEventStateDragging(event, policyFlags);
@@ -286,8 +286,8 @@
@Override
public void onDoubleTapAndHold(MotionEvent event, int policyFlags) {
- // Ignore the event if we aren't touch exploring.
- if (!mState.isTouchExploring()) {
+ // Ignore the event if we aren't touch interacting.
+ if (!mState.isTouchInteracting()) {
return;
}
@@ -304,8 +304,7 @@
@Override
public boolean onDoubleTap(MotionEvent event, int policyFlags) {
- // Ignore the event if we aren't touch exploring.
- if (!mState.isTouchExploring()) {
+ if (!mState.isTouchInteracting()) {
return false;
}
@@ -380,6 +379,94 @@
}
/**
+ * Handles a motion event in the clear state i.e. no fingers are touching the screen.
+ */
+ private void handleMotionEventStateClear(
+ MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ switch (event.getActionMasked()) {
+ // The only way to leave the clear state is for a pointer to go down.
+ case MotionEvent.ACTION_DOWN:
+ handleActionDown(event, policyFlags);
+ break;
+ default:
+ // Some other nonsensical event.
+ break;
+ }
+ }
+
+ /**
+ * Handles ACTION_DOWN while in the clear or touch interacting states. This event represents the
+ * first finger touching the screen.
+ */
+ private void handleActionDown(MotionEvent event, int policyFlags) {
+ mAms.onTouchInteractionStart();
+
+ // If we still have not notified the user for the last
+ // touch, we figure out what to do. If were waiting
+ // we resent the delayed callback and wait again.
+ mSendHoverEnterAndMoveDelayed.cancel();
+ mSendHoverExitDelayed.cancel();
+
+ // If a touch exploration gesture is in progress send events for its end.
+ if (mState.isTouchExploring()) {
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
+ }
+
+ // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double
+ // tap.
+ if (!mGestureDetector.firstTapDetected() && mState.isClear()) {
+ mSendTouchExplorationEndDelayed.forceSendAndRemove();
+ mSendTouchInteractionEndDelayed.forceSendAndRemove();
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
+ } else {
+ // Let gesture to handle to avoid duplicated TYPE_TOUCH_INTERACTION_END event.
+ mSendTouchInteractionEndDelayed.cancel();
+ }
+
+ if (!mGestureDetector.firstTapDetected() && !mState.isTouchExploring()) {
+ if (!mSendHoverEnterAndMoveDelayed.isPending()) {
+ // Queue a delayed transition to STATE_TOUCH_EXPLORING.
+ // If we do not detect that this is a gesture, delegation or drag the transition
+ // will fire by default.
+ // The idea is to avoid getting stuck in STATE_TOUCH_INTERACTING
+ final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
+ final int pointerIdBits = (1 << pointerId);
+ mSendHoverEnterAndMoveDelayed.post(event, pointerIdBits, policyFlags);
+ } else {
+ // Cache the event until we discern exploration from gesturing.
+ mSendHoverEnterAndMoveDelayed.addEvent(event);
+ }
+ }
+ }
+
+ /**
+ * Handles a motion event in touch interacting state.
+ *
+ * @param event The event to be handled.
+ * @param rawEvent The raw (unmodified) motion event.
+ * @param policyFlags The policy flags associated with the event.
+ */
+ private void handleMotionEventStateTouchInteracting(
+ MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ // Continue the previous interaction.
+ mSendTouchInteractionEndDelayed.cancel();
+ handleActionDown(event, policyFlags);
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ handleActionPointerDown();
+ break;
+ case MotionEvent.ACTION_MOVE:
+ handleActionMoveStateTouchInteracting(event, rawEvent, policyFlags);
+ break;
+ case MotionEvent.ACTION_UP:
+ handleActionUp(event, policyFlags);
+ break;
+ }
+ }
+
+ /**
* Handles a motion event in touch exploring state.
*
* @param event The event to be handled.
@@ -390,60 +477,19 @@
MotionEvent event, MotionEvent rawEvent, int policyFlags) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- handleActionDownStateTouchExploring(event, policyFlags);
+ // We should have already received ACTION_DOWN. Ignore.
break;
case MotionEvent.ACTION_POINTER_DOWN:
- handleActionPointerDownStateTouchExploring();
+ handleActionPointerDown();
break;
case MotionEvent.ACTION_MOVE:
handleActionMoveStateTouchExploring(event, rawEvent, policyFlags);
break;
case MotionEvent.ACTION_UP:
- handleActionUpStateTouchExploring(event, policyFlags);
+ handleActionUp(event, policyFlags);
break;
- }
- }
-
- /**
- * Handles ACTION_DOWN while in the default touch exploring state. This event represents the
- * first finger touching the screen.
- */
- private void handleActionDownStateTouchExploring(MotionEvent event, int policyFlags) {
- mAms.onTouchInteractionStart();
-
- // If we still have not notified the user for the last
- // touch, we figure out what to do. If were waiting
- // we resent the delayed callback and wait again.
- mSendHoverEnterAndMoveDelayed.cancel();
- mSendHoverExitDelayed.cancel();
-
- // If a touch exploration gesture is in progress send events for its end.
- if (mState.isTouchExplorationInProgress()) {
- sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
- }
-
- // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double
- // tap.
- if (!mGestureDetector.firstTapDetected()) {
- mSendTouchExplorationEndDelayed.forceSendAndRemove();
- mSendTouchInteractionEndDelayed.forceSendAndRemove();
- sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
- } else {
- // Let gesture to handle to avoid duplicated TYPE_TOUCH_INTERACTION_END event.
- mSendTouchInteractionEndDelayed.cancel();
- }
-
- if (!mGestureDetector.firstTapDetected() && !mState.isTouchExplorationInProgress()) {
- if (!mSendHoverEnterAndMoveDelayed.isPending()) {
- // Deliver hover enter with a delay to have a chance
- // to detect what the user is trying to do.
- final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
- final int pointerIdBits = (1 << pointerId);
- mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits, policyFlags);
- } else {
- // Cache the event until we discern exploration from gesturing.
- mSendHoverEnterAndMoveDelayed.addEvent(event);
- }
+ default:
+ break;
}
}
@@ -451,7 +497,7 @@
* Handles ACTION_POINTER_DOWN when in the touch exploring state. This event represents an
* additional finger touching the screen.
*/
- private void handleActionPointerDownStateTouchExploring() {
+ private void handleActionPointerDown() {
// Another finger down means that if we have not started to deliver
// hover events, we will not have to. The code for ACTION_MOVE will
// decide what we will actually do next.
@@ -459,10 +505,10 @@
mSendHoverExitDelayed.cancel();
}
/**
- * Handles ACTION_MOVE while in the initial touch exploring state. This is where transitions to
+ * Handles ACTION_MOVE while in the touch interacting state. This is where transitions to
* delegating and dragging states are handled.
*/
- private void handleActionMoveStateTouchExploring(
+ private void handleActionMoveStateTouchInteracting(
MotionEvent event, MotionEvent rawEvent, int policyFlags) {
final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
final int pointerIndex = event.findPointerIndex(pointerId);
@@ -474,41 +520,14 @@
if (mSendHoverEnterAndMoveDelayed.isPending()) {
// Cache the event until we discern exploration from gesturing.
mSendHoverEnterAndMoveDelayed.addEvent(event);
- } else if (mState.isTouchExplorationInProgress()) {
- sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
- sendMotionEvent(
- event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags);
}
break;
case 2:
+ // Make sure we don't have any pending transitions to touch exploration
+ mSendHoverEnterAndMoveDelayed.cancel();
+ mSendHoverExitDelayed.cancel();
// More than one pointer so the user is not touch exploring
// and now we have to decide whether to delegate or drag.
- if (mSendHoverEnterAndMoveDelayed.isPending()) {
- // We have not started sending events so cancel
- // scheduled sending events.
- mSendHoverEnterAndMoveDelayed.cancel();
- mSendHoverExitDelayed.cancel();
- } else if (mState.isTouchExplorationInProgress()) {
- // If the user is touch exploring the second pointer may be
- // performing a double tap to activate an item without need
- // for the user to lift his exploring finger.
- // It is *important* to use the distance traveled by the pointers
- // on the screen which may or may not be magnified.
- final float deltaX =
- mReceivedPointerTracker.getReceivedPointerDownX(pointerId)
- - rawEvent.getX(pointerIndex);
- final float deltaY =
- mReceivedPointerTracker.getReceivedPointerDownY(pointerId)
- - rawEvent.getY(pointerIndex);
- final double moveDelta = Math.hypot(deltaX, deltaY);
- if (moveDelta < mDoubleTapSlop) {
- break;
- }
- // We are sending events so send exit and gesture
- // end since we transition to another state.
- sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
- }
-
// Remove move history before send injected non-move events
event = MotionEvent.obtainNoHistory(event);
if (isDraggingGesture(event)) {
@@ -525,19 +544,6 @@
}
break;
default:
- // More than one pointer so the user is not touch exploring
- // and now we have to decide whether to delegate or drag.
- if (mSendHoverEnterAndMoveDelayed.isPending()) {
- // We have not started sending events so cancel
- // scheduled sending events.
- mSendHoverEnterAndMoveDelayed.cancel();
- mSendHoverExitDelayed.cancel();
- } else {
- // We are sending events so send exit and gesture
- // end since we transition to another state.
- sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
- }
-
// More than two pointers are delegated to the view hierarchy.
mState.startDelegating();
event = MotionEvent.obtainNoHistory(event);
@@ -547,14 +553,13 @@
}
/**
- * Handles ACTION_UP while in the initial touch exploring state. This event represents all
- * fingers being lifted from the screen.
+ * Handles ACTION_UP while in the touch interacting state. This event represents all fingers
+ * being lifted from the screen.
*/
- private void handleActionUpStateTouchExploring(MotionEvent event, int policyFlags) {
+ private void handleActionUp(MotionEvent event, int policyFlags) {
mAms.onTouchInteractionEnd();
final int pointerId = event.getPointerId(event.getActionIndex());
final int pointerIdBits = (1 << pointerId);
-
if (mSendHoverEnterAndMoveDelayed.isPending()) {
// If we have not delivered the enter schedule an exit.
mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags);
@@ -562,13 +567,69 @@
// The user is touch exploring so we send events for end.
sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
}
-
if (!mSendTouchInteractionEndDelayed.isPending()) {
mSendTouchInteractionEndDelayed.post();
}
}
/**
+ * Handles move events while touch exploring. this is also where we drag or delegate based on
+ * the number of fingers moving on the screen.
+ */
+ private void handleActionMoveStateTouchExploring(
+ MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
+ final int pointerIdBits = (1 << pointerId);
+ final int pointerIndex = event.findPointerIndex(pointerId);
+ switch (event.getPointerCount()) {
+ case 1:
+ // Touch exploration.
+ sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
+ sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags);
+ break;
+ case 2:
+ if (mSendHoverEnterAndMoveDelayed.isPending()) {
+ // We have not started sending events so cancel
+ // scheduled sending events.
+ mSendHoverEnterAndMoveDelayed.cancel();
+ mSendHoverExitDelayed.cancel();
+ }
+ // If the user is touch exploring the second pointer may be
+ // performing a double tap to activate an item without need
+ // for the user to lift his exploring finger.
+ // It is *important* to use the distance traveled by the pointers
+ // on the screen which may or may not be magnified.
+ final float deltaX =
+ mReceivedPointerTracker.getReceivedPointerDownX(pointerId)
+ - rawEvent.getX(pointerIndex);
+ final float deltaY =
+ mReceivedPointerTracker.getReceivedPointerDownY(pointerId)
+ - rawEvent.getY(pointerIndex);
+ final double moveDelta = Math.hypot(deltaX, deltaY);
+ if (moveDelta > mDoubleTapSlop) {
+ // The user is trying to either delegate or drag.
+ handleActionMoveStateTouchInteracting(event, rawEvent, policyFlags);
+ } else {
+ // Otherwise the double tap will be handled by the gesture detector.
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
+ }
+ break;
+ default:
+ // Three or more fingers is something other than touch exploration.
+ if (mSendHoverEnterAndMoveDelayed.isPending()) {
+ // We have not started sending events so cancel
+ // scheduled sending events.
+ mSendHoverEnterAndMoveDelayed.cancel();
+ mSendHoverExitDelayed.cancel();
+ } else {
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
+ }
+ handleActionMoveStateTouchInteracting(event, rawEvent, policyFlags);
+ break;
+ }
+ }
+
+ /**
* Handles a motion event in dragging state.
*
* @param event The event to be handled.
@@ -670,7 +731,6 @@
// Send an event to the end of the drag gesture.
sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
}
- mState.startTouchExploring();
} break;
}
}
@@ -697,7 +757,6 @@
mAms.onTouchInteractionEnd();
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
- mState.startTouchExploring();
} break;
default: {
// Deliver the event.
@@ -717,7 +776,6 @@
}
mExitGestureDetectionModeDelayed.cancel();
- mState.startTouchExploring();
}
/**
@@ -731,8 +789,13 @@
AccessibilityEvent event = AccessibilityEvent.obtain(type);
event.setWindowId(mAms.getActiveWindowId());
accessibilityManager.sendAccessibilityEvent(event);
- mState.onInjectedAccessibilityEvent(type);
+ if (DEBUG) {
+ Slog.d(
+ LOG_TAG,
+ "Sending accessibility event" + AccessibilityEvent.eventTypeToString(type));
+ }
}
+ mState.onInjectedAccessibilityEvent(type);
}
/**
@@ -915,6 +978,10 @@
MAX_DRAGGING_ANGLE_COS);
}
+ public TouchState getState() {
+ return mState;
+ }
+
/**
* Class for delayed exiting from gesture detecting mode.
*/
@@ -947,8 +1014,7 @@
private int mPointerIdBits;
private int mPolicyFlags;
- public void post(MotionEvent event, boolean touchExplorationInProgress,
- int pointerIdBits, int policyFlags) {
+ public void post(MotionEvent event, int pointerIdBits, int policyFlags) {
cancel();
addEvent(event);
mPointerIdBits = pointerIdBits;
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
index 820c1a7..17e969a 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
@@ -41,20 +41,33 @@
public static final int ALL_POINTER_ID_BITS = 0xFFFFFFFF;
// States that the touch explorer can be in.
- public static final int STATE_TOUCH_EXPLORING = 0x00000001;
- public static final int STATE_DRAGGING = 0x00000002;
- public static final int STATE_DELEGATING = 0x00000003;
- public static final int STATE_GESTURE_DETECTING = 0x00000004;
+ // In the clear state the user is not touching the screen.
+ public static final int STATE_CLEAR = 0;
+ // The user is touching the screen and we are trying to figure out their intent.
+ // This state gets its name from the TYPE_TOUCH_INTERACTION start and end accessibility events.
+ public static final int STATE_TOUCH_INTERACTING = 1;
+ // The user is explicitly exploring the screen.
+ public static final int STATE_TOUCH_EXPLORING = 2;
+ // the user is dragging with two fingers.
+ public static final int STATE_DRAGGING = 3;
+ // The user is performing some other two finger gesture which we pass through to the view
+ // hierarchy as a one-finger gesture e.g. two-finger scrolling.
+ public static final int STATE_DELEGATING = 4;
+ // The user is performing something that might be a gesture.
+ public static final int STATE_GESTURE_DETECTING = 5;
- @IntDef({STATE_TOUCH_EXPLORING, STATE_DRAGGING, STATE_DELEGATING, STATE_GESTURE_DETECTING})
+ @IntDef({
+ STATE_CLEAR,
+ STATE_TOUCH_INTERACTING,
+ STATE_TOUCH_EXPLORING,
+ STATE_DRAGGING,
+ STATE_DELEGATING,
+ STATE_GESTURE_DETECTING
+ })
public @interface State {}
// The current state of the touch explorer.
- private int mState = STATE_TOUCH_EXPLORING;
- // Whether touch exploration is in progress.
- // TODO: Add separate states to represent intend detection and actual touch exploration so that
- // only one variable describes the state.
- private boolean mTouchExplorationInProgress;
+ private int mState = STATE_CLEAR;
// Helper class to track received pointers.
// Todo: collapse or hide this class so multiple classes don't modify it.
private final ReceivedPointerTracker mReceivedPointerTracker;
@@ -69,8 +82,7 @@
/** Clears the internal shared state. */
public void clear() {
- mState = STATE_TOUCH_EXPLORING;
- mTouchExplorationInProgress = false;
+ setState(STATE_CLEAR);
// Reset the pointer trackers.
mReceivedPointerTracker.clear();
mInjectedPointerTracker.clear();
@@ -94,18 +106,33 @@
mReceivedPointerTracker.onMotionEvent(rawEvent);
}
- /**
- * Updates the state in response to an accessibility event being sent from TouchExplorer.
- *
- * @param type The event type.
- */
public void onInjectedAccessibilityEvent(int type) {
+ // The below state transitions go here because the related events are often sent on a
+ // delay.
+ // This allows state to accurately reflect the state in the moment.
+ // TODO: replaced the delayed event senders with delayed state transitions
+ // so that state transitions trigger events rather than events triggering state
+ // transitions.
switch (type) {
+ case AccessibilityEvent.TYPE_TOUCH_INTERACTION_START:
+ startTouchInteracting();
+ break;
+ case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
+ clear();
+ break;
case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START:
- mTouchExplorationInProgress = true;
+ startTouchExploring();
break;
case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:
- mTouchExplorationInProgress = false;
+ startTouchInteracting();
+ break;
+ case AccessibilityEvent.TYPE_GESTURE_DETECTION_START:
+ startGestureDetecting();
+ break;
+ case AccessibilityEvent.TYPE_GESTURE_DETECTION_END:
+ startTouchInteracting();
+ break;
+ default:
break;
}
}
@@ -117,6 +144,7 @@
/** Transitions to a new state. */
public void setState(@State int state) {
+ if (mState == state) return;
if (DEBUG) {
Slog.i(LOG_TAG, getStateSymbolicName(mState) + "->" + getStateSymbolicName(state));
}
@@ -159,26 +187,32 @@
setState(STATE_DRAGGING);
}
- public boolean isTouchExplorationInProgress() {
- return mTouchExplorationInProgress;
+ public boolean isTouchInteracting() {
+ return mState == STATE_TOUCH_INTERACTING;
}
- public void setTouchExplorationInProgress(boolean touchExplorationInProgress) {
- mTouchExplorationInProgress = touchExplorationInProgress;
+ /**
+ * Transitions to the touch interacting state, where we attempt to figure out what the user is
+ * doing.
+ */
+ public void startTouchInteracting() {
+ setState(STATE_TOUCH_INTERACTING);
}
+ public boolean isClear() {
+ return mState == STATE_CLEAR;
+ }
/** Returns a string representation of the current state. */
public String toString() {
- return "TouchState { "
- + "mState: "
- + getStateSymbolicName(mState)
- + ", mTouchExplorationInProgress"
- + mTouchExplorationInProgress
- + " }";
+ return "TouchState { " + "mState: " + getStateSymbolicName(mState) + " }";
}
/** Returns a string representation of the specified state. */
public static String getStateSymbolicName(int state) {
switch (state) {
+ case STATE_CLEAR:
+ return "STATE_CLEAR";
+ case STATE_TOUCH_INTERACTING:
+ return "STATE_TOUCH_INTERACTING";
case STATE_TOUCH_EXPLORING:
return "STATE_TOUCH_EXPLORING";
case STATE_DRAGGING:
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
index d7e68f8..5844f98 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionSessionId;
import android.app.prediction.AppTargetEvent;
@@ -61,7 +62,8 @@
public AppPredictionManagerService(Context context) {
super(context, new FrameworkResourcesServiceNameResolver(context,
- com.android.internal.R.string.config_defaultAppPredictionService), null);
+ com.android.internal.R.string.config_defaultAppPredictionService), null,
+ PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
@@ -80,6 +82,22 @@
getContext().enforceCallingPermission(MANAGE_APP_PREDICTIONS, TAG);
}
+ @Override // from AbstractMasterSystemService
+ protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+ final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageUpdatedLocked();
+ }
+ }
+
+ @Override // from AbstractMasterSystemService
+ protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+ final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageRestartedLocked();
+ }
+ }
+
@Override
protected int getMaximumTemporaryServiceDurationMs() {
return MAX_TEMP_SERVICE_DURATION_MS;
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 03c4542..4f49fb7 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -251,6 +251,40 @@
// Do nothing, eventually the system will bind to the remote service again...
}
+ void onPackageUpdatedLocked() {
+ if (isDebug()) {
+ Slog.v(TAG, "onPackageUpdatedLocked()");
+ }
+ destroyAndRebindRemoteService();
+ }
+
+ void onPackageRestartedLocked() {
+ if (isDebug()) {
+ Slog.v(TAG, "onPackageRestartedLocked()");
+ }
+ destroyAndRebindRemoteService();
+ }
+
+ private void destroyAndRebindRemoteService() {
+ if (mRemoteService == null) {
+ return;
+ }
+
+ if (isDebug()) {
+ Slog.d(TAG, "Destroying the old remote service.");
+ }
+ mRemoteService.destroy();
+ mRemoteService = null;
+
+ mRemoteService = getRemoteServiceLocked();
+ if (mRemoteService != null) {
+ if (isDebug()) {
+ Slog.d(TAG, "Rebinding to the new remote service.");
+ }
+ mRemoteService.reconnect();
+ }
+ }
+
/**
* Called after the remote service connected, it's used to restore state from a 'zombie'
* service (i.e., after it died).
diff --git a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
index c82e7a0..04e0e7f 100644
--- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
+++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
@@ -135,6 +135,13 @@
}
/**
+ * Schedules a request to bind to the remote service.
+ */
+ public void reconnect() {
+ super.scheduleBind();
+ }
+
+ /**
* Failure callback
*/
public interface RemoteAppPredictionServiceCallbacks
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 6b7c3e6..c689ed1 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -212,8 +212,7 @@
(u, s, t) -> onAugmentedServiceNameChanged(u, s, t));
if (mSupportedSmartSuggestionModes != AutofillManager.FLAG_SMART_SUGGESTION_OFF) {
- final UserManager um = getContext().getSystemService(UserManager.class);
- final List<UserInfo> users = um.getUsers();
+ final List<UserInfo> users = getSupportedUsers();
for (int i = 0; i < users.size(); i++) {
final int userId = users.get(i).id;
// Must eager load the services so they bind to the augmented autofill service
@@ -325,6 +324,11 @@
}
@Override // from SystemService
+ public boolean isSupported(UserInfo userInfo) {
+ return userInfo.isFull() || userInfo.isManagedProfile();
+ }
+
+ @Override // from SystemService
public void onSwitchUser(int userHandle) {
if (sDebug) Slog.d(TAG, "Hiding UI when user switched");
mUi.hideAll(null);
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 48f16ac..256ca50 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2419,6 +2419,7 @@
Slog.v(TAG, "entered on virtual child " + id + ": " + virtualBounds);
}
+ final boolean isSameViewEntered = Objects.equals(mCurrentViewId, viewState.id);
// Update the view states first...
mCurrentViewId = viewState.id;
if (value != null) {
@@ -2451,6 +2452,10 @@
hideAugmentedAutofillLocked(viewState);
}
+ if (isSameViewEntered) {
+ return;
+ }
+
// If the ViewState is ready to be displayed, onReady() will be called.
viewState.update(value, virtualBounds, flags);
break;
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 5c6258f..c8dbb36 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -147,8 +147,7 @@
mRequestsHistory = null;
}
- final UserManager um = getContext().getSystemService(UserManager.class);
- final List<UserInfo> users = um.getUsers();
+ final List<UserInfo> users = getSupportedUsers();
for (int i = 0; i < users.size(); i++) {
final int userId = users.get(i).id;
final boolean disabled = !isEnabledBySettings(userId);
@@ -174,6 +173,11 @@
}
@Override // from SystemService
+ public boolean isSupported(UserInfo userInfo) {
+ return userInfo.isFull() || userInfo.isManagedProfile();
+ }
+
+ @Override // from SystemService
public void onStart() {
publishBinderService(CONTENT_CAPTURE_MANAGER_SERVICE,
new ContentCaptureManagerServiceStub());
@@ -336,8 +340,7 @@
if (verbose) {
Slog.v(mTag, "setDisabledByDeviceConfig(): explicitlyEnabled=" + explicitlyEnabled);
}
- final UserManager um = getContext().getSystemService(UserManager.class);
- final List<UserInfo> users = um.getUsers();
+ final List<UserInfo> users = getSupportedUsers();
final boolean newDisabledValue;
diff --git a/services/core/Android.bp b/services/core/Android.bp
index c838c60..1643221 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -53,7 +53,7 @@
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
"dnsresolver_aidl_interface-V2-java",
- "netd_aidl_interface-V2-java",
+ "netd_aidl_interface-java",
"netd_event_listener_interface-java",
],
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e67ccc4..2a2dc3d 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1102,7 +1102,7 @@
mSettingsObserver = new SettingsObserver(mContext, mHandler);
registerSettingsCallbacks();
- final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext);
+ final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext, mHandler);
dataConnectionStats.startMonitoring();
mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
@@ -4551,7 +4551,7 @@
Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown");
return false;
}
- setLockdownTracker(new LockdownVpnTracker(mContext, mNMS, this, vpn, profile));
+ setLockdownTracker(new LockdownVpnTracker(mContext, this, mHandler, vpn, profile));
} else {
setLockdownTracker(null);
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 59e0a28..9efaad8 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1008,11 +1008,15 @@
@Override
public void startTethering(String[] dhcpRange) {
+ startTetheringWithConfiguration(true, dhcpRange);
+ }
+
+ @Override
+ public void startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
// an odd number of addrs will fail
-
try {
- mNetdService.tetherStart(dhcpRange);
+ mNetdService.tetherStartWithConfiguration(usingLegacyDnsProxy, dhcpRange);
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index ea3dd3d..73ec561 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -131,6 +131,10 @@
@GuardedBy("mLock")
private long mUptimeAtLastStateSync;
+ private final Runnable mSyncRequests = this::syncRequests;
+ private final Runnable mSyncStateWithScheduledReason = this::syncStateWithScheduledReason;
+ private final Runnable mSaveToFile = this::saveToFile;
+
private PackageWatchdog(Context context) {
// Needs to be constructed inline
this(context, new AtomicFile(
@@ -349,7 +353,7 @@
// Must only run synchronous tasks as this runs on the ShutdownThread and no other
// thread is guaranteed to run during shutdown.
if (!mAllObservers.isEmpty()) {
- mLongTaskHandler.removeCallbacks(this::saveToFileAsync);
+ mLongTaskHandler.removeCallbacks(mSaveToFile);
pruneObserversLocked();
saveToFile();
Slog.i(TAG, "Last write to update package durations");
@@ -424,8 +428,8 @@
* Serializes and syncs health check requests with the {@link ExplicitHealthCheckController}.
*/
private void syncRequestsAsync() {
- mShortTaskHandler.removeCallbacks(this::syncRequests);
- mShortTaskHandler.post(this::syncRequests);
+ mShortTaskHandler.removeCallbacks(mSyncRequests);
+ mShortTaskHandler.post(mSyncRequests);
}
/**
@@ -569,14 +573,14 @@
@GuardedBy("mLock")
private void scheduleNextSyncStateLocked() {
long durationMs = getNextStateSyncMillisLocked();
- mShortTaskHandler.removeCallbacks(this::syncStateWithScheduledReason);
+ mShortTaskHandler.removeCallbacks(mSyncStateWithScheduledReason);
if (durationMs == Long.MAX_VALUE) {
Slog.i(TAG, "Cancelling state sync, nothing to sync");
mUptimeAtLastStateSync = 0;
} else {
Slog.i(TAG, "Scheduling next state sync in " + durationMs + "ms");
mUptimeAtLastStateSync = SystemClock.uptimeMillis();
- mShortTaskHandler.postDelayed(this::syncStateWithScheduledReason, durationMs);
+ mShortTaskHandler.postDelayed(mSyncStateWithScheduledReason, durationMs);
}
}
@@ -802,8 +806,8 @@
}
private void saveToFileAsync() {
- if (!mLongTaskHandler.hasCallbacks(this::saveToFile)) {
- mLongTaskHandler.post(this::saveToFile);
+ if (!mLongTaskHandler.hasCallbacks(mSaveToFile)) {
+ mLongTaskHandler.post(mSaveToFile);
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 4fab7c1..8367e890 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -140,6 +140,7 @@
import com.android.internal.util.Preconditions;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.storage.AppFuseBridge;
+import com.android.server.storage.StorageSessionController;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal.ScreenObserver;
@@ -498,6 +499,9 @@
private final StorageManagerInternalImpl mStorageManagerInternal
= new StorageManagerInternalImpl();
+ // Not guarded by a lock.
+ private final StorageSessionController mStorageSessionController;
+
class ObbState implements IBinder.DeathRecipient {
public ObbState(String rawPath, String canonicalPath, int callingUid,
IObbActionListener token, int nonce, String volId) {
@@ -647,12 +651,20 @@
Slog.i(TAG, "Ignoring mount " + vol.getId() + " due to policy");
break;
}
- mount(vol);
+
+ // TODO(b/135341433): Remove paranoid logging when FUSE is stable
+ Slog.i(TAG, "Mounting volume " + vol);
+ // TODO(b/135341433): Update to use new vold API that gets or mounts fuse fd
+ // Ensure that we can pass user of a volume to the new API
+ mStorageSessionController.onVolumeMounted(mCurrentUserId, mount(vol), vol);
+ Slog.i(TAG, "Mounted volume " + vol);
+
break;
}
case H_VOLUME_UNMOUNT: {
final VolumeInfo vol = (VolumeInfo) msg.obj;
unmount(vol);
+ mStorageSessionController.onVolumeUnmounted(mCurrentUserId, vol);
break;
}
case H_VOLUME_BROADCAST: {
@@ -733,6 +745,7 @@
}
}
mVold.onUserRemoved(userId);
+ mStorageSessionController.onUserRemoved(userId);
}
} catch (Exception e) {
Slog.wtf(TAG, e);
@@ -951,7 +964,10 @@
}
try {
+ // TODO(b/135341433): Remove paranoid logging when FUSE is stable
+ Slog.i(TAG, "Resetting vold");
mVold.reset();
+ Slog.i(TAG, "Reset vold");
// Tell vold about all existing and started users
for (UserInfo user : users) {
@@ -976,6 +992,7 @@
// staging area is ready so it's ready for zygote-forked apps to
// bind mount against.
try {
+ mStorageSessionController.onUserStarted(userId);
mVold.onUserStarted(userId);
mStoraged.onUserStarted(userId);
} catch (Exception e) {
@@ -1516,6 +1533,12 @@
// Add OBB Action Handler to StorageManagerService thread.
mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());
+ mStorageSessionController = new StorageSessionController(mContext,
+ userId -> {
+ Slog.i(TAG, "Storage session ended for user: " + userId + ". Resetting...");
+ mHandler.obtainMessage(H_RESET).sendToTarget();
+ });
+
// Initialize the last-fstrim tracking if necessary
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
@@ -1814,11 +1837,18 @@
mount(vol);
}
- private void mount(VolumeInfo vol) {
+ private FileDescriptor mount(VolumeInfo vol) {
try {
- mVold.mount(vol.id, vol.mountFlags, vol.mountUserId);
+ // TODO(b/135341433): Now, emulated (and private?) volumes are shared across users
+ // This means the mountUserId on such volumes is USER_NULL. This breaks fuse which
+ // requires a valid user to mount a volume. Create individual volumes per user in vold
+ // and remove this property check
+ int userId = SystemProperties.getBoolean("persist.sys.fuse", false)
+ ? mCurrentUserId : vol.mountUserId;
+ return mVold.mount(vol.id, vol.mountFlags, userId);
} catch (Exception e) {
Slog.wtf(TAG, e);
+ return null;
}
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 7bc2e6d..8eb5d9b 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2318,9 +2318,8 @@
return true;
}
+ /** @return {@code true} if the restart is scheduled. */
private final boolean scheduleServiceRestartLocked(ServiceRecord r, boolean allowCancel) {
- boolean canceled = false;
-
if (mAm.mAtmInternal.isShuttingDown()) {
Slog.w(TAG, "Not scheduling restart of crashed service " + r.shortInstanceName
+ " - system is shutting down");
@@ -2337,10 +2336,12 @@
final long now = SystemClock.uptimeMillis();
+ final String reason;
if ((r.serviceInfo.applicationInfo.flags
&ApplicationInfo.FLAG_PERSISTENT) == 0) {
long minDuration = mAm.mConstants.SERVICE_RESTART_DURATION;
long resetTime = mAm.mConstants.SERVICE_RESET_RUN_DURATION;
+ boolean canceled = false;
// Any delivered but not yet finished starts should be put back
// on the pending list.
@@ -2367,6 +2368,17 @@
r.deliveredStarts.clear();
}
+ if (allowCancel) {
+ final boolean shouldStop = r.canStopIfKilled(canceled);
+ if (shouldStop && !r.hasAutoCreateConnections()) {
+ // Nothing to restart.
+ return false;
+ }
+ reason = (r.startRequested && !shouldStop) ? "start-requested" : "connection";
+ } else {
+ reason = "always";
+ }
+
r.totalRestartCount++;
if (r.restartDelay == 0) {
r.restartCount++;
@@ -2418,6 +2430,7 @@
r.restartCount = 0;
r.restartDelay = 0;
r.nextRestartTime = now;
+ reason = "persistent";
}
if (!mRestartingServices.contains(r)) {
@@ -2432,11 +2445,11 @@
mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Slog.w(TAG, "Scheduling restart of crashed service "
- + r.shortInstanceName + " in " + r.restartDelay + "ms");
+ + r.shortInstanceName + " in " + r.restartDelay + "ms for " + reason);
EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
r.userId, r.shortInstanceName, r.restartDelay);
- return canceled;
+ return true;
}
final void performServiceRestartLocked(ServiceRecord r) {
@@ -3651,22 +3664,21 @@
|| !mAm.mUserController.isUserRunning(sr.userId, 0)) {
bringDownServiceLocked(sr);
} else {
- boolean canceled = scheduleServiceRestartLocked(sr, true);
+ final boolean scheduled = scheduleServiceRestartLocked(sr, true /* allowCancel */);
// Should the service remain running? Note that in the
// extreme case of so many attempts to deliver a command
// that it failed we also will stop it here.
- if (sr.startRequested && (sr.stopIfKilled || canceled)) {
- if (sr.pendingStarts.size() == 0) {
- sr.startRequested = false;
- if (sr.tracker != null) {
- sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
- SystemClock.uptimeMillis());
- }
- if (!sr.hasAutoCreateConnections()) {
- // Whoops, no reason to restart!
- bringDownServiceLocked(sr);
- }
+ if (!scheduled) {
+ bringDownServiceLocked(sr);
+ } else if (sr.canStopIfKilled(false /* isStartCanceled */)) {
+ // Update to stopped state because the explicit start is gone. The service is
+ // scheduled to restart for other reason (e.g. connections) so we don't bring
+ // down it.
+ sr.startRequested = false;
+ if (sr.tracker != null) {
+ sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
+ SystemClock.uptimeMillis());
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 84f5530..3dc33f8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4644,7 +4644,7 @@
}
boolean didSomething = mProcessList.killPackageProcessesLocked(packageName, appId, userId,
- ProcessList.INVALID_ADJ, callerWillRestart, true /* allowRestart */, doit,
+ ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit,
evenPersistent, true /* setRemoved */,
packageName == null ? ("stop user " + userId) : ("stop " + packageName));
@@ -5268,7 +5268,7 @@
storageManager.commitChanges();
} catch (Exception e) {
PowerManager pm = (PowerManager)
- mInjector.getContext().getSystemService(Context.POWER_SERVICE);
+ mContext.getSystemService(Context.POWER_SERVICE);
pm.reboot("Checkpoint commit failed");
}
@@ -8285,8 +8285,13 @@
if (shareDescription != null) {
triggerShellBugreport.putExtra(EXTRA_DESCRIPTION, shareDescription);
}
- // Send broadcast to shell to trigger bugreport using Bugreport API
- mContext.sendBroadcast(triggerShellBugreport);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ // Send broadcast to shell to trigger bugreport using Bugreport API
+ mContext.sendBroadcast(triggerShellBugreport);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
} else {
SystemProperties.set("dumpstate.options", type);
SystemProperties.set("ctl.start", "bugreport");
@@ -9154,10 +9159,10 @@
}
t.traceEnd();
}
- // Automotive will re-start system user as background (so its unlocked), then start a
- // full user as foreground. Hence, we need to skip some steps that would otherwise be
- // done twice.
- // TODO(b/138956267): this workdound shouldn't be necessary once we move the
+
+ // On Automotive, at this point the system user has already been started and unlocked,
+ // and some of the tasks we do here have already been done. So skip those in that case.
+ // TODO(b/132262830): this workdound shouldn't be necessary once we move the
// headless-user start logic to UserManager-land
final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
@@ -13919,9 +13924,9 @@
// Remove published content providers.
for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
ContentProviderRecord cpr = app.pubProviders.valueAt(i);
- final boolean always = app.bad || !allowRestart;
- boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
- if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
+ final boolean alwaysRemove = app.bad || !allowRestart;
+ final boolean inLaunching = removeDyingProviderLocked(app, cpr, alwaysRemove);
+ if (!alwaysRemove && inLaunching && cpr.hasConnectionOrHandle()) {
// We left the provider in the launching list, need to
// restart it.
restart = true;
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 8619ad5..8c038aa 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -19,9 +19,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import android.app.INotificationManager;
import android.app.Notification;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -33,7 +31,6 @@
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
-import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -623,6 +620,14 @@
}
}
+ /**
+ * @return {@code true} if the killed service which was started by {@link Context#startService}
+ * has no reason to start again. Note this condition doesn't consider the bindings.
+ */
+ boolean canStopIfKilled(boolean isStartCanceled) {
+ return startRequested && (stopIfKilled || isStartCanceled) && pendingStarts.isEmpty();
+ }
+
void updateHasBindingWhitelistingBgActivityStarts() {
boolean hasWhitelistingBinding = false;
for (int conni = connections.size() - 1; conni >= 0; conni--) {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 2b4cc3c..5fe72dd 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1755,9 +1755,10 @@
for (int i = 0; i < startedUsers.size(); i++) {
UserState uss = startedUsers.valueAt(i);
if (systemUserFinishedBooting && uss.mHandle.isSystem()) {
- // Automotive will re-start system user as background, which in turn will call
- // finishUserboot(). Hence, we need to check it here to avoid calling it twice.
- // TODO(b/138956267): this workdound shouldn't be necessary once we move the
+ // On Automotive, at this point the system user has already been started and
+ // unlocked, and some of the tasks we do here have already been done. So skip those
+ // in that case.
+ // TODO(b/132262830): this workdound shouldn't be necessary once we move the
// headless-user start logic to UserManager-land
Slog.d(TAG, "sendBootCompleted(): skipping on non-current system user");
continue;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 6d6a148..cc8e3f0 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2973,28 +2973,49 @@
out.startTag(null, "app-ops");
out.attribute(null, "v", String.valueOf(CURRENT_VERSION));
+ SparseArray<SparseIntArray> uidStatesClone;
synchronized (this) {
+ uidStatesClone = new SparseArray<>(mUidStates.size());
+
final int uidStateCount = mUidStates.size();
- for (int i = 0; i < uidStateCount; i++) {
- UidState uidState = mUidStates.valueAt(i);
- if (uidState.opModes != null && uidState.opModes.size() > 0) {
- out.startTag(null, "uid");
- out.attribute(null, "n", Integer.toString(uidState.uid));
- SparseIntArray uidOpModes = uidState.opModes;
- final int opCount = uidOpModes.size();
- for (int j = 0; j < opCount; j++) {
- final int op = uidOpModes.keyAt(j);
- final int mode = uidOpModes.valueAt(j);
- out.startTag(null, "op");
- out.attribute(null, "n", Integer.toString(op));
- out.attribute(null, "m", Integer.toString(mode));
- out.endTag(null, "op");
+ for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) {
+ UidState uidState = mUidStates.valueAt(uidStateNum);
+ int uid = mUidStates.keyAt(uidStateNum);
+
+ SparseIntArray opModes = uidState.opModes;
+ if (opModes != null && opModes.size() > 0) {
+ uidStatesClone.put(uid, new SparseIntArray(opModes.size()));
+
+ final int opCount = opModes.size();
+ for (int opCountNum = 0; opCountNum < opCount; opCountNum++) {
+ uidStatesClone.get(uid).put(
+ opModes.keyAt(opCountNum),
+ opModes.valueAt(opCountNum));
}
- out.endTag(null, "uid");
}
}
}
+ final int uidStateCount = uidStatesClone.size();
+ for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) {
+ SparseIntArray opModes = uidStatesClone.valueAt(uidStateNum);
+ if (opModes != null && opModes.size() > 0) {
+ out.startTag(null, "uid");
+ out.attribute(null, "n",
+ Integer.toString(uidStatesClone.keyAt(uidStateNum)));
+ final int opCount = opModes.size();
+ for (int opCountNum = 0; opCountNum < opCount; opCountNum++) {
+ final int op = opModes.keyAt(opCountNum);
+ final int mode = opModes.valueAt(opCountNum);
+ out.startTag(null, "op");
+ out.attribute(null, "n", Integer.toString(op));
+ out.attribute(null, "m", Integer.toString(mode));
+ out.endTag(null, "op");
+ }
+ out.endTag(null, "uid");
+ }
+ }
+
if (allOps != null) {
String lastPkg = null;
for (int i=0; i<allOps.size(); i++) {
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 24e6a75..4af3627 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -514,7 +514,6 @@
}
public boolean getFaceEnabledForApps(int userId) {
- Slog.e(TAG, "getFaceEnabledForApps: " + userId, new Exception());
if (!mFaceEnabledForApps.containsKey(userId)) {
onChange(true /* selfChange */, FACE_UNLOCK_APP_ENABLED, userId);
}
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 044e417..027e2fb 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -47,11 +47,10 @@
public final class CompatConfig {
private static final String TAG = "CompatConfig";
- private static final String CONFIG_FILE_SUFFIX = "platform_compat_config.xml";
private static final CompatConfig sInstance = new CompatConfig().initConfigFromLib(
Environment.buildPath(
- Environment.getRootDirectory(), "etc", "sysconfig"));
+ Environment.getRootDirectory(), "etc", "compatconfig"));
@GuardedBy("mChanges")
private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>();
@@ -212,10 +211,9 @@
return this;
}
for (File f : libraryDir.listFiles()) {
+ Slog.d(TAG, "Found a config file: " + f.getPath());
//TODO(b/138222363): Handle duplicate ids across config files.
- if (f.getPath().endsWith(CONFIG_FILE_SUFFIX)) {
- readConfig(f);
- }
+ readConfig(f);
}
return this;
}
@@ -223,7 +221,7 @@
private void readConfig(File configFile) {
try (InputStream in = new BufferedInputStream(new FileInputStream(configFile))) {
for (Change change : XmlParser.read(in).getCompatChange()) {
- Slog.w(TAG, "Adding: " + change.toString());
+ Slog.d(TAG, "Adding: " + change.toString());
addChange(new CompatChange(change));
}
} catch (IOException | DatatypeConfigurationException | XmlPullParserException e) {
diff --git a/services/core/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
index 4990ea1..27f11ff 100644
--- a/services/core/java/com/android/server/connectivity/DataConnectionStats.java
+++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
@@ -21,6 +21,8 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
+import android.os.Handler;
+import android.os.Looper;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
@@ -39,15 +41,19 @@
private final Context mContext;
private final IBatteryStats mBatteryStats;
+ private final Handler mListenerHandler;
+ private final PhoneStateListener mPhoneStateListener;
private IccCardConstants.State mSimState = IccCardConstants.State.READY;
private SignalStrength mSignalStrength;
private ServiceState mServiceState;
private int mDataState = TelephonyManager.DATA_DISCONNECTED;
- public DataConnectionStats(Context context) {
+ public DataConnectionStats(Context context, Handler listenerHandler) {
mContext = context;
mBatteryStats = BatteryStatsService.getService();
+ mListenerHandler = listenerHandler;
+ mPhoneStateListener = new PhoneStateListenerImpl(listenerHandler.getLooper());
}
public void startMonitoring() {
@@ -63,7 +69,7 @@
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
- mContext.registerReceiver(this, filter);
+ mContext.registerReceiver(this, filter, null /* broadcastPermission */, mListenerHandler);
}
@Override
@@ -129,7 +135,11 @@
&& mServiceState.getState() != ServiceState.STATE_POWER_OFF;
}
- private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+ private class PhoneStateListenerImpl extends PhoneStateListener {
+ PhoneStateListenerImpl(Looper looper) {
+ super(looper);
+ }
+
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
mSignalStrength = signalStrength;
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 86d1212..5fd5c4b 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -455,7 +455,20 @@
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- ((BluetoothPan) proxy).setBluetoothTethering(enable);
+ // Clear identify is fine because caller already pass tethering permission at
+ // ConnectivityService#startTethering()(or stopTethering) before the control comes
+ // here. Bluetooth will check tethering permission again that there is
+ // Context#getOpPackageName() under BluetoothPan#setBluetoothTethering() to get
+ // caller's package name for permission check.
+ // Calling BluetoothPan#setBluetoothTethering() here means the package name always
+ // be system server. If calling identity is not cleared, that package's uid might
+ // not match calling uid and end up in permission denied.
+ final long identityToken = Binder.clearCallingIdentity();
+ try {
+ ((BluetoothPan) proxy).setBluetoothTethering(enable);
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
// TODO: Enabling bluetooth tethering can fail asynchronously here.
// We should figure out a way to bubble up that failure instead of sending success.
final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 4d5dc6a..2b849d6 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -297,6 +297,11 @@
mHdmiControlBroadcastReceiver = new HdmiControlBroadcastReceiver();
@Nullable
+ // Save callback when the device is still under logcial address allocation
+ // Invoke once new local device is ready.
+ private IHdmiControlCallback mDisplayStatusCallback = null;
+
+ @Nullable
private HdmiCecController mCecController;
// HDMI port information. Stored in the unmodifiable list to keep the static information
@@ -763,6 +768,11 @@
// Address allocation completed for all devices. Notify each device.
if (allocatingDevices.size() == ++finished[0]) {
mAddressAllocated = true;
+ // Reinvoke the saved display status callback once the local device is ready.
+ if (mDisplayStatusCallback != null) {
+ queryDisplayStatus(mDisplayStatusCallback);
+ mDisplayStatusCallback = null;
+ }
if (initiatedBy != INITIATED_BY_HOTPLUG) {
// In case of the hotplug we don't call onInitializeCecComplete()
// since we reallocate the logical address only.
@@ -2192,6 +2202,13 @@
@ServiceThreadOnly
private void queryDisplayStatus(final IHdmiControlCallback callback) {
assertRunOnServiceThread();
+ if (!mAddressAllocated) {
+ mDisplayStatusCallback = callback;
+ Slog.d(TAG, "Local device is under address allocation. "
+ + "Queue display callback for later process.");
+ return;
+ }
+
HdmiCecLocalDevicePlayback source = playback();
if (source == null) {
Slog.w(TAG, "Local playback device not available");
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 9782f30..d71ffb7 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -48,6 +48,7 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -79,7 +80,7 @@
S extends AbstractPerUserSystemService<S, M>> extends SystemService {
/** On a package update, does not refresh the per-user service in the cache. */
- public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0;
+ public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0x00000001;
/**
* On a package update, removes any existing per-user services in the cache.
@@ -87,20 +88,40 @@
* <p>This does not immediately recreate these services. It is assumed they will be recreated
* for the next user request.
*/
- public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 1;
+ public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 0x00000002;
/**
* On a package update, removes and recreates any existing per-user services in the cache.
*/
- public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 2;
+ public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 0x00000004;
- @IntDef(flag = true, prefix = { "PACKAGE_UPDATE_POLICY_" }, value = {
+ /** On a package restart, does not refresh the per-user service in the cache. */
+ public static final int PACKAGE_RESTART_POLICY_NO_REFRESH = 0x00000010;
+
+ /**
+ * On a package restart, removes any existing per-user services in the cache.
+ *
+ * <p>This does not immediately recreate these services. It is assumed they will be recreated
+ * for the next user request.
+ */
+ public static final int PACKAGE_RESTART_POLICY_REFRESH_LAZY = 0x00000020;
+
+ /**
+ * On a package restart, removes and recreates any existing per-user services in the cache.
+ */
+ public static final int PACKAGE_RESTART_POLICY_REFRESH_EAGER = 0x00000040;
+
+ @IntDef(flag = true, prefix = { "PACKAGE_" }, value = {
PACKAGE_UPDATE_POLICY_NO_REFRESH,
PACKAGE_UPDATE_POLICY_REFRESH_LAZY,
- PACKAGE_UPDATE_POLICY_REFRESH_EAGER
+ PACKAGE_UPDATE_POLICY_REFRESH_EAGER,
+ PACKAGE_RESTART_POLICY_NO_REFRESH,
+ PACKAGE_RESTART_POLICY_REFRESH_LAZY,
+ PACKAGE_RESTART_POLICY_REFRESH_EAGER
})
+
@Retention(RetentionPolicy.SOURCE)
- public @interface PackageUpdatePolicy {}
+ public @interface ServicePackagePolicyFlags {}
/**
* Log tag
@@ -153,12 +174,10 @@
private final SparseArray<S> mServicesCache = new SparseArray<>();
/**
- * Whether the per-user service should be removed from the cache when its apk is updated.
- *
- * <p>One of {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
- * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY} or {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}.
+ * Value that determines whether the per-user service should be removed from the cache when its
+ * apk is updated or restarted.
*/
- private final @PackageUpdatePolicy int mPackageUpdatePolicy;
+ private final @ServicePackagePolicyFlags int mServicePackagePolicyFlags;
/**
* Name of the service packages whose APK are being updated, keyed by user id.
@@ -167,6 +186,12 @@
private SparseArray<String> mUpdatingPackageNames;
/**
+ * Lazy-loadable reference to {@link UserManagerInternal}.
+ */
+ @Nullable
+ private UserManagerInternal mUm;
+
+ /**
* Default constructor.
*
* <p>When using this constructor, the {@link AbstractPerUserSystemService} is removed from
@@ -184,11 +209,11 @@
@Nullable ServiceNameResolver serviceNameResolver,
@Nullable String disallowProperty) {
this(context, serviceNameResolver, disallowProperty,
- /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_LAZY);
+ PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_LAZY);
}
/**
- * Full constructor.
+ * Full Constructor.
*
* @param context system context.
* @param serviceNameResolver resolver for
@@ -197,19 +222,32 @@
* @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
* disables the service. <b>NOTE: </b> you'll also need to add it to
* {@code UserRestrictionsUtils.USER_RESTRICTIONS}.
- * @param packageUpdatePolicy when {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, the
- * {@link AbstractPerUserSystemService} is removed from the cache when the service
- * package is updated; when {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, the
- * {@link AbstractPerUserSystemService} is removed from the cache and immediately
- * re-added when the service package is updated; when
- * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, the service is untouched during the update.
+ * @param servicePackagePolicyFlags a combination of
+ * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
+ * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY},
+ * {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER},
+ * {@link #PACKAGE_RESTART_POLICY_NO_REFRESH},
+ * {@link #PACKAGE_RESTART_POLICY_REFRESH_LAZY} or
+ * {@link #PACKAGE_RESTART_POLICY_REFRESH_EAGER}
*/
protected AbstractMasterSystemService(@NonNull Context context,
- @Nullable ServiceNameResolver serviceNameResolver,
- @Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy) {
+ @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty,
+ @ServicePackagePolicyFlags int servicePackagePolicyFlags) {
super(context);
- mPackageUpdatePolicy = packageUpdatePolicy;
+ final int updatePolicyMask = PACKAGE_UPDATE_POLICY_NO_REFRESH
+ | PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_UPDATE_POLICY_REFRESH_EAGER;
+ if ((servicePackagePolicyFlags & updatePolicyMask) == 0) {
+ // If the package update policy is not set, add the default flag
+ servicePackagePolicyFlags |= PACKAGE_UPDATE_POLICY_REFRESH_LAZY;
+ }
+ final int restartPolicyMask = PACKAGE_RESTART_POLICY_NO_REFRESH
+ | PACKAGE_RESTART_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_EAGER;
+ if ((servicePackagePolicyFlags & restartPolicyMask) == 0) {
+ // If the package restart policy is not set, add the default flag
+ servicePackagePolicyFlags |= PACKAGE_RESTART_POLICY_REFRESH_LAZY;
+ }
+ mServicePackagePolicyFlags = servicePackagePolicyFlags;
mServiceNameResolver = serviceNameResolver;
if (mServiceNameResolver != null) {
@@ -222,9 +260,8 @@
} else {
mDisabledByUserRestriction = new SparseBooleanArray();
// Hookup with UserManager to disable service when necessary.
- final UserManager um = context.getSystemService(UserManager.class);
- final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
- final List<UserInfo> users = um.getUsers();
+ final UserManagerInternal umi = getUserManagerInternal();
+ final List<UserInfo> users = getSupportedUsers();
for (int i = 0; i < users.size(); i++) {
final int userId = users.get(i).id;
final boolean disabled = umi.getUserRestriction(userId, disallowProperty);
@@ -606,6 +643,20 @@
}
/**
+ * Called after the package data that provides the service for the given user is cleared.
+ */
+ protected void onServicePackageDataClearedLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")");
+ }
+
+ /**
+ * Called after the package that provides the service for the given user is restarted.
+ */
+ protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")");
+ }
+
+ /**
* Called after the service is removed from the cache.
*/
@SuppressWarnings("unused")
@@ -649,6 +700,36 @@
}
/**
+ * Gets a cached reference to {@link UserManagerInternal}.
+ */
+ @NonNull
+ protected UserManagerInternal getUserManagerInternal() {
+ if (mUm == null) {
+ if (verbose) Slog.v(mTag, "lazy-loading UserManagerInternal");
+ mUm = LocalServices.getService(UserManagerInternal.class);
+ }
+ return mUm;
+ }
+
+ /**
+ * Gets a list of all supported users (i.e., those that pass the {@link #isSupported(UserInfo)}
+ * check).
+ */
+ @NonNull
+ protected List<UserInfo> getSupportedUsers() {
+ final UserInfo[] allUsers = getUserManagerInternal().getUserInfos();
+ final int size = allUsers.length;
+ final List<UserInfo> supportedUsers = new ArrayList<>(size);
+ for (int i = 0; i < size; i++) {
+ final UserInfo userInfo = allUsers[i];
+ if (isSupported(userInfo)) {
+ supportedUsers.add(userInfo);
+ }
+ }
+ return supportedUsers;
+ }
+
+ /**
* Asserts that the given package name is owned by the UID making this call.
*
* @throws SecurityException when it's not...
@@ -677,15 +758,14 @@
final int size = mServicesCache.size();
pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
pw.print(" Verbose: "); pw.println(realVerbose);
- pw.print("Refresh on package update: "); pw.println(mPackageUpdatePolicy);
+ pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags);
if (mUpdatingPackageNames != null) {
pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
}
if (mServiceNameResolver != null) {
pw.print(prefix); pw.print("Name resolver: ");
mServiceNameResolver.dumpShort(pw); pw.println();
- final UserManager um = getContext().getSystemService(UserManager.class);
- final List<UserInfo> users = um.getUsers();
+ final List<UserInfo> users = getSupportedUsers();
for (int i = 0; i < users.size(); i++) {
final int userId = users.get(i).id;
pw.print(prefix2); pw.print(userId); pw.print(": ");
@@ -733,7 +813,12 @@
}
mUpdatingPackageNames.put(userId, packageName);
onServicePackageUpdatingLocked(userId);
- if (mPackageUpdatePolicy != PACKAGE_UPDATE_POLICY_NO_REFRESH) {
+ if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being updated");
+ }
+ } else {
if (debug) {
Slog.d(mTag, "Removing service for user " + userId
+ " because package " + activePackageName
@@ -741,18 +826,14 @@
}
removeCachedServiceLocked(userId);
- if (mPackageUpdatePolicy == PACKAGE_UPDATE_POLICY_REFRESH_EAGER) {
+ if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
+ != 0) {
if (debug) {
Slog.d(mTag, "Eagerly recreating service for user "
+ userId);
}
getServiceForUserLocked(userId);
}
- } else {
- if (debug) {
- Slog.d(mTag, "Holding service for user " + userId + " while package "
- + activePackageName + " is being updated");
- }
}
}
}
@@ -804,7 +885,13 @@
if (!doit) {
return true;
}
- removeCachedServiceLocked(getChangingUserId());
+ final String action = intent.getAction();
+ final int userId = getChangingUserId();
+ if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
+ handleActiveServiceRestartedLocked(activePackageName, userId);
+ } else {
+ removeCachedServiceLocked(userId);
+ }
} else {
handlePackageUpdateLocked(pkg);
}
@@ -813,6 +900,23 @@
return false;
}
+ @Override
+ public void onPackageDataCleared(String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName);
+ final int userId = getChangingUserId();
+ synchronized (mLock) {
+ final S service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ final ComponentName componentName = service.getServiceComponentName();
+ if (componentName != null) {
+ if (packageName.equals(componentName.getPackageName())) {
+ onServicePackageDataClearedLocked(userId);
+ }
+ }
+ }
+ }
+ }
+
private void handleActiveServiceRemoved(@UserIdInt int userId) {
synchronized (mLock) {
removeCachedServiceLocked(userId);
@@ -824,6 +928,31 @@
}
}
+ private void handleActiveServiceRestartedLocked(String activePackageName,
+ @UserIdInt int userId) {
+ if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being restarted");
+ }
+ } else {
+ if (debug) {
+ Slog.d(mTag, "Removing service for user " + userId
+ + " because package " + activePackageName
+ + " is being restarted");
+ }
+ removeCachedServiceLocked(userId);
+
+ if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Eagerly recreating service for user " + userId);
+ }
+ getServiceForUserLocked(userId);
+ }
+ }
+ onServicePackageRestartedLocked(userId);
+ }
+
private String getActiveServicePackageNameLocked() {
final int userId = getChangingUserId();
final S service = peekServiceForUserLocked(userId);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index f38f2f9..ccc0d4b 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -217,6 +217,11 @@
private final RecoverableKeyStoreManager mRecoverableKeyStoreManager;
private boolean mFirstCallToVold;
+ // Current password metric for all users on the device. Updated when user unlocks
+ // the device or changes password. Removed when user is stopped.
+ @GuardedBy("this")
+ final SparseArray<PasswordMetrics> mUserPasswordMetrics = new SparseArray<>();
+
protected IGateKeeperService mGateKeeperService;
protected IAuthSecret mAuthSecretService;
@@ -424,6 +429,13 @@
return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
}
+ /**
+ * Return the {@link DevicePolicyManager} object.
+ *
+ * Since LockSettingsService is considered a lower-level component than DevicePolicyManager,
+ * do NOT hold any lock in this class while calling into DevicePolicyManager to prevent
+ * the risk of deadlock.
+ */
public DevicePolicyManager getDevicePolicyManager() {
return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
}
@@ -593,6 +605,9 @@
// the device.
int strongAuthRequired = LockPatternUtils.StrongAuthTracker.getDefaultFlags(mContext);
requireStrongAuth(strongAuthRequired, userId);
+ synchronized (this) {
+ mUserPasswordMetrics.remove(userId);
+ }
}
public void onStartUser(final int userId) {
@@ -1501,7 +1516,7 @@
setKeystorePassword(null, userId);
fixateNewestUserKeyAuth(userId);
synchronizeUnifiedWorkChallengeForProfiles(userId, null);
- notifyActivePasswordMetricsAvailable(CREDENTIAL_TYPE_NONE, null, userId);
+ setUserPasswordMetrics(CREDENTIAL_TYPE_NONE, null, userId);
sendCredentialsOnChangeIfRequired(
credentialType, credential, userId, isLockTiedToParent);
return;
@@ -1946,7 +1961,7 @@
Log.w(TAG, "progressCallback throws exception", e);
}
}
- notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
+ setUserPasswordMetrics(storedHash.type, credential, userId);
unlockKeystore(credential, userId);
Slog.i(TAG, "Unlocking user " + userId + " with token length "
@@ -1988,32 +2003,40 @@
}
/**
- * Call this method to notify DPMS regarding the latest password metric. This should be called
- * when the user is authenticating or when a new password is being set.
+ * Keep track of the given user's latest password metric. This should be called
+ * when the user is authenticating or when a new password is being set. In comparison,
+ * {@link #notifyPasswordChanged} only needs to be called when the user changes the password.
*/
- private void notifyActivePasswordMetricsAvailable(
- @CredentialType int credentialType, byte[] password, @UserIdInt int userId) {
- final PasswordMetrics metrics =
- PasswordMetrics.computeForCredential(credentialType, password);
+ private void setUserPasswordMetrics(@CredentialType int credentialType, byte[] password,
+ @UserIdInt int userHandle) {
+ synchronized (this) {
+ mUserPasswordMetrics.put(userHandle,
+ PasswordMetrics.computeForCredential(credentialType, password));
+ }
+ }
- // Asynchronous to avoid dead lock
- mHandler.post(() -> {
- final DevicePolicyManager dpm = (DevicePolicyManager)
- mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- dpm.setActivePasswordState(metrics, userId);
- });
+ @VisibleForTesting
+ PasswordMetrics getUserPasswordMetrics(int userHandle) {
+ if (!isUserSecure(userHandle)) {
+ // for users without password, mUserPasswordMetrics might not be initialized
+ // since the user never unlock the device manually. In this case, always
+ // return a default metrics object. This is to distinguish this case from
+ // the case where during boot user password is unknown yet (returning null here)
+ return new PasswordMetrics();
+ }
+ synchronized (this) {
+ return mUserPasswordMetrics.get(userHandle);
+ }
}
/**
- * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before
+ * Call after {@link #setUserPasswordMetrics} so metrics are updated before
* reporting the password changed.
*/
private void notifyPasswordChanged(@UserIdInt int userId) {
// Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering
mHandler.post(() -> {
- DevicePolicyManager dpm = (DevicePolicyManager)
- mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- dpm.reportPasswordChanged(userId);
+ mInjector.getDevicePolicyManager().reportPasswordChanged(userId);
LocalServices.getService(WindowManagerInternal.class).reportPasswordChanged(userId);
});
}
@@ -2582,7 +2605,7 @@
}
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
- notifyActivePasswordMetricsAvailable(credentialType, userCredential, userId);
+ setUserPasswordMetrics(credentialType, userCredential, userId);
unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
// Do resetLockout / revokeChallenge when all profiles are unlocked
@@ -2676,7 +2699,7 @@
setSyntheticPasswordHandleLocked(newHandle, userId);
synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
- notifyActivePasswordMetricsAvailable(credentialType, credential, userId);
+ setUserPasswordMetrics(credentialType, credential, userId);
if (profilePasswords != null) {
for (Map.Entry<Integer, byte[]> entry : profilePasswords.entrySet()) {
@@ -2982,6 +3005,8 @@
pw.println("hasPassword: " + havePassword(userId));
pw.println("hasPattern: " + havePattern(userId)); // print raw credential type instead?
pw.println("SeparateChallenge: " + getSeparateProfileChallengeEnabled(userId));
+ pw.println(String.format("metrics: %s",
+ getUserPasswordMetrics(userId) != null ? "known" : "unknown"));
pw.decreaseIndent();
}
pw.println();
@@ -3158,5 +3183,23 @@
public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) {
return LockSettingsService.this.unlockUserWithToken(tokenHandle, token, userId);
}
+
+ @Override
+ public PasswordMetrics getUserPasswordMetrics(int userHandle) {
+ long identity = Binder.clearCallingIdentity();
+ try {
+ if (isManagedProfileWithUnifiedLock(userHandle)) {
+ // A managed profile with unified challenge is supposed to be protected by the
+ // parent lockscreen, so asking for its password metrics is not really useful,
+ // as this method would just return the metrics of the random profile password
+ Slog.w(TAG, "Querying password metrics for unified challenge profile: "
+ + userHandle);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ return LockSettingsService.this.getUserPasswordMetrics(userHandle);
+ }
+
}
}
diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java
index 3f15b38..77fbe41 100644
--- a/services/core/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java
@@ -19,6 +19,8 @@
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.provider.Settings.ACTION_VPN_SETTINGS;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -32,7 +34,7 @@
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkInfo.State;
-import android.os.INetworkManagementService;
+import android.os.Handler;
import android.security.Credentials;
import android.security.KeyStore;
import android.text.TextUtils;
@@ -63,22 +65,19 @@
private static final String ACTION_LOCKDOWN_RESET = "com.android.server.action.LOCKDOWN_RESET";
- private static final int ROOT_UID = 0;
+ @NonNull private final Context mContext;
+ @NonNull private final ConnectivityService mConnService;
+ @NonNull private final Handler mHandler;
+ @NonNull private final Vpn mVpn;
+ @NonNull private final VpnProfile mProfile;
- private final Context mContext;
- private final INetworkManagementService mNetService;
- private final ConnectivityService mConnService;
- private final Vpn mVpn;
- private final VpnProfile mProfile;
+ @NonNull private final Object mStateLock = new Object();
- private final Object mStateLock = new Object();
+ @NonNull private final PendingIntent mConfigIntent;
+ @NonNull private final PendingIntent mResetIntent;
- private final PendingIntent mConfigIntent;
- private final PendingIntent mResetIntent;
-
+ @Nullable
private String mAcceptedEgressIface;
- private String mAcceptedIface;
- private List<LinkAddress> mAcceptedSourceAddr;
private int mErrorCount;
@@ -86,11 +85,14 @@
return KeyStore.getInstance().contains(Credentials.LOCKDOWN_VPN);
}
- public LockdownVpnTracker(Context context, INetworkManagementService netService,
- ConnectivityService connService, Vpn vpn, VpnProfile profile) {
+ public LockdownVpnTracker(@NonNull Context context,
+ @NonNull ConnectivityService connService,
+ @NonNull Handler handler,
+ @NonNull Vpn vpn,
+ @NonNull VpnProfile profile) {
mContext = Preconditions.checkNotNull(context);
- mNetService = Preconditions.checkNotNull(netService);
mConnService = Preconditions.checkNotNull(connService);
+ mHandler = Preconditions.checkNotNull(handler);
mVpn = Preconditions.checkNotNull(vpn);
mProfile = Preconditions.checkNotNull(profile);
@@ -176,11 +178,6 @@
final String iface = vpnConfig.interfaze;
final List<LinkAddress> sourceAddrs = vpnConfig.addresses;
- if (TextUtils.equals(iface, mAcceptedIface)
- && sourceAddrs.equals(mAcceptedSourceAddr)) {
- return;
- }
-
Slog.d(TAG, "VPN connected using iface=" + iface +
", sourceAddr=" + sourceAddrs.toString());
EventLogTags.writeLockdownVpnConnected(egressType);
@@ -205,7 +202,7 @@
mVpn.setLockdown(true);
final IntentFilter resetFilter = new IntentFilter(ACTION_LOCKDOWN_RESET);
- mContext.registerReceiver(mResetReceiver, resetFilter, CONNECTIVITY_INTERNAL, null);
+ mContext.registerReceiver(mResetReceiver, resetFilter, CONNECTIVITY_INTERNAL, mHandler);
handleStateChangedLocked();
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index b4a8099..976a0c6 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -217,6 +217,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.os.SomeArgs;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ConcurrentUtils;
@@ -3281,7 +3282,7 @@
@Override
public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue,
- long timeoutMillis, String callingPackage) {
+ long networkTypeMask, long timeoutMillis, String callingPackage) {
enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
// We can only override when carrier told us about plans
@@ -3299,11 +3300,16 @@
final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(),
NETPOLICY_OVERRIDE_ENABLED, 1) != 0;
if (overrideEnabled || overrideValue == 0) {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
- overrideMask, overrideValue, subId));
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = subId;
+ args.arg2 = overrideMask;
+ args.arg3 = overrideValue;
+ args.arg4 = networkTypeMask;
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args));
if (timeoutMillis > 0) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
- overrideMask, 0, subId), timeoutMillis);
+ args.arg3 = 0;
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args),
+ timeoutMillis);
}
}
}
@@ -4439,10 +4445,11 @@
}
private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
- int overrideMask, int overrideValue) {
+ int overrideMask, int overrideValue, long networkTypeMask) {
if (listener != null) {
try {
- listener.onSubscriptionOverride(subId, overrideMask, overrideValue);
+ listener.onSubscriptionOverride(subId, overrideMask, overrideValue,
+ networkTypeMask);
} catch (RemoteException ignored) {
}
}
@@ -4543,13 +4550,16 @@
return true;
}
case MSG_SUBSCRIPTION_OVERRIDE: {
- final int overrideMask = msg.arg1;
- final int overrideValue = msg.arg2;
- final int subId = (int) msg.obj;
+ final SomeArgs args = (SomeArgs) msg.obj;
+ final int subId = (int) args.arg1;
+ final int overrideMask = (int) args.arg2;
+ final int overrideValue = (int) args.arg3;
+ final long networkTypeMask = (long) args.arg4;
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue);
+ dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue,
+ networkTypeMask);
}
mListeners.finishBroadcast();
return true;
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 1da5bc6..dc00cb4 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -261,11 +261,12 @@
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- populateAllPackagesCacheIfNeeded();
+ // Post populateAllPackagesCacheIfNeeded to a background thread, since it's
+ // expensive to run it in broadcast handler thread.
+ BackgroundThread.getHandler().post(() -> populateAllPackagesCacheIfNeeded());
mContext.unregisterReceiver(this);
}
- }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED), /* broadcastPermission */ null,
- BackgroundThread.getHandler());
+ }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
}
private void populateAllPackagesCacheIfNeeded() {
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index c712431..08e55d3 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -34,6 +34,8 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManager;
+import android.provider.DeviceConfig;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.StatsLog;
@@ -84,6 +86,12 @@
// Used for calculating space threshold for downgrading unused apps.
private static final int LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE = 2;
+ private static final int DEFAULT_INACTIVE_APP_THRESHOLD_DAYS = 10;
+
+ private static final String DOWNGRADE_UNUSED_APPS_ENABLED = "downgrade_unused_apps_enabled";
+ private static final String INACTIVE_APP_THRESHOLD_DAYS = "inactive_app_threshold_days";
+ private static final String LOW_STORAGE_MULTIPLIER_FOR_DOWNGRADE =
+ "low_storage_threshold_multiplier_for_downgrade";
/**
* Set of failed packages remembered across job runs.
@@ -103,8 +111,6 @@
private final AtomicBoolean mExitPostBootUpdate = new AtomicBoolean(false);
private final File mDataDir = Environment.getDataDirectory();
- private static final long mDowngradeUnusedAppsThresholdInMillis =
- getDowngradeUnusedAppsThresholdInMillis();
public static void schedule(Context context) {
if (isBackgroundDexoptDisabled()) {
@@ -346,14 +352,14 @@
// Only downgrade apps when space is low on device.
// Threshold is selected above the lowStorageThreshold so that we can pro-actively clean
// up disk before user hits the actual lowStorageThreshold.
- final long lowStorageThresholdForDowngrade = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE
+ final long lowStorageThresholdForDowngrade = getLowThresholdMultiplierForDowngrade()
* lowStorageThreshold;
boolean shouldDowngrade = shouldDowngrade(lowStorageThresholdForDowngrade);
Log.d(TAG, "Should Downgrade " + shouldDowngrade);
if (shouldDowngrade) {
Set<String> unusedPackages =
- pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
- Log.d(TAG, "Unsused Packages " + String.join(",", unusedPackages));
+ pm.getUnusedPackages(getDowngradeUnusedAppsThresholdInMillis());
+ Log.d(TAG, "Unused Packages " + String.join(",", unusedPackages));
if (!unusedPackages.isEmpty()) {
for (String pkg : unusedPackages) {
@@ -362,12 +368,9 @@
// Should be aborted by the scheduler.
return abortCode;
}
- if (downgradePackage(pm, pkg, /*isForPrimaryDex*/ true)) {
+ if (downgradePackage(pm, pkg)) {
updatedPackages.add(pkg);
}
- if (supportSecondaryDex) {
- downgradePackage(pm, pkg, /*isForPrimaryDex*/ false);
- }
}
pkgs = new ArraySet<>(pkgs);
@@ -415,39 +418,45 @@
* Try to downgrade the package to a smaller compilation filter.
* eg. if the package is in speed-profile the package will be downgraded to verify.
* @param pm PackageManagerService
- * @param pkg The package to be downgraded.
- * @param isForPrimaryDex. Apps can have several dex file, primary and secondary.
- * @return true if the package was downgraded.
+ * @param pkg The package to be downgraded
+ * @return true if the package was downgraded
*/
- private boolean downgradePackage(PackageManagerService pm, String pkg,
- boolean isForPrimaryDex) {
+ private boolean downgradePackage(PackageManagerService pm, String pkg) {
Log.d(TAG, "Downgrading " + pkg);
- boolean dex_opt_performed = false;
+ boolean downgradedPrimary = false;
int reason = PackageManagerService.REASON_INACTIVE_PACKAGE_DOWNGRADE;
int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
| DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB
| DexoptOptions.DEXOPT_DOWNGRADE;
+
long package_size_before = getPackageSize(pm, pkg);
-
- if (isForPrimaryDex) {
- // This applies for system apps or if packages location is not a directory, i.e.
- // monolithic install.
- if (!pm.canHaveOatDir(pkg)) {
- // For apps that don't have the oat directory, instead of downgrading,
- // remove their compiler artifacts from dalvik cache.
- pm.deleteOatArtifactsOfPackage(pkg);
- } else {
- dex_opt_performed = performDexOptPrimary(pm, pkg, reason, dexoptFlags);
- }
+ // An aggressive downgrade deletes the oat files.
+ boolean aggressive = false;
+ // This applies for system apps or if packages location is not a directory, i.e.
+ // monolithic install.
+ if (!pm.canHaveOatDir(pkg)) {
+ // For apps that don't have the oat directory, instead of downgrading,
+ // remove their compiler artifacts from dalvik cache.
+ pm.deleteOatArtifactsOfPackage(pkg);
+ aggressive = true;
+ downgradedPrimary = true;
} else {
- dex_opt_performed = performDexOptSecondary(pm, pkg, reason, dexoptFlags);
+ downgradedPrimary = performDexOptPrimary(pm, pkg, reason, dexoptFlags);
+
+ if (supportSecondaryDex()) {
+ performDexOptSecondary(pm, pkg, reason, dexoptFlags);
+ }
}
- if (dex_opt_performed) {
+ // This metric aims to log the storage savings when downgrading.
+ // The way disk size is measured using getPackageSize only looks at the primary apks.
+ // Any logs that are due to secondary dex files will show 0% size reduction and pollute
+ // the metrics.
+ if (downgradedPrimary) {
StatsLog.write(StatsLog.APP_DOWNGRADED, pkg, package_size_before,
- getPackageSize(pm, pkg), /*aggressive=*/ false);
+ getPackageSize(pm, pkg), aggressive);
}
- return dex_opt_performed;
+ return downgradedPrimary;
}
private boolean supportSecondaryDex() {
@@ -471,7 +480,7 @@
* concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
* @param pm An instance of PackageManagerService
* @param pkg The package to be downgraded.
- * @param isForPrimaryDex. Apps can have several dex file, primary and secondary.
+ * @param isForPrimaryDex Apps can have several dex file, primary and secondary.
* @return true if the package was downgraded.
*/
private boolean optimizePackage(PackageManagerService pm, String pkg,
@@ -588,12 +597,6 @@
// the checks above. This check is not "live" - the value is determined by a background
// restart with a period of ~1 minute.
PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");
- if (pm.isStorageLow()) {
- if (DEBUG_DEXOPT) {
- Log.i(TAG, "Low storage, skipping this run");
- }
- return false;
- }
final ArraySet<String> pkgs = pm.getOptimizablePackages();
if (pkgs.isEmpty()) {
@@ -643,17 +646,77 @@
}
private static long getDowngradeUnusedAppsThresholdInMillis() {
+ long defaultValue = Long.MAX_VALUE;
+ if (isDowngradeFeatureEnabled()) {
+ return getInactiveAppsThresholdMillis();
+ }
final String sysPropKey = "pm.dexopt.downgrade_after_inactive_days";
String sysPropValue = SystemProperties.get(sysPropKey);
if (sysPropValue == null || sysPropValue.isEmpty()) {
Log.w(TAG, "SysProp " + sysPropKey + " not set");
- return Long.MAX_VALUE;
+ return defaultValue;
}
- return TimeUnit.DAYS.toMillis(Long.parseLong(sysPropValue));
+ try {
+ return TimeUnit.DAYS.toMillis(Long.parseLong(sysPropValue));
+ } catch (NumberFormatException e) {
+ Log.w(TAG, "Couldn't parse long for pm.dexopt.downgrade_after_inactive_days: "
+ + sysPropValue + ". Returning default value instead.");
+ return defaultValue;
+ }
}
private static boolean isBackgroundDexoptDisabled() {
return SystemProperties.getBoolean("pm.dexopt.disable_bg_dexopt" /* key */,
false /* default */);
}
+
+ private static boolean isDowngradeFeatureEnabled() {
+ // DeviceConfig enables the control of on device features via remotely configurable flags,
+ // compared to SystemProperties which is only a way of sharing info system-widely, but are
+ // not configurable on the server-side.
+ String downgradeUnusedAppsEnabledFlag =
+ DeviceConfig.getProperty(
+ DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ DOWNGRADE_UNUSED_APPS_ENABLED);
+ return !TextUtils.isEmpty(downgradeUnusedAppsEnabledFlag)
+ && Boolean.parseBoolean(downgradeUnusedAppsEnabledFlag);
+ }
+
+ private static long getInactiveAppsThresholdMillis() {
+ long defaultValue = TimeUnit.DAYS.toMillis(DEFAULT_INACTIVE_APP_THRESHOLD_DAYS);
+ String inactiveAppThresholdDaysFlag =
+ DeviceConfig.getProperty(DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ INACTIVE_APP_THRESHOLD_DAYS);
+ if (!TextUtils.isEmpty(inactiveAppThresholdDaysFlag)) {
+ try {
+ return TimeUnit.DAYS.toMillis(Long.parseLong(inactiveAppThresholdDaysFlag));
+ } catch (NumberFormatException e) {
+ Log.w(TAG, "Couldn't parse long for " + INACTIVE_APP_THRESHOLD_DAYS + " flag: "
+ + inactiveAppThresholdDaysFlag + ". Returning default value instead.");
+ return defaultValue;
+ }
+ }
+ return defaultValue;
+ }
+
+ private static int getLowThresholdMultiplierForDowngrade() {
+ int defaultValue = LOW_THRESHOLD_MULTIPLIER_FOR_DOWNGRADE;
+ if (isDowngradeFeatureEnabled()) {
+ String lowStorageThresholdMultiplierFlag =
+ DeviceConfig.getProperty(DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ LOW_STORAGE_MULTIPLIER_FOR_DOWNGRADE);
+ if (!TextUtils.isEmpty(lowStorageThresholdMultiplierFlag)) {
+ try {
+ return Integer.parseInt(lowStorageThresholdMultiplierFlag);
+ } catch (NumberFormatException e) {
+ Log.w(TAG, "Couldn't parse long for "
+ + LOW_STORAGE_MULTIPLIER_FOR_DOWNGRADE + " flag: "
+ + lowStorageThresholdMultiplierFlag
+ + ". Returning default value instead.");
+ return defaultValue;
+ }
+ }
+ }
+ return defaultValue;
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 3aeb2b1..b632d18f 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -505,6 +505,11 @@
params.installFlags &= ~PackageManager.INSTALL_REQUEST_DOWNGRADE;
}
+ if (callingUid != Process.SYSTEM_UID) {
+ // Only system_server can use INSTALL_DISABLE_VERIFICATION.
+ params.installFlags &= ~PackageManager.INSTALL_DISABLE_VERIFICATION;
+ }
+
boolean isApex = (params.installFlags & PackageManager.INSTALL_APEX) != 0;
if (params.isStaged || isApex) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, TAG);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2bf5f4d..41403fd 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2149,6 +2149,14 @@
pkgList.add(packageName);
sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
}
+ } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib
+ for (int i = 0; i < res.libraryConsumers.size(); i++) {
+ PackageParser.Package pkg = res.libraryConsumers.get(i);
+ // send broadcast that all consumers of the static shared library have changed
+ sendPackageChangedBroadcast(pkg.packageName, false /*killFlag*/,
+ new ArrayList<>(Collections.singletonList(pkg.packageName)),
+ pkg.applicationInfo.uid);
+ }
}
// Work that needs to happen on first install within each user
@@ -11878,6 +11886,9 @@
}
}
}
+ if (reconciledPkg.installResult != null) {
+ reconciledPkg.installResult.libraryConsumers = clientLibPkgs;
+ }
if ((scanFlags & SCAN_BOOTING) != 0) {
// No apps can run during boot scan, so they don't need to be frozen
@@ -15157,6 +15168,8 @@
String installerPackageName;
PackageRemovedInfo removedInfo;
ArrayMap<String, PackageInstalledInfo> addedChildPackages;
+ // The set of packages consuming this shared library or null if no consumers exist.
+ ArrayList<PackageParser.Package> libraryConsumers;
public void setError(int code, String msg) {
setReturnCode(code);
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 85bc9f3..af1a095 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -94,9 +94,11 @@
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.PrintWriterPrinter;
+import android.util.SparseArray;
import com.android.internal.content.PackageHelper;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
@@ -347,17 +349,33 @@
}
private int getStagedSessions() {
- final PrintWriter pw = getOutPrintWriter();
+ final IndentingPrintWriter pw = new IndentingPrintWriter(
+ getOutPrintWriter(), /* singleIndent */ " ", /* wrapLength */ 120);
try {
- List<SessionInfo> stagedSessionsList =
+ List<SessionInfo> stagedSessions =
mInterface.getPackageInstaller().getStagedSessions().getList();
- for (SessionInfo session: stagedSessionsList) {
- pw.println("appPackageName = " + session.getAppPackageName()
- + "; sessionId = " + session.getSessionId()
- + "; isStaged = " + session.isStaged()
- + "; isStagedSessionReady = " + session.isStagedSessionReady()
- + "; isStagedSessionApplied = " + session.isStagedSessionApplied()
- + "; isStagedSessionFailed = " + session.isStagedSessionFailed() + ";");
+ final SparseArray<SessionInfo> sessionById = new SparseArray<>(stagedSessions.size());
+ for (SessionInfo session : stagedSessions) {
+ sessionById.put(session.getSessionId(), session);
+ }
+ for (SessionInfo session: stagedSessions) {
+ if (session.getParentSessionId() != SessionInfo.INVALID_ID) {
+ continue;
+ }
+ printStagedSession(session, pw);
+ if (session.isMultiPackage()) {
+ pw.increaseIndent();
+ final int[] childIds = session.getChildSessionIds();
+ for (int i = 0; i < childIds.length; i++) {
+ final SessionInfo childSession = sessionById.get(childIds[i]);
+ if (childSession == null) {
+ pw.println("sessionId = " + childIds[i] + "; not found");
+ } else {
+ printStagedSession(childSession, pw);
+ }
+ }
+ pw.decreaseIndent();
+ }
}
} catch (RemoteException e) {
pw.println("Failure ["
@@ -368,6 +386,15 @@
return 1;
}
+ private static void printStagedSession(SessionInfo session, PrintWriter pw) {
+ pw.println("sessionId = " + session.getSessionId()
+ + "; appPackageName = " + session.getAppPackageName()
+ + "; isStaged = " + session.isStaged()
+ + "; isReady = " + session.isStagedSessionReady()
+ + "; isApplied = " + session.isStagedSessionApplied()
+ + "; isFailed = " + session.isStagedSessionFailed() + ";");
+ }
+
private int uninstallSystemUpdates() {
final PrintWriter pw = getOutPrintWriter();
List<String> failedUninstalls = new LinkedList<>();
@@ -3097,7 +3124,7 @@
pw.println(" [--user USER_ID] INTENT");
pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
pw.println("");
- pw.println(" install [-lrtsfdgw] [-i PACKAGE] [--user USER_ID|all|current]");
+ pw.println(" install [-rtsfdgw] [-i PACKAGE] [--user USER_ID|all|current]");
pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
@@ -3108,7 +3135,6 @@
pw.println(" [PATH|-]");
pw.println(" Install an application. Must provide the apk data to install, either as a");
pw.println(" file path or '-' to read from stdin. Options are:");
- pw.println(" -l: forward lock application");
pw.println(" -R: disallow replacement of existing application");
pw.println(" -t: allow test packages");
pw.println(" -i: specify package name of installer owning the app");
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1fe5512..65fb35d 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -4180,6 +4180,17 @@
}
return userData == null ? null : userData.info;
}
+
+ public @NonNull UserInfo[] getUserInfos() {
+ synchronized (mUsersLock) {
+ int userSize = mUsers.size();
+ UserInfo[] allInfos = new UserInfo[userSize];
+ for (int i = 0; i < userSize; i++) {
+ allInfos[i] = mUsers.valueAt(i).info;
+ }
+ return allInfos;
+ }
+ }
}
/* Remove all the users except of the system one. */
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 5a410d7..22929d8 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -650,9 +650,9 @@
private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
int flagValues, int callingUid, int userId, boolean overridePolicy,
PermissionCallback callback) {
- if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
+ if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
&& ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
- Log.i(TAG, "System is updating flags for "
+ Log.i(TAG, "System is updating flags for " + packageName + " "
+ permName + " for user " + userId + " "
+ DebugUtils.flagsToString(
PackageManager.class, "FLAG_PERMISSION_", flagMask)
@@ -1185,7 +1185,7 @@
boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
&& ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
- Log.i(TAG, "System is granting "
+ Log.i(TAG, "System is granting " + packageName + " "
+ permName + " for user " + userId + " on behalf of uid " + callingUid
+ " " + mPackageManagerInt.getNameForUid(callingUid),
new RuntimeException());
@@ -1232,7 +1232,8 @@
return;
}
- final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
+ final int uid = UserHandle.getUid(userId,
+ UserHandle.getAppId(pkg.applicationInfo.uid));
final PackageSetting ps = (PackageSetting) pkg.mExtras;
final PermissionsState permissionsState = ps.getPermissionsState();
@@ -1344,9 +1345,9 @@
// TODO swap permission name and package name
private void revokeRuntimePermissionInternal(String permName, String packageName,
boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
- if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
+ if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
&& ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
- Log.i(TAG, "System is revoking "
+ Log.i(TAG, "System is revoking " + packageName + " "
+ permName + " for user " + userId + " on behalf of uid " + callingUid
+ " " + mPackageManagerInt.getNameForUid(callingUid),
new RuntimeException());
@@ -1432,7 +1433,8 @@
}
if (callback != null) {
- callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
+ callback.onPermissionRevoked(UserHandle.getUid(userId,
+ UserHandle.getAppId(pkg.applicationInfo.uid)), userId);
}
if (bp.isRuntime()) {
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index bfd280c..ddbd9c9 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -282,15 +282,6 @@
rollbacks.add(rollback.info);
}
}
-
- // Also return new rollbacks for which the PackageRollbackInfo is complete.
- for (NewRollback newRollback : mNewRollbacks) {
- if (newRollback.rollback.info.getPackages().size()
- == newRollback.packageSessionIds.length
- && !newRollback.isCancelled) {
- rollbacks.add(newRollback.rollback.info);
- }
- }
return new ParceledListSlice<>(rollbacks);
}
}
diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java
new file mode 100644
index 0000000..2d36a0d
--- /dev/null
+++ b/services/core/java/com/android/server/storage/StorageSessionController.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.storage;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.ParcelFileDescriptor;
+import android.os.storage.VolumeInfo;
+import android.provider.MediaStore;
+import android.service.storage.ExternalStorageService;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Controls storage sessions for users initiated by the {@link StorageManagerService}.
+ * Each user on the device will be represented by a {@link StorageUserConnection}.
+ */
+public final class StorageSessionController {
+ private static final String TAG = "StorageSessionController";
+
+ private final Object mLock = new Object();
+ private final Context mContext;
+ private final Callback mCallback;
+ @GuardedBy("mLock")
+ private ComponentName mExternalStorageServiceComponent;
+ @GuardedBy("mLock")
+ private final SparseArray<StorageUserConnection> mConnections = new SparseArray<>();
+
+ public StorageSessionController(Context context, Callback callback) {
+ mContext = Preconditions.checkNotNull(context);
+ mCallback = Preconditions.checkNotNull(callback);
+ }
+
+ /**
+ * Starts a storage session associated with {@code deviceFd} for {@code vol}.
+ * Does nothing if a session is already started or starting. If the user associated with
+ * {@code vol} is not yet ready, the session will be retried {@link #onUserStarted}.
+ *
+ * A session must be ended with {@link #endSession} when no longer required.
+ */
+ public void onVolumeMounted(int userId, FileDescriptor deviceFd, VolumeInfo vol) {
+ if (deviceFd == null) {
+ Slog.w(TAG, "Null device fd. Session not started for " + vol);
+ return;
+ }
+
+ // Get realpath for the fd, paths that are not /dev/null need additional
+ // setup by the ExternalStorageService before they can be ready
+ String realPath;
+ try {
+ realPath = ParcelFileDescriptor.getFile(deviceFd).getPath();
+ } catch (IOException e) {
+ Slog.wtf(TAG, "Could not get real path from fd: " + deviceFd, e);
+ return;
+ }
+
+ if ("/dev/null".equals(realPath)) {
+ Slog.i(TAG, "Volume ready for use: " + vol);
+ return;
+ }
+
+ synchronized (mLock) {
+ StorageUserConnection connection = mConnections.get(userId);
+ if (connection == null) {
+ Slog.i(TAG, "Creating new session for vol: " + vol);
+ connection = new StorageUserConnection(mContext, userId, this);
+ mConnections.put(userId, connection);
+ }
+ try {
+ Slog.i(TAG, "Starting session for vol: " + vol);
+ connection.startSession(deviceFd, vol);
+ } catch (ExternalStorageServiceException e) {
+ Slog.e(TAG, "Failed to start session for vol: " + vol, e);
+ }
+ }
+ }
+
+ /**
+ * Ends a storage session for {@code vol}. Does nothing if the session is already
+ * ended or ending. Ending a session discards all resources associated with that session.
+ */
+ public void onVolumeUnmounted(int userId, VolumeInfo vol) {
+ synchronized (mLock) {
+ StorageUserConnection connection = mConnections.get(userId);
+ if (connection != null) {
+ Slog.i(TAG, "Ending session for vol: " + vol);
+ try {
+ if (connection.endSession(vol)) {
+ mConnections.remove(userId);
+ }
+ } catch (ExternalStorageServiceException e) {
+ Slog.e(TAG, "Failed to end session for vol: " + vol, e);
+ }
+ } else {
+ Slog.w(TAG, "Session already ended for vol: " + vol);
+ }
+ }
+ }
+
+ /** Restarts all sessions for {@code userId}. */
+ public void onUserStarted(int userId) {
+ synchronized (mLock) {
+ StorageUserConnection connection = mConnections.get(userId);
+ if (connection != null) {
+ try {
+ Slog.i(TAG, "Restarting all sessions for user: " + userId);
+ connection.startAllSessions();
+ } catch (ExternalStorageServiceException e) {
+ Slog.e(TAG, "Failed to start all sessions", e);
+ }
+ } else {
+ // TODO(b/135341433): What does this mean in multi-user
+ }
+ }
+ }
+
+ /** Ends all sessions for {@code userId}. */
+ public void onUserRemoved(int userId) {
+ synchronized (mLock) {
+ StorageUserConnection connection = mConnections.get(userId);
+ if (connection != null) {
+ try {
+ Slog.i(TAG, "Ending all sessions for user: " + userId);
+ connection.endAllSessions();
+ mConnections.remove(userId);
+ } catch (ExternalStorageServiceException e) {
+ Slog.e(TAG, "Failed to end all sessions", e);
+ }
+ } else {
+ // TODO(b/135341433): What does this mean in multi-user
+ }
+ }
+ }
+
+ /** Returns the {@link ExternalStorageService} component name. */
+ @Nullable
+ public ComponentName getExternalStorageServiceComponentName() {
+ synchronized (mLock) {
+ if (mExternalStorageServiceComponent == null) {
+ ProviderInfo provider = mContext.getPackageManager().resolveContentProvider(
+ MediaStore.AUTHORITY, PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_SYSTEM_ONLY);
+
+ if (provider == null) {
+ Slog.e(TAG, "No valid MediaStore provider found.");
+ }
+ String packageName = provider.applicationInfo.packageName;
+
+ Intent intent = new Intent(ExternalStorageService.SERVICE_INTERFACE);
+ intent.setPackage(packageName);
+ ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
+ PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+ if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+ Slog.e(TAG, "No valid ExternalStorageService component found.");
+ return null;
+ }
+
+ ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
+ if (!Manifest.permission.BIND_EXTERNAL_STORAGE_SERVICE
+ .equals(serviceInfo.permission)) {
+ Slog.e(TAG, name.flattenToShortString() + " does not require permission "
+ + Manifest.permission.BIND_EXTERNAL_STORAGE_SERVICE);
+ return null;
+ }
+ mExternalStorageServiceComponent = name;
+ }
+ return mExternalStorageServiceComponent;
+ }
+ }
+
+ /** Returns the {@link StorageManagerService} callback. */
+ public Callback getCallback() {
+ return mCallback;
+ }
+
+ /** Callback to listen to session events from the {@link StorageSessionController}. */
+ public interface Callback {
+ /** Called when a {@link StorageUserConnection} is disconnected. */
+ void onUserDisconnected(int userId);
+ }
+
+ /** Exception thrown when communication with the {@link ExternalStorageService}. */
+ public static class ExternalStorageServiceException extends Exception {
+ public ExternalStorageServiceException(Throwable cause) {
+ super(cause);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java
new file mode 100644
index 0000000..ff9c900
--- /dev/null
+++ b/services/core/java/com/android/server/storage/StorageUserConnection.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.storage;
+
+import static android.service.storage.ExternalStorageService.EXTRA_ERROR;
+import static android.service.storage.ExternalStorageService.FLAG_SESSION_ATTRIBUTE_INDEXABLE;
+import static android.service.storage.ExternalStorageService.FLAG_SESSION_TYPE_FUSE;
+
+import static com.android.server.storage.StorageSessionController.ExternalStorageServiceException;
+
+import android.annotation.MainThread;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelableException;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.storage.VolumeInfo;
+import android.service.storage.ExternalStorageService;
+import android.service.storage.IExternalStorageService;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Controls the lifecycle of the {@link ActiveConnection} to an {@link ExternalStorageService}
+ * for a user and manages storage sessions represented by a {@link Session}.
+ */
+public final class StorageUserConnection {
+ private static final String TAG = "StorageUserConnection";
+
+ private final Object mLock = new Object();
+ private final Context mContext;
+ private final int mUserId;
+ private final StorageSessionController mSessionController;
+ private final ActiveConnection mActiveConnection = new ActiveConnection();
+ @GuardedBy("mLock") private final Map<String, Session> mSessions = new HashMap<>();
+
+ public StorageUserConnection(Context context, int userId, StorageSessionController controller) {
+ mContext = Preconditions.checkNotNull(context);
+ mUserId = Preconditions.checkArgumentNonnegative(userId);
+ mSessionController = controller;
+ }
+
+ /** Starts a session for a user */
+ public void startSession(FileDescriptor deviceFd, VolumeInfo vol)
+ throws ExternalStorageServiceException {
+ String sessionId = vol.getId();
+ String upperPath = vol.getPath().getPath();
+ String lowerPath = vol.getInternalPath().getPath();
+ Slog.i(TAG, "Starting session with id: " + sessionId + " and upperPath: " + upperPath
+ + " and lowerPath: " + lowerPath);
+ Session session = new Session(sessionId, deviceFd, upperPath, lowerPath);
+ synchronized (mLock) {
+ // TODO(b/135341433): Ensure we don't replace a session without ending the previous
+ mSessions.put(sessionId, session);
+ // TODO(b/135341433): If this fails, maybe its at boot, how to handle if not boot?
+ mActiveConnection.startSessionLocked(session);
+ }
+ }
+
+ /**
+ * Ends a session for a user.
+ *
+ * @return {@code true} if there are no more sessions for this user, {@code false} otherwise
+ **/
+ public boolean endSession(VolumeInfo vol) throws ExternalStorageServiceException {
+ synchronized (mLock) {
+ Session session = mSessions.remove(vol.getId());
+ if (session != null) {
+ mActiveConnection.endSessionLocked(session);
+ mSessions.remove(session.sessionId);
+ }
+ boolean isAllSessionsEnded = mSessions.isEmpty();
+ if (isAllSessionsEnded) {
+ mActiveConnection.close();
+ }
+ return isAllSessionsEnded;
+ }
+ }
+
+ /** Starts all available sessions for a user */
+ public void startAllSessions() throws ExternalStorageServiceException {
+ synchronized (mLock) {
+ for (Session session : mSessions.values()) {
+ mActiveConnection.startSessionLocked(session);
+ }
+ }
+ }
+
+ /** Ends all available sessions for a user */
+ public void endAllSessions() throws ExternalStorageServiceException {
+ synchronized (mLock) {
+ for (Session session : mSessions.values()) {
+ mActiveConnection.endSessionLocked(session);
+ mSessions.remove(session.sessionId);
+ }
+ mActiveConnection.close();
+ }
+ }
+
+ private final class ActiveConnection implements AutoCloseable {
+ // Lifecycle connection to the external storage service, needed to unbind.
+ // We should only try to bind if mServiceConnection is null.
+ // Non-null indicates we are connected or connecting.
+ @GuardedBy("mLock") @Nullable private ServiceConnection mServiceConnection;
+ // Binder object representing the external storage service.
+ // Non-null indicates we are connected
+ @GuardedBy("mLock") @Nullable private IExternalStorageService mRemote;
+ // Exception, if any, thrown from #startSessionLocked or #endSessionLocked
+ // Local variables cannot be referenced from a lambda expression :( so we
+ // save the exception received in the callback here. Since we guard access
+ // (and clear the exception state) with the same lock which we hold during
+ // the entire transaction, there is no risk of race.
+ @GuardedBy("mLock") @Nullable private ParcelableException mLastException;
+
+ @Override
+ public void close() {
+ synchronized (mLock) {
+ if (mServiceConnection != null) {
+ mContext.unbindService(mServiceConnection);
+ }
+ mServiceConnection = null;
+ mRemote = null;
+ }
+ }
+
+ public void startSessionLocked(Session session) throws ExternalStorageServiceException {
+ if (mServiceConnection == null || mRemote == null) {
+ if (mServiceConnection == null) {
+ // Not bound
+ bindLocked();
+ } // else we are binding. In any case when we bind we'll re-start all sessions
+ return;
+ }
+
+ CountDownLatch latch = new CountDownLatch(1);
+ try {
+ mRemote.startSession(session.sessionId,
+ FLAG_SESSION_TYPE_FUSE | FLAG_SESSION_ATTRIBUTE_INDEXABLE,
+ new ParcelFileDescriptor(session.deviceFd), session.upperPath,
+ session.lowerPath, new RemoteCallback(result ->
+ setResultLocked(latch, result)));
+
+ } catch (RemoteException e) {
+ throw new ExternalStorageServiceException(e);
+ }
+ waitAndReturnResultLocked(latch);
+ }
+
+ public void endSessionLocked(Session session) throws ExternalStorageServiceException {
+ if (mRemote == null) {
+ // TODO(b/135341433): This assumes if there is no connection, there are no
+ // session resources held. Need to document in the ExternalStorageService
+ // API that implementors should end all sessions and clean up resources
+ // when the binding is lost, onDestroy?
+ return;
+ }
+
+ CountDownLatch latch = new CountDownLatch(1);
+ try {
+ mRemote.endSession(session.sessionId, new RemoteCallback(result ->
+ setResultLocked(latch, result)));
+ } catch (RemoteException e) {
+ throw new ExternalStorageServiceException(e);
+ }
+ waitAndReturnResultLocked(latch);
+ }
+
+ private void setResultLocked(CountDownLatch latch, Bundle result) {
+ mLastException = result.getParcelable(EXTRA_ERROR);
+ latch.countDown();
+ }
+
+ private void waitAndReturnResultLocked(CountDownLatch latch)
+ throws ExternalStorageServiceException {
+ try {
+ // TODO(b/140025078): Call ActivityManager ANR API?
+ latch.await(20, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException(
+ "Interrupted while waiting for ExternalStorageService result");
+ }
+ if (mLastException != null) {
+ mLastException = null;
+ try {
+ mLastException.maybeRethrow(IOException.class);
+ } catch (IOException e) {
+ throw new ExternalStorageServiceException(e);
+ }
+ throw new RuntimeException(mLastException);
+ }
+ mLastException = null;
+ }
+
+ private void bindLocked() {
+ ComponentName name = mSessionController.getExternalStorageServiceComponentName();
+ if (name == null) {
+ Slog.i(TAG, "Not ready to bind to the ExternalStorageService for user " + mUserId);
+ return;
+ }
+
+ ServiceConnection connection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Slog.i(TAG, "Service: [" + name + "] connected. User [" + mUserId + "]");
+ handleConnection(service);
+ }
+
+ @Override
+ @MainThread
+ public void onServiceDisconnected(ComponentName name) {
+ // Service crashed or process was killed, #onServiceConnected will be called
+ // Don't need to re-bind.
+ Slog.i(TAG, "Service: [" + name + "] disconnected. User [" + mUserId + "]");
+ handleDisconnection();
+ }
+
+ @Override
+ public void onBindingDied(ComponentName name) {
+ // Application hosting service probably got updated
+ // Need to re-bind.
+ Slog.i(TAG, "Service: [" + name + "] died. User [" + mUserId + "]");
+ handleDisconnection();
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ // Should never happen. Service returned null from #onBind.
+ Slog.wtf(TAG, "Service: [" + name + "] is null. User [" + mUserId + "]");
+ }
+
+ private void handleConnection(IBinder service) {
+ synchronized (mLock) {
+ if (mServiceConnection != null) {
+ mRemote = IExternalStorageService.Stub.asInterface(service);
+ } else {
+ Slog.wtf(TAG, "Service connected without a connection object??");
+ }
+ }
+
+ try {
+ startAllSessions();
+ } catch (ExternalStorageServiceException e) {
+ Slog.e(TAG, "Failed to start all sessions", e);
+ }
+ }
+
+ private void handleDisconnection() {
+ close();
+ // Clear all sessions because we will need a new device fd since
+ // StorageManagerService will reset the device mount state and #startSession
+ // will be called for any required mounts.
+ synchronized (mLock) {
+ mSessions.clear();
+ }
+ // Notify StorageManagerService so it can restart all necessary sessions
+ mSessionController.getCallback().onUserDisconnected(mUserId);
+ }
+ };
+
+ Slog.i(TAG, "Binding to the ExternalStorageService for user " + mUserId);
+ // TODO(b/135341433): Verify required service flags BIND_IMPORTANT?
+ if (mContext.bindServiceAsUser(new Intent().setComponent(name), connection,
+ Context.BIND_AUTO_CREATE, UserHandle.of(mUserId))) {
+ Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId);
+ mServiceConnection = connection;
+ // Reset the remote, we will set when we connect
+ mRemote = null;
+ } else {
+ Slog.w(TAG, "Failed to bind to the ExternalStorageService for user " + mUserId);
+ }
+ }
+ }
+
+ private static final class Session {
+ public final String sessionId;
+ public final FileDescriptor deviceFd;
+ public final String lowerPath;
+ public final String upperPath;
+
+ Session(String sessionId, FileDescriptor deviceFd, String upperPath,
+ String lowerPath) {
+ this.sessionId = sessionId;
+ this.upperPath = upperPath;
+ this.lowerPath = lowerPath;
+ this.deviceFd = deviceFd;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index fc36e99..36e906c 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1935,7 +1935,10 @@
* HistoryRecord.
* Normally the server-side record will be removed when the client reports back after
* destruction. If, however, at this point there is no client process attached, the record will
- * removed immediately.
+ * be removed immediately.
+ *
+ * @return {@code true} if activity was immediately removed from history, {@code false}
+ * otherwise.
*/
boolean destroyImmediately(boolean removeFromApp, String reason) {
if (DEBUG_SWITCH || DEBUG_CLEANUP) {
@@ -2918,7 +2921,7 @@
return false;
}
- boolean handleAlreadyVisible() {
+ void handleAlreadyVisible() {
stopFreezingScreenLocked(false);
try {
if (returningOptions != null) {
@@ -2926,7 +2929,6 @@
}
} catch(RemoteException e) {
}
- return mState == RESUMED;
}
static void activityResumedLocked(IBinder token) {
@@ -3430,8 +3432,8 @@
return false;
}
final ActivityStack stack = getActivityStack();
- if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
- || !mHaveState || !stopped) {
+ if (isState(RESUMED) || stack == null || this == stack.mPausingActivity || !mHaveState
+ || !stopped) {
// We're not ready for this kind of thing.
return false;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 8bdedff..5bd557d 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2088,15 +2088,12 @@
boolean aboveTop = top != null;
final boolean stackShouldBeVisible = shouldBeVisible(starting);
boolean behindFullscreenActivity = !stackShouldBeVisible;
- boolean resumeNextActivity = isFocusable() && isInStackLocked(starting) == null;
+ final boolean resumeTopActivity = isFocusable() && isInStackLocked(starting) == null;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
- if (r.finishing) {
- continue;
- }
final boolean isTop = r == top;
if (aboveTop && !isTop) {
continue;
@@ -2112,6 +2109,9 @@
behindFullscreenActivity, r);
}
if (reallyVisible) {
+ if (r.finishing) {
+ continue;
+ }
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
+ " finishing=" + r.finishing + " state=" + r.getState());
// First: if this is not the current activity being started, make
@@ -2122,15 +2122,8 @@
}
if (!r.attachedToProcess()) {
- if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
- resumeNextActivity, r)) {
- if (activityNdx >= activities.size()) {
- // Record may be removed if its process needs to restart.
- activityNdx = activities.size() - 1;
- } else {
- resumeNextActivity = false;
- }
- }
+ makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
+ resumeTopActivity && isTop, r);
} else if (r.visible) {
// If this activity is already visible, then there is nothing to do here.
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
@@ -2140,10 +2133,7 @@
r.makeClientVisible();
}
- if (r.handleAlreadyVisible()) {
- resumeNextActivity = false;
- }
-
+ r.handleAlreadyVisible();
if (notifyClients) {
r.makeActiveIfNeeded(starting);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3c5947a..f2ca2ba8 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -82,6 +82,8 @@
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE;
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
+import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
@@ -3237,11 +3239,12 @@
synchronized (mGlobalLock) {
final long origId = Binder.clearCallingIdentity();
try {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null || !r.isDestroyable()) {
return false;
}
- return r.safelyDestroy("app-req");
+ r.destroyImmediately(true /* removeFromApp */, "app-req");
+ return r.isState(DESTROYING, DESTROYED);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index d4e95cf..6b2f9da 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -462,7 +462,7 @@
// new rotation animation after the old one finally finishes. It's better to defer the
// app transition.
if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() &&
- mService.getDefaultDisplayContentLocked().rotationNeedsUpdate()) {
+ mDisplayContent.getDisplayRotation().needsUpdate()) {
if (DEBUG_APP_TRANSITIONS) {
Slog.v(TAG, "Delaying app transition for screen rotation animation to finish");
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e851a06..71a0126 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -130,9 +130,7 @@
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_REMOVING_FOCUS;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIGN_LAYERS;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
-import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_ACTIVE;
import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
-import static com.android.server.wm.WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION;
import static com.android.server.wm.WindowManagerService.dipToPixel;
import static com.android.server.wm.WindowManagerService.logSurface;
import static com.android.server.wm.WindowState.EXCLUSION_LEFT;
@@ -148,6 +146,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
@@ -323,7 +322,7 @@
private final Display mDisplay;
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
private final DisplayPolicy mDisplayPolicy;
- private DisplayRotation mDisplayRotation;
+ private final DisplayRotation mDisplayRotation;
DisplayFrames mDisplayFrames;
private final RemoteCallbackList<ISystemGestureExclusionListener>
@@ -352,22 +351,6 @@
float mCompatibleScreenScale;
/**
- * Current rotation of the display.
- * Constants as per {@link android.view.Surface.Rotation}.
- *
- * @see #updateRotationUnchecked()
- */
- private int mRotation = 0;
-
- /**
- * Last applied orientation of the display.
- * Constants as per {@link android.content.pm.ActivityInfo.ScreenOrientation}.
- *
- * @see #updateOrientationFromAppTokens()
- */
- private int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-
- /**
* Orientation forced by some window. If there is no visible window that specifies orientation
* it is set to {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}.
*
@@ -407,7 +390,6 @@
// Accessed directly by all users.
private boolean mLayoutNeeded;
int pendingLayoutChanges;
- int mDeferredRotationPauseCount;
/**
* Used to gate application window layout until we have sent the complete configuration.
@@ -1138,25 +1120,17 @@
return mInsetsStateController;
}
- @VisibleForTesting
- void setDisplayRotation(DisplayRotation displayRotation) {
- mDisplayRotation = displayRotation;
- }
-
+ @Surface.Rotation
int getRotation() {
- return mRotation;
+ return mDisplayRotation.getRotation();
}
- @VisibleForTesting
- void setRotation(int newRotation) {
- mRotation = newRotation;
- mDisplayRotation.setRotation(newRotation);
- }
-
+ @ScreenOrientation
int getLastOrientation() {
- return mLastOrientation;
+ return mDisplayRotation.getLastOrientation();
}
+ @ScreenOrientation
int getLastWindowForcedOrientation() {
return mLastWindowForcedOrientation;
}
@@ -1166,48 +1140,6 @@
}
/**
- * Temporarily pauses rotation changes until resumed.
- *
- * This can be used to prevent rotation changes from occurring while the user is
- * performing certain operations, such as drag and drop.
- *
- * This call nests and must be matched by an equal number of calls to
- * {@link #resumeRotationLocked}.
- */
- void pauseRotationLocked() {
- mDeferredRotationPauseCount++;
- }
-
- /**
- * Resumes normal rotation changes after being paused.
- */
- void resumeRotationLocked() {
- if (mDeferredRotationPauseCount <= 0) {
- return;
- }
-
- mDeferredRotationPauseCount--;
- if (mDeferredRotationPauseCount == 0) {
- updateRotationAndSendNewConfigIfNeeded();
- }
- }
-
- /**
- * If this is true we have updated our desired orientation, but not yet changed the real
- * orientation our applied our screen rotation animation. For example, because a previous
- * screen rotation was in progress.
- *
- * @return {@code true} if the there is an ongoing rotation change.
- */
- boolean rotationNeedsUpdate() {
- final int lastOrientation = getLastOrientation();
- final int oldRotation = getRotation();
-
- final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation);
- return oldRotation != rotation;
- }
-
- /**
* The display content may have configuration set from {@link #DisplayWindowSettings}. This
* callback let the owner of container know there is existing configuration to prevent the
* values from being replaced by the initializing {@link #ActivityDisplay}.
@@ -1225,7 +1157,7 @@
configureDisplayPolicy();
setLayoutNeeded();
- boolean configChanged = updateOrientationFromAppTokens();
+ boolean configChanged = updateOrientation();
final Configuration currentDisplayConfig = getConfiguration();
mTmpConfiguration.setTo(currentDisplayConfig);
computeScreenConfiguration(mTmpConfiguration);
@@ -1263,8 +1195,8 @@
@Override
boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
ConfigurationContainer requestingContainer) {
- final Configuration config = updateOrientationFromAppTokens(
- getRequestedOverrideConfiguration(), freezeDisplayToken, false);
+ final Configuration config = updateOrientation(
+ getRequestedOverrideConfiguration(), freezeDisplayToken, false /* forceUpdate */);
// If display rotation class tells us that it doesn't consider app requested orientation,
// this display won't rotate just because of an app changes its requested orientation. Thus
// it indicates that this display chooses not to handle this request.
@@ -1298,31 +1230,35 @@
/**
* Determine the new desired orientation of this display.
*
- * The orientation is computed from non-application windows first. If none of the
- * non-application windows specify orientation, the orientation is computed from application
- * tokens.
- *
- * @return {@code true} if the orientation is changed.
+ * @see #getOrientation()
+ * @return {@code true} if the orientation is changed and the caller should call
+ * {@link #sendNewConfiguration} if the method returns {@code true}.
*/
- boolean updateOrientationFromAppTokens() {
- return updateOrientationFromAppTokens(false /* forceUpdate */);
+ boolean updateOrientation() {
+ return mDisplayRotation.updateOrientation(getOrientation(), false /* forceUpdate */);
}
/**
- * Update orientation of the target display, returning a non-null new Configuration if it has
+ * Update orientation of the display, returning a non-null new Configuration if it has
* changed from the current orientation. If a non-null configuration is returned, someone must
* call {@link WindowManagerService#setNewDisplayOverrideConfiguration(Configuration,
* DisplayContent)} to tell the window manager it can unfreeze the screen. This will typically
- * be done by calling {@link WindowManagerService#sendNewConfiguration(int)}.
+ * be done by calling {@link #sendNewConfiguration}.
+ *
+ * @param currentConfig The current requested override configuration (it is usually set from
+ * the last {@link #sendNewConfiguration}) of the display. It is used to
+ * check if the configuration container has the latest state.
+ * @param freezeDisplayToken Freeze the app window token if the orientation is changed.
+ * @param forceUpdate See {@link DisplayRotation#updateRotationUnchecked(boolean)}
*/
- Configuration updateOrientationFromAppTokens(Configuration currentConfig,
- IBinder freezeDisplayToken, boolean forceUpdate) {
+ Configuration updateOrientation(Configuration currentConfig, IBinder freezeDisplayToken,
+ boolean forceUpdate) {
if (!mDisplayReady) {
return null;
}
Configuration config = null;
- if (updateOrientationFromAppTokens(forceUpdate)) {
+ if (mDisplayRotation.updateOrientation(getOrientation(), forceUpdate)) {
// If we changed the orientation but mOrientationChangeComplete is already true,
// we used seamless rotation, and we don't need to freeze the screen.
if (freezeDisplayToken != null && !mWmService.mRoot.mOrientationChangeComplete) {
@@ -1345,10 +1281,7 @@
if (currentConfig.diff(mTmpConfiguration) != 0) {
mWaitingForConfig = true;
setLayoutNeeded();
- int[] anim = new int[2];
- getDisplayPolicy().selectRotationAnimationLw(anim);
-
- mWmService.startFreezingDisplayLocked(anim[0], anim[1], this);
+ mDisplayRotation.prepareNormalRotationAnimation();
config = new Configuration(mTmpConfiguration);
}
}
@@ -1356,163 +1289,14 @@
return config;
}
-
- private boolean updateOrientationFromAppTokens(boolean forceUpdate) {
- final int req = getOrientation();
- if (req != mLastOrientation || forceUpdate) {
- mLastOrientation = req;
- mDisplayRotation.setCurrentOrientation(req);
- return updateRotationUnchecked(forceUpdate);
- }
- return false;
- }
-
- /**
- * Update rotation of the display and send configuration if the rotation is changed.
- *
- * @return {@code true} if the rotation has been changed and the new config is sent.
- */
- boolean updateRotationAndSendNewConfigIfNeeded() {
- final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
- if (changed) {
- sendNewConfiguration();
- }
- return changed;
- }
-
/**
* Update rotation of the display.
*
* @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
- * {@link WindowManagerService#sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
+ * {@link #sendNewConfiguration} TO UNFREEZE THE SCREEN.
*/
boolean updateRotationUnchecked() {
- return updateRotationUnchecked(false /* forceUpdate */);
- }
-
- /**
- * Update rotation of the DisplayContent with an option to force the update. This updates
- * the container's perception of rotation and, depending on the top activities, will freeze
- * the screen or start seamless rotation. The display itself gets rotated in
- * {@link #applyRotationLocked} during {@link DisplayContent#sendNewConfiguration}.
- *
- * @param forceUpdate Force the rotation update. Sometimes in WM we might skip updating
- * orientation because we're waiting for some rotation to finish or display
- * to unfreeze, which results in configuration of the previously visible
- * activity being applied to a newly visible one. Forcing the rotation
- * update allows to workaround this issue.
- * @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
- * {@link WindowManagerService#sendNewConfiguration(int)} TO COMPLETE THE ROTATION AND
- * UNFREEZE THE SCREEN.
- */
- boolean updateRotationUnchecked(boolean forceUpdate) {
- ScreenRotationAnimation screenRotationAnimation;
- if (!forceUpdate) {
- if (mDeferredRotationPauseCount > 0) {
- // Rotation updates have been paused temporarily. Defer the update until
- // updates have been resumed.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
- return false;
- }
-
- screenRotationAnimation =
- mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
- if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
- // Rotation updates cannot be performed while the previous rotation change
- // animation is still in progress. Skip this update. We will try updating
- // again after the animation is finished and the display is unfrozen.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
- return false;
- }
- if (mWmService.mDisplayFrozen) {
- // Even if the screen rotation animation has finished (e.g. isAnimating
- // returns false), there is still some time where we haven't yet unfrozen
- // the display. We also need to abort rotation here.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
- "Deferring rotation, still finishing previous rotation");
- return false;
- }
- }
-
- if (!mWmService.mDisplayEnabled) {
- // No point choosing a rotation if the display is not enabled.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, display is not enabled.");
- return false;
- }
-
- final int oldRotation = mRotation;
- final int lastOrientation = mLastOrientation;
- final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation);
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Computed rotation=" + rotation + " for display id="
- + mDisplayId + " based on lastOrientation=" + lastOrientation
- + " and oldRotation=" + oldRotation);
- boolean mayRotateSeamlessly = mDisplayPolicy.shouldRotateSeamlessly(mDisplayRotation,
- oldRotation, rotation);
-
- if (mayRotateSeamlessly) {
- final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);
- if (seamlessRotated != null && !forceUpdate) {
- // We can't rotate (seamlessly or not) while waiting for the last seamless rotation
- // to complete (that is, waiting for windows to redraw). It's tempting to check
- // w.mSeamlessRotationCount but that could be incorrect in the case of
- // window-removal.
- return false;
- }
-
- // In the presence of the PINNED stack or System Alert
- // windows we unfortunately can not seamlessly rotate.
- if (hasPinnedStack()) {
- mayRotateSeamlessly = false;
- }
- for (int i = 0; i < mWmService.mSessions.size(); i++) {
- if (mWmService.mSessions.valueAt(i).hasAlertWindowSurfaces()) {
- mayRotateSeamlessly = false;
- break;
- }
- }
- }
- final boolean rotateSeamlessly = mayRotateSeamlessly;
-
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
- + " selected orientation " + lastOrientation
- + ", got rotation " + rotation);
-
- if (oldRotation == rotation) {
- // No change.
- return false;
- }
-
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
- + " rotation changed to " + rotation
- + " from " + oldRotation
- + ", lastOrientation=" + lastOrientation);
-
- if (DisplayContent.deltaRotation(rotation, oldRotation) != 2) {
- mWaitingForConfig = true;
- }
-
- mRotation = rotation;
-
- mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
- mWmService.mH.sendNewMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT,
- this, WINDOW_FREEZE_TIMEOUT_DURATION);
-
- setLayoutNeeded();
- final int[] anim = new int[2];
- mDisplayPolicy.selectRotationAnimationLw(anim);
-
- if (!rotateSeamlessly) {
- mWmService.startFreezingDisplayLocked(anim[0], anim[1], this);
- // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
- } else {
- // The screen rotation animation uses a screenshot to freeze the screen
- // while windows resize underneath.
- // When we are rotating seamlessly, we allow the elements to transition
- // to their rotated state independently and without a freeze required.
- mWmService.startSeamlessRotation();
- }
-
- return true;
+ return mDisplayRotation.updateRotationUnchecked(false /* forceUpdate */);
}
/**
@@ -1523,10 +1307,11 @@
* @param rotation the rotation to apply.
*/
void applyRotationLocked(final int oldRotation, final int rotation) {
- mDisplayRotation.setRotation(rotation);
- final boolean rotateSeamlessly = mWmService.isRotatingSeamlessly();
- ScreenRotationAnimation screenRotationAnimation = rotateSeamlessly
+ mDisplayRotation.applyCurrentRotation(rotation);
+ final boolean rotateSeamlessly = mDisplayRotation.isRotatingSeamlessly();
+ final ScreenRotationAnimation screenRotationAnimation = rotateSeamlessly
? null : mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
+ final Transaction transaction = getPendingTransaction();
// We need to update our screen size information to match the new rotation. If the rotation
// has actually changed then this method will return true and, according to the comment at
// the top of the method, the caller is obligated to call computeNewConfigurationLocked().
@@ -1537,15 +1322,14 @@
// NOTE: We disable the rotation in the emulator because
// it doesn't support hardware OpenGL emulation yet.
if (screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) {
- screenRotationAnimation.setRotation(getPendingTransaction(), rotation);
+ screenRotationAnimation.setRotation(transaction, rotation);
}
forAllWindows(w -> {
- w.seamlesslyRotateIfAllowed(getPendingTransaction(), oldRotation, rotation,
- rotateSeamlessly);
+ w.seamlesslyRotateIfAllowed(transaction, oldRotation, rotation, rotateSeamlessly);
}, true /* traverseTopToBottom */);
- mWmService.mDisplayManagerInternal.performTraversal(getPendingTransaction());
+ mWmService.mDisplayManagerInternal.performTraversal(transaction);
scheduleAnimation();
forAllWindows(w -> {
@@ -1627,19 +1411,20 @@
*/
private DisplayInfo updateDisplayAndOrientation(int uiMode, Configuration outConfig) {
// Use the effective "visual" dimensions based on current rotation
- final boolean rotated = (mRotation == ROTATION_90 || mRotation == ROTATION_270);
+ final int rotation = getRotation();
+ final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
final int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
// Update application display metrics.
- final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(mRotation);
+ final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation);
final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout();
- final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, mRotation, uiMode,
+ final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
displayCutout);
- final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, mRotation, uiMode,
+ final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
displayCutout);
- mDisplayInfo.rotation = mRotation;
+ mDisplayInfo.rotation = rotation;
mDisplayInfo.logicalWidth = dw;
mDisplayInfo.logicalHeight = dh;
mDisplayInfo.logicalDensityDpi = mBaseDisplayDensity;
@@ -2044,7 +1829,7 @@
return mTaskStackContainers.getPinnedStack();
}
- private boolean hasPinnedStack() {
+ boolean hasPinnedStack() {
return mTaskStackContainers.getPinnedStack() != null;
}
@@ -2198,6 +1983,11 @@
return mImeWindowsContainers.forAllWindows(callback, traverseTopToBottom);
}
+ /**
+ * In the general case, the orientation is computed from the above app windows first. If none of
+ * the above app windows specify orientation, the orientation is computed from the child window
+ * container, e.g. {@link AppWindowToken#getOrientation(int)}.
+ */
@Override
int getOrientation() {
final WindowManagerPolicy policy = mWmService.mPolicy;
@@ -2222,8 +2012,8 @@
// things aren't stable while the display is frozen, for example the window could be
// momentarily unavailable due to activity relaunch.
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
- + " is frozen while keyguard locked, return " + mLastOrientation);
- return mLastOrientation;
+ + " is frozen while keyguard locked, return " + getLastOrientation());
+ return getLastOrientation();
}
} else {
final int orientation = mAboveAppWindowsContainers.getOrientation();
@@ -2835,7 +2625,7 @@
}
proto.write(DPI, mBaseDisplayDensity);
mDisplayInfo.writeToProto(proto, DISPLAY_INFO);
- proto.write(ROTATION, mRotation);
+ proto.write(ROTATION, getRotation());
final ScreenRotationAnimation screenRotationAnimation =
mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
if (screenRotationAnimation != null) {
@@ -2892,8 +2682,6 @@
pw.println();
pw.print(prefix); pw.print("mLayoutSeq="); pw.println(mLayoutSeq);
- pw.print(prefix);
- pw.print("mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
pw.print(" mCurrentFocus="); pw.println(mCurrentFocus);
if (mLastFocus != mCurrentFocus) {
@@ -3264,6 +3052,15 @@
return mTmpWindow != null;
}
+ boolean hasAlertWindowSurfaces() {
+ for (int i = mWmService.mSessions.size() - 1; i >= 0; --i) {
+ if (mWmService.mSessions.valueAt(i).hasAlertWindowSurfaces(this)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Set input method window for the display.
* @param win Set when window added or Null when destroyed.
@@ -3747,7 +3544,7 @@
if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
- if (updateOrientationFromAppTokens()) {
+ if (updateOrientation()) {
setLayoutNeeded();
sendNewConfiguration();
}
@@ -3887,7 +3684,7 @@
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
// TODO: Not sure if we really need to set the rotation here since we are updating from
// the display info above...
- mDisplayFrames.mRotation = mRotation;
+ mDisplayFrames.mRotation = getRotation();
mDisplayPolicy.beginLayoutLw(mDisplayFrames, getConfiguration().uiMode);
int seq = mLayoutSeq + 1;
@@ -4002,25 +3799,6 @@
}
}
- void onSeamlessRotationTimeout() {
- // Used to indicate the layout is needed.
- mTmpWindow = null;
-
- forAllWindows(w -> {
- if (!w.mSeamlesslyRotated) {
- return;
- }
- mTmpWindow = w;
- w.setDisplayLayoutNeeded();
- w.finishSeamlessRotation(true /* timeout */);
- mWmService.markForSeamlessRotation(w, false);
- }, true /* traverseTopToBottom */);
-
- if (mTmpWindow != null) {
- mWmService.mWindowPlacerLocked.performSurfacePlacement();
- }
- }
-
void setExitingTokensHasVisible(boolean hasVisible) {
for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
mExitingTokens.get(i).hasVisible = hasVisible;
@@ -4502,11 +4280,11 @@
}
if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
- "No app is requesting an orientation, return " + mLastOrientation
+ "No app is requesting an orientation, return " + getLastOrientation()
+ " for display id=" + mDisplayId);
// The next app has not been requested to be visible, so we keep the current orientation
// to prevent freezing/unfreezing the display too early.
- return mLastOrientation;
+ return getLastOrientation();
}
@Override
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index e5962ae..8328770 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -57,10 +57,6 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
@@ -257,7 +253,6 @@
private volatile boolean mNavigationBarCanMove;
private volatile boolean mNavigationBarLetsThroughTaps;
private volatile boolean mNavigationBarAlwaysShowOnSideGesture;
- private volatile boolean mAllowSeamlessRotationDespiteNavBarMoving;
// Written by vr manager thread, only read in this class.
private volatile boolean mPersistentVrModeEnabled;
@@ -1151,81 +1146,6 @@
}
/**
- * Determine the animation to run for a rotation transition based on the
- * top fullscreen windows {@link WindowManager.LayoutParams#rotationAnimation}
- * and whether it is currently fullscreen and frontmost.
- *
- * @param anim The exiting animation resource id is stored in anim[0], the
- * entering animation resource id is stored in anim[1].
- */
- public void selectRotationAnimationLw(int anim[]) {
- // If the screen is off or non-interactive, force a jumpcut.
- final boolean forceJumpcut = !mScreenOnFully || !mService.mPolicy.okToAnimate();
- if (DEBUG_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen="
- + mTopFullscreenOpaqueWindowState + " rotationAnimation="
- + (mTopFullscreenOpaqueWindowState == null
- ? "0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation)
- + " forceJumpcut=" + forceJumpcut);
- if (forceJumpcut) {
- anim[0] = R.anim.rotation_animation_jump_exit;
- anim[1] = R.anim.rotation_animation_enter;
- return;
- }
- if (mTopFullscreenOpaqueWindowState != null) {
- int animationHint = mTopFullscreenOpaqueWindowState.getRotationAnimationHint();
- if (animationHint < 0 && mTopIsFullscreen) {
- animationHint = mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation;
- }
- switch (animationHint) {
- case ROTATION_ANIMATION_CROSSFADE:
- case ROTATION_ANIMATION_SEAMLESS: // Crossfade is fallback for seamless.
- anim[0] = R.anim.rotation_animation_xfade_exit;
- anim[1] = R.anim.rotation_animation_enter;
- break;
- case ROTATION_ANIMATION_JUMPCUT:
- anim[0] = R.anim.rotation_animation_jump_exit;
- anim[1] = R.anim.rotation_animation_enter;
- break;
- case ROTATION_ANIMATION_ROTATE:
- default:
- anim[0] = anim[1] = 0;
- break;
- }
- } else {
- anim[0] = anim[1] = 0;
- }
- }
-
- /**
- * Validate whether the current top fullscreen has specified the same
- * {@link WindowManager.LayoutParams#rotationAnimation} value as that
- * being passed in from the previous top fullscreen window.
- *
- * @param exitAnimId exiting resource id from the previous window.
- * @param enterAnimId entering resource id from the previous window.
- * @param forceDefault For rotation animations only, if true ignore the
- * animation values and just return false.
- * @return true if the previous values are still valid, false if they
- * should be replaced with the default.
- */
- public boolean validateRotationAnimationLw(int exitAnimId, int enterAnimId,
- boolean forceDefault) {
- switch (exitAnimId) {
- case R.anim.rotation_animation_xfade_exit:
- case R.anim.rotation_animation_jump_exit:
- // These are the only cases that matter.
- if (forceDefault) {
- return false;
- }
- int anim[] = new int[2];
- selectRotationAnimationLw(anim);
- return (exitAnimId == anim[0] && enterAnimId == anim[1]);
- default:
- return true;
- }
- }
-
- /**
* Called when a new system UI visibility is being reported, allowing
* the policy to adjust what is actually reported.
* @param visibility The raw visibility reported by the status bar.
@@ -2388,6 +2308,14 @@
displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);
}
+ WindowState getTopFullscreenOpaqueWindow() {
+ return mTopFullscreenOpaqueWindowState;
+ }
+
+ boolean isTopLayoutFullscreen() {
+ return mTopIsFullscreen;
+ }
+
/**
* Called following layout of all windows before each window has policy applied.
*/
@@ -2773,8 +2701,7 @@
mNavigationBarCanMove =
mDisplayContent.mBaseDisplayWidth != mDisplayContent.mBaseDisplayHeight
&& res.getBoolean(R.bool.config_navBarCanMove);
- mAllowSeamlessRotationDespiteNavBarMoving =
- res.getBoolean(R.bool.config_allowSeamlessRotationDespiteNavBarMoving);
+ mDisplayContent.getDisplayRotation().updateUserDependentConfiguration(res);
}
/**
@@ -3562,45 +3489,6 @@
return (systemUiFlags & disableNavigationBar) == disableNavigationBar;
}
- boolean shouldRotateSeamlessly(DisplayRotation displayRotation, int oldRotation,
- int newRotation) {
- // For the upside down rotation we don't rotate seamlessly as the navigation
- // bar moves position.
- // Note most apps (using orientation:sensor or user as opposed to fullSensor)
- // will not enter the reverse portrait orientation, so actually the
- // orientation won't change at all.
- if (oldRotation == displayRotation.getUpsideDownRotation()
- || newRotation == displayRotation.getUpsideDownRotation()) {
- return false;
- }
- // If the navigation bar can't change sides, then it will
- // jump when we change orientations and we don't rotate
- // seamlessly - unless that is allowed, eg. with gesture
- // navigation where the navbar is low-profile enough that this isn't very noticeable.
- if (!navigationBarCanMove() && !mAllowSeamlessRotationDespiteNavBarMoving) {
- return false;
- }
-
- final WindowState w = mTopFullscreenOpaqueWindowState;
- if (w == null || w != mFocusedWindow) {
- return false;
- }
- // If the bounds of activity window is different from its parent, then reject to be seamless
- // because the window position may change after rotation that will look like a sudden jump.
- if (w.mAppToken != null && !w.mAppToken.matchParentBounds()) {
- return false;
- }
-
- // We only enable seamless rotation if the top window has requested
- // it and is in the fullscreen opaque state. Seamless rotation
- // requires freezing various Surface states and won't work well
- // with animations, so we disable it in the animation case for now.
- if (!w.isAnimatingLw() && w.getAttrs().rotationAnimation == ROTATION_ANIMATION_SEAMLESS) {
- return true;
- }
- return false;
- }
-
private final Runnable mHiddenNavPanic = new Runnable() {
@Override
public void run() {
@@ -3665,7 +3553,7 @@
}
void dump(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("DisplayPolicy");
+ pw.print(prefix); pw.println("DisplayPolicy");
prefix += " ";
pw.print(prefix);
pw.print("mCarDockEnablesAccelerometer="); pw.print(mCarDockEnablesAccelerometer);
@@ -3724,12 +3612,12 @@
pw.print(prefix); pw.print("mForcingShowNavBarLayer=");
pw.println(mForcingShowNavBarLayer);
}
- pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);
+ pw.print(prefix); pw.print("mTopIsFullscreen="); pw.println(mTopIsFullscreen);
pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
pw.print(" mForceStatusBarFromKeyguard="); pw.println(mForceStatusBarFromKeyguard);
- pw.print(" mForceShowSystemBarsFromExternal=");
- pw.println(mForceShowSystemBarsFromExternal);
- pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn);
+ pw.print(prefix); pw.print("mForceShowSystemBarsFromExternal=");
+ pw.print(mForceShowSystemBarsFromExternal);
+ pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn);
mStatusBarController.dump(pw, prefix);
mNavigationBarController.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 410cc94..4d188f4 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -16,11 +16,21 @@
package com.android.server.wm;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
+
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_ACTIVE;
+import static com.android.server.wm.WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION;
+import android.annotation.AnimRes;
import android.annotation.IntDef;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -28,6 +38,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -41,6 +52,7 @@
import android.util.SparseArray;
import android.view.Surface;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.UiThread;
@@ -59,6 +71,13 @@
public class DisplayRotation {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayRotation" : TAG_WM;
+ private static class RotationAnimationPair {
+ @AnimRes
+ int mEnter;
+ @AnimRes
+ int mExit;
+ }
+
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
private final DisplayPolicy mDisplayPolicy;
@@ -72,12 +91,30 @@
private final int mCarDockRotation;
private final int mDeskDockRotation;
private final int mUndockedHdmiRotation;
+ private final RotationAnimationPair mTmpRotationAnim = new RotationAnimationPair();
private OrientationListener mOrientationListener;
private StatusBarManagerInternal mStatusBarManagerInternal;
private SettingsObserver mSettingsObserver;
- private int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ @ScreenOrientation
+ private int mCurrentAppOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
+ /**
+ * Last applied orientation of the display.
+ *
+ * @see #updateOrientationFromApp
+ */
+ @ScreenOrientation
+ private int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
+ /**
+ * Current rotation of the display.
+ *
+ * @see #updateRotationUnchecked
+ */
+ @Surface.Rotation
+ private int mRotation;
@VisibleForTesting
int mLandscapeRotation; // default landscape
@@ -88,11 +125,52 @@
@VisibleForTesting
int mUpsideDownRotation; // "other" portrait
- // Behavior of rotation suggestions. (See Settings.Secure.SHOW_ROTATION_SUGGESTION)
+ private boolean mAllowSeamlessRotationDespiteNavBarMoving;
+
+ private int mDeferredRotationPauseCount;
+
+ /**
+ * A count of the windows which are 'seamlessly rotated', e.g. a surface at an old orientation
+ * is being transformed. We freeze orientation updates while any windows are seamlessly rotated,
+ * so we need to track when this hits zero so we can apply deferred orientation updates.
+ */
+ private int mSeamlessRotationCount;
+
+ /**
+ * True in the interval from starting seamless rotation until the last rotated window draws in
+ * the new orientation.
+ */
+ private boolean mRotatingSeamlessly;
+
+ /**
+ * Behavior of rotation suggestions.
+ *
+ * @see Settings.Secure#SHOW_ROTATION_SUGGESTIONS
+ */
private int mShowRotationSuggestions;
- private int mAllowAllRotations = -1;
+ private static final int ALLOW_ALL_ROTATIONS_UNDEFINED = -1;
+ private static final int ALLOW_ALL_ROTATIONS_DISABLED = 0;
+ private static final int ALLOW_ALL_ROTATIONS_ENABLED = 1;
+
+ @IntDef({ ALLOW_ALL_ROTATIONS_UNDEFINED, ALLOW_ALL_ROTATIONS_DISABLED,
+ ALLOW_ALL_ROTATIONS_ENABLED })
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface AllowAllRotations {}
+
+ /**
+ * Whether to allow the screen to rotate to all rotations (including 180 degree) according to
+ * the sensor even when the current orientation is not
+ * {@link ActivityInfo#SCREEN_ORIENTATION_FULL_SENSOR} or
+ * {@link ActivityInfo#SCREEN_ORIENTATION_FULL_USER}.
+ */
+ @AllowAllRotations
+ private int mAllowAllRotations = ALLOW_ALL_ROTATIONS_UNDEFINED;
+
+ @WindowManagerPolicy.UserRotationMode
private int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+
+ @Surface.Rotation
private int mUserRotation = Surface.ROTATION_0;
/**
@@ -125,6 +203,7 @@
* regardless of all other states (including app requrested orientation). {@code true} the
* display rotation should be fixed to user specified rotation, {@code false} otherwise.
*/
+ @FixedToUserRotation
private int mFixedToUserRotation = FIXED_TO_USER_ROTATION_DEFAULT;
private int mDemoHdmiRotation;
@@ -149,21 +228,17 @@
mLock = lock;
isDefaultDisplay = displayContent.isDefaultDisplay;
- mSupportAutoRotation = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_supportAutoRotation);
- mLidOpenRotation = readRotation(
- com.android.internal.R.integer.config_lidOpenRotation);
- mCarDockRotation = readRotation(
- com.android.internal.R.integer.config_carDockRotation);
- mDeskDockRotation = readRotation(
- com.android.internal.R.integer.config_deskDockRotation);
- mUndockedHdmiRotation = readRotation(
- com.android.internal.R.integer.config_undockedHdmiRotation);
+ mSupportAutoRotation =
+ mContext.getResources().getBoolean(R.bool.config_supportAutoRotation);
+ mLidOpenRotation = readRotation(R.integer.config_lidOpenRotation);
+ mCarDockRotation = readRotation(R.integer.config_carDockRotation);
+ mDeskDockRotation = readRotation(R.integer.config_deskDockRotation);
+ mUndockedHdmiRotation = readRotation(R.integer.config_undockedHdmiRotation);
if (isDefaultDisplay) {
final Handler uiHandler = UiThread.getHandler();
mOrientationListener = new OrientationListener(mContext, uiHandler);
- mOrientationListener.setCurrentRotation(displayContent.getRotation());
+ mOrientationListener.setCurrentRotation(mRotation);
mSettingsObserver = new SettingsObserver(uiHandler);
mSettingsObserver.observe();
}
@@ -188,12 +263,21 @@
return -1;
}
+ /**
+ * Updates the configuration which may have different values depending on current user, e.g.
+ * runtime resource overlay.
+ */
+ void updateUserDependentConfiguration(Resources currentUserRes) {
+ mAllowSeamlessRotationDespiteNavBarMoving =
+ currentUserRes.getBoolean(R.bool.config_allowSeamlessRotationDespiteNavBarMoving);
+ }
+
void configure(int width, int height, int shortSizeDp, int longSizeDp) {
final Resources res = mContext.getResources();
if (width > height) {
mLandscapeRotation = Surface.ROTATION_0;
mSeascapeRotation = Surface.ROTATION_180;
- if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
+ if (res.getBoolean(R.bool.config_reverseDefaultRotation)) {
mPortraitRotation = Surface.ROTATION_90;
mUpsideDownRotation = Surface.ROTATION_270;
} else {
@@ -203,7 +287,7 @@
} else {
mPortraitRotation = Surface.ROTATION_0;
mUpsideDownRotation = Surface.ROTATION_180;
- if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
+ if (res.getBoolean(R.bool.config_reverseDefaultRotation)) {
mLandscapeRotation = Surface.ROTATION_270;
mSeascapeRotation = Surface.ROTATION_90;
} else {
@@ -246,19 +330,325 @@
&& !"true".equals(SystemProperties.get("config.override_forced_orient"));
}
- void setRotation(int rotation) {
+ void applyCurrentRotation(@Surface.Rotation int rotation) {
if (mOrientationListener != null) {
mOrientationListener.setCurrentRotation(rotation);
}
}
- void setCurrentOrientation(int newOrientation) {
+ @VisibleForTesting
+ void setRotation(@Surface.Rotation int rotation) {
+ mRotation = rotation;
+ }
+
+ @Surface.Rotation
+ int getRotation() {
+ return mRotation;
+ }
+
+ @ScreenOrientation
+ int getLastOrientation() {
+ return mLastOrientation;
+ }
+
+ boolean updateOrientation(@ScreenOrientation int newOrientation, boolean forceUpdate) {
+ if (newOrientation == mLastOrientation && !forceUpdate) {
+ return false;
+ }
+ mLastOrientation = newOrientation;
if (newOrientation != mCurrentAppOrientation) {
mCurrentAppOrientation = newOrientation;
if (isDefaultDisplay) {
updateOrientationListenerLw();
}
}
+ return updateRotationUnchecked(forceUpdate);
+ }
+
+ /**
+ * Update rotation of the display and send configuration if the rotation is changed.
+ *
+ * @return {@code true} if the rotation has been changed and the new config is sent.
+ */
+ boolean updateRotationAndSendNewConfigIfChanged() {
+ final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
+ if (changed) {
+ mDisplayContent.sendNewConfiguration();
+ }
+ return changed;
+ }
+
+ /**
+ * Update rotation with an option to force the update. This updates the container's perception
+ * of rotation and, depending on the top activities, will freeze the screen or start seamless
+ * rotation. The display itself gets rotated in {@link DisplayContent#applyRotationLocked}
+ * during {@link DisplayContent#sendNewConfiguration}.
+ *
+ * @param forceUpdate Force the rotation update. Sometimes in WM we might skip updating
+ * orientation because we're waiting for some rotation to finish or display
+ * to unfreeze, which results in configuration of the previously visible
+ * activity being applied to a newly visible one. Forcing the rotation
+ * update allows to workaround this issue.
+ * @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
+ * {@link DisplayContent#sendNewConfiguration} TO COMPLETE THE ROTATION AND UNFREEZE
+ * THE SCREEN.
+ */
+ boolean updateRotationUnchecked(boolean forceUpdate) {
+ final int displayId = mDisplayContent.getDisplayId();
+ if (!forceUpdate) {
+ if (mDeferredRotationPauseCount > 0) {
+ // Rotation updates have been paused temporarily. Defer the update until updates
+ // have been resumed.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
+ return false;
+ }
+
+ final ScreenRotationAnimation screenRotationAnimation =
+ mService.mAnimator.getScreenRotationAnimationLocked(displayId);
+ if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
+ // Rotation updates cannot be performed while the previous rotation change animation
+ // is still in progress. Skip this update. We will try updating again after the
+ // animation is finished and the display is unfrozen.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
+ return false;
+ }
+ if (mService.mDisplayFrozen) {
+ // Even if the screen rotation animation has finished (e.g. isAnimating returns
+ // false), there is still some time where we haven't yet unfrozen the display. We
+ // also need to abort rotation here.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+ "Deferring rotation, still finishing previous rotation");
+ return false;
+ }
+ }
+
+ if (!mService.mDisplayEnabled) {
+ // No point choosing a rotation if the display is not enabled.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, display is not enabled.");
+ return false;
+ }
+
+ final int oldRotation = mRotation;
+ final int lastOrientation = mLastOrientation;
+ final int rotation = rotationForOrientation(lastOrientation, oldRotation);
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Computed rotation=" + rotation + " for display id="
+ + displayId + " based on lastOrientation=" + lastOrientation
+ + " and oldRotation=" + oldRotation);
+
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + displayId
+ + " selected orientation " + lastOrientation
+ + ", got rotation " + rotation);
+
+ if (oldRotation == rotation) {
+ // No change.
+ return false;
+ }
+
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + displayId
+ + " rotation changed to " + rotation
+ + " from " + oldRotation
+ + ", lastOrientation=" + lastOrientation);
+
+ if (DisplayContent.deltaRotation(rotation, oldRotation) != 2) {
+ mDisplayContent.mWaitingForConfig = true;
+ }
+
+ mRotation = rotation;
+
+ mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
+ mService.mH.sendNewMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT,
+ mDisplayContent, WINDOW_FREEZE_TIMEOUT_DURATION);
+
+ mDisplayContent.setLayoutNeeded();
+
+ if (shouldRotateSeamlessly(oldRotation, rotation, forceUpdate)) {
+ // The screen rotation animation uses a screenshot to freeze the screen while windows
+ // resize underneath. When we are rotating seamlessly, we allow the elements to
+ // transition to their rotated state independently and without a freeze required.
+ prepareSeamlessRotation();
+ } else {
+ prepareNormalRotationAnimation();
+ }
+
+ return true;
+ }
+
+ void prepareNormalRotationAnimation() {
+ final RotationAnimationPair anim = selectRotationAnimation();
+ mService.startFreezingDisplayLocked(anim.mExit, anim.mEnter, mDisplayContent);
+ }
+
+ private void prepareSeamlessRotation() {
+ // We are careful to reset this in case a window was removed before it finished
+ // seamless rotation.
+ mSeamlessRotationCount = 0;
+ mRotatingSeamlessly = true;
+ }
+
+ boolean isRotatingSeamlessly() {
+ return mRotatingSeamlessly;
+ }
+
+ @VisibleForTesting
+ boolean shouldRotateSeamlessly(int oldRotation, int newRotation, boolean forceUpdate) {
+ final WindowState w = mDisplayPolicy.getTopFullscreenOpaqueWindow();
+ if (w == null || w != mDisplayContent.mCurrentFocus) {
+ return false;
+ }
+ // We only enable seamless rotation if the top window has requested it and is in the
+ // fullscreen opaque state. Seamless rotation requires freezing various Surface states and
+ // won't work well with animations, so we disable it in the animation case for now.
+ if (w.getAttrs().rotationAnimation != ROTATION_ANIMATION_SEAMLESS || w.isAnimatingLw()) {
+ return false;
+ }
+
+ // For the upside down rotation we don't rotate seamlessly as the navigation bar moves
+ // position. Note most apps (using orientation:sensor or user as opposed to fullSensor)
+ // will not enter the reverse portrait orientation, so actually the orientation won't change
+ // at all.
+ if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) {
+ return false;
+ }
+
+ // If the navigation bar can't change sides, then it will jump when we change orientations
+ // and we don't rotate seamlessly - unless that is allowed, eg. with gesture navigation
+ // where the navbar is low-profile enough that this isn't very noticeable.
+ if (!mAllowSeamlessRotationDespiteNavBarMoving && !mDisplayPolicy.navigationBarCanMove()) {
+ return false;
+ }
+
+ // If the bounds of activity window is different from its parent, then reject to be seamless
+ // because the window position may change after rotation that will look like a sudden jump.
+ if (w.mAppToken != null && !w.mAppToken.matchParentBounds()) {
+ return false;
+ }
+
+ // In the presence of the PINNED stack or System Alert windows we unfortunately can not
+ // seamlessly rotate.
+ if (mDisplayContent.hasPinnedStack() || mDisplayContent.hasAlertWindowSurfaces()) {
+ return false;
+ }
+
+ // We can't rotate (seamlessly or not) while waiting for the last seamless rotation to
+ // complete (that is, waiting for windows to redraw). It's tempting to check
+ // mSeamlessRotationCount but that could be incorrect in the case of window-removal.
+ if (!forceUpdate && mDisplayContent.getWindow(win -> win.mSeamlesslyRotated) != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) {
+ if (seamlesslyRotated == w.mSeamlesslyRotated || w.mForceSeamlesslyRotate) {
+ return;
+ }
+
+ w.mSeamlesslyRotated = seamlesslyRotated;
+ if (seamlesslyRotated) {
+ mSeamlessRotationCount++;
+ } else {
+ mSeamlessRotationCount--;
+ }
+ if (mSeamlessRotationCount == 0) {
+ if (DEBUG_ORIENTATION) {
+ Slog.i(TAG, "Performing post-rotate rotation after seamless rotation");
+ }
+ // Finish seamless rotation.
+ mRotatingSeamlessly = false;
+
+ updateRotationAndSendNewConfigIfChanged();
+ }
+ }
+
+ void onSeamlessRotationTimeout() {
+ final boolean[] isLayoutNeeded = { false };
+
+ mDisplayContent.forAllWindows(w -> {
+ if (!w.mSeamlesslyRotated) {
+ return;
+ }
+ isLayoutNeeded[0] = true;
+ w.setDisplayLayoutNeeded();
+ w.finishSeamlessRotation(true /* timeout */);
+ markForSeamlessRotation(w, false /* seamlesslyRotated */);
+ }, true /* traverseTopToBottom */);
+
+ if (isLayoutNeeded[0]) {
+ mService.mWindowPlacerLocked.performSurfacePlacement();
+ }
+ }
+
+ /**
+ * Returns the animation to run for a rotation transition based on the top fullscreen windows
+ * {@link android.view.WindowManager.LayoutParams#rotationAnimation} and whether it is currently
+ * fullscreen and frontmost.
+ */
+ private RotationAnimationPair selectRotationAnimation() {
+ // If the screen is off or non-interactive, force a jumpcut.
+ final boolean forceJumpcut = !mDisplayPolicy.isScreenOnFully()
+ || !mService.mPolicy.okToAnimate();
+ final WindowState topFullscreen = mDisplayPolicy.getTopFullscreenOpaqueWindow();
+ if (DEBUG_ANIM) Slog.i(TAG, "selectRotationAnimation topFullscreen="
+ + topFullscreen + " rotationAnimation="
+ + (topFullscreen == null ? 0 : topFullscreen.getAttrs().rotationAnimation)
+ + " forceJumpcut=" + forceJumpcut);
+ if (forceJumpcut) {
+ mTmpRotationAnim.mExit = R.anim.rotation_animation_jump_exit;
+ mTmpRotationAnim.mEnter = R.anim.rotation_animation_enter;
+ return mTmpRotationAnim;
+ }
+ if (topFullscreen != null) {
+ int animationHint = topFullscreen.getRotationAnimationHint();
+ if (animationHint < 0 && mDisplayPolicy.isTopLayoutFullscreen()) {
+ animationHint = topFullscreen.getAttrs().rotationAnimation;
+ }
+ switch (animationHint) {
+ case ROTATION_ANIMATION_CROSSFADE:
+ case ROTATION_ANIMATION_SEAMLESS: // Crossfade is fallback for seamless.
+ mTmpRotationAnim.mExit = R.anim.rotation_animation_xfade_exit;
+ mTmpRotationAnim.mEnter = R.anim.rotation_animation_enter;
+ break;
+ case ROTATION_ANIMATION_JUMPCUT:
+ mTmpRotationAnim.mExit = R.anim.rotation_animation_jump_exit;
+ mTmpRotationAnim.mEnter = R.anim.rotation_animation_enter;
+ break;
+ case ROTATION_ANIMATION_ROTATE:
+ default:
+ mTmpRotationAnim.mExit = mTmpRotationAnim.mEnter = 0;
+ break;
+ }
+ } else {
+ mTmpRotationAnim.mExit = mTmpRotationAnim.mEnter = 0;
+ }
+ return mTmpRotationAnim;
+ }
+
+ /**
+ * Validate whether the current top fullscreen has specified the same
+ * {@link android.view.WindowManager.LayoutParams#rotationAnimation} value as that being passed
+ * in from the previous top fullscreen window.
+ *
+ * @param exitAnimId exiting resource id from the previous window.
+ * @param enterAnimId entering resource id from the previous window.
+ * @param forceDefault For rotation animations only, if true ignore the animation values and
+ * just return false.
+ * @return {@code true} if the previous values are still valid, false if they should be replaced
+ * with the default.
+ */
+ boolean validateRotationAnimation(int exitAnimId, int enterAnimId, boolean forceDefault) {
+ switch (exitAnimId) {
+ case R.anim.rotation_animation_xfade_exit:
+ case R.anim.rotation_animation_jump_exit:
+ // These are the only cases that matter.
+ if (forceDefault) {
+ return false;
+ }
+ final RotationAnimationPair anim = selectRotationAnimation();
+ return exitAnimId == anim.mExit && enterAnimId == anim.mEnter;
+ default:
+ return true;
+ }
}
void restoreSettings(int userRotationMode, int userRotation,
@@ -327,7 +717,7 @@
}
void freezeRotation(int rotation) {
- rotation = (rotation == -1) ? mDisplayContent.getRotation() : rotation;
+ rotation = (rotation == -1) ? mRotation : rotation;
setUserRotation(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation);
}
@@ -407,6 +797,30 @@
}
/**
+ * Temporarily pauses rotation changes until resumed.
+ * <p>
+ * This can be used to prevent rotation changes from occurring while the user is performing
+ * certain operations, such as drag and drop.
+ * <p>
+ * This call nests and must be matched by an equal number of calls to {@link #resume}.
+ */
+ void pause() {
+ mDeferredRotationPauseCount++;
+ }
+
+ /** Resumes normal rotation changes after being paused. */
+ void resume() {
+ if (mDeferredRotationPauseCount <= 0) {
+ return;
+ }
+
+ mDeferredRotationPauseCount--;
+ if (mDeferredRotationPauseCount == 0) {
+ updateRotationAndSendNewConfigIfChanged();
+ }
+ }
+
+ /**
* Various use cases for invoking this function:
* <li>Screen turning off, should always disable listeners if already enabled.</li>
* <li>Screen turned on and current app has sensor based orientation, enable listeners
@@ -515,14 +929,28 @@
}
/**
- * Given an orientation constant, returns the appropriate surface rotation,
- * taking into account sensors, docking mode, rotation lock, and other factors.
+ * If this is true we have updated our desired orientation, but not yet changed the real
+ * orientation our applied our screen rotation animation. For example, because a previous
+ * screen rotation was in progress.
+ *
+ * @return {@code true} if the there is an ongoing rotation change.
+ */
+ boolean needsUpdate() {
+ final int oldRotation = mRotation;
+ final int rotation = rotationForOrientation(mLastOrientation, oldRotation);
+ return oldRotation != rotation;
+ }
+
+ /**
+ * Given an orientation constant, returns the appropriate surface rotation, taking into account
+ * sensors, docking mode, rotation lock, and other factors.
*
* @param orientation An orientation constant, such as
- * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
+ * {@link ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
* @param lastRotation The most recently used rotation.
* @return The surface rotation to use.
*/
+ @VisibleForTesting
int rotationForOrientation(int orientation, int lastRotation) {
if (DEBUG_ORIENTATION) {
Slog.v(TAG, "rotationForOrientation(orient="
@@ -614,15 +1042,16 @@
|| orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
// Otherwise, use sensor only if requested by the application or enabled
// by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR.
- if (mAllowAllRotations < 0) {
- // Can't read this during init() because the context doesn't
- // have display metrics at that time so we cannot determine
- // tablet vs. phone then.
+ if (mAllowAllRotations == ALLOW_ALL_ROTATIONS_UNDEFINED) {
+ // Can't read this during init() because the context doesn't have display metrics at
+ // that time so we cannot determine tablet vs. phone then.
mAllowAllRotations = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
+ R.bool.config_allowAllRotations)
+ ? ALLOW_ALL_ROTATIONS_ENABLED
+ : ALLOW_ALL_ROTATIONS_DISABLED;
}
if (sensorRotation != Surface.ROTATION_180
- || mAllowAllRotations == 1
+ || mAllowAllRotations == ALLOW_ALL_ROTATIONS_ENABLED
|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
preferredRotation = sensorRotation;
@@ -883,6 +1312,10 @@
pw.println(prefix + "DisplayRotation");
pw.println(prefix + " mCurrentAppOrientation="
+ ActivityInfo.screenOrientationToString(mCurrentAppOrientation));
+ pw.println(prefix + " mLastOrientation=" + mLastOrientation);
+ pw.print(prefix + " mRotation=" + mRotation);
+ pw.println(" mDeferredRotationPauseCount=" + mDeferredRotationPauseCount);
+
pw.print(prefix + " mLandscapeRotation=" + Surface.rotationToString(mLandscapeRotation));
pw.println(" mSeascapeRotation=" + Surface.rotationToString(mSeascapeRotation));
pw.print(prefix + " mPortraitRotation=" + Surface.rotationToString(mPortraitRotation));
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index c8f7af5..c48f07c 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -305,7 +305,7 @@
if (DEBUG_ORIENTATION) {
Slog.d(TAG_WM, "Pausing rotation during drag");
}
- mDisplayContent.pauseRotationLocked();
+ mDisplayContent.getDisplayRotation().pause();
}
void tearDown() {
@@ -324,7 +324,7 @@
if (DEBUG_ORIENTATION) {
Slog.d(TAG_WM, "Resuming rotation after drag");
}
- mDisplayContent.resumeRotationLocked();
+ mDisplayContent.getDisplayRotation().resume();
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 402ec59..b7835aa 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -106,6 +106,11 @@
@Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider) {
if (mWin != null) {
mWin.setInsetProvider(null);
+ // The window may be animating such that we can hand out the leash to the control
+ // target. Revoke the leash by cancelling the animation to correct the state.
+ // TODO: Ideally, we should wait for the animation to finish so previous window can
+ // animate-out as new one animates-in.
+ mWin.cancelAnimation();
}
mWin = win;
mFrameProvider = frameProvider;
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 3401de6..eb5d096 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -636,7 +636,7 @@
final DisplayContent displayContent = mRootWindowContainer.getDisplayContent(displayId);
Configuration config = null;
if (displayContent != null) {
- config = displayContent.updateOrientationFromAppTokens(
+ config = displayContent.updateOrientation(
getDisplayOverrideConfiguration(displayId),
starting != null && starting.mayFreezeScreenLocked(starting.app)
? starting.appToken : null,
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a00bee0..968d02b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -925,8 +925,7 @@
boolean updateRotationUnchecked() {
boolean changed = false;
for (int i = mChildren.size() - 1; i >= 0; i--) {
- final DisplayContent displayContent = mChildren.get(i);
- if (displayContent.updateRotationAndSendNewConfigIfNeeded()) {
+ if (mChildren.get(i).getDisplayRotation().updateRotationAndSendNewConfigIfChanged()) {
changed = true;
}
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 9f8f265..4a76042 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -40,6 +40,7 @@
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
+import android.util.ArraySet;
import android.util.MergedConfiguration;
import android.util.Slog;
import android.view.DisplayCutout;
@@ -57,9 +58,7 @@
import com.android.server.wm.WindowManagerService.H;
import java.io.PrintWriter;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.function.BiConsumer;
/**
@@ -75,9 +74,9 @@
SurfaceSession mSurfaceSession;
private int mNumWindow = 0;
// Set of visible application overlay window surfaces connected to this session.
- private final Set<WindowSurfaceController> mAppOverlaySurfaces = new HashSet<>();
+ private final ArraySet<WindowSurfaceController> mAppOverlaySurfaces = new ArraySet<>();
// Set of visible alert window surfaces connected to this session.
- private final Set<WindowSurfaceController> mAlertWindowSurfaces = new HashSet<>();
+ private final ArraySet<WindowSurfaceController> mAlertWindowSurfaces = new ArraySet<>();
private final DragDropController mDragDropController;
final boolean mCanAddInternalSystemWindow;
final boolean mCanHideNonSystemOverlayWindows;
@@ -609,8 +608,15 @@
return mStringName;
}
- boolean hasAlertWindowSurfaces() {
- return !mAlertWindowSurfaces.isEmpty();
+ /** @return {@code true} if there is an alert window surface on the given display. */
+ boolean hasAlertWindowSurfaces(DisplayContent displayContent) {
+ for (int i = mAlertWindowSurfaces.size() - 1; i >= 0; i--) {
+ final WindowSurfaceController surfaceController = mAlertWindowSurfaces.valueAt(i);
+ if (surfaceController.mAnimator.mWin.getDisplayContent() == displayContent) {
+ return true;
+ }
+ }
+ return false;
}
public void blessInputSurface(int displayId, SurfaceControl surface,
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 2fc64ea..8b0b6ce 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -304,7 +304,7 @@
if (DEBUG_ORIENTATION) {
Slog.d(TAG, "Pausing rotation during re-position");
}
- mDisplayContent.pauseRotationLocked();
+ mDisplayContent.getDisplayRotation().pause();
// Notify InputMonitor to take mDragWindowHandle.
mDisplayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
@@ -347,7 +347,7 @@
if (DEBUG_ORIENTATION) {
Slog.d(TAG, "Resuming rotation after re-position");
}
- mDisplayContent.resumeRotationLocked();
+ mDisplayContent.getDisplayRotation().resume();
mDisplayContent = null;
mClientCallback.unlinkToDeath(this, 0 /* flags */);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b25677a..d49d245 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -141,7 +141,6 @@
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Matrix;
-import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -667,19 +666,6 @@
WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
SettingsObserver mSettingsObserver;
- /**
- * A count of the windows which are 'seamlessly rotated', e.g. a surface
- * at an old orientation is being transformed. We freeze orientation updates
- * while any windows are seamlessly rotated, so we need to track when this
- * hits zero so we can apply deferred orientation updates.
- */
- private int mSeamlessRotationCount = 0;
- /**
- * True in the interval from starting seamless rotation until the last rotated
- * window draws in the new orientation.
- */
- private boolean mRotatingSeamlessly = false;
-
private final class SettingsObserver extends ContentObserver {
private final Uri mDisplayInversionEnabledUri =
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
@@ -1247,7 +1233,6 @@
return res;
}
- boolean reportNewConfig = false;
WindowState parentWindow = null;
long origId;
final int callingUid = Binder.getCallingUid();
@@ -1623,11 +1608,7 @@
if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addWindow: New client "
+ client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5));
- if (win.isVisibleOrAdding() && displayContent.updateOrientationFromAppTokens()) {
- reportNewConfig = true;
- }
-
- if (reportNewConfig) {
+ if (win.isVisibleOrAdding() && displayContent.updateOrientation()) {
displayContent.sendNewConfiguration();
}
}
@@ -1791,11 +1772,11 @@
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win);
mWindowMap.remove(win.mClient.asBinder());
- markForSeamlessRotation(win, false);
+ final DisplayContent dc = win.getDisplayContent();
+ dc.getDisplayRotation().markForSeamlessRotation(win, false /* seamlesslyRotated */);
win.resetAppOpsState();
- final DisplayContent dc = win.getDisplayContent();
if (dc.mCurrentFocus == null) {
dc.mWinRemovedSinceNullFocus.add(win);
}
@@ -2241,9 +2222,8 @@
displayContent.mUnknownAppVisibilityController.notifyRelayouted(win.mAppToken);
}
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
- "relayoutWindow: updateOrientationFromAppTokens");
- configChanged = displayContent.updateOrientationFromAppTokens();
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: updateOrientation");
+ configChanged = displayContent.updateOrientation();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (toBeDisplayed && win.mIsWallpaper) {
@@ -4859,7 +4839,7 @@
case SEAMLESS_ROTATION_TIMEOUT: {
final DisplayContent displayContent = (DisplayContent) msg.obj;
synchronized (mGlobalLock) {
- displayContent.onSeamlessRotationTimeout();
+ displayContent.getDisplayRotation().onSeamlessRotationTimeout();
}
break;
}
@@ -5321,7 +5301,7 @@
void startFreezingDisplayLocked(int exitAnim, int enterAnim,
DisplayContent displayContent) {
- if (mDisplayFrozen || mRotatingSeamlessly) {
+ if (mDisplayFrozen || displayContent.getDisplayRotation().isRotatingSeamlessly()) {
return;
}
@@ -5430,8 +5410,8 @@
if (DEBUG_ORIENTATION) Slog.i(TAG_WM, "**** Dismissing screen rotation animation");
DisplayInfo displayInfo = displayContent.getDisplayInfo();
// Get rotation animation again, with new top window
- if (!displayContent.getDisplayPolicy()
- .validateRotationAnimationLw(mExitAnimId, mEnterAnimId, false)) {
+ if (!displayContent.getDisplayRotation().validateRotationAnimation(
+ mExitAnimId, mEnterAnimId, false /* forceDefault */)) {
mExitAnimId = mEnterAnimId = 0;
}
if (screenRotationAnimation.dismiss(mTransaction, MAX_ANIMATION_DURATION,
@@ -5458,7 +5438,7 @@
// to avoid inconsistent states. However, something interesting
// could have actually changed during that time so re-evaluate it
// now to catch that.
- configChanged = displayContent != null && displayContent.updateOrientationFromAppTokens();
+ configChanged = displayContent != null && displayContent.updateOrientation();
// A little kludge: a lot could have happened while the
// display was frozen, so now that we are coming back we
@@ -6984,26 +6964,6 @@
mPolicy.requestUserActivityNotification();
}
- void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) {
- if (seamlesslyRotated == w.mSeamlesslyRotated || w.mForceSeamlesslyRotate) {
- return;
- }
- w.mSeamlesslyRotated = seamlesslyRotated;
- if (seamlesslyRotated) {
- mSeamlessRotationCount++;
- } else {
- mSeamlessRotationCount--;
- }
- if (mSeamlessRotationCount == 0) {
- if (DEBUG_ORIENTATION) {
- Slog.i(TAG, "Performing post-rotate rotation after seamless rotation");
- }
- finishSeamlessRotation();
-
- w.getDisplayContent().updateRotationAndSendNewConfigIfNeeded();
- }
- }
-
private final class LocalService extends WindowManagerInternal {
@Override
public void requestTraversalFromDisplayManager() {
@@ -7531,22 +7491,6 @@
return mSurfaceBuilderFactory.make(s);
}
- void startSeamlessRotation() {
- // We are careful to reset this in case a window was removed before it finished
- // seamless rotation.
- mSeamlessRotationCount = 0;
-
- mRotatingSeamlessly = true;
- }
-
- boolean isRotatingSeamlessly() {
- return mRotatingSeamlessly;
- }
-
- void finishSeamlessRotation() {
- mRotatingSeamlessly = false;
- }
-
/**
* Called when the state of lock task mode changes. This should be used to disable immersive
* mode confirmation.
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d87a0ed..4900869 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -652,7 +652,8 @@
if (mForceSeamlesslyRotate || requested) {
mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo());
mPendingSeamlessRotate.unrotate(transaction, this);
- mWmService.markForSeamlessRotation(this, true);
+ getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
+ true /* seamlesslyRotated */);
}
}
@@ -661,7 +662,8 @@
mPendingSeamlessRotate.finish(this, timeout);
mFinishSeamlessRotateFrameNumber = getFrameNumber();
mPendingSeamlessRotate = null;
- mWmService.markForSeamlessRotation(this, false);
+ getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
+ false /* seamlesslyRotated */);
}
}
@@ -2086,7 +2088,7 @@
// So just update orientation if needed.
if (wasVisible) {
final DisplayContent displayContent = getDisplayContent();
- if (displayContent.updateOrientationFromAppTokens()) {
+ if (displayContent.updateOrientation()) {
displayContent.sendNewConfiguration();
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f933b09..478bc88 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -248,6 +248,7 @@
import com.android.internal.util.StatLogger;
import com.android.internal.util.XmlUtils;
import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockSettingsInternal;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
import com.android.server.SystemServerInitThreadPool;
@@ -500,6 +501,7 @@
final UsageStatsManagerInternal mUsageStatsManagerInternal;
final TelephonyManager mTelephonyManager;
private final LockPatternUtils mLockPatternUtils;
+ private final LockSettingsInternal mLockSettingsInternal;
private final DeviceAdminServiceController mDeviceAdminServiceController;
private final OverlayPackagesProvider mOverlayPackagesProvider;
@@ -739,7 +741,6 @@
final SparseArray<DevicePolicyData> mUserData = new SparseArray<>();
@GuardedBy("getLockObject()")
- final SparseArray<PasswordMetrics> mUserPasswordMetrics = new SparseArray<>();
final Handler mHandler;
final Handler mBackgroundHandler;
@@ -1994,6 +1995,10 @@
return IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE));
}
+ LockSettingsInternal getLockSettingsInternal() {
+ return LocalServices.getService(LockSettingsInternal.class);
+ }
+
boolean isBuildDebuggable() {
return Build.IS_DEBUGGABLE;
}
@@ -2233,7 +2238,7 @@
mLocalService = new LocalService();
mLockPatternUtils = injector.newLockPatternUtils();
-
+ mLockSettingsInternal = injector.getLockSettingsInternal();
// TODO: why does SecurityLogMonitor need to be created even when mHasFeature == false?
mSecurityLogMonitor = new SecurityLogMonitor(this);
@@ -2309,17 +2314,6 @@
}
/**
- * Provides PasswordMetrics object corresponding to the given user.
- * @param userHandle the user for whom to provide metrics.
- * @return the user password metrics, or {@code null} if none have been associated with
- * the user yet (for example, if the device has booted but not been unlocked).
- */
- @GuardedBy("getLockObject()")
- PasswordMetrics getUserPasswordMetricsLocked(int userHandle) {
- return mUserPasswordMetrics.get(userHandle);
- }
-
- /**
* Creates and loads the policy data from xml for data that is shared between
* various profiles of a user. In contrast to {@link #getUserData(int)}
* it allows access to data of users other than the calling user.
@@ -2353,9 +2347,6 @@
if (policy != null) {
mUserData.remove(userHandle);
}
- if (mUserPasswordMetrics.get(userHandle) != null) {
- mUserPasswordMetrics.remove(userHandle);
- }
File policyFile = new File(mInjector.environmentGetUserSystemDirectory(userHandle),
DEVICE_POLICIES_XML);
@@ -4183,15 +4174,16 @@
private void updatePasswordValidityCheckpointLocked(int userHandle, boolean parent) {
final int credentialOwner = getCredentialOwner(userHandle, parent);
DevicePolicyData policy = getUserData(credentialOwner);
- PasswordMetrics metrics = getUserPasswordMetricsLocked(credentialOwner);
- if (metrics == null) {
- metrics = new PasswordMetrics();
+ PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
+ // Update the checkpoint only if the user's password metrics is known
+ if (metrics != null) {
+ final boolean newCheckpoint = isPasswordSufficientForUserWithoutCheckpointLocked(
+ metrics, userHandle, parent);
+ if (newCheckpoint != policy.mPasswordValidAtLastCheckpoint) {
+ policy.mPasswordValidAtLastCheckpoint = newCheckpoint;
+ saveSettingsLocked(credentialOwner);
+ }
}
- policy.mPasswordValidAtLastCheckpoint =
- isPasswordSufficientForUserWithoutCheckpointLocked(
- metrics, userHandle, parent);
-
- saveSettingsLocked(credentialOwner);
}
/**
@@ -4766,7 +4758,7 @@
getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
int credentialOwner = getCredentialOwner(userHandle, parent);
DevicePolicyData policy = getUserDataUnchecked(credentialOwner);
- PasswordMetrics metrics = getUserPasswordMetricsLocked(credentialOwner);
+ PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
return isActivePasswordSufficientForUserLocked(
policy.mPasswordValidAtLastCheckpoint, metrics, userHandle, parent);
}
@@ -4796,15 +4788,15 @@
enforceUserUnlocked(targetUser, false);
int credentialOwner = getCredentialOwner(userHandle, false);
DevicePolicyData policy = getUserDataUnchecked(credentialOwner);
- PasswordMetrics metrics = getUserPasswordMetricsLocked(credentialOwner);
+ PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
return isActivePasswordSufficientForUserLocked(
policy.mPasswordValidAtLastCheckpoint, metrics, targetUser, false);
}
}
private boolean isActivePasswordSufficientForUserLocked(
- boolean passwordValidAtLastCheckpoint, PasswordMetrics metrics, int userHandle,
- boolean parent) {
+ boolean passwordValidAtLastCheckpoint, @Nullable PasswordMetrics metrics,
+ int userHandle, boolean parent) {
if (!mInjector.storageManagerIsFileBasedEncryptionEnabled() && (metrics == null)) {
// Before user enters their password for the first time after a reboot, return the
// value of this flag, which tells us whether the password was valid the last time
@@ -4815,9 +4807,10 @@
}
if (metrics == null) {
- // This could happen if the user never had a password set, for example, so
- // setActivePasswordState has never been called for it.
- metrics = new PasswordMetrics();
+ // Called on a FBE device when the user password exists but its metrics is unknown.
+ // This shouldn't happen since we enforce the user to be unlocked (which would result
+ // in the metrics known to the framework on a FBE device) at all call sites.
+ throw new IllegalStateException("isActivePasswordSufficient called on FBE-locked user");
}
return isPasswordSufficientForUserWithoutCheckpointLocked(metrics, userHandle, parent);
@@ -4829,7 +4822,7 @@
* {@code userId} (or its parent, if {@code parent} is set to {@code true}).
*/
private boolean isPasswordSufficientForUserWithoutCheckpointLocked(
- PasswordMetrics metrics, @UserIdInt int userId, boolean parent) {
+ @NonNull PasswordMetrics metrics, @UserIdInt int userId, boolean parent) {
final int requiredQuality = getPasswordQuality(null, userId, parent);
if (requiredQuality >= PASSWORD_QUALITY_NUMERIC
@@ -4867,7 +4860,7 @@
synchronized (getLockObject()) {
int targetUserId = getCredentialOwner(callingUserId, /* parent= */ false);
- PasswordMetrics metrics = getUserPasswordMetricsLocked(targetUserId);
+ PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(targetUserId);
return metrics == null ? PASSWORD_COMPLEXITY_NONE : metrics.determineComplexity();
}
}
@@ -6707,31 +6700,6 @@
}
}
- /**
- * Notify DPMS regarding the metric of the current password. This happens when the user changes
- * the password, but also when the user just unlocks the keyguard. In comparison,
- * reportPasswordChanged() is only called when the user changes the password.
- */
- @Override
- public void setActivePasswordState(PasswordMetrics metrics, int userHandle) {
- if (!mLockPatternUtils.hasSecureLockScreen()) {
- return;
- }
- enforceFullCrossUsersPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
-
- // If the managed profile doesn't have a separate password, set the metrics to default
- if (isManagedProfile(userHandle) && !isSeparateProfileChallengeEnabled(userHandle)) {
- metrics = new PasswordMetrics();
- }
-
- validateQualityConstant(metrics.quality);
- synchronized (getLockObject()) {
- mUserPasswordMetrics.put(userHandle, metrics);
- }
- }
-
@Override
public void reportPasswordChanged(@UserIdInt int userId) {
if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
diff --git a/services/net/Android.bp b/services/net/Android.bp
index fb548f9..8f8f9f9 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -67,7 +67,7 @@
static_libs: [
"dnsresolver_aidl_interface-V2-java",
"ipmemorystore-client",
- "netd_aidl_interface-V2-java",
+ "netd_aidl_interface-java",
"networkstack-aidl-interfaces-V3-java",
],
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
index 274ca36..104aacb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
@@ -16,15 +16,18 @@
package com.android.server.accessibility.gestures;
+import static com.android.server.accessibility.gestures.TouchState.STATE_CLEAR;
+import static com.android.server.accessibility.gestures.TouchState.STATE_DELEGATING;
+import static com.android.server.accessibility.gestures.TouchState.STATE_DRAGGING;
+import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_EXPLORING;
+
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import android.content.Context;
import android.graphics.PointF;
import android.os.SystemClock;
import android.testing.DexmakerShareClassLoaderRule;
-import android.util.DebugUtils;
import android.view.InputDevice;
import android.view.MotionEvent;
@@ -46,10 +49,6 @@
@RunWith(AndroidJUnit4.class)
public class TouchExplorerTest {
- public static final int STATE_TOUCH_EXPLORING = 0x00000001;
- public static final int STATE_DRAGGING = 0x00000002;
- public static final int STATE_DELEGATING = 0x00000004;
-
private static final int FLAG_1FINGER = 0x8000;
private static final int FLAG_2FINGERS = 0x0100;
private static final int FLAG_3FINGERS = 0x0200;
@@ -112,7 +111,7 @@
@Test
public void testTwoFingersMove_shouldDelegatingAndInjectActionDownPointerDown() {
- goFromStateIdleTo(STATE_MOVING_2FINGERS);
+ goFromStateClearTo(STATE_MOVING_2FINGERS);
assertState(STATE_DELEGATING);
assertCapturedEvents(
@@ -123,7 +122,7 @@
@Test
public void testTwoFingersDrag_shouldDraggingAndActionDown() {
- goFromStateIdleTo(STATE_DRAGGING_2FINGERS);
+ goFromStateClearTo(STATE_DRAGGING_2FINGERS);
assertState(STATE_DRAGGING);
assertCapturedEvents(MotionEvent.ACTION_DOWN);
@@ -133,7 +132,7 @@
@Test
public void testTwoFingersNotDrag_shouldDelegatingAndActionUpDownPointerDown() {
// only from dragging state, and withMoveHistory no dragging
- goFromStateIdleTo(STATE_PINCH_2FINGERS);
+ goFromStateClearTo(STATE_PINCH_2FINGERS);
assertState(STATE_DELEGATING);
assertCapturedEvents(
@@ -146,7 +145,7 @@
@Test
public void testThreeFingersMove_shouldDelegatingAnd3ActionPointerDown() {
- goFromStateIdleTo(STATE_MOVING_3FINGERS);
+ goFromStateClearTo(STATE_MOVING_3FINGERS);
assertState(STATE_DELEGATING);
assertCapturedEvents(
@@ -165,52 +164,47 @@
return new PointF(x, y);
}
- private static String stateToString(int state) {
- return DebugUtils.valueToString(TouchExplorerTest.class, "STATE_", state);
- }
-
- private void goFromStateIdleTo(int state) {
+ private void goFromStateClearTo(int state) {
try {
switch (state) {
- case STATE_TOUCH_EXPLORING: {
+ case STATE_CLEAR: {
mTouchExplorer.onDestroy();
}
break;
case STATE_TOUCH_EXPLORING_1FINGER: {
- goFromStateIdleTo(STATE_TOUCH_EXPLORING);
send(downEvent());
}
break;
case STATE_TOUCH_EXPLORING_2FINGER: {
- goFromStateIdleTo(STATE_TOUCH_EXPLORING_1FINGER);
+ goFromStateClearTo(STATE_TOUCH_EXPLORING_1FINGER);
send(pointerDownEvent());
}
break;
case STATE_TOUCH_EXPLORING_3FINGER: {
- goFromStateIdleTo(STATE_TOUCH_EXPLORING_2FINGER);
+ goFromStateClearTo(STATE_TOUCH_EXPLORING_2FINGER);
send(thirdPointerDownEvent());
}
break;
case STATE_MOVING_2FINGERS: {
- goFromStateIdleTo(STATE_TOUCH_EXPLORING_2FINGER);
+ goFromStateClearTo(STATE_TOUCH_EXPLORING_2FINGER);
moveEachPointers(mLastEvent, p(10, 0), p(5, 10));
send(mLastEvent);
}
break;
case STATE_DRAGGING_2FINGERS: {
- goFromStateIdleTo(STATE_TOUCH_EXPLORING_2FINGER);
+ goFromStateClearTo(STATE_TOUCH_EXPLORING_2FINGER);
moveEachPointers(mLastEvent, p(10, 0), p(10, 0));
send(mLastEvent);
}
break;
case STATE_PINCH_2FINGERS: {
- goFromStateIdleTo(STATE_DRAGGING_2FINGERS);
+ goFromStateClearTo(STATE_DRAGGING_2FINGERS);
moveEachPointers(mLastEvent, p(10, 0), p(-10, 1));
send(mLastEvent);
}
break;
case STATE_MOVING_3FINGERS: {
- goFromStateIdleTo(STATE_TOUCH_EXPLORING_3FINGER);
+ goFromStateClearTo(STATE_TOUCH_EXPLORING_3FINGER);
moveEachPointers(mLastEvent, p(1, 0), p(1, 0), p(1, 0));
send(mLastEvent);
}
@@ -219,7 +213,8 @@
throw new IllegalArgumentException("Illegal state: " + state);
}
} catch (Throwable t) {
- throw new RuntimeException("Failed to go to state " + stateToString(state), t);
+ throw new RuntimeException("Failed to go to state "
+ + TouchState.getStateSymbolicName(state), t);
}
}
@@ -234,9 +229,9 @@
}
private void assertState(int expect) {
- final String expectState = "STATE_" + stateToString(expect);
- assertTrue(String.format("Expect state: %s, but: %s", expectState, mTouchExplorer),
- mTouchExplorer.toString().contains(expectState));
+ assertEquals(
+ TouchState.getStateSymbolicName(expect),
+ TouchState.getStateSymbolicName(mTouchExplorer.getState().getState()));
}
private void assertCapturedEvents(int... actionsInOrder) {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index ce83df7..64ea59d 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -48,6 +48,7 @@
import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockSettingsInternal;
import com.android.server.net.NetworkPolicyManagerInternal;
import java.io.File;
@@ -210,6 +211,11 @@
}
@Override
+ LockSettingsInternal getLockSettingsInternal() {
+ return services.lockSettingsInternal;
+ }
+
+ @Override
IAudioService getIAudioService() {
return services.iaudioService;
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 9ae9824..d6cb9826 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -40,6 +40,7 @@
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -764,7 +765,7 @@
}
/**
- * Test for: @{link DevicePolicyManager#setActivePasswordState}
+ * Test for: @{link DevicePolicyManager#reportPasswordChanged}
*
* Validates that when the password for a user changes, the notification broadcast intent
* {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is sent to managed profile owners, in
@@ -806,7 +807,7 @@
}
/**
- * Test for: @{link DevicePolicyManager#setActivePasswordState}
+ * Test for: @{link DevicePolicyManager#reportPasswordChanged}
*
* Validates that when the password for a managed profile changes, the notification broadcast
* intent {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is only sent to the profile, not
@@ -4258,6 +4259,10 @@
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
mContext.packageName = admin1.getPackageName();
setupDeviceOwner();
+ final int userHandle = UserHandle.getUserId(mContext.binder.callingUid);
+ // When there is no lockscreen, user password metrics is always empty.
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(userHandle))
+ .thenReturn(new PasswordMetrics());
// If no password requirements are set, isActivePasswordSufficient should succeed.
assertTrue(dpm.isActivePasswordSufficient());
@@ -4266,14 +4271,7 @@
dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
reset(mContext.spiedContext);
- final int userHandle = UserHandle.getUserId(mContext.binder.callingUid);
- PasswordMetrics passwordMetricsNoSymbols = new PasswordMetrics(
- DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 9,
- 8, 2,
- 6, 1,
- 0, 1);
// This should be ignored, as there is no lock screen.
- dpm.setActivePasswordState(passwordMetricsNoSymbols, userHandle);
dpm.reportPasswordChanged(userHandle);
// No broadcast should be sent.
@@ -4290,19 +4288,24 @@
final int userHandle = UserHandle.getUserId(mContext.binder.callingUid);
final long ident = mContext.binder.clearCallingIdentity();
- dpm.setActivePasswordState(passwordMetrics, userHandle);
+ when(getServices().lockSettingsInternal.getUserPasswordMetrics(userHandle))
+ .thenReturn(passwordMetrics);
dpm.reportPasswordChanged(userHandle);
// Drain ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED broadcasts as part of
// reportPasswordChanged()
- // This broadcast should be sent 4 times:
+ // This broadcast should be sent 2-4 times:
// * Twice from calls to DevicePolicyManagerService.updatePasswordExpirationsLocked,
// once for each affected user, in DevicePolicyManagerService.reportPasswordChanged.
- // * Twice from calls to DevicePolicyManagerService.saveSettingsLocked
+ // * Optionally, at most twice from calls to DevicePolicyManagerService.saveSettingsLocked
// in DevicePolicyManagerService.reportPasswordChanged, once with the userId
// the password change is relevant to and another with the credential owner of said
- // userId.
- verify(mContext.spiedContext, times(4)).sendBroadcastAsUser(
+ // userId, if the password checkpoint value changes.
+ verify(mContext.spiedContext, atMost(4)).sendBroadcastAsUser(
+ MockUtils.checkIntentAction(
+ DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+ MockUtils.checkUserHandle(userHandle));
+ verify(mContext.spiedContext, atLeast(2)).sendBroadcastAsUser(
MockUtils.checkIntentAction(
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
MockUtils.checkUserHandle(userHandle));
@@ -5224,9 +5227,9 @@
mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY);
when(getServices().userManager.getCredentialOwnerProfile(DpmMockContext.CALLER_USER_HANDLE))
.thenReturn(DpmMockContext.CALLER_USER_HANDLE);
- dpms.mUserPasswordMetrics.put(
- DpmMockContext.CALLER_USER_HANDLE,
- PasswordMetrics.computeForPassword("asdf".getBytes()));
+ when(getServices().lockSettingsInternal
+ .getUserPasswordMetrics(DpmMockContext.CALLER_USER_HANDLE))
+ .thenReturn(PasswordMetrics.computeForPassword("asdf".getBytes()));
assertEquals(PASSWORD_COMPLEXITY_MEDIUM, dpm.getPasswordComplexity());
}
@@ -5241,12 +5244,12 @@
when(getServices().userManager.getCredentialOwnerProfile(DpmMockContext.CALLER_USER_HANDLE))
.thenReturn(parentUser.id);
- dpms.mUserPasswordMetrics.put(
- DpmMockContext.CALLER_USER_HANDLE,
- PasswordMetrics.computeForPassword("asdf".getBytes()));
- dpms.mUserPasswordMetrics.put(
- parentUser.id,
- PasswordMetrics.computeForPassword("parentUser".getBytes()));
+ when(getServices().lockSettingsInternal
+ .getUserPasswordMetrics(DpmMockContext.CALLER_USER_HANDLE))
+ .thenReturn(PasswordMetrics.computeForPassword("asdf".getBytes()));
+ when(getServices().lockSettingsInternal
+ .getUserPasswordMetrics(parentUser.id))
+ .thenReturn(PasswordMetrics.computeForPassword("parentUser".getBytes()));
assertEquals(PASSWORD_COMPLEXITY_HIGH, dpm.getPasswordComplexity());
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index f6f365e..b0d0303 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -64,6 +64,7 @@
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockSettingsInternal;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -102,6 +103,7 @@
public final IBackupManager ibackupManager;
public final IAudioService iaudioService;
public final LockPatternUtils lockPatternUtils;
+ public final LockSettingsInternal lockSettingsInternal;
public final StorageManagerForMock storageManager;
public final WifiManager wifiManager;
public final SettingsForMock settings;
@@ -143,6 +145,7 @@
ibackupManager = mock(IBackupManager.class);
iaudioService = mock(IAudioService.class);
lockPatternUtils = mock(LockPatternUtils.class);
+ lockSettingsInternal = mock(LockSettingsInternal.class);
storageManager = mock(StorageManagerForMock.class);
wifiManager = mock(WifiManager.class);
settings = mock(SettingsForMock.class);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 1cd590c..341b8f0 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -341,6 +341,7 @@
final byte[] pattern = "123654".getBytes();
final byte[] token = "some-high-entropy-secure-token".getBytes();
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
+ reset(mDevicePolicyManager);
final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
assertFalse(mService.hasPendingEscrowToken(PRIMARY_USER_ID));
@@ -360,7 +361,8 @@
flushHandlerTasks();
final PasswordMetrics metric = PasswordMetrics.computeForCredential(
LockPatternUtils.CREDENTIAL_TYPE_PATTERN, pattern);
- verify(mDevicePolicyManager).setActivePasswordState(metric, PRIMARY_USER_ID);
+ assertEquals(metric, mService.getUserPasswordMetrics(PRIMARY_USER_ID));
+ verify(mDevicePolicyManager).reportPasswordChanged(PRIMARY_USER_ID);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID)
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 13748cb..31babd0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -30,6 +30,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -866,7 +867,7 @@
mActivity.setState(PAUSED, "test");
mActivity.finishIfPossible("test", false /* oomAdj */);
- verify(mActivity).setVisibility(eq(false));
+ verify(mActivity, atLeast(1)).setVisibility(eq(false));
verify(mActivity.getDisplay().mDisplayContent)
.prepareAppTransition(eq(TRANSIT_TASK_CLOSE), eq(false) /* alwaysKeepCurrent */);
verify(mActivity.getDisplay().mDisplayContent).executeAppTransition();
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 60c5f0b..c83e5cb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -26,6 +26,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
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.spyOn;
@@ -1122,6 +1123,22 @@
assertThat(result).isEqualTo(taskTop);
}
+ @Test
+ public void testNonTopVisibleActivityNotResume() {
+ final ActivityRecord nonTopVisibleActivity =
+ new ActivityBuilder(mService).setTask(mTask).build();
+ new ActivityBuilder(mService).setTask(mTask).build();
+ doReturn(false).when(nonTopVisibleActivity).attachedToProcess();
+ doReturn(true).when(nonTopVisibleActivity).shouldBeVisibleIgnoringKeyguard(anyBoolean());
+ doNothing().when(mSupervisor).startSpecificActivityLocked(any(), anyBoolean(),
+ anyBoolean());
+
+ mStack.ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
+ false /* preserveWindows */);
+ verify(mSupervisor).startSpecificActivityLocked(any(), eq(false) /* andResume */,
+ anyBoolean());
+ }
+
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/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index e387e18..1f634b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -36,7 +36,6 @@
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
@@ -160,7 +159,7 @@
// Set initial orientation and update.
mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
- mDisplayContent.updateOrientationFromAppTokens(
+ mDisplayContent.updateOrientation(
mDisplayContent.getRequestedOverrideConfiguration(),
null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation());
@@ -168,7 +167,7 @@
// Update the orientation to perform 180 degree rotation and check that resize was reported.
mToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
- mDisplayContent.updateOrientationFromAppTokens(
+ mDisplayContent.updateOrientation(
mDisplayContent.getRequestedOverrideConfiguration(),
null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
// In this test, DC will not get config update. Set the waiting flag to false.
@@ -181,8 +180,8 @@
@Test
public void testLandscapeSeascapeRotationByPolicy() {
+ // This instance has been spied in {@link TestActivityDisplay}.
final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
- spyOn(displayRotation);
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
TYPE_BASE_APPLICATION);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 6289768..44f3ee41 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -445,7 +445,7 @@
.computeSafeInsets(200, 400).getDisplayCutout();
dc.mInitialDisplayCutout = cutout;
- dc.setRotation(Surface.ROTATION_0);
+ dc.getDisplayRotation().setRotation(Surface.ROTATION_0);
dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
assertEquals(cutout, dc.getDisplayInfo().displayCutout);
@@ -476,7 +476,7 @@
.computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
dc.mInitialDisplayCutout = cutout;
- dc.setRotation(Surface.ROTATION_90);
+ dc.getDisplayRotation().setRotation(Surface.ROTATION_90);
dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
// ----o---------- -------------
@@ -608,18 +608,18 @@
portraitDisplay.mInitialDisplayHeight = 2000;
portraitDisplay.mInitialDisplayWidth = 1000;
- portraitDisplay.setRotation(Surface.ROTATION_0);
+ portraitDisplay.getDisplayRotation().setRotation(Surface.ROTATION_0);
assertFalse(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
- portraitDisplay.setRotation(Surface.ROTATION_90);
+ portraitDisplay.getDisplayRotation().setRotation(Surface.ROTATION_90);
assertTrue(isOptionsPanelAtRight(portraitDisplay.getDisplayId()));
final DisplayContent landscapeDisplay = createNewDisplay();
landscapeDisplay.mInitialDisplayHeight = 1000;
landscapeDisplay.mInitialDisplayWidth = 2000;
- landscapeDisplay.setRotation(Surface.ROTATION_0);
+ landscapeDisplay.getDisplayRotation().setRotation(Surface.ROTATION_0);
assertTrue(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
- landscapeDisplay.setRotation(Surface.ROTATION_90);
+ landscapeDisplay.getDisplayRotation().setRotation(Surface.ROTATION_90);
assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 6a3c81ab..3ead9779 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -28,16 +28,12 @@
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
-import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
-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.spyOn;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
@@ -52,7 +48,6 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
-import android.view.Surface;
import android.view.WindowManager;
import androidx.test.filters.FlakyTest;
@@ -213,32 +208,15 @@
}
@Test
- public void testShouldRotateSeamlessly() {
- final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
+ public void testComputeTopFullscreenOpaqueWindow() {
final WindowManager.LayoutParams attrs = mAppWindow.mAttrs;
attrs.x = attrs.y = 0;
attrs.height = attrs.width = WindowManager.LayoutParams.MATCH_PARENT;
- attrs.rotationAnimation = ROTATION_ANIMATION_SEAMLESS;
- final DisplayRotation displayRotation = mock(DisplayRotation.class);
- doReturn(Surface.ROTATION_180).when(displayRotation).getUpsideDownRotation();
+ final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
+ policy.applyPostLayoutPolicyLw(
+ mAppWindow, attrs, null /* attached */, null /* imeTarget */);
- synchronized (mWm.mGlobalLock) {
- policy.focusChangedLw(null /* lastFocus */, mAppWindow);
- policy.applyPostLayoutPolicyLw(
- mAppWindow, attrs, null /* attached */, null /* imeTarget */);
- spyOn(policy);
- doReturn(true).when(policy).navigationBarCanMove();
- // The focused fullscreen opaque window without override bounds should be able to be
- // rotated seamlessly.
- assertTrue(policy.shouldRotateSeamlessly(
- displayRotation, Surface.ROTATION_0, Surface.ROTATION_90));
-
- spyOn(mAppWindow.mAppToken);
- doReturn(false).when(mAppWindow.mAppToken).matchParentBounds();
- // No seamless rotation if the window may be positioned with offset after rotation.
- assertFalse(policy.shouldRotateSeamlessly(
- displayRotation, Surface.ROTATION_0, Surface.ROTATION_90));
- }
+ assertEquals(mAppWindow, policy.getTopFullscreenOpaqueWindow());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index 49d38c0..059ff3d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -24,6 +24,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.atMost;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
@@ -55,6 +56,7 @@
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.view.Surface;
+import android.view.WindowManager;
import androidx.test.filters.SmallTest;
@@ -584,6 +586,33 @@
SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_0));
}
+ @Test
+ public void testShouldRotateSeamlessly() throws Exception {
+ mBuilder.build();
+
+ final WindowState win = mock(WindowState.class);
+ win.mAppToken = mock(AppWindowToken.class);
+ final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams();
+ attrs.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
+
+ doReturn(attrs).when(win).getAttrs();
+ doReturn(true).when(mMockDisplayPolicy).navigationBarCanMove();
+ doReturn(win).when(mMockDisplayPolicy).getTopFullscreenOpaqueWindow();
+ mMockDisplayContent.mCurrentFocus = win;
+ mTarget.mUpsideDownRotation = Surface.ROTATION_180;
+
+ doReturn(true).when(win.mAppToken).matchParentBounds();
+ // The focused fullscreen opaque window without override bounds should be able to be
+ // rotated seamlessly.
+ assertTrue(mTarget.shouldRotateSeamlessly(
+ Surface.ROTATION_0, Surface.ROTATION_90, false /* forceUpdate */));
+
+ doReturn(false).when(win.mAppToken).matchParentBounds();
+ // No seamless rotation if the window may be positioned with offset after rotation.
+ assertFalse(mTarget.shouldRotateSeamlessly(
+ Surface.ROTATION_0, Surface.ROTATION_90, false /* forceUpdate */));
+ }
+
// ========================
// Non-rotation API Tests
// ========================
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestActivityDisplay.java b/services/tests/wmtests/src/com/android/server/wm/TestActivityDisplay.java
index c143969..778f0ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestActivityDisplay.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestActivityDisplay.java
@@ -69,20 +69,22 @@
mSupervisor = supervisor;
spyOn(this);
spyOn(mDisplayContent);
+
+ final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
+ spyOn(displayRotation);
doAnswer(invocation -> {
// Bypass all the rotation animation and display freezing stuff for testing and just
// set the rotation we want for the display
- final DisplayContent dc = mDisplayContent;
- final int oldRotation = dc.getRotation();
- final int rotation = dc.getDisplayRotation().rotationForOrientation(
- dc.getLastOrientation(), oldRotation);
+ final int oldRotation = displayRotation.getRotation();
+ final int rotation = displayRotation.rotationForOrientation(
+ displayRotation.getLastOrientation(), oldRotation);
if (oldRotation == rotation) {
return false;
}
- dc.setLayoutNeeded();
- dc.setRotation(rotation);
+ mDisplayContent.setLayoutNeeded();
+ displayRotation.setRotation(rotation);
return true;
- }).when(mDisplayContent).updateRotationUnchecked(anyBoolean());
+ }).when(displayRotation).updateRotationUnchecked(anyBoolean());
}
@SuppressWarnings("TypeParameterUnusedInFormals")
diff --git a/telecomm/java/android/telecom/AudioState.java b/telecomm/java/android/telecom/AudioState.java
index 6b9b83d..8b8c86b 100644
--- a/telecomm/java/android/telecom/AudioState.java
+++ b/telecomm/java/android/telecom/AudioState.java
@@ -16,6 +16,8 @@
package android.telecom;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Build;
@@ -81,7 +83,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == null) {
return false;
}
@@ -93,6 +95,7 @@
getSupportedRouteMask() == state.getSupportedRouteMask();
}
+ @NonNull
@Override
public String toString() {
return String.format(Locale.US,
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
index 3a34005..1c03d80 100644
--- a/telephony/java/android/telephony/CallAttributes.java
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -44,6 +45,7 @@
this.mCallQuality = callQuality;
}
+ @NonNull
@Override
public String toString() {
return "mPreciseCallState=" + mPreciseCallState + " mNetworkType=" + mNetworkType
@@ -109,7 +111,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o == null || !(o instanceof CallAttributes) || hashCode() != o.hashCode()) {
return false;
}
diff --git a/telephony/java/android/telephony/CallQuality.java b/telephony/java/android/telephony/CallQuality.java
index 10a04a9..028280c 100644
--- a/telephony/java/android/telephony/CallQuality.java
+++ b/telephony/java/android/telephony/CallQuality.java
@@ -17,6 +17,8 @@
package android.telephony;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -252,6 +254,7 @@
}
// Parcelable things
+ @NonNull
@Override
public String toString() {
return "CallQuality: {downlinkCallQualityLevel=" + mDownlinkCallQualityLevel
@@ -285,7 +288,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o == null || !(o instanceof CallQuality) || hashCode() != o.hashCode()) {
return false;
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 654b54d..2aca206 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2791,6 +2791,13 @@
"opportunistic_network_data_switch_exit_hysteresis_time_long";
/**
+ * Controls time in milli seconds until DcTracker reevaluates 5G connection state.
+ * @hide
+ */
+ public static final String KEY_5G_WATCHDOG_TIME_MS_LONG =
+ "5g_watchdog_time_long";
+
+ /**
* Indicates zero or more emergency number prefix(es), because some carrier requires
* if users dial an emergency number address with a specific prefix, the combination of the
* prefix and the address is also a valid emergency number to dial. For example, an emergency
@@ -3565,6 +3572,8 @@
sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG, 10000);
/* Default value is 3 seconds. */
sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 3000);
+ /* Default value is 1 hour. */
+ sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
sDefaults.putAll(Gps.getDefaults());
sDefaults.putAll(Wifi.getDefaults());
sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
@@ -3799,7 +3808,7 @@
* @see #getConfigForSubId
*/
@Nullable
- public PersistableBundle getConfigByComponentForSubId(String prefix, int subId) {
+ public PersistableBundle getConfigByComponentForSubId(@NonNull String prefix, int subId) {
PersistableBundle configs = getConfigForSubId(subId);
if (configs == null) {
diff --git a/telephony/java/android/telephony/CarrierRestrictionRules.java b/telephony/java/android/telephony/CarrierRestrictionRules.java
index 950ae6c..c138018 100644
--- a/telephony/java/android/telephony/CarrierRestrictionRules.java
+++ b/telephony/java/android/telephony/CarrierRestrictionRules.java
@@ -323,6 +323,7 @@
}
};
+ @NonNull
@Override
public String toString() {
return "CarrierRestrictionRules(allowed:" + mAllowedCarriers + ", excluded:"
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 3dd9318..407ced7 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -134,6 +135,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return new StringBuilder().append(this.getClass().getName())
@@ -155,7 +157,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (!(o instanceof DataSpecificRegistrationInfo)) return false;
diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java
index ec9f078..7994c1b 100644
--- a/telephony/java/android/telephony/LteVopsSupportInfo.java
+++ b/telephony/java/android/telephony/LteVopsSupportInfo.java
@@ -17,6 +17,8 @@
package android.telephony;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -94,7 +96,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o == null || !(o instanceof LteVopsSupportInfo)) {
return false;
}
@@ -112,6 +114,7 @@
/**
* @return string representation.
*/
+ @NonNull
@Override
public String toString() {
return ("LteVopsSupportInfo : "
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 2fae949..a76b8da 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -501,6 +501,7 @@
}
}
+ @NonNull
@Override
public String toString() {
return new StringBuilder("NetworkRegistrationInfo{")
@@ -531,7 +532,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (!(o instanceof NetworkRegistrationInfo)) {
diff --git a/telephony/java/android/telephony/PhoneNumberRange.java b/telephony/java/android/telephony/PhoneNumberRange.java
index c35a485..e6f107e 100644
--- a/telephony/java/android/telephony/PhoneNumberRange.java
+++ b/telephony/java/android/telephony/PhoneNumberRange.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -104,7 +105,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PhoneNumberRange that = (PhoneNumberRange) o;
@@ -119,6 +120,7 @@
return Objects.hash(mCountryCode, mPrefix, mLowerBound, mUpperBound);
}
+ @NonNull
@Override
public String toString() {
return "PhoneNumberRange{"
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index f03a9dc..af3ba5e 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -217,6 +217,9 @@
}
String scheme = uri.getScheme();
+ if (scheme == null) {
+ return null;
+ }
if (scheme.equals("tel") || scheme.equals("sip")) {
return uri.getSchemeSpecificPart();
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index 5fb9bac..701a375 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -17,6 +17,8 @@
package android.telephony;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
@@ -276,7 +278,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -294,6 +296,7 @@
&& mPreciseDisconnectCause == other.mPreciseDisconnectCause);
}
+ @NonNull
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index cd4fbac..90d443a 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -177,7 +177,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (!(obj instanceof PreciseDataConnectionState)) {
return false;
@@ -191,6 +191,7 @@
&& mState == other.mState;
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index b44e4f1..cd0f57e 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -53,7 +53,6 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -1555,15 +1554,13 @@
public boolean
deleteMessageFromIcc(int messageIndex) {
boolean success = false;
- byte[] pdu = new byte[SMS_RECORD_LENGTH-1];
- Arrays.fill(pdu, (byte)0xff);
try {
ISms iSms = getISmsService();
if (iSms != null) {
success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
ActivityThread.currentPackageName(),
- messageIndex, STATUS_ON_ICC_FREE, pdu);
+ messageIndex, STATUS_ON_ICC_FREE, null /* pdu */);
}
} catch (RemoteException ex) {
// ignore it
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 5e47e49..d93d1d6a 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -53,6 +53,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.telephony.TelephonyManager.NetworkType;
import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsMmTelManager;
import android.util.DisplayMetrics;
@@ -2454,10 +2455,51 @@
*/
public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
@DurationMillisLong long timeoutMillis) {
+ setSubscriptionOverrideUnmetered(subId, null, overrideUnmetered, timeoutMillis);
+ }
+
+ /**
+ * Temporarily override the billing relationship between a carrier and
+ * a specific subscriber to be considered unmetered for the given network
+ * types. This will be reflected to apps via
+ * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}.
+ * This method is only accessible to the following narrow set of apps:
+ * <ul>
+ * <li>The carrier app for this subscriberId, as determined by
+ * {@link TelephonyManager#hasCarrierPrivileges()}.
+ * <li>The carrier app explicitly delegated access through
+ * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
+ * </ul>
+ *
+ * @param subId the subscriber this override applies to.
+ * @param networkTypes all network types to set an override for. A null
+ * network type means to apply the override to all network types.
+ * Any unspecified network types will default to metered.
+ * @param overrideUnmetered set if the billing relationship should be
+ * considered unmetered.
+ * @param timeoutMillis the timeout after which the requested override will
+ * be automatically cleared, or {@code 0} to leave in the
+ * requested state until explicitly cleared, or the next reboot,
+ * whichever happens first.
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
+ * {@hide}
+ */
+ public void setSubscriptionOverrideUnmetered(int subId,
+ @Nullable @NetworkType int[] networkTypes, boolean overrideUnmetered,
+ @DurationMillisLong long timeoutMillis) {
try {
+ long networkTypeMask = 0;
+ if (networkTypes != null) {
+ for (int networkType : networkTypes) {
+ networkTypeMask |= TelephonyManager.getBitMaskForNetworkType(networkType);
+ }
+ } else {
+ networkTypeMask = ~0;
+ }
final int overrideValue = overrideUnmetered ? OVERRIDE_UNMETERED : 0;
getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_UNMETERED, overrideValue,
- timeoutMillis, mContext.getOpPackageName());
+ networkTypeMask, timeoutMillis, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2489,10 +2531,52 @@
*/
public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
@DurationMillisLong long timeoutMillis) {
+ setSubscriptionOverrideCongested(subId, null, overrideCongested, timeoutMillis);
+ }
+
+ /**
+ * Temporarily override the billing relationship plan between a carrier and
+ * a specific subscriber to be considered congested. This will cause the
+ * device to delay certain network requests when possible, such as developer
+ * jobs that are willing to run in a flexible time window.
+ * <p>
+ * This method is only accessible to the following narrow set of apps:
+ * <ul>
+ * <li>The carrier app for this subscriberId, as determined by
+ * {@link TelephonyManager#hasCarrierPrivileges()}.
+ * <li>The carrier app explicitly delegated access through
+ * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
+ * </ul>
+ *
+ * @param subId the subscriber this override applies to.
+ * @param networkTypes all network types to set an override for. A null
+ * network type means to apply the override to all network types.
+ * Any unspecified network types will default to not congested.
+ * @param overrideCongested set if the subscription should be considered
+ * congested.
+ * @param timeoutMillis the timeout after which the requested override will
+ * be automatically cleared, or {@code 0} to leave in the
+ * requested state until explicitly cleared, or the next reboot,
+ * whichever happens first.
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
+ * @hide
+ */
+ public void setSubscriptionOverrideCongested(int subId,
+ @Nullable @NetworkType int[] networkTypes, boolean overrideCongested,
+ @DurationMillisLong long timeoutMillis) {
try {
+ long networkTypeMask = 0;
+ if (networkTypes != null) {
+ for (int networkType : networkTypes) {
+ networkTypeMask |= TelephonyManager.getBitMaskForNetworkType(networkType);
+ }
+ } else {
+ networkTypeMask = ~0;
+ }
final int overrideValue = overrideCongested ? OVERRIDE_CONGESTED : 0;
getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_CONGESTED, overrideValue,
- timeoutMillis, mContext.getOpPackageName());
+ networkTypeMask, timeoutMillis, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/telephony/java/android/telephony/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java
index e0838b3..ec2050f 100644
--- a/telephony/java/android/telephony/SubscriptionPlan.java
+++ b/telephony/java/android/telephony/SubscriptionPlan.java
@@ -131,7 +131,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj instanceof SubscriptionPlan) {
final SubscriptionPlan other = (SubscriptionPlan) obj;
return Objects.equals(cycleRule, other.cycleRule)
diff --git a/telephony/java/android/telephony/TelephonyHistogram.java b/telephony/java/android/telephony/TelephonyHistogram.java
index 63bdac5..b94cb60 100644
--- a/telephony/java/android/telephony/TelephonyHistogram.java
+++ b/telephony/java/android/telephony/TelephonyHistogram.java
@@ -15,13 +15,12 @@
*/
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
/**
* Parcelable class to store Telephony histogram.
@@ -238,6 +237,8 @@
}
}
+ @NonNull
+ @Override
public String toString() {
String basic = " Histogram id = " + mId + " Time(ms): min = " + mMinTimeMs + " max = "
+ mMaxTimeMs + " avg = " + mAverageTimeMs + " Count = " + mSampleCount;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 553bff2..475563d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2829,6 +2829,55 @@
}
}
+ /**
+ * Returns the bitmask for a given technology (network type)
+ * @param networkType for which bitmask is returned
+ * @return the network type bitmask
+ * {@hide}
+ */
+ public static @NetworkTypeBitMask long getBitMaskForNetworkType(@NetworkType int networkType) {
+ switch(networkType) {
+ case NETWORK_TYPE_GSM:
+ return NETWORK_TYPE_BITMASK_GSM;
+ case NETWORK_TYPE_GPRS:
+ return NETWORK_TYPE_BITMASK_GPRS;
+ case NETWORK_TYPE_EDGE:
+ return NETWORK_TYPE_BITMASK_EDGE;
+ case NETWORK_TYPE_CDMA:
+ return NETWORK_TYPE_BITMASK_CDMA;
+ case NETWORK_TYPE_1xRTT:
+ return NETWORK_TYPE_BITMASK_1xRTT;
+ case NETWORK_TYPE_EVDO_0:
+ return NETWORK_TYPE_BITMASK_EVDO_0;
+ case NETWORK_TYPE_EVDO_A:
+ return NETWORK_TYPE_BITMASK_EVDO_A;
+ case NETWORK_TYPE_EVDO_B:
+ return NETWORK_TYPE_BITMASK_EVDO_B;
+ case NETWORK_TYPE_EHRPD:
+ return NETWORK_TYPE_BITMASK_EHRPD;
+ case NETWORK_TYPE_HSUPA:
+ return NETWORK_TYPE_BITMASK_HSUPA;
+ case NETWORK_TYPE_HSDPA:
+ return NETWORK_TYPE_BITMASK_HSDPA;
+ case NETWORK_TYPE_HSPA:
+ return NETWORK_TYPE_BITMASK_HSPA;
+ case NETWORK_TYPE_HSPAP:
+ return NETWORK_TYPE_BITMASK_HSPAP;
+ case NETWORK_TYPE_UMTS:
+ return NETWORK_TYPE_BITMASK_UMTS;
+ case NETWORK_TYPE_TD_SCDMA:
+ return NETWORK_TYPE_BITMASK_TD_SCDMA;
+ case NETWORK_TYPE_LTE:
+ return NETWORK_TYPE_BITMASK_LTE;
+ case NETWORK_TYPE_LTE_CA:
+ return NETWORK_TYPE_BITMASK_LTE_CA;
+ case NETWORK_TYPE_NR:
+ return NETWORK_TYPE_BITMASK_NR;
+ default:
+ return NETWORK_TYPE_BITMASK_UNKNOWN;
+ }
+ }
+
//
//
// SIM Card
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
index 37a4491..811722f 100644
--- a/telephony/java/android/telephony/UiccAccessRule.java
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -15,6 +15,7 @@
*/
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.pm.PackageInfo;
@@ -213,7 +214,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -236,6 +237,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
return "cert: " + IccUtils.bytesToHexString(mCertificateHash) + " pkg: " +
diff --git a/telephony/java/android/telephony/UiccSlotInfo.java b/telephony/java/android/telephony/UiccSlotInfo.java
index fb1da7b..a0e949a 100644
--- a/telephony/java/android/telephony/UiccSlotInfo.java
+++ b/telephony/java/android/telephony/UiccSlotInfo.java
@@ -16,6 +16,8 @@
package android.telephony;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -179,7 +181,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -210,6 +212,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
return "UiccSlotInfo (mIsActive="
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index 17699d7..9170e88 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -213,6 +213,7 @@
*/
public int getMtu() { return mMtu; }
+ @NonNull
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -233,7 +234,7 @@
}
@Override
- public boolean equals (Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (!(o instanceof DataCallResponse)) {
diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java
index c53ade1..0d79ec9 100644
--- a/telephony/java/android/telephony/data/DataProfile.java
+++ b/telephony/java/android/telephony/data/DataProfile.java
@@ -257,6 +257,7 @@
return 0;
}
+ @NonNull
@Override
public String toString() {
return "DataProfile=" + mProfileId + "/" + mProtocolType + "/" + mAuthType
@@ -303,7 +304,7 @@
};
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DataProfile that = (DataProfile) o;
diff --git a/telephony/java/android/telephony/euicc/EuiccNotification.java b/telephony/java/android/telephony/euicc/EuiccNotification.java
index b27f775..c348cff 100644
--- a/telephony/java/android/telephony/euicc/EuiccNotification.java
+++ b/telephony/java/android/telephony/euicc/EuiccNotification.java
@@ -16,6 +16,7 @@
package android.telephony.euicc;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
@@ -107,7 +108,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@@ -132,6 +133,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
return "EuiccNotification (seq="
diff --git a/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java b/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
index 89842ae..d5a05ae 100644
--- a/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
+++ b/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
@@ -16,6 +16,7 @@
package android.telephony.euicc;
import android.annotation.IntDef;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,7 +29,6 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -204,7 +204,7 @@
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
diff --git a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
index 9b72d58..79cdfef 100644
--- a/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
+++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java
@@ -185,6 +185,7 @@
out.writeInt(mServiceClass);
}
+ @NonNull
@Override
public String toString() {
return super.toString() + ", Condition: " + mCondition
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 2087914..77ee205 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -539,7 +539,7 @@
mMediaProfile = profile.mMediaProfile;
}
-
+ @NonNull
@Override
public String toString() {
return "{ serviceType=" + mServiceType
diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java
index 44595b5..6f062f4 100644
--- a/telephony/java/android/telephony/ims/ImsConferenceState.java
+++ b/telephony/java/android/telephony/ims/ImsConferenceState.java
@@ -16,6 +16,7 @@
package android.telephony.ims;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Bundle;
import android.os.Parcel;
@@ -176,6 +177,7 @@
return Call.STATE_ACTIVE;
}
+ @NonNull
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index 37b11ed..eb2ebca 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -213,6 +213,7 @@
return mIsHeld;
}
+ @NonNull
@Override
public String toString() {
return "ImsExternalCallState { mCallId = " + mCallId +
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 20aba4d..1e0d9a78 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -17,6 +17,7 @@
package android.telephony.ims;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
@@ -1183,6 +1184,8 @@
/**
* @return the string format of {@link ImsReasonInfo}
*/
+ @NonNull
+ @Override
public String toString() {
return "ImsReasonInfo :: {" + mCode + ", " + mExtraCode + ", " + mExtraMessage + "}";
}
diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java
index 32b4382..ec2ff6c 100644
--- a/telephony/java/android/telephony/ims/ImsSsData.java
+++ b/telephony/java/android/telephony/ims/ImsSsData.java
@@ -570,6 +570,8 @@
return mCfInfo;
}
+ @NonNull
+ @Override
public String toString() {
return "[ImsSsData] " + "ServiceType: " + getServiceType()
+ " RequestType: " + getRequestType()
diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java
index 9912ece..be34f9d 100644
--- a/telephony/java/android/telephony/ims/ImsSsInfo.java
+++ b/telephony/java/android/telephony/ims/ImsSsInfo.java
@@ -254,6 +254,7 @@
out.writeInt(mClirOutgoingState);
}
+ @NonNull
@Override
public String toString() {
return super.toString() + ", Status: " + ((mStatus == 0) ? "disabled" : "enabled")
diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
index fd75a6b..c1f059e 100644
--- a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
+++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
@@ -16,6 +16,7 @@
package android.telephony.ims;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
@@ -194,6 +195,7 @@
mRttMode = profile.mRttMode;
}
+ @NonNull
@Override
public String toString() {
return "{ audioQuality=" + mAudioQuality +
diff --git a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
index 2e4288d..1630368 100644
--- a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
+++ b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java
@@ -17,6 +17,7 @@
package android.telephony.ims;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -67,6 +68,7 @@
history = in.createStringArray();
}
+ @NonNull
@Override
public String toString() {
return "{ notificationType=" + notificationType +
diff --git a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
index 80fc09e..87a5094 100644
--- a/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
+++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java
@@ -16,6 +16,7 @@
package android.telephony.ims.feature;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -98,6 +99,7 @@
return radioTech;
}
+ @NonNull
@Override
public String toString() {
return "CapabilityPair{"
@@ -219,6 +221,7 @@
}
}
+ @NonNull
@Override
public String toString() {
return "CapabilityChangeRequest{"
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 056a0ab..20c191d 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -291,6 +291,7 @@
return super.isCapable(capabilities);
}
+ @NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder("MmTel Capabilities - [");
diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
index 3b298bb..cd9ebbf 100644
--- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
+++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
@@ -16,6 +16,8 @@
package android.telephony.ims.stub;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -60,7 +62,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -77,6 +79,7 @@
return result;
}
+ @NonNull
@Override
public String toString() {
return "{s=" + slotId + ", f=" + ImsFeature.FEATURE_LOG_MAP.get(featureType) + "}";
diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java
index 52b51d2..ac258cd 100644
--- a/telephony/java/android/telephony/mbms/DownloadRequest.java
+++ b/telephony/java/android/telephony/mbms/DownloadRequest.java
@@ -17,6 +17,7 @@
package android.telephony.mbms;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.content.Intent;
@@ -381,7 +382,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null) {
return false;
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index e1113eb..668a6af 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -111,6 +111,9 @@
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_5G_NETWORK_CHANGED = BASE + 52;
+ public static final int EVENT_5G_TIMER_HYSTERESIS = BASE + 53;
+ public static final int EVENT_5G_TIMER_WATCHDOG = BASE + 54;
/***** Constants *****/
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 6b3126d..d892e55 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -696,6 +696,89 @@
}
/**
+ * Pre-processes an SMS WAP for Teleservice Id 0xFDEA(65002).
+ *
+ * It requires an additional header parsing to extract new Message Identifier and new User Data
+ * from WDP SMS User Data.
+ *
+ * - WDP SMS User Data Subparameter =
+ * |User Data SUBPARAMETER_ID ~ NUM_FIELDS| + |CHARi| + |RESERVED|
+ *
+ * - WDP SMS User Data Subparameter CHARi =
+ * |New Message Identifier Subparameter(HEADER_IND = 0)| +
+ * |New User Data Subparameter(MSG_ENCODING = ENCODING_OCTET)|
+ *
+ * @return true if preprocessing is successful, false otherwise.
+ */
+ public boolean preprocessCdmaFdeaWap() {
+ try {
+ BitwiseInputStream inStream = new BitwiseInputStream(mUserData);
+
+ // Message Identifier SUBPARAMETER_ID(0x00)
+ if (inStream.read(8) != 0x00) {
+ Rlog.e(LOG_TAG, "Invalid FDEA WDP Header Message Identifier SUBPARAMETER_ID");
+ return false;
+ }
+
+ // Message Identifier SUBPARAM_LEN(0x03)
+ if (inStream.read(8) != 0x03) {
+ Rlog.e(LOG_TAG, "Invalid FDEA WDP Header Message Identifier SUBPARAM_LEN");
+ return false;
+ }
+
+ // Message Identifier MESSAGE_TYPE
+ mBearerData.messageType = inStream.read(4);
+
+ // Message Identifier MESSAGE_ID
+ int msgId = inStream.read(8) << 8;
+ msgId |= inStream.read(8);
+ mBearerData.messageId = msgId;
+ mMessageRef = msgId;
+
+ // Message Identifier HEADER_IND
+ mBearerData.hasUserDataHeader = (inStream.read(1) == 1);
+ if (mBearerData.hasUserDataHeader) {
+ Rlog.e(LOG_TAG, "Invalid FDEA WDP Header Message Identifier HEADER_IND");
+ return false;
+ }
+
+ // Message Identifier RESERVED
+ inStream.skip(3);
+
+ // User Data SUBPARAMETER_ID(0x01)
+ if (inStream.read(8) != 0x01) {
+ Rlog.e(LOG_TAG, "Invalid FDEA WDP Header User Data SUBPARAMETER_ID");
+ return false;
+ }
+
+ // User Data SUBPARAM_LEN
+ int userDataLen = inStream.read(8) * 8;
+
+ // User Data MSG_ENCODING
+ mBearerData.userData.msgEncoding = inStream.read(5);
+ int consumedBits = 5;
+ if (mBearerData.userData.msgEncoding != UserData.ENCODING_OCTET) {
+ Rlog.e(LOG_TAG, "Invalid FDEA WDP Header User Data MSG_ENCODING");
+ return false;
+ }
+
+ // User Data NUM_FIELDS
+ mBearerData.userData.numFields = inStream.read(8);
+ consumedBits += 8;
+
+ int remainingBits = userDataLen - consumedBits;
+ int dataBits = mBearerData.userData.numFields * 8;
+ dataBits = dataBits < remainingBits ? dataBits : remainingBits;
+ mBearerData.userData.payload = inStream.readByteArray(dataBits);
+ mUserData = mBearerData.userData.payload;
+ return true;
+ } catch (BitwiseInputStream.AccessException ex) {
+ Rlog.e(LOG_TAG, "Fail to preprocess FDEA WAP: " + ex);
+ }
+ return false;
+ }
+
+ /**
* Parses a SMS message from its BearerData stream.
*/
@UnsupportedAppUsage
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index 2181bc4..d9be548 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -781,13 +781,13 @@
" > " + SmsConstants.MAX_USER_DATA_BYTES + " bytes)");
}
- /*
- * TODO(cleanup): figure out what the right answer is WRT paddingBits field
- *
- * userData.paddingBits = (userData.payload.length * 8) - (userData.numFields * 7);
- * userData.paddingBits = 0; // XXX this seems better, but why?
- *
- */
+ if (bData.userData.msgEncoding == UserData.ENCODING_7BIT_ASCII) {
+ bData.userData.paddingBits =
+ (bData.userData.payload.length * 8) - (bData.userData.numFields * 7);
+ } else {
+ bData.userData.paddingBits = 0;
+ }
+
int dataBits = (bData.userData.payload.length * 8) - bData.userData.paddingBits;
int paramBits = dataBits + 13;
if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
index 6af174c..3440c65 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
@@ -39,6 +39,9 @@
static public final int TELESERVICE_WEMT = 0x1005;
static public final int TELESERVICE_SCPT = 0x1006;
+ /** Carriers specific Teleservice IDs. */
+ public static final int TELESERVICE_FDEA_WAP = 0xFDEA; // 65002
+
/**
* The following are defined as extensions to the standard teleservices
*/
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 5bb818b..da32c8c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -1247,6 +1247,7 @@
int encodingType = ENCODING_UNKNOWN;
+ Resources r = Resources.getSystem();
// Look up the data encoding scheme
if ((mDataCodingScheme & 0x80) == 0) {
userDataCompressed = (0 != (mDataCodingScheme & 0x20));
@@ -1268,7 +1269,6 @@
case 1: // 8 bit data
//Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet string
//that's stored in 8-bit unpacked format) characters.
- Resources r = Resources.getSystem();
if (r.getBoolean(com.android.internal.
R.bool.config_sms_decode_gsm_8bit_data)) {
encodingType = ENCODING_8BIT;
@@ -1278,7 +1278,8 @@
case 3: // reserved
Rlog.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
+ (mDataCodingScheme & 0xff));
- encodingType = ENCODING_8BIT;
+ encodingType = r.getInteger(
+ com.android.internal.R.integer.default_reserved_data_coding_scheme);
break;
}
}
@@ -1432,7 +1433,6 @@
case ENCODING_8BIT:
//Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet string
//that's stored in 8-bit unpacked format) characters.
- Resources r = Resources.getSystem();
if (r.getBoolean(com.android.internal.
R.bool.config_sms_decode_gsm_8bit_data)) {
mMessageBody = p.getUserDataGSM8bit(count);
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 9a653cf..34ac3dc 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -19,14 +19,14 @@
java_sdk_library {
name: "android.test.mock",
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ":framework-srcs",
+ ],
api_packages: [
"android.test.mock",
],
-
- srcs_lib: "framework-minus-apex",
- srcs_lib_whitelist_pkgs: ["android"],
compile_dex: true,
}
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/AndroidManifest.xml b/tests/BackgroundDexOptServiceIntegrationTests/AndroidManifest.xml
index aec9f77..7291dc7 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/AndroidManifest.xml
+++ b/tests/BackgroundDexOptServiceIntegrationTests/AndroidManifest.xml
@@ -28,6 +28,8 @@
<uses-permission android:name="android.permission.SET_TIME" />
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
+ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
index 7d826f7..4cd56c3 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
+++ b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
@@ -22,6 +22,7 @@
import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
import android.os.storage.StorageManager;
+import android.provider.DeviceConfig;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -30,7 +31,9 @@
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -52,6 +55,13 @@
* 3. Under low storage conditions and package is recently used, check
* that dexopt upgrades test app to $(getprop pm.dexopt.bg-dexopt).
*
+ * When downgrade feature is on (downgrade_unused_apps_enabled flag is set to true):
+ * 4 On low storage, check that the inactive packages are downgraded.
+ * 5. On low storage, check that used packages are upgraded.
+ * 6. On storage completely full, dexopt fails.
+ * 7. Not on low storage, unused packages are upgraded.
+ * 8. Low storage, unused app is downgraded. When app is used again, app is upgraded.
+ *
* Each test case runs "cmd package bg-dexopt-job com.android.frameworks.bgdexopttest".
*
* The setup for these tests make sure this package has been configured to have been recently used
@@ -59,6 +69,10 @@
* recently used, it sets the time forward more than
* `getprop pm.dexopt.downgrade_after_inactive_days` days.
*
+ * For some of the tests, the DeviceConfig flags inactive_app_threshold_days and
+ * downgrade_unused_apps_enabled are set. These turn on/off the downgrade unused apps feature for
+ * all devices and set the time threshold for unused apps.
+ *
* For tests that require low storage, the phone is filled up.
*
* Run with "atest BackgroundDexOptServiceIntegrationTests".
@@ -80,10 +94,14 @@
"pm.dexopt.downgrade_after_inactive_days", 0);
// Needs to be between 1.0 and 2.0.
private static final double LOW_STORAGE_MULTIPLIER = 1.5;
+ private static final int DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS = 15;
// The file used to fill up storage.
private File mBigFile;
+ @Rule
+ public ExpectedException mExpectedException = ExpectedException.none();
+
// Remember start time.
@BeforeClass
public static void setUpAll() {
@@ -196,11 +214,27 @@
logSpaceRemaining();
}
+ private void fillUpStorageCompletely() throws IOException {
+ fillUpStorage((getStorageLowBytes()));
+ }
+
// Fill up storage so that device is in low storage condition.
private void fillUpToLowStorage() throws IOException {
fillUpStorage((long) (getStorageLowBytes() * LOW_STORAGE_MULTIPLIER));
}
+ private void setInactivePackageThreshold(int threshold) {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ "inactive_app_threshold_days", Integer.toString(threshold), false);
+ }
+
+ private void enableDowngradeFeature(boolean enabled) {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ "downgrade_unused_apps_enabled", Boolean.toString(enabled), false);
+ }
+
// TODO(aeubanks): figure out how to get scheduled bg-dexopt to run
private static void runBackgroundDexOpt() throws IOException {
String result = runShellCommand("cmd package bg-dexopt-job " + PACKAGE_NAME);
@@ -244,7 +278,7 @@
// Test that background dexopt under normal conditions succeeds.
@Test
- public void testBackgroundDexOpt() throws IOException {
+ public void testBackgroundDexOpt_normalConditions_dexOptSucceeds() throws IOException {
// Set filter to quicken.
compilePackageWithFilter(PACKAGE_NAME, "verify");
Assert.assertEquals("verify", getCompilerFilter(PACKAGE_NAME));
@@ -257,17 +291,16 @@
// Test that background dexopt under low storage conditions upgrades used packages.
@Test
- public void testBackgroundDexOptDowngradeSkipRecentlyUsedPackage() throws IOException {
+ public void testBackgroundDexOpt_lowStorage_usedPkgsUpgraded() throws IOException {
// Should be less than DOWNGRADE_AFTER_DAYS.
long deltaDays = DOWNGRADE_AFTER_DAYS - 1;
try {
+ enableDowngradeFeature(false);
// Set time to future.
setTimeFutureDays(deltaDays);
-
// Set filter to quicken.
compilePackageWithFilter(PACKAGE_NAME, "quicken");
Assert.assertEquals("quicken", getCompilerFilter(PACKAGE_NAME));
-
// Fill up storage to trigger low storage threshold.
fillUpToLowStorage();
@@ -282,18 +315,20 @@
}
// Test that background dexopt under low storage conditions downgrades unused packages.
+ // This happens if the system property pm.dexopt.downgrade_after_inactive_days is set
+ // (e.g. on Android Go devices).
@Test
- public void testBackgroundDexOptDowngradeSuccessful() throws IOException {
+ public void testBackgroundDexOpt_lowStorage_unusedPkgsDowngraded()
+ throws IOException {
// Should be more than DOWNGRADE_AFTER_DAYS.
long deltaDays = DOWNGRADE_AFTER_DAYS + 1;
try {
+ enableDowngradeFeature(false);
// Set time to future.
setTimeFutureDays(deltaDays);
-
// Set filter to quicken.
compilePackageWithFilter(PACKAGE_NAME, "quicken");
Assert.assertEquals("quicken", getCompilerFilter(PACKAGE_NAME));
-
// Fill up storage to trigger low storage threshold.
fillUpToLowStorage();
@@ -307,4 +342,134 @@
}
}
+ // Test that the background dexopt downgrades inactive packages when the downgrade feature is
+ // enabled.
+ @Test
+ public void testBackgroundDexOpt_downgradeFeatureEnabled_lowStorage_inactivePkgsDowngraded()
+ throws IOException {
+ // Should be more than DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS.
+ long deltaDays = DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS + 1;
+ try {
+ enableDowngradeFeature(true);
+ setInactivePackageThreshold(DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS);
+ // Set time to future.
+ setTimeFutureDays(deltaDays);
+ // Set filter to quicken.
+ compilePackageWithFilter(PACKAGE_NAME, "quicken");
+ Assert.assertEquals("quicken", getCompilerFilter(PACKAGE_NAME));
+ // Fill up storage to trigger low storage threshold.
+ fillUpToLowStorage();
+
+ runBackgroundDexOpt();
+
+ // Verify that downgrade is successful.
+ Assert.assertEquals(DOWNGRADE_COMPILER_FILTER, getCompilerFilter(PACKAGE_NAME));
+ } finally {
+ // Reset time.
+ setTimeFutureDays(-deltaDays);
+ }
+ }
+
+ // Test that the background dexopt upgrades used packages when the downgrade feature is enabled.
+ // This test doesn't fill the device storage completely, but to a multiplier of the low storage
+ // threshold and this is why apps can still be optimized.
+ @Test
+ public void testBackgroundDexOpt_downgradeFeatureEnabled_lowStorage_usedPkgsUpgraded()
+ throws IOException {
+ enableDowngradeFeature(true);
+ // Set filter to quicken.
+ compilePackageWithFilter(PACKAGE_NAME, "quicken");
+ Assert.assertEquals("quicken", getCompilerFilter(PACKAGE_NAME));
+ // Fill up storage to trigger low storage threshold.
+ fillUpToLowStorage();
+
+ runBackgroundDexOpt();
+
+ /// Verify that bg-dexopt is successful in upgrading the used packages.
+ Assert.assertEquals(BG_DEXOPT_COMPILER_FILTER, getCompilerFilter(PACKAGE_NAME));
+ }
+
+ // Test that the background dexopt fails and doesn't change the compilation filter of used
+ // packages when the downgrade feature is enabled and the storage is filled up completely.
+ // The bg-dexopt shouldn't optimise nor downgrade these packages.
+ @Test
+ public void testBackgroundDexOpt_downgradeFeatureEnabled_fillUpStorageCompletely_dexOptFails()
+ throws IOException {
+ enableDowngradeFeature(true);
+ String previousCompilerFilter = getCompilerFilter(PACKAGE_NAME);
+
+ // Fill up storage completely, without using a multiplier for the low storage threshold.
+ fillUpStorageCompletely();
+
+ // When the bg dexopt runs with the storage filled up completely, it will fail.
+ mExpectedException.expect(IllegalStateException.class);
+ runBackgroundDexOpt();
+
+ /// Verify that bg-dexopt doesn't change the compilation filter of used apps.
+ Assert.assertEquals(previousCompilerFilter, getCompilerFilter(PACKAGE_NAME));
+ }
+
+ // Test that the background dexopt upgrades the unused packages when the downgrade feature is
+ // on if the device is not low on storage.
+ @Test
+ public void testBackgroundDexOpt_downgradeFeatureEnabled_notLowStorage_unusedPkgsUpgraded()
+ throws IOException {
+ // Should be more than DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS.
+ long deltaDays = DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS + 1;
+ try {
+ enableDowngradeFeature(true);
+ setInactivePackageThreshold(DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS);
+ // Set time to future.
+ setTimeFutureDays(deltaDays);
+ // Set filter to quicken.
+ compilePackageWithFilter(PACKAGE_NAME, "quicken");
+ Assert.assertEquals("quicken", getCompilerFilter(PACKAGE_NAME));
+
+ runBackgroundDexOpt();
+
+ // Verify that bg-dexopt is successful in upgrading the unused packages when the device
+ // is not low on storage.
+ Assert.assertEquals(BG_DEXOPT_COMPILER_FILTER, getCompilerFilter(PACKAGE_NAME));
+ } finally {
+ // Reset time.
+ setTimeFutureDays(-deltaDays);
+ }
+ }
+
+ // Test that when an unused package (which was downgraded) is used again, it's re-optimized when
+ // bg-dexopt runs again.
+ @Test
+ public void testBackgroundDexOpt_downgradeFeatureEnabled_downgradedPkgsUpgradedAfterUse()
+ throws IOException {
+ // Should be more than DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS.
+ long deltaDays = DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS + 1;
+ try {
+ enableDowngradeFeature(true);
+ setInactivePackageThreshold(DOWNGRADE_FEATURE_PKG_INACTIVE_AFTER_DAYS);
+ // Set time to future.
+ setTimeFutureDays(deltaDays);
+ // Fill up storage to trigger low storage threshold.
+ fillUpToLowStorage();
+ // Set filter to quicken.
+ compilePackageWithFilter(PACKAGE_NAME, "quicken");
+ Assert.assertEquals("quicken", getCompilerFilter(PACKAGE_NAME));
+
+ runBackgroundDexOpt();
+
+ // Verify that downgrade is successful.
+ Assert.assertEquals(DOWNGRADE_COMPILER_FILTER, getCompilerFilter(PACKAGE_NAME));
+
+ // Reset time.
+ setTimeFutureDays(-deltaDays);
+ deltaDays = 0;
+ runBackgroundDexOpt();
+
+ // Verify that bg-dexopt is successful in upgrading the unused packages that were used
+ // again.
+ Assert.assertEquals(BG_DEXOPT_COMPILER_FILTER, getCompilerFilter(PACKAGE_NAME));
+ } finally {
+ // Reset time.
+ setTimeFutureDays(-deltaDays);
+ }
+ }
}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index 720c1af..ed8f272 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -19,6 +19,8 @@
import static com.android.cts.install.lib.InstallUtils.processUserData;
import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
import static com.android.cts.rollback.lib.RollbackUtils.getUniqueRollbackInfoForPackage;
+import static com.android.cts.rollback.lib.RollbackUtils.waitForAvailableRollback;
+import static com.android.cts.rollback.lib.RollbackUtils.waitForUnavailableRollback;
import static com.google.common.truth.Truth.assertThat;
@@ -118,8 +120,7 @@
}
// The app should not be available for rollback.
- assertThat(
- getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
+ waitForUnavailableRollback(TestApp.A);
// There should be no recently committed rollbacks for this package.
assertThat(getUniqueRollbackInfoForPackage(
@@ -134,9 +135,7 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
// The app should now be available for rollback.
- RollbackInfo available = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
- assertThat(available).isNotNull();
+ RollbackInfo available = waitForAvailableRollback(TestApp.A);
assertThat(available).isNotStaged();
assertThat(available).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
@@ -197,14 +196,12 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
// Both test apps should now be available for rollback.
- RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
+ RollbackInfo rollbackA = waitForAvailableRollback(TestApp.A);
assertThat(rollbackA).isNotNull();
assertThat(rollbackA).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
- RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.B);
+ RollbackInfo rollbackB = waitForAvailableRollback(TestApp.B);
assertThat(rollbackB).isNotNull();
assertThat(rollbackB).packagesContainsExactly(
Rollback.from(TestApp.B2).to(TestApp.B1));
@@ -213,14 +210,12 @@
rm.reloadPersistedData();
// The apps should still be available for rollback.
- rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
+ rollbackA = waitForAvailableRollback(TestApp.A);
assertThat(rollbackA).isNotNull();
assertThat(rollbackA).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
- rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.B);
+ rollbackB = waitForAvailableRollback(TestApp.B);
assertThat(rollbackB).isNotNull();
assertThat(rollbackB).packagesContainsExactly(
Rollback.from(TestApp.B2).to(TestApp.B1));
@@ -255,15 +250,13 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
// The app should now be available for rollback.
- RollbackInfo availableA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
+ RollbackInfo availableA = waitForAvailableRollback(TestApp.A);
assertThat(availableA).isNotNull();
assertThat(availableA).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1),
Rollback.from(TestApp.B2).to(TestApp.B1));
- RollbackInfo availableB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.B);
+ RollbackInfo availableB = waitForAvailableRollback(TestApp.B);
assertThat(availableB).isNotNull();
assertThat(availableB).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1),
@@ -276,13 +269,13 @@
rm.reloadPersistedData();
// The apps should still be available for rollback.
- availableA = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A);
+ availableA = waitForAvailableRollback(TestApp.A);
assertThat(availableA).isNotNull();
assertThat(availableA).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1),
Rollback.from(TestApp.B2).to(TestApp.B1));
- availableB = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.B);
+ availableB = waitForAvailableRollback(TestApp.B);
assertThat(availableB).isNotNull();
assertThat(availableB).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1),
@@ -334,8 +327,7 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
// The app should now be available for rollback.
- RollbackInfo available = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
+ RollbackInfo available = waitForAvailableRollback(TestApp.A);
assertThat(available).isNotNull();
// Roll back the app.
@@ -405,13 +397,11 @@
// Check that the rollback data has not expired
Thread.sleep(1000);
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
- assertThat(rollback).isNotNull();
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
assertThat(rollback).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
- // Give it a little more time, but still not the long enough to expire
+ // Give it a little more time, but still not long enough to expire
Thread.sleep(expirationTime / 2);
rollback = getUniqueRollbackInfoForPackage(
rm.getAvailableRollbacks(), TestApp.A);
@@ -536,9 +526,7 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
// The app should now be available for rollback.
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
- assertThat(rollback).isNotNull();
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
assertThat(rollback).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
@@ -570,9 +558,7 @@
Install.single(TestApp.A2).setEnableRollback().commit();
processUserData(TestApp.A);
- RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
RollbackUtils.rollback(rollback.getRollbackId());
processUserData(TestApp.A);
} finally {
@@ -598,10 +584,7 @@
Install.single(TestApp.ASplit2).setEnableRollback().commit();
processUserData(TestApp.A);
- RollbackManager rm = RollbackUtils.getRollbackManager();
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
- assertThat(rollback).isNotNull();
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
RollbackUtils.rollback(rollback.getRollbackId());
processUserData(TestApp.A);
} finally {
@@ -644,7 +627,6 @@
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS);
- RollbackManager rm = RollbackUtils.getRollbackManager();
// Prep installation of the test apps.
Uninstall.packages(TestApp.A);
@@ -659,15 +641,11 @@
// Both test apps should now be available for rollback, and the
// RollbackInfo returned for the rollbacks should be correct.
- RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
- assertThat(rollbackA).isNotNull();
+ RollbackInfo rollbackA = waitForAvailableRollback(TestApp.A);
assertThat(rollbackA).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
- RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.B);
- assertThat(rollbackB).isNotNull();
+ RollbackInfo rollbackB = waitForAvailableRollback(TestApp.B);
assertThat(rollbackB).packagesContainsExactly(
Rollback.from(TestApp.B2).to(TestApp.B1));
@@ -822,8 +800,7 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
// TestApp.A should now be available for rollback.
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
assertThat(rollback).isNotNull();
assertThat(rollback).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1),
@@ -938,7 +915,6 @@
Manifest.permission.TEST_MANAGE_ROLLBACKS,
Manifest.permission.FORCE_STOP_PACKAGES,
Manifest.permission.RESTART_PACKAGES);
- RollbackManager rm = RollbackUtils.getRollbackManager();
// Prep installation of the test apps.
Uninstall.packages(TestApp.A, TestApp.B);
@@ -952,13 +928,11 @@
// Both test apps should now be available for rollback, and the
// targetPackage returned for rollback should be correct.
- RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
+ RollbackInfo rollbackA = waitForAvailableRollback(TestApp.A);
assertThat(rollbackA).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
- RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.B);
+ RollbackInfo rollbackB = waitForAvailableRollback(TestApp.B);
assertThat(rollbackB).packagesContainsExactly(
Rollback.from(TestApp.B2).to(TestApp.B1));
@@ -1002,8 +976,7 @@
Install.single(TestApp.A2).setEnableRollback().commit();
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
- RollbackInfo rollback = getUniqueRollbackInfoForPackage(
- rm.getAvailableRollbacks(), TestApp.A);
+ RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
assertThat(rollback).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
@@ -1047,6 +1020,7 @@
Uninstall.packages(TestApp.A);
Install.single(TestApp.A1).commit();
+ waitForUnavailableRollback(TestApp.A);
// Block the RollbackManager to make extra sure it will not be
// able to enable the rollback in time.
@@ -1055,6 +1029,10 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+ // Give plenty of time for RollbackManager to unblock and attempt
+ // to make the rollback available before asserting that the
+ // rollback was not made available.
+ Thread.sleep(TimeUnit.SECONDS.toMillis(2));
assertThat(
getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
} finally {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index f3c735c..6ae639a 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -5692,7 +5692,6 @@
String[] values = tcpBufferSizes.split(",");
String rmemValues = String.join(" ", values[0], values[1], values[2]);
String wmemValues = String.join(" ", values[3], values[4], values[5]);
- waitForIdle();
verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues);
reset(mMockNetd);
}
@@ -5700,18 +5699,32 @@
@Test
public void testTcpBufferReset() throws Exception {
final String testTcpBufferSizes = "1,2,3,4,5,6";
+ final NetworkRequest networkRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ final TestNetworkCallback networkCallback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(networkRequest, networkCallback);
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
reset(mMockNetd);
// Switching default network updates TCP buffer sizes.
mCellNetworkAgent.connect(false);
+ networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES);
// Change link Properties should have updated tcp buffer size.
LinkProperties lp = new LinkProperties();
lp.setTcpBufferSizes(testTcpBufferSizes);
mCellNetworkAgent.sendLinkProperties(lp);
+ networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verifyTcpBufferSizeChange(testTcpBufferSizes);
+
+ // Clean up.
+ mCellNetworkAgent.disconnect();
+ networkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ networkCallback.assertNoCallback();
+ mCm.unregisterNetworkCallback(networkCallback);
}
@Test
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index 6ce2121..6a03c73 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -211,6 +211,7 @@
/** Draft 11mc version supported, including major and minor version. e.g, draft 4.3 is 43 */
public int mcVersion;
+ @NonNull
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -1130,6 +1131,7 @@
*/
public int preamble;
+ @NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index f2ae447..eb5a717 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.pm.PackageManager;
@@ -510,6 +511,12 @@
public String preSharedKey;
/**
+ * Optional SAE Password Id for use with WPA3-SAE. It is an ASCII string.
+ * @hide
+ */
+ public @Nullable String saePasswordId;
+
+ /**
* Four WEP keys. For each of the four values, provide either an ASCII
* string enclosed in double quotation marks (e.g., {@code "abcdef"}),
* a string of hex digits (e.g., {@code 0102030405}), or an empty string
@@ -2004,6 +2011,9 @@
sbuf.append('*');
}
+ sbuf.append('\n').append(" SAE Password Id: ");
+ sbuf.append(this.saePasswordId);
+
sbuf.append("\nEnterprise config:\n");
sbuf.append(enterpriseConfig);
@@ -2372,6 +2382,7 @@
providerFriendlyName = source.providerFriendlyName;
isHomeProviderNetwork = source.isHomeProviderNetwork;
preSharedKey = source.preSharedKey;
+ saePasswordId = source.saePasswordId;
mNetworkSelectionStatus.copy(source.getNetworkSelectionStatus());
apBand = source.apBand;
@@ -2462,6 +2473,7 @@
dest.writeLong(roamingConsortiumId);
}
dest.writeString(preSharedKey);
+ dest.writeString(saePasswordId);
for (String wepKey : wepKeys) {
dest.writeString(wepKey);
}
@@ -2537,6 +2549,7 @@
config.roamingConsortiumIds[i] = in.readLong();
}
config.preSharedKey = in.readString();
+ config.saePasswordId = in.readString();
for (int i = 0; i < config.wepKeys.length; i++) {
config.wepKeys[i] = in.readString();
}
@@ -2608,6 +2621,7 @@
out.writeInt(apBand);
out.writeInt(apChannel);
BackupUtils.writeString(out, preSharedKey);
+ BackupUtils.writeString(out, saePasswordId);
out.writeInt(getAuthType());
out.writeBoolean(hiddenSSID);
return baos.toByteArray();
@@ -2631,6 +2645,7 @@
config.apBand = in.readInt();
config.apChannel = in.readInt();
config.preSharedKey = BackupUtils.readString(in);
+ config.saePasswordId = BackupUtils.readString(in);
config.allowedKeyManagement.set(in.readInt());
if (version >= 3) {
config.hiddenSSID = in.readBoolean();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e9c24cd..6bf7bfb9 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -634,10 +634,19 @@
*/
public static final int SAP_START_FAILURE_NO_CHANNEL = 1;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"IFACE_IP_MODE_"}, value = {
+ IFACE_IP_MODE_UNSPECIFIED,
+ IFACE_IP_MODE_CONFIGURATION_ERROR,
+ IFACE_IP_MODE_TETHERED,
+ IFACE_IP_MODE_LOCAL_ONLY})
+ public @interface IfaceIpMode {}
+
/**
* Interface IP mode unspecified.
*
- * @see updateInterfaceIpState(String, int)
+ * @see #updateInterfaceIpState(String, int)
*
* @hide
*/
@@ -646,7 +655,7 @@
/**
* Interface IP mode for configuration error.
*
- * @see updateInterfaceIpState(String, int)
+ * @see #updateInterfaceIpState(String, int)
*
* @hide
*/
@@ -655,7 +664,7 @@
/**
* Interface IP mode for tethering.
*
- * @see updateInterfaceIpState(String, int)
+ * @see #updateInterfaceIpState(String, int)
*
* @hide
*/
@@ -664,7 +673,7 @@
/**
* Interface IP mode for Local Only Hotspot.
*
- * @see updateInterfaceIpState(String, int)
+ * @see #updateInterfaceIpState(String, int)
*
* @hide
*/
@@ -2670,9 +2679,9 @@
/**
* Call allowing ConnectivityService to update WifiService with interface mode changes.
*
- * The possible modes include: {@link IFACE_IP_MODE_TETHERED},
- * {@link IFACE_IP_MODE_LOCAL_ONLY},
- * {@link IFACE_IP_MODE_CONFIGURATION_ERROR}
+ * The possible modes include: {@link #IFACE_IP_MODE_TETHERED},
+ * {@link #IFACE_IP_MODE_LOCAL_ONLY},
+ * {@link #IFACE_IP_MODE_CONFIGURATION_ERROR}
*
* @param ifaceName String name of the updated interface
* @param mode int representing the new mode
@@ -3397,6 +3406,7 @@
private final CloseGuard mCloseGuard = CloseGuard.get();
private final WifiConfiguration mConfig;
+ private boolean mClosed = false;
/** @hide */
@VisibleForTesting
@@ -3412,8 +3422,13 @@
@Override
public void close() {
try {
- stopLocalOnlyHotspot();
- mCloseGuard.close();
+ synchronized (mLock) {
+ if (!mClosed) {
+ mClosed = true;
+ stopLocalOnlyHotspot();
+ mCloseGuard.close();
+ }
+ }
} catch (Exception e) {
Log.e(TAG, "Failed to stop Local Only Hotspot.");
}
diff --git a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java b/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
index 8262a7a..95b2e77 100644
--- a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
+++ b/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java
@@ -16,8 +16,8 @@
package android.net.wifi;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
-
import android.os.Parcel;
import android.os.Parcelable;
@@ -39,7 +39,7 @@
public WifiNetworkConnectionStatistics() { }
-
+ @NonNull
@Override
public String toString() {
StringBuilder sbuf = new StringBuilder();
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
index 57dff9d..a32bd54 100644
--- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
+++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
@@ -16,6 +16,7 @@
package android.net.wifi.hotspot2;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.graphics.drawable.Icon;
@@ -219,7 +220,7 @@
}
@Override
- public boolean equals(Object thatObject) {
+ public boolean equals(@Nullable Object thatObject) {
if (this == thatObject) {
return true;
}
@@ -246,6 +247,7 @@
mServerUri, mNetworkAccessIdentifier, mMethodList);
}
+ @NonNull
@Override
public String toString() {
return "OsuProvider{mOsuSsid=" + mOsuSsid
diff --git a/wifi/java/android/net/wifi/rtt/RangingRequest.java b/wifi/java/android/net/wifi/rtt/RangingRequest.java
index 70af03e..318efa6 100644
--- a/wifi/java/android/net/wifi/rtt/RangingRequest.java
+++ b/wifi/java/android/net/wifi/rtt/RangingRequest.java
@@ -17,6 +17,7 @@
package android.net.wifi.rtt;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.MacAddress;
import android.net.wifi.ScanResult;
@@ -245,7 +246,7 @@
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
diff --git a/wifi/java/android/net/wifi/rtt/ResponderConfig.java b/wifi/java/android/net/wifi/rtt/ResponderConfig.java
index e6ae483..64dfc34 100644
--- a/wifi/java/android/net/wifi/rtt/ResponderConfig.java
+++ b/wifi/java/android/net/wifi/rtt/ResponderConfig.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.MacAddress;
import android.net.wifi.ScanResult;
@@ -443,7 +444,7 @@
};
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}