Merge "TaskOrganizer: Don't set any position at all."
diff --git a/Android.bp b/Android.bp
index ffb4d3a..2318f7b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -734,6 +734,7 @@
         "core/java/android/annotation/RequiresPermission.java",
         "core/java/android/annotation/SystemApi.java",
         "core/java/android/annotation/TestApi.java",
+        "core/java/com/android/internal/annotations/GuardedBy.java",
     ],
 }
 // Build ext.jar
diff --git a/apex/statsd/Android.bp b/apex/statsd/Android.bp
index 09ca1d2..1f9f18c 100644
--- a/apex/statsd/Android.bp
+++ b/apex/statsd/Android.bp
@@ -19,8 +19,9 @@
 }
 
 apex_defaults {
-    // libc.so and libcutils.so are included in the apex
-    // native_shared_libs: ["libc", "libcutils"],
+    native_shared_libs: [
+        "libstats_jni",
+    ],
     // binaries: ["vold"],
     java_libs: [
         "framework-statsd",
@@ -44,3 +45,33 @@
     // com.android.os.statsd.pk8 (the private key)
     certificate: "com.android.os.statsd",
 }
+
+
+// JNI library for StatsLog.write
+cc_library_shared {
+    name: "libstats_jni",
+    srcs: ["jni/**/*.cpp"],
+    shared_libs: [
+        "libnativehelper", // Has stable abi - should not be copied into apex.
+        "liblog",  // Has a stable abi - should not be copied into apex.
+    ],
+    static_libs: [
+        //TODO: make shared - need libstatssocket to also live in the apex.
+        "libstatssocket",
+        "libcutils", // TODO: remove - needed by libstatssocket
+    ],
+    //TODO: is libc++_static correct?
+    stl: "libc++_static",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+        "-Wno-unused-parameter",
+    ],
+    apex_available: [
+        "com.android.os.statsd",
+        "test_com.android.os.statsd",
+        //TODO (b/148620413): remove platform.
+         "//apex_available:platform",
+    ],
+}
\ No newline at end of file
diff --git a/core/jni/android_util_StatsLog.cpp b/apex/statsd/jni/android_util_StatsLog.cpp
similarity index 71%
rename from core/jni/android_util_StatsLog.cpp
rename to apex/statsd/jni/android_util_StatsLog.cpp
index 9225fc2..9d410eb 100644
--- a/core/jni/android_util_StatsLog.cpp
+++ b/apex/statsd/jni/android_util_StatsLog.cpp
@@ -17,12 +17,9 @@
 #define LOG_NAMESPACE "StatsLog.tag."
 #define LOG_TAG "StatsLog_println"
 
-#include <assert.h>
-
 #include "jni.h"
+#include <log/log.h>
 #include <nativehelper/JNIHelp.h>
-#include "utils/misc.h"
-#include "core_jni_helpers.h"
 #include "stats_buffer_writer.h"
 
 namespace android {
@@ -57,7 +54,27 @@
 
 int register_android_util_StatsLog(JNIEnv* env)
 {
-    return RegisterMethodsOrDie(env, "android/util/StatsLog", gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "android/util/StatsLog", gMethods, NELEM(gMethods));
 }
-
 }; // namespace android
+
+/*
+ * JNI Initialization
+ */
+jint JNI_OnLoad(JavaVM* jvm, void* reserved) {
+    JNIEnv* e;
+    int status;
+
+    ALOGV("statsd : loading JNI\n");
+    // Check JNI version
+    if (jvm->GetEnv((void**)&e, JNI_VERSION_1_4)) {
+        ALOGE("JNI version mismatch error");
+        return JNI_ERR;
+    }
+    status = android::register_android_util_StatsLog(e);
+    if (status < 0) {
+        ALOGE("jni statsd registration failure, status: %d", status);
+        return JNI_ERR;
+    }
+    return JNI_VERSION_1_4;
+}
diff --git a/api/current.txt b/api/current.txt
index 510db01..a50a4c2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9990,7 +9990,7 @@
     method public abstract android.content.Context createDisplayContext(@NonNull android.view.Display);
     method @NonNull public android.content.Context createFeatureContext(@Nullable String);
     method public abstract android.content.Context createPackageContext(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @NonNull public android.content.Context createWindowContext(int);
+    method @NonNull public android.content.Context createWindowContext(int, @Nullable android.os.Bundle);
     method public abstract String[] databaseList();
     method public abstract boolean deleteDatabase(String);
     method public abstract boolean deleteFile(String);
@@ -31129,11 +31129,6 @@
     field @Deprecated public static final String[] strings;
   }
 
-  @Deprecated public static class WifiConfiguration.SuiteBCipher {
-    field @Deprecated public static final int ECDHE_ECDSA = 0; // 0x0
-    field @Deprecated public static final int ECDHE_RSA = 1; // 0x1
-  }
-
   public class WifiEnterpriseConfig implements android.os.Parcelable {
     ctor public WifiEnterpriseConfig();
     ctor public WifiEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
@@ -31616,6 +31611,7 @@
     method public android.net.wifi.hotspot2.pps.Credential getCredential();
     method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
     method public long getSubscriptionExpirationTimeInMillis();
+    method @NonNull public String getUniqueId() throws java.lang.IllegalStateException;
     method public boolean isOsuProvisioned();
     method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
     method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
@@ -31796,8 +31792,8 @@
     method public boolean isGroupOwner();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroup> CREATOR;
-    field public static final int PERSISTENT_NET_ID = -2; // 0xfffffffe
-    field public static final int TEMPORARY_NET_ID = -1; // 0xffffffff
+    field public static final int NETWORK_ID_PERSISTENT = -2; // 0xfffffffe
+    field public static final int NETWORK_ID_TEMPORARY = -1; // 0xffffffff
   }
 
   public class WifiP2pInfo implements android.os.Parcelable {
@@ -36944,7 +36940,7 @@
     ctor public VibrationAttributes.Builder();
     ctor public VibrationAttributes.Builder(@Nullable android.os.VibrationAttributes);
     method @NonNull public android.os.VibrationAttributes build();
-    method @NonNull public android.os.VibrationAttributes.Builder replaceFlags(int);
+    method @NonNull public android.os.VibrationAttributes.Builder setFlags(int, int);
     method @NonNull public android.os.VibrationAttributes.Builder setUsage(int);
   }
 
@@ -46381,7 +46377,6 @@
   public final class BarringInfo implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public android.telephony.BarringInfo.BarringServiceInfo getBarringServiceInfo(int);
-    method public boolean isServiceBarred(int);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final int BARRING_SERVICE_TYPE_CS_FALLBACK = 5; // 0x5
     field public static final int BARRING_SERVICE_TYPE_CS_SERVICE = 0; // 0x0
diff --git a/api/system-current.txt b/api/system-current.txt
index 0930f68..83889d4 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1604,7 +1604,7 @@
   }
 
   public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
   }
 
   public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile {
@@ -6233,7 +6233,7 @@
   }
 
   public abstract class NetworkAgent {
-    ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
+    ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkScore, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
     method @Nullable public android.net.Network getNetwork();
     method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
     method public void onAutomaticReconnectDisabled();
@@ -6248,7 +6248,7 @@
     method @NonNull public android.net.Network register();
     method public void sendLinkProperties(@NonNull android.net.LinkProperties);
     method public void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
-    method public void sendNetworkScore(int);
+    method public void sendNetworkScore(@NonNull android.net.NetworkScore);
     method public void sendSocketKeepaliveEvent(int, int);
     method public void setConnected();
     method @Deprecated public void setLegacyExtraInfo(@Nullable String);
@@ -6351,6 +6351,55 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
   }
 
+  public final class NetworkScore implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.NetworkScore.Metrics getEndToEndMetrics();
+    method @NonNull public android.net.NetworkScore.Metrics getLinkLayerMetrics();
+    method public int getRange();
+    method @IntRange(from=android.net.NetworkScore.UNKNOWN_SIGNAL_STRENGTH, to=android.net.NetworkScore.MAX_SIGNAL_STRENGTH) public int getSignalStrength();
+    method public boolean hasPolicy(int);
+    method public boolean isExiting();
+    method @NonNull public android.net.NetworkScore withExiting(boolean);
+    method @NonNull public android.net.NetworkScore withSignalStrength(@IntRange(from=android.net.NetworkScore.UNKNOWN_SIGNAL_STRENGTH) int);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkScore> CREATOR;
+    field public static final int MAX_SIGNAL_STRENGTH = 1000; // 0x3e8
+    field public static final int MIN_SIGNAL_STRENGTH = 0; // 0x0
+    field public static final int POLICY_DEFAULT_SUBSCRIPTION = 8; // 0x8
+    field public static final int POLICY_IGNORE_ON_WIFI = 4; // 0x4
+    field public static final int POLICY_LOCKDOWN_VPN = 1; // 0x1
+    field public static final int POLICY_VPN = 2; // 0x2
+    field public static final int RANGE_CLOSE = 1; // 0x1
+    field public static final int RANGE_LONG = 4; // 0x4
+    field public static final int RANGE_MEDIUM = 3; // 0x3
+    field public static final int RANGE_SHORT = 2; // 0x2
+    field public static final int RANGE_UNKNOWN = 0; // 0x0
+    field public static final int UNKNOWN_SIGNAL_STRENGTH = -1; // 0xffffffff
+  }
+
+  public static class NetworkScore.Builder {
+    ctor public NetworkScore.Builder();
+    method @NonNull public android.net.NetworkScore.Builder addPolicy(int);
+    method @NonNull public android.net.NetworkScore build();
+    method @NonNull public android.net.NetworkScore.Builder clearPolicy(int);
+    method @NonNull public android.net.NetworkScore.Builder setEndToEndMetrics(@NonNull android.net.NetworkScore.Metrics);
+    method @NonNull public android.net.NetworkScore.Builder setExiting(boolean);
+    method @NonNull public android.net.NetworkScore.Builder setLegacyScore(int);
+    method @NonNull public android.net.NetworkScore.Builder setLinkLayerMetrics(@NonNull android.net.NetworkScore.Metrics);
+    method @NonNull public android.net.NetworkScore.Builder setRange(int);
+    method @NonNull public android.net.NetworkScore.Builder setSignalStrength(@IntRange(from=android.net.NetworkScore.UNKNOWN_SIGNAL_STRENGTH, to=android.net.NetworkScore.MAX_SIGNAL_STRENGTH) int);
+  }
+
+  public static class NetworkScore.Metrics {
+    ctor public NetworkScore.Metrics(@IntRange(from=android.net.NetworkScore.Metrics.LATENCY_UNKNOWN) int, @IntRange(from=android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN) int, @IntRange(from=android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN) int);
+    field public static final int BANDWIDTH_UNKNOWN = -1; // 0xffffffff
+    field @NonNull public static final android.net.NetworkScore.Metrics EMPTY;
+    field public static final int LATENCY_UNKNOWN = -1; // 0xffffffff
+    field @IntRange(from=android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN) public final int downlinkBandwidthKBps;
+    field @IntRange(from=android.net.NetworkScore.Metrics.LATENCY_UNKNOWN) public final int latencyMs;
+    field @IntRange(from=android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN) public final int uplinkBandwidthKBps;
+  }
+
   public class NetworkScoreManager {
     method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, android.Manifest.permission.REQUEST_NETWORK_SCORES}) public boolean clearScores() throws java.lang.SecurityException;
     method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, android.Manifest.permission.REQUEST_NETWORK_SCORES}) public void disableScoring() throws java.lang.SecurityException;
@@ -7465,6 +7514,7 @@
     method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus getNetworkSelectionStatus();
     method @Deprecated @NonNull public String getPrintableSsid();
     method @Deprecated @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();
+    method @Deprecated public int getRecentFailureReason();
     method @Deprecated @Nullable public android.net.StaticIpConfiguration getStaticIpConfiguration();
     method @Deprecated public boolean hasNoInternetAccess();
     method @Deprecated public boolean isEphemeral();
@@ -7482,6 +7532,8 @@
     field @Deprecated public static final int METERED_OVERRIDE_NOT_METERED = 2; // 0x2
     field @Deprecated public static final int RANDOMIZATION_NONE = 0; // 0x0
     field @Deprecated public static final int RANDOMIZATION_PERSISTENT = 1; // 0x1
+    field @Deprecated public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; // 0x11
+    field @Deprecated public static final int RECENT_FAILURE_NONE = 0; // 0x0
     field @Deprecated public boolean allowAutojoin;
     field @Deprecated public int apBand;
     field @Deprecated public int carrierId;
@@ -7497,7 +7549,6 @@
     field @Deprecated public int numAssociation;
     field @Deprecated public int numScorerOverride;
     field @Deprecated public int numScorerOverrideAndSwitchedNetwork;
-    field @Deprecated @NonNull public final android.net.wifi.WifiConfiguration.RecentFailure recentFailure;
     field @Deprecated public boolean requirePMF;
     field @Deprecated @Nullable public String saePasswordId;
     field @Deprecated public boolean shared;
@@ -7543,12 +7594,6 @@
     method @Deprecated @NonNull public android.net.wifi.WifiConfiguration.NetworkSelectionStatus.Builder setNetworkSelectionStatus(int);
   }
 
-  @Deprecated public static class WifiConfiguration.RecentFailure {
-    method @Deprecated public int getAssociationStatus();
-    field @Deprecated public static final int NONE = 0; // 0x0
-    field @Deprecated public static final int STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17; // 0x11
-  }
-
   public class WifiEnterpriseConfig implements android.os.Parcelable {
     method @Nullable public String[] getCaCertificateAliases();
     method @NonNull public String getCaPath();
diff --git a/api/test-current.txt b/api/test-current.txt
index e0b5b34..1e81943 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1688,6 +1688,55 @@
     field public static final int TRANSPORT_TEST = 7; // 0x7
   }
 
+  public final class NetworkScore implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.NetworkScore.Metrics getEndToEndMetrics();
+    method @NonNull public android.net.NetworkScore.Metrics getLinkLayerMetrics();
+    method public int getRange();
+    method @IntRange(from=android.net.NetworkScore.UNKNOWN_SIGNAL_STRENGTH, to=android.net.NetworkScore.MAX_SIGNAL_STRENGTH) public int getSignalStrength();
+    method public boolean hasPolicy(int);
+    method public boolean isExiting();
+    method @NonNull public android.net.NetworkScore withExiting(boolean);
+    method @NonNull public android.net.NetworkScore withSignalStrength(@IntRange(from=android.net.NetworkScore.UNKNOWN_SIGNAL_STRENGTH) int);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkScore> CREATOR;
+    field public static final int MAX_SIGNAL_STRENGTH = 1000; // 0x3e8
+    field public static final int MIN_SIGNAL_STRENGTH = 0; // 0x0
+    field public static final int POLICY_DEFAULT_SUBSCRIPTION = 8; // 0x8
+    field public static final int POLICY_IGNORE_ON_WIFI = 4; // 0x4
+    field public static final int POLICY_LOCKDOWN_VPN = 1; // 0x1
+    field public static final int POLICY_VPN = 2; // 0x2
+    field public static final int RANGE_CLOSE = 1; // 0x1
+    field public static final int RANGE_LONG = 4; // 0x4
+    field public static final int RANGE_MEDIUM = 3; // 0x3
+    field public static final int RANGE_SHORT = 2; // 0x2
+    field public static final int RANGE_UNKNOWN = 0; // 0x0
+    field public static final int UNKNOWN_SIGNAL_STRENGTH = -1; // 0xffffffff
+  }
+
+  public static class NetworkScore.Builder {
+    ctor public NetworkScore.Builder();
+    method @NonNull public android.net.NetworkScore.Builder addPolicy(int);
+    method @NonNull public android.net.NetworkScore build();
+    method @NonNull public android.net.NetworkScore.Builder clearPolicy(int);
+    method @NonNull public android.net.NetworkScore.Builder setEndToEndMetrics(@NonNull android.net.NetworkScore.Metrics);
+    method @NonNull public android.net.NetworkScore.Builder setExiting(boolean);
+    method @NonNull public android.net.NetworkScore.Builder setLegacyScore(int);
+    method @NonNull public android.net.NetworkScore.Builder setLinkLayerMetrics(@NonNull android.net.NetworkScore.Metrics);
+    method @NonNull public android.net.NetworkScore.Builder setRange(int);
+    method @NonNull public android.net.NetworkScore.Builder setSignalStrength(@IntRange(from=android.net.NetworkScore.UNKNOWN_SIGNAL_STRENGTH, to=android.net.NetworkScore.MAX_SIGNAL_STRENGTH) int);
+  }
+
+  public static class NetworkScore.Metrics {
+    ctor public NetworkScore.Metrics(@IntRange(from=android.net.NetworkScore.Metrics.LATENCY_UNKNOWN) int, @IntRange(from=android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN) int, @IntRange(from=android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN) int);
+    field public static final int BANDWIDTH_UNKNOWN = -1; // 0xffffffff
+    field @NonNull public static final android.net.NetworkScore.Metrics EMPTY;
+    field public static final int LATENCY_UNKNOWN = -1; // 0xffffffff
+    field @IntRange(from=android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN) public final int downlinkBandwidthKBps;
+    field @IntRange(from=android.net.NetworkScore.Metrics.LATENCY_UNKNOWN) public final int latencyMs;
+    field @IntRange(from=android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN) public final int uplinkBandwidthKBps;
+  }
+
   public class NetworkStack {
     field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK";
   }
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index d065401..12058ca 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -232,8 +232,8 @@
         NfcCardemulationOccurred nfc_cardemulation_occurred = 137 [(module) = "nfc"];
         NfcTagOccurred nfc_tag_occurred = 138 [(module) = "nfc"];
         NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139 [(module) = "nfc"];
-        SeStateChanged se_state_changed = 140;
-        SeOmapiReported se_omapi_reported = 141;
+        SeStateChanged se_state_changed = 140 [(module) = "secure_element"];
+        SeOmapiReported se_omapi_reported = 141 [(module) = "secure_element"];
         BroadcastDispatchLatencyReported broadcast_dispatch_latency_reported =
                 142 [(module) = "framework"];
         AttentionManagerServiceResultReported attention_manager_service_result_reported =
@@ -387,6 +387,9 @@
             249 [(module) = "cellbroadcast"];
         CellBroadcastMessageError cb_message_error =
             250 [(module) = "cellbroadcast"];
+        WifiHealthStatReported wifi_health_stat_reported = 251 [(module) = "wifi"];
+        WifiFailureStatReported wifi_failure_stat_reported = 252 [(module) = "wifi"];
+        WifiConnectionResultReported wifi_connection_result_reported = 253 [(module) = "wifi"];
     }
 
     // Pulled events will start at field 10000.
@@ -658,6 +661,81 @@
 }
 
 /**
+ * Logs the change in wifi health.
+ *
+ * Logged from:
+ *   frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiDataStall.java
+ */
+message WifiHealthStatReported {
+    // duration this stat is obtained over in milliseconds
+    optional int32 duration_millis = 1;
+    // whether wifi is classified as sufficient for the user's data traffic, determined
+    // by whether the calculated throughput exceeds the average demand within |duration_millis|
+    optional bool is_sufficient = 2;
+    // whether the calculated throughput is exceeds the minimum required for typical usage
+    optional bool is_throughput_good = 3;
+    // whether cellular data is available
+    optional bool is_cell_data_available = 4;
+    // the WLAN channel the connected network is on (ie. 2412)
+    optional int32 frequency = 5;
+}
+
+/**
+ * Logged when wifi detects a significant change in connection failure rate.
+ *
+ * Logged from: frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiHealthMonitor.java
+ *
+ */
+message WifiFailureStatReported {
+    enum AbnormalityType {
+        UNKNOWN = 0;
+        SIGNIFICANT_INCREASE = 1;
+        SIGNIFICANT_DECREASE = 2;
+        SIMPLY_HIGH = 3;
+    }
+    enum FailureType {
+        FAILURE_UNKNOWN = 0;
+        FAILURE_CONNECTION = 1;
+        FAILURE_ASSOCIATION_REJECTION = 2;
+        FAILURE_ASSOCIATION_TIMEOUT = 3;
+        FAILURE_AUTHENTICATION = 4;
+        FAILURE_NON_LOCAL_DISCONNECTION = 5;
+        FAILURE_SHORT_CONNECTION_DUE_TO_NON_LOCAL_DISCONNECTION = 6;
+    }
+    // Reason for uploading this stat
+    optional AbnormalityType abnormality_type = 1;
+    // The particular type of failure
+    optional FailureType failure_type = 2;
+    // How many times we have encountered this combination of AbnormalityType and FailureType
+    optional int32 failure_count = 3;
+}
+
+/**
+ * Logs whether a wifi connection is successful and reasons for failure if it isn't.
+ *
+ * Logged from:
+ *   frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java
+ */
+message WifiConnectionResultReported {
+    enum FailureCode {
+        FAILURE_UNKNOWN = 0;
+        FAILURE_ASSOCIATION_TIMEOUT = 1;
+        FAILURE_ASSOCIATION_REJECTION = 2;
+        FAILURE_AUTHENTICATION_GENERAL = 3;
+        FAILURE_AUTHENTICATION_EAP = 4;
+        FAILURE_DHCP = 5;
+        FAILURE_NETWORK_DISCONNECTION = 6;
+        FAILURE_ROAM_TIMEOUT = 7;
+    }
+    // true represents a successful connection
+    optional bool connection_result = 1;
+    // reason for the connection failure
+    optional FailureCode failure_code = 2;
+    // scan rssi before the connection attempt
+    optional int32 rssi = 3;
+}
+
+/**
  * Logs when memory stats of a process is reported.
  *
  * Logged from:
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7285da6..04d3e39 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2373,13 +2373,13 @@
     }
 
     @Override
-    public @NonNull WindowContext createWindowContext(int type) {
+    public @NonNull WindowContext createWindowContext(int type, Bundle options) {
         if (getDisplay() == null) {
             throw new UnsupportedOperationException("WindowContext can only be created from "
                     + "other visual contexts, such as Activity or one created with "
                     + "Context#createDisplayContext(Display)");
         }
-        return new WindowContext(this, null /* token */, type);
+        return new WindowContext(this, null /* token */, type, options);
     }
 
     ContextImpl createBaseWindowContext(IBinder token) {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 59c17192..65a5f6b 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -365,11 +365,9 @@
         registerService(Context.TETHERING_SERVICE, TetheringManager.class,
                 new CachedServiceFetcher<TetheringManager>() {
             @Override
-            public TetheringManager createService(ContextImpl ctx) throws ServiceNotFoundException {
-                IBinder b = ServiceManager.getService(Context.TETHERING_SERVICE);
-                if (b == null) return null;
-
-                return new TetheringManager(ctx, b);
+            public TetheringManager createService(ContextImpl ctx) {
+                return new TetheringManager(
+                        ctx, () -> ServiceManager.getService(Context.TETHERING_SERVICE));
             }});
 
 
diff --git a/core/java/android/app/TaskEmbedder.java b/core/java/android/app/TaskEmbedder.java
index 93b1ea8..761b225 100644
--- a/core/java/android/app/TaskEmbedder.java
+++ b/core/java/android/app/TaskEmbedder.java
@@ -48,7 +48,6 @@
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.SurfaceControl;
-import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.inputmethod.InputMethodManager;
 
@@ -131,6 +130,7 @@
     private TaskStackListener mTaskStackListener;
     private Listener mListener;
     private boolean mOpened; // Protected by mGuard.
+    private DisplayMetrics mTmpDisplayMetrics;
 
     private final CloseGuard mGuard = CloseGuard.get();
 
@@ -594,10 +594,11 @@
 
     /** Get density of the hosting display. */
     private int getBaseDisplayDensity() {
-        final WindowManager wm = mContext.getSystemService(WindowManager.class);
-        final DisplayMetrics metrics = new DisplayMetrics();
-        wm.getDefaultDisplay().getMetrics(metrics);
-        return metrics.densityDpi;
+        if (mTmpDisplayMetrics == null) {
+            mTmpDisplayMetrics = new DisplayMetrics();
+        }
+        mContext.getDisplay().getMetrics(mTmpDisplayMetrics);
+        return mTmpDisplayMetrics.densityDpi;
     }
 
     /**
diff --git a/core/java/android/app/WindowContext.java b/core/java/android/app/WindowContext.java
index 22cc14b..36ae450 100644
--- a/core/java/android/app/WindowContext.java
+++ b/core/java/android/app/WindowContext.java
@@ -32,7 +32,7 @@
  * windows. Its resources and configuration are adjusted to the area of the display that will be
  * used when a new window is added via {@link android.view.WindowManager.addView}.
  *
- * @see Context#createWindowContext(int)
+ * @see Context#createWindowContext(int, Bundle)
  * @hide
  */
 // TODO(b/128338354): Handle config/display changes from server side.
@@ -53,7 +53,7 @@
      * @param type Window type to be used with this context.
      * @hide
      */
-    public WindowContext(Context base, IBinder token, int type) {
+    public WindowContext(Context base, IBinder token, int type, Bundle options) {
         super(null /* base */);
 
         mWms = WindowManagerGlobal.getWindowManagerService();
@@ -76,7 +76,7 @@
             return;
         }
         try {
-            mWms.addWindowContextToken(mToken, type, mDisplayId, getPackageName());
+            mWms.addWindowTokenWithOptions(mToken, type, mDisplayId, options, getPackageName());
             // TODO(window-context): remove token with a DeathObserver
         }  catch (RemoteException e) {
             mOwnsToken = false;
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index e24b040..325fd94 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2162,6 +2162,33 @@
     }
 
     /**
+     * Fetches a list of the most recently connected bluetooth devices ordered by how recently they
+     * were connected with most recently first and least recently last
+     *
+     * @return {@link List} of bonded {@link BluetoothDevice} ordered by how recently they were
+     * connected
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    public @NonNull List<BluetoothDevice> getMostRecentlyConnectedDevices() {
+        if (getState() != STATE_ON) {
+            return new ArrayList<>();
+        }
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) {
+                return mService.getMostRecentlyConnectedDevices();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return new ArrayList<>();
+    }
+
+    /**
      * Return the set of {@link BluetoothDevice} objects that are bonded
      * (paired) to the local adapter.
      * <p>If Bluetooth state is not {@link #STATE_ON}, this API
diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java
index a923be6..b5959c0 100644
--- a/core/java/android/bluetooth/BluetoothHidDevice.java
+++ b/core/java/android/bluetooth/BluetoothHidDevice.java
@@ -706,7 +706,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index dfa4fb7..ec40b7e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5728,14 +5728,13 @@
      * shared, however common state (ClassLoader, other Resources for the
      * same configuration) may be so the Context itself can be fairly lightweight.
      *
-     * The returned display Context provides a {@link WindowManager}
-     * (see {@link #getSystemService(String)}) that is configured to show windows
-     * on the given display.  The WindowManager's {@link WindowManager#getDefaultDisplay}
-     * method can be used to retrieve the Display from the returned Context.
+     * To obtain an instance of a {@link WindowManager} (see {@link #getSystemService(String)}) that
+     * is configured to show windows on the given display call
+     * {@link #createWindowContext(int, Bundle)} on the returned display Context or use an
+     * {@link android.app.Activity}.
      *
-     * @param display A {@link Display} object specifying the display
-     * for whose metrics the Context's resources should be tailored and upon which
-     * new windows should be shown.
+     * @param display A {@link Display} object specifying the display for whose metrics the
+     * Context's resources should be tailored.
      *
      * @return A {@link Context} for the display.
      */
@@ -5763,7 +5762,7 @@
      * final DisplayManager dm = anyContext.getSystemService(DisplayManager.class);
      * final Display primaryDisplay = dm.getDisplay(DEFAULT_DISPLAY);
      * final Context windowContext = anyContext.createDisplayContext(primaryDisplay)
-     *         .createWindowContext(TYPE_APPLICATION_OVERLAY);
+     *         .createWindowContext(TYPE_APPLICATION_OVERLAY, null);
      * final View overlayView = Inflater.from(windowContext).inflate(someLayoutXml, null);
      *
      * // WindowManager.LayoutParams initialization
@@ -5783,6 +5782,7 @@
      * </p>
      *
      * @param type Window type in {@link WindowManager.LayoutParams}
+     * @param options Bundle used to pass window-related options.
      * @return A {@link Context} that can be used to create windows.
      * @throws UnsupportedOperationException if this is called on a non-UI context, such as
      *         {@link android.app.Application Application} or {@link android.app.Service Service}.
@@ -5794,7 +5794,7 @@
      * @see #WALLPAPER_SERVICE
      * @throws IllegalArgumentException if token is invalid
      */
-    public @NonNull Context createWindowContext(int type)  {
+    public @NonNull Context createWindowContext(int type, @Nullable Bundle options)  {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
 
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index b2b7988..f6515e8 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -978,8 +978,8 @@
 
     @Override
     @NonNull
-    public Context createWindowContext(int type) {
-        return mBase.createWindowContext(type);
+    public Context createWindowContext(int type, @Nullable Bundle options) {
+        return mBase.createWindowContext(type, options);
     }
 
     @Override
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 9ee56a9..c5b9a43 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -316,6 +316,7 @@
         CameraManagerGlobal.get().unregisterTorchCallback(callback);
     }
 
+    // TODO(b/147726300): Investigate how to support foldables/multi-display devices.
     private Size getDisplaySize() {
         Size ret = new Size(0, 0);
 
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 92047dc..da9cc8a 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -16,7 +16,6 @@
 
 package android.inputmethodservice;
 
-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;
@@ -52,7 +51,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
@@ -64,6 +62,7 @@
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
+import android.util.Size;
 import android.view.Gravity;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
@@ -560,12 +559,10 @@
         @Override
         public void updateInputMethodDisplay(int displayId) {
             // Update display for adding IME window to the right display.
-            if (displayId != DEFAULT_DISPLAY) {
-                // TODO(b/111364446) Need to address context lifecycle issue if need to re-create
-                // for update resources & configuration correctly when show soft input
-                // in non-default display.
-                updateDisplay(displayId);
-            }
+            // TODO(b/111364446) Need to address context lifecycle issue if need to re-create
+            // for update resources & configuration correctly when show soft input
+            // in non-default display.
+            updateDisplay(displayId);
         }
 
         /**
@@ -1466,8 +1463,9 @@
      * screen orientation changes.
      */
     public int getMaxWidth() {
-        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
-        return wm.getDefaultDisplay().getWidth();
+        final WindowManager windowManager = getSystemService(WindowManager.class);
+        final Size windowSize = windowManager.getCurrentWindowMetrics().getSize();
+        return windowSize.getWidth();
     }
     
     /**
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ce9693d..fa12c08 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -3322,15 +3322,19 @@
     // of dependent changes that would conflict throughout the automerger graph. Having this
     // temporarily helps with the process of going through with all these dependent changes across
     // the entire tree.
+    // STOPSHIP (b/148055573) : remove this before R is released.
     /**
      * @hide
      * Register a NetworkAgent with ConnectivityService.
      * @return Network corresponding to NetworkAgent.
+     * @deprecated use the version that takes a NetworkScore and a provider ID.
      */
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+    @Deprecated
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
             NetworkCapabilities nc, int score, NetworkAgentConfig config) {
-        return registerNetworkAgent(messenger, ni, lp, nc, score, config, NetworkProvider.ID_NONE);
+        final NetworkScore ns = new NetworkScore.Builder().setLegacyScore(score).build();
+        return registerNetworkAgent(messenger, ni, lp, nc, ns, config, NetworkProvider.ID_NONE);
     }
 
     /**
@@ -3340,7 +3344,7 @@
      */
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
-            NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) {
+            NetworkCapabilities nc, NetworkScore score, NetworkAgentConfig config, int providerId) {
         try {
             return mService.registerNetworkAgent(messenger, ni, lp, nc, score, config, providerId);
         } catch (RemoteException e) {
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 3e9e7fa..0dc66b5 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -26,6 +26,7 @@
 import android.net.NetworkInfo;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkRequest;
+import android.net.NetworkScore;
 import android.net.NetworkState;
 import android.net.ISocketKeepaliveCallback;
 import android.net.ProxyInfo;
@@ -154,7 +155,7 @@
     void declareNetworkRequestUnfulfillable(in NetworkRequest request);
 
     Network registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
-            in NetworkCapabilities nc, int score, in NetworkAgentConfig config,
+            in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config,
             in int factorySerialNumber);
 
     NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 7cc569a..ddf8dbb 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -117,13 +117,6 @@
     public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
 
     /**
-     * Centralize the place where base network score, and network score scaling, will be
-     * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE
-     * @hide
-     */
-    public static final int WIFI_BASE_SCORE = 60;
-
-    /**
      * Sent by the NetworkAgent to ConnectivityService to pass the current
      * network score.
      * obj = network score Integer
@@ -272,7 +265,13 @@
      */
     public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
 
+    // STOPSHIP (b/148055573) : remove this before R is released.
+    private static NetworkScore makeNetworkScore(int score) {
+        return new NetworkScore.Builder().setLegacyScore(score).build();
+    }
+
     /** @hide TODO: remove and replace usage with the public constructor. */
+    // STOPSHIP (b/148055573) : remove this before R is released.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score) {
         this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE);
@@ -280,6 +279,7 @@
     }
 
     /** @hide TODO: remove and replace usage with the public constructor. */
+    // STOPSHIP (b/148055573) : remove this before R is released.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config) {
         this(looper, context, logTag, ni, nc, lp, score, config, NetworkProvider.ID_NONE);
@@ -287,6 +287,7 @@
     }
 
     /** @hide TODO: remove and replace usage with the public constructor. */
+    // STOPSHIP (b/148055573) : remove this before R is released.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, int providerId) {
         this(looper, context, logTag, ni, nc, lp, score, null, providerId);
@@ -294,10 +295,12 @@
     }
 
     /** @hide TODO: remove and replace usage with the public constructor. */
+    // STOPSHIP (b/148055573) : remove this before R is released.
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config,
             int providerId) {
-        this(looper, context, logTag, nc, lp, score, config, providerId, ni, true /* legacy */);
+        this(looper, context, logTag, nc, lp, makeNetworkScore(score), config, providerId, ni,
+                true /* legacy */);
         register();
     }
 
@@ -323,8 +326,9 @@
      * @param provider the {@link NetworkProvider} managing this agent.
      */
     public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
-            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
-            @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
+            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
+            @NonNull NetworkScore score, @NonNull NetworkAgentConfig config,
+            @Nullable NetworkProvider provider) {
         this(looper, context, logTag, nc, lp, score, config,
                 provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(),
                 getLegacyNetworkInfo(config), false /* legacy */);
@@ -334,12 +338,12 @@
         public final Context context;
         public final NetworkCapabilities capabilities;
         public final LinkProperties properties;
-        public final int score;
+        public final NetworkScore score;
         public final NetworkAgentConfig config;
         public final NetworkInfo info;
         InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities,
-                @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config,
-                @NonNull NetworkInfo info) {
+                @NonNull LinkProperties properties, @NonNull NetworkScore score,
+                @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) {
             this.context = context;
             this.capabilities = capabilities;
             this.properties = properties;
@@ -351,7 +355,7 @@
     private volatile InitialConfiguration mInitialConfiguration;
 
     private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag,
-            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
+            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, NetworkScore score,
             @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni,
             boolean legacy) {
         mHandler = new NetworkAgentHandler(looper);
@@ -646,22 +650,8 @@
      * Must be called by the agent to update the score of this network.
      * @param score the new score.
      */
-    public void sendNetworkScore(int score) {
-        if (score < 0) {
-            throw new IllegalArgumentException("Score must be >= 0");
-        }
-        final NetworkScore ns = new NetworkScore();
-        ns.putIntExtension(NetworkScore.LEGACY_SCORE, score);
-        updateScore(ns);
-    }
-
-    /**
-     * Must be called by the agent when it has a new {@link NetworkScore} for this network.
-     * @param ns the new score.
-     * @hide TODO: unhide the NetworkScore class, and rename to sendNetworkScore.
-     */
-    public void updateScore(@NonNull NetworkScore ns) {
-        queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new NetworkScore(ns));
+    public void sendNetworkScore(@NonNull final NetworkScore score) {
+        queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score);
     }
 
     /**
diff --git a/core/java/android/net/NetworkScore.aidl b/core/java/android/net/NetworkScore.aidl
new file mode 100644
index 0000000..be9a98b
--- /dev/null
+++ b/core/java/android/net/NetworkScore.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable NetworkScore;
diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java
index 13f2994..ae17378 100644
--- a/core/java/android/net/NetworkScore.java
+++ b/core/java/android/net/NetworkScore.java
@@ -15,12 +15,18 @@
  */
 package android.net;
 
+import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
@@ -28,57 +34,392 @@
  *
  * A NetworkScore object represents the characteristics of a network that affects how good the
  * network is considered for a particular use.
+ *
+ * This class is not thread-safe.
  * @hide
  */
+@TestApi
+@SystemApi
 public final class NetworkScore implements Parcelable {
+    /** An object containing scoring-relevant metrics for a network. */
+    public static class Metrics {
+        /** Value meaning the latency is unknown. */
+        public static final int LATENCY_UNKNOWN = -1;
 
-    // The key of bundle which is used to get the legacy network score of NetworkAgentInfo.
-    // TODO: Remove this when the transition to NetworkScore is over.
-    public static final String LEGACY_SCORE = "LEGACY_SCORE";
+        /** Value meaning the bandwidth is unknown. */
+        public static final int BANDWIDTH_UNKNOWN = -1;
+
+        /**
+         * Round-trip delay in milliseconds to the relevant destination for this Metrics object.
+         *
+         * LATENCY_UNKNOWN if unknown.
+         */
+        @IntRange(from = LATENCY_UNKNOWN)
+        public final int latencyMs;
+
+        /**
+         * Downlink in kB/s with the relevant destination for this Metrics object.
+         *
+         * BANDWIDTH_UNKNOWN if unknown. If directional bandwidth is unknown, up and downlink
+         * bandwidth can have the same value.
+         */
+        @IntRange(from = BANDWIDTH_UNKNOWN)
+        public final int downlinkBandwidthKBps;
+
+        /**
+         * Uplink in kB/s with the relevant destination for this Metrics object.
+         *
+         * BANDWIDTH_UNKNOWN if unknown. If directional bandwidth is unknown, up and downlink
+         * bandwidth can have the same value.
+         */
+        @IntRange(from = BANDWIDTH_UNKNOWN)
+        public final int uplinkBandwidthKBps;
+
+        /** Constructor */
+        public Metrics(@IntRange(from = LATENCY_UNKNOWN) final int latency,
+                @IntRange(from = BANDWIDTH_UNKNOWN) final int downlinkBandwidth,
+                @IntRange(from = BANDWIDTH_UNKNOWN) final int uplinkBandwidth) {
+            latencyMs = latency;
+            downlinkBandwidthKBps = downlinkBandwidth;
+            uplinkBandwidthKBps = uplinkBandwidth;
+        }
+
+        /** toString */
+        public String toString() {
+            return "latency = " + latencyMs + " downlinkBandwidth = " + downlinkBandwidthKBps
+                    + "uplinkBandwidth = " + uplinkBandwidthKBps;
+        }
+
+        @NonNull
+        public static final Metrics EMPTY =
+                new Metrics(LATENCY_UNKNOWN, BANDWIDTH_UNKNOWN, BANDWIDTH_UNKNOWN);
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = "POLICY_", value = {
+            POLICY_LOCKDOWN_VPN,
+            POLICY_VPN,
+            POLICY_IGNORE_ON_WIFI,
+            POLICY_DEFAULT_SUBSCRIPTION
+    })
+    public @interface Policy {
+    }
+
+    /**
+     * This network is a VPN with lockdown enabled.
+     *
+     * If a network with this bit is present in the list of candidates and not connected,
+     * no network can satisfy the request.
+     */
+    public static final int POLICY_LOCKDOWN_VPN = 1 << 0;
+
+    /**
+     * This network is a VPN.
+     *
+     * If a network with this bit is present and the request UID is included in the UID ranges
+     * of this network, it outscores all other networks without this bit.
+     */
+    public static final int POLICY_VPN = 1 << 1;
+
+    /**
+     * This network should not be used if a previously validated WiFi network is available.
+     *
+     * If a network with this bit is present and a previously validated WiFi is present too, the
+     * network with this bit is outscored by it. This stays true if the WiFi network
+     * becomes unvalidated : this network will not be considered.
+     */
+    public static final int POLICY_IGNORE_ON_WIFI = 1 << 2;
+
+    /**
+     * This network is the default subscription for this transport.
+     *
+     * If a network with this bit is present, other networks of the same transport without this
+     * bit are outscored by it. A device with two active subscriptions and a setting
+     * to decide the default one would have this policy bit on the network for the default
+     * subscription so that when both are active at the same time, the device chooses the
+     * network associated with the default subscription rather than the one with the best link
+     * quality (which will happen if policy doesn't dictate otherwise).
+     */
+    public static final int POLICY_DEFAULT_SUBSCRIPTION = 1 << 3;
+
+    /**
+     * Policy bits for this network. Filled in by the NetworkAgent.
+     */
+    private final int mPolicy;
+
+    /**
+     * Predicted metrics to the gateway (it contains latency and bandwidth to the gateway).
+     * This is filled by the NetworkAgent with the theoretical values of the link if available,
+     * although they may fill it with predictions from historical data if available.
+     * Note that while this member cannot be null, any and all of its members can be unknown.
+     */
     @NonNull
-    private final Bundle mExtensions;
+    private final Metrics mLinkLayerMetrics;
 
-    public NetworkScore() {
-        mExtensions = new Bundle();
-    }
+    /**
+     * Predicted metrics to representative servers.
+     * This is filled by connectivity with (if available) a best-effort estimate of the performance
+     * information to servers the user connects to in similar circumstances, and predicted from
+     * actual measurements if possible.
+     * Note that while this member cannot be null, any and all of its members can be unknown.
+     */
+    @NonNull
+    private final Metrics mEndToEndMetrics;
 
-    public NetworkScore(@NonNull NetworkScore source) {
-        mExtensions = new Bundle(source.mExtensions);
+    /** Value meaning the signal strength is unknown. */
+    public static final int UNKNOWN_SIGNAL_STRENGTH = -1;
+
+    /** The smallest meaningful signal strength. */
+    public static final int MIN_SIGNAL_STRENGTH = 0;
+
+    /** The largest meaningful signal strength. */
+    public static final int MAX_SIGNAL_STRENGTH = 1000;
+
+    /**
+     * User-visible measure of the strength of the signal normalized 1~1000.
+     * This represents a measure of the signal strength for this network.
+     * If unknown, this has value UNKNOWN_SIGNAL_STRENGTH.
+     */
+    // A good way to populate this value is to fill it with the number of bars displayed in
+    // the system UI, scaled 0 to 1000. This is what the user sees and it makes sense to them.
+    // Cellular for example could quantize the ASU value (see SignalStrength#getAsuValue) into
+    // this, while WiFi could scale the RSSI (see WifiManager#calculateSignalLevel).
+    @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH)
+    private final int mSignalStrength;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = "RANGE_", value = {
+            RANGE_UNKNOWN, RANGE_CLOSE, RANGE_SHORT, RANGE_MEDIUM, RANGE_LONG
+    })
+    public @interface Range {
     }
 
     /**
-     * Put the value of parcelable inside the bundle by key.
+     * The range of this network is not known.
+     * This can be used by VPN the range of which depends on the range of the underlying network.
      */
-    public void putExtension(@Nullable String key, @Nullable Parcelable value) {
-        mExtensions.putParcelable(key, value);
+    public static final int RANGE_UNKNOWN = 0;
+
+    /**
+     * This network typically only operates at close range, like an NFC beacon.
+     */
+    public static final int RANGE_CLOSE = 1;
+
+    /**
+     * This network typically operates at a range of a few meters to a few dozen meters, like WiFi.
+     */
+    public static final int RANGE_SHORT = 2;
+
+    /**
+     * This network typically operates at a range of a few dozen to a few hundred meters, like CBRS.
+     */
+    public static final int RANGE_MEDIUM = 3;
+
+    /**
+     * This network typically offers continuous connectivity up to many kilometers away, like LTE.
+     */
+    public static final int RANGE_LONG = 4;
+
+    /**
+     * The typical range of this networking technology.
+     *
+     * This is one of the RANGE_* constants and is filled by the NetworkAgent.
+     * This may be useful when evaluating how desirable a network is, because for two networks that
+     * have equivalent performance and cost, the one that won't lose IP continuity when the user
+     * moves is probably preferable.
+     * Agents should fill this with the largest typical range this technology provides. See the
+     * descriptions of the individual constants for guidance.
+     *
+     * If unknown, this is set to RANGE_UNKNOWN.
+     */
+    @Range private final int mRange;
+
+    /**
+     * A prediction of whether this network is likely to be unusable in a few seconds.
+     *
+     * NetworkAgents set this to true to mean they are aware that usability is limited due to
+     * low signal strength, congestion, or other reasons, and indicates that the system should
+     * only use this network as a last resort. An example would be a WiFi network when the device
+     * is about to move outside of range.
+     *
+     * This is filled by the NetworkAgent. Agents that don't know whether this network is likely
+     * to be unusable soon should set this to false.
+     */
+    private final boolean mExiting;
+
+    /**
+     * The legacy score, as a migration strategy from Q to R.
+     * STOPSHIP : remove this before R ships.
+     */
+    private final int mLegacyScore;
+
+    /**
+     * Create a new NetworkScore object.
+     */
+    private NetworkScore(@Policy final int policy, @Nullable final Metrics l2Perf,
+            @Nullable final Metrics e2ePerf,
+            @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH)
+            final int signalStrength,
+            @Range final int range, final boolean exiting, final int legacyScore) {
+        mPolicy = policy;
+        mLinkLayerMetrics = null != l2Perf ? l2Perf : Metrics.EMPTY;
+        mEndToEndMetrics = null != e2ePerf ? e2ePerf : Metrics.EMPTY;
+        mSignalStrength = signalStrength;
+        mRange = range;
+        mExiting = exiting;
+        mLegacyScore = legacyScore;
     }
 
     /**
-     * Put the value of int inside the bundle by key.
+     * Utility function to return a copy of this with a different exiting value.
      */
-    public void putIntExtension(@Nullable String key, int value) {
-        mExtensions.putInt(key, value);
+    @NonNull public NetworkScore withExiting(final boolean exiting) {
+        return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics,
+                mSignalStrength, mRange, exiting, mLegacyScore);
     }
 
     /**
-     * Get the value of non primitive type by key.
+     * Utility function to return a copy of this with a different signal strength.
      */
-    public <T extends Parcelable> T getExtension(@Nullable String key) {
-        return mExtensions.getParcelable(key);
+    @NonNull public NetworkScore withSignalStrength(
+            @IntRange(from = UNKNOWN_SIGNAL_STRENGTH) final int signalStrength) {
+        return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics,
+                signalStrength, mRange, mExiting, mLegacyScore);
     }
 
     /**
-     * Get the value of int by key.
+     * Returns whether this network has a particular policy flag.
+     * @param policy the policy, as one of the POLICY_* constants.
      */
-    public int getIntExtension(@Nullable String key) {
-        return mExtensions.getInt(key);
+    public boolean hasPolicy(@Policy final int policy) {
+        return 0 != (mPolicy & policy);
     }
 
     /**
-     * Remove the entry by given key.
+     * Returns the Metrics representing the performance of the link layer.
+     *
+     * This contains the theoretical performance of the link, if available.
+     * Note that while this function cannot return null, any and/or all of the members of the
+     * returned object can be null if unknown.
      */
-    public void removeExtension(@Nullable String key) {
-        mExtensions.remove(key);
+    @NonNull public Metrics getLinkLayerMetrics() {
+        return mLinkLayerMetrics;
+    }
+
+    /**
+     * Returns the Metrics representing the end-to-end performance of the network.
+     *
+     * This contains the end-to-end performance of the link, if available.
+     * Note that while this function cannot return null, any and/or all of the members of the
+     * returned object can be null if unknown.
+     */
+    @NonNull public Metrics getEndToEndMetrics() {
+        return mEndToEndMetrics;
+    }
+
+    /**
+     * Returns the signal strength of this network normalized 0~1000, or UNKNOWN_SIGNAL_STRENGTH.
+     */
+    @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH)
+    public int getSignalStrength() {
+        return mSignalStrength;
+    }
+
+    /**
+     * Returns the typical range of this network technology as one of the RANGE_* constants.
+     */
+    @Range public int getRange() {
+        return mRange;
+    }
+
+    /** Returns a prediction of whether this network is likely to be unusable in a few seconds. */
+    public boolean isExiting() {
+        return mExiting;
+    }
+
+    /**
+     * Get the legacy score.
+     * @hide
+     */
+    public int getLegacyScore() {
+        return mLegacyScore;
+    }
+
+    /** Builder for NetworkScore. */
+    public static class Builder {
+        private int mPolicy = 0;
+        @NonNull
+        private Metrics mLinkLayerMetrics = new Metrics(Metrics.LATENCY_UNKNOWN,
+                Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN);
+        @NonNull
+        private Metrics mEndToMetrics = new Metrics(Metrics.LATENCY_UNKNOWN,
+                Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN);
+        private int mSignalStrength = UNKNOWN_SIGNAL_STRENGTH;
+        private int mRange = RANGE_UNKNOWN;
+        private boolean mExiting = false;
+        private int mLegacyScore = 0;
+        @NonNull private Bundle mExtensions = new Bundle();
+
+        /** Create a new builder. */
+        public Builder() { }
+
+        /** Add a policy flag. */
+        @NonNull public Builder addPolicy(@Policy final int policy) {
+            mPolicy |= policy;
+            return this;
+        }
+
+        /** Clear a policy flag */
+        @NonNull public Builder clearPolicy(@Policy final int policy) {
+            mPolicy &= ~policy;
+            return this;
+        }
+
+        /** Set the link layer metrics. */
+        @NonNull public Builder setLinkLayerMetrics(@NonNull final Metrics linkLayerMetrics) {
+            mLinkLayerMetrics = linkLayerMetrics;
+            return this;
+        }
+
+        /** Set the end-to-end metrics. */
+        @NonNull public Builder setEndToEndMetrics(@NonNull final Metrics endToEndMetrics) {
+            mEndToMetrics = endToEndMetrics;
+            return this;
+        }
+
+        /** Set the signal strength. */
+        @NonNull public Builder setSignalStrength(
+                @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH)
+                        final int signalStrength) {
+            mSignalStrength = signalStrength;
+            return this;
+        }
+
+        /** Set the range. */
+        @NonNull public Builder setRange(@Range final int range) {
+            mRange = range;
+            return this;
+        }
+
+        /** Set whether this network is exiting. */
+        @NonNull public Builder setExiting(final boolean exiting) {
+            mExiting = exiting;
+            return this;
+        }
+
+        /** Add a parcelable extension. */
+        @NonNull public Builder setLegacyScore(final int legacyScore) {
+            mLegacyScore = legacyScore;
+            return this;
+        }
+
+        /** Build the NetworkScore object represented by this builder. */
+        @NonNull public NetworkScore build() {
+            return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToMetrics,
+                    mSignalStrength, mRange, mExiting, mLegacyScore);
+        }
     }
 
     @Override
@@ -88,9 +429,17 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        synchronized (this) {
-            dest.writeBundle(mExtensions);
-        }
+        dest.writeInt(mPolicy);
+        dest.writeInt(mLinkLayerMetrics.latencyMs);
+        dest.writeInt(mLinkLayerMetrics.downlinkBandwidthKBps);
+        dest.writeInt(mLinkLayerMetrics.uplinkBandwidthKBps);
+        dest.writeInt(mEndToEndMetrics.latencyMs);
+        dest.writeInt(mEndToEndMetrics.downlinkBandwidthKBps);
+        dest.writeInt(mEndToEndMetrics.uplinkBandwidthKBps);
+        dest.writeInt(mSignalStrength);
+        dest.writeInt(mRange);
+        dest.writeBoolean(mExiting);
+        dest.writeInt(mLegacyScore);
     }
 
     public static final @NonNull Creator<NetworkScore> CREATOR = new Creator<NetworkScore>() {
@@ -106,57 +455,52 @@
     };
 
     private NetworkScore(@NonNull Parcel in) {
-        mExtensions = in.readBundle();
+        mPolicy = in.readInt();
+        mLinkLayerMetrics = new Metrics(in.readInt(), in.readInt(), in.readInt());
+        mEndToEndMetrics = new Metrics(in.readInt(), in.readInt(), in.readInt());
+        mSignalStrength = in.readInt();
+        mRange = in.readInt();
+        mExiting = in.readBoolean();
+        mLegacyScore = in.readInt();
     }
 
-    // TODO: Modify this method once new fields are added into this class.
     @Override
     public boolean equals(@Nullable Object obj) {
         if (!(obj instanceof NetworkScore)) {
             return false;
         }
         final NetworkScore other = (NetworkScore) obj;
-        return bundlesEqual(mExtensions, other.mExtensions);
+        return mPolicy == other.mPolicy
+                && mLinkLayerMetrics.latencyMs == other.mLinkLayerMetrics.latencyMs
+                && mLinkLayerMetrics.uplinkBandwidthKBps
+                == other.mLinkLayerMetrics.uplinkBandwidthKBps
+                && mEndToEndMetrics.latencyMs == other.mEndToEndMetrics.latencyMs
+                && mEndToEndMetrics.uplinkBandwidthKBps
+                == other.mEndToEndMetrics.uplinkBandwidthKBps
+                && mSignalStrength == other.mSignalStrength
+                && mRange == other.mRange
+                && mExiting == other.mExiting
+                && mLegacyScore == other.mLegacyScore;
     }
 
     @Override
     public int hashCode() {
-        int result = 29;
-        for (String key : mExtensions.keySet()) {
-            final Object value = mExtensions.get(key);
-            // The key may be null, so call Objects.hash() is safer.
-            result += 31 * value.hashCode() + 37 * Objects.hash(key);
-        }
-        return result;
-    }
-
-    // mExtensions won't be null since the constructor will create it.
-    private boolean bundlesEqual(@NonNull Bundle bundle1, @NonNull Bundle bundle2) {
-        if (bundle1 == bundle2) {
-            return true;
-        }
-
-        // This is unlikely but it's fine to add this clause here.
-        if (null == bundle1 || null == bundle2) {
-            return false;
-        }
-
-        if (bundle1.size() != bundle2.size()) {
-            return false;
-        }
-
-        for (String key : bundle1.keySet()) {
-            final Object value1 = bundle1.get(key);
-            final Object value2 = bundle2.get(key);
-            if (!Objects.equals(value1, value2)) {
-                return false;
-            }
-        }
-        return true;
+        return Objects.hash(mPolicy,
+                mLinkLayerMetrics.latencyMs, mLinkLayerMetrics.uplinkBandwidthKBps,
+                mEndToEndMetrics.latencyMs, mEndToEndMetrics.uplinkBandwidthKBps,
+                mSignalStrength, mRange, mExiting, mLegacyScore);
     }
 
     /** Convert to a string */
     public String toString() {
-        return "NetworkScore[" + mExtensions.toString() + "]";
+        return "NetworkScore ["
+                + "Policy = " + mPolicy
+                + " LinkLayerMetrics = " + mLinkLayerMetrics
+                + " EndToEndMetrics = " + mEndToEndMetrics
+                + " SignalStrength = " + mSignalStrength
+                + " Range = " + mRange
+                + " Exiting = " + mExiting
+                + " LegacyScore = " + mLegacyScore
+                + "]";
     }
 }
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index cdcb3ff..be22458 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -41,7 +41,6 @@
 import android.text.format.DateFormat;
 import android.util.Log;
 import android.view.Display;
-import android.view.WindowManager;
 
 import libcore.io.Streams;
 
@@ -615,8 +614,7 @@
 
             // On TV, reboot quiescently if the screen is off
             if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
-                WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-                if (wm.getDefaultDisplay().getState() != Display.STATE_ON) {
+                if (context.getDisplay().getState() != Display.STATE_ON) {
                     reason += ",quiescent";
                 }
             }
diff --git a/core/java/android/os/VibrationAttributes.java b/core/java/android/os/VibrationAttributes.java
index 3e16640..27782fa 100644
--- a/core/java/android/os/VibrationAttributes.java
+++ b/core/java/android/os/VibrationAttributes.java
@@ -391,11 +391,23 @@
          * Replaces flags
          * @param flags any combination of flags.
          * @return the same Builder instance.
+         * @hide
          */
         public @NonNull Builder replaceFlags(int flags) {
             mFlags = flags;
             return this;
         }
+
+        /**
+         * Set flags
+         * @param flags combination of flags to be set.
+         * @param mask Bit range that should be changed.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setFlags(int flags, int mask) {
+            mFlags = (mFlags & ~mask) | (flags & mask);
+            return this;
+        }
     }
 }
 
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 7161b07..6adba63 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -149,7 +149,7 @@
     }
 
     /**
-     * Returns the size of this work source.
+     * Returns the number of uids in this work source.
      * @hide
      */
     @TestApi
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 023f000..531ade0 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -168,9 +168,11 @@
     public static final int LISTEN_SIGNAL_STRENGTHS                         = 0x00000100;
 
     /**
-     * Listen for always reported changes of the network signal strengths (cellular),
+     * Listen for changes of the network signal strengths (cellular) always reported from modem,
      * even in some situations such as the screen of the device is off.
      *
+     * @see #onSignalStrengthsChanged
+     *
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
diff --git a/core/java/android/timezone/CountryTimeZones.java b/core/java/android/timezone/CountryTimeZones.java
index e5bbdf4..5875761 100644
--- a/core/java/android/timezone/CountryTimeZones.java
+++ b/core/java/android/timezone/CountryTimeZones.java
@@ -56,7 +56,7 @@
          */
         @NonNull
         public String getTimeZoneId() {
-            return mDelegate.timeZoneId;
+            return mDelegate.getTimeZoneId();
         }
 
         /**
@@ -187,7 +187,7 @@
      * would be a good choice <em>generally</em> when there's no other information available.
      */
     public boolean isDefaultTimeZoneBoosted() {
-        return mDelegate.getDefaultTimeZoneBoost();
+        return mDelegate.isDefaultTimeZoneBoosted();
     }
 
     /**
@@ -220,7 +220,8 @@
                 mDelegate.lookupByOffsetWithBias(
                         totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias);
         return delegateOffsetResult == null ? null :
-                new OffsetResult(delegateOffsetResult.mTimeZone, delegateOffsetResult.mOneMatch);
+                new OffsetResult(
+                        delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
     }
 
     /**
diff --git a/core/java/android/timezone/TzDataSetVersion.java b/core/java/android/timezone/TzDataSetVersion.java
index 605155e..efe50a0 100644
--- a/core/java/android/timezone/TzDataSetVersion.java
+++ b/core/java/android/timezone/TzDataSetVersion.java
@@ -111,23 +111,23 @@
 
     /** Returns the major version number. See {@link TzDataSetVersion}. */
     public int getFormatMajorVersion() {
-        return mDelegate.formatMajorVersion;
+        return mDelegate.getFormatMajorVersion();
     }
 
     /** Returns the minor version number. See {@link TzDataSetVersion}. */
     public int getFormatMinorVersion() {
-        return mDelegate.formatMinorVersion;
+        return mDelegate.getFormatMinorVersion();
     }
 
     /** Returns the tzdb version string. See {@link TzDataSetVersion}. */
     @NonNull
     public String getRulesVersion() {
-        return mDelegate.rulesVersion;
+        return mDelegate.getRulesVersion();
     }
 
     /** Returns the Android revision. See {@link TzDataSetVersion}. */
     public int getRevision() {
-        return mDelegate.revision;
+        return mDelegate.getRevision();
     }
 
     @Override
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index c325874..36f4e53 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -81,7 +81,7 @@
         }
         CountryTimeZones.OffsetResult offsetResult = countryTimeZones.lookupByOffsetWithBias(
                 offsetMillis, isDst, null /* dstOffsetMillis */, whenMillis, bias);
-        return offsetResult != null ? offsetResult.mTimeZone : null;
+        return offsetResult != null ? offsetResult.getTimeZone() : null;
     }
 
     /**
@@ -109,8 +109,8 @@
 
         List<String> timeZoneIds = new ArrayList<>();
         for (TimeZoneMapping timeZoneMapping : countryTimeZones.getTimeZoneMappings()) {
-            if (timeZoneMapping.showInPicker) {
-                timeZoneIds.add(timeZoneMapping.timeZoneId);
+            if (timeZoneMapping.isShownInPicker()) {
+                timeZoneIds.add(timeZoneMapping.getTimeZoneId());
             }
         }
         return Collections.unmodifiableList(timeZoneIds);
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index e1f1581..f9a023f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -120,12 +120,14 @@
      *
      * @param token Token to be registered.
      * @param type Window type to be used with this token.
+     * @param options A bundle used to pass window-related options.
      * @param displayId The ID of the display where this token should be added.
      * @param packageName The name of package to request to add window token.
      * @return {@link WindowManagerGlobal#ADD_OKAY} if the addition was successful, an error code
      *         otherwise.
      */
-    int addWindowContextToken(IBinder token, int type, int displayId, String packageName);
+    int addWindowTokenWithOptions(IBinder token, int type, int displayId, in Bundle options,
+            String packageName);
     void addWindowToken(IBinder token, int type, int displayId);
     void removeWindowToken(IBinder token, int displayId);
     void prepareAppTransition(int transit, boolean alwaysKeepCurrent);
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index a66b508..47a79bd 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -28,6 +28,7 @@
 import android.os.RemoteException;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
+import android.util.Size;
 import android.util.SparseArray;
 import android.util.TypedValue;
 
@@ -408,11 +409,9 @@
         mAmbiguousGestureMultiplier = multiplierValue.getFloat();
 
         // Size of the screen in bytes, in ARGB_8888 format
-        final WindowManager win = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-        final Display display = win.getDefaultDisplay();
-        final Point size = new Point();
-        display.getRealSize(size);
-        mMaximumDrawingCacheSize = 4 * size.x * size.y;
+        final WindowManager windowManager = context.getSystemService(WindowManager.class);
+        final Size maxWindowSize = windowManager.getMaximumWindowMetrics().getSize();
+        mMaximumDrawingCacheSize = 4 * maxWindowSize.getWidth() * maxWindowSize.getHeight();
 
         mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);
         mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
diff --git a/core/java/android/view/autofill/AutofillPopupWindow.java b/core/java/android/view/autofill/AutofillPopupWindow.java
index 8266207..8d3dc83 100644
--- a/core/java/android/view/autofill/AutofillPopupWindow.java
+++ b/core/java/android/view/autofill/AutofillPopupWindow.java
@@ -19,13 +19,13 @@
 import static android.view.autofill.Helper.sVerbose;
 
 import android.annotation.NonNull;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.transition.Transition;
 import android.util.Log;
+import android.util.Size;
 import android.view.View;
 import android.view.View.OnTouchListener;
 import android.view.ViewTreeObserver;
@@ -127,11 +127,12 @@
             // If it is not fullscreen height, put window at bottom. Computes absolute position.
             // Note that we cannot easily change default gravity from Gravity.TOP to
             // Gravity.BOTTOM because PopupWindow base class does not expose computeGravity().
-            final Point outPoint = new Point();
-            anchor.getContext().getDisplay().getSize(outPoint);
-            width = outPoint.x;
+            final WindowManager windowManager = anchor.getContext()
+                    .getSystemService(WindowManager.class);
+            final Size windowSize = windowManager.getCurrentWindowMetrics().getSize();
+            width = windowSize.getWidth();
             if (height != LayoutParams.MATCH_PARENT) {
-                offsetY = outPoint.y - height;
+                offsetY = windowSize.getHeight() - height;
             }
             actualAnchor = anchor;
         } else if (virtualBounds != null) {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index f13a638..863e8a2 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2125,8 +2125,9 @@
                 return new Pair<>(Insets.NONE, insets);
             }
 
-            boolean includeIme = (getAttributes().softInputMode & SOFT_INPUT_MASK_ADJUST)
-                    == SOFT_INPUT_ADJUST_RESIZE;
+            boolean includeIme =
+                    (getViewRootImpl().mWindowAttributes.softInputMode & SOFT_INPUT_MASK_ADJUST)
+                            == SOFT_INPUT_ADJUST_RESIZE;
             Insets insetsToApply;
             if (ViewRootImpl.sNewInsetsMode == 0) {
                 insetsToApply = insets.getSystemWindowInsets();
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index f9e98e7..69b1609 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -29,7 +29,6 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.WindowManager;
 
 import android.widget.PopupWindow;
 import com.android.internal.R;
@@ -211,8 +210,7 @@
     }
 
     private boolean isContentRectWithinBounds() {
-        mContext.getSystemService(WindowManager.class)
-            .getDefaultDisplay().getRealSize(mDisplaySize);
+        mContext.getDisplay().getRealSize(mDisplaySize);
         mScreenRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
 
         return intersectsClosed(mContentRectOnScreen, mScreenRect)
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index bac6025..0aeaa47 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -24,10 +24,12 @@
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.util.Size;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.WindowMetrics;
 import android.widget.PopupWindow.OnDismissListener;
 
 import com.android.internal.view.menu.MenuPresenter.Callback;
@@ -224,13 +226,10 @@
      */
     @NonNull
     private MenuPopup createPopup() {
-        final WindowManager windowManager = (WindowManager) mContext.getSystemService(
-            Context.WINDOW_SERVICE);
-        final Display display = windowManager.getDefaultDisplay();
-        final Point displaySize = new Point();
-        display.getRealSize(displaySize);
+        final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
+        final Size maxWindowSize = windowManager.getMaximumWindowMetrics().getSize();
 
-        final int smallestWidth = Math.min(displaySize.x, displaySize.y);
+        final int smallestWidth = Math.min(maxWindowSize.getWidth(), maxWindowSize.getHeight());
         final int minSmallestWidthCascading = mContext.getResources().getDimensionPixelSize(
             com.android.internal.R.dimen.cascading_menus_min_smallest_width);
         final boolean enableCascadingSubmenus = smallestWidth >= minSmallestWidthCascading;
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index a2f514a..c04efa3 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -147,7 +147,6 @@
                 "android_service_DataLoaderService.cpp",
                 "android_util_AssetManager.cpp",
                 "android_util_Binder.cpp",
-                "android_util_StatsLog.cpp",
                 "android_util_MemoryIntArray.cpp",
                 "android_util_Process.cpp",
                 "android_util_StringBlock.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 9783b65..790ac08 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -108,7 +108,6 @@
 extern int register_android_app_admin_SecurityLog(JNIEnv* env);
 extern int register_android_content_AssetManager(JNIEnv* env);
 extern int register_android_util_EventLog(JNIEnv* env);
-extern int register_android_util_StatsLog(JNIEnv* env);
 extern int register_android_util_StatsLogInternal(JNIEnv* env);
 extern int register_android_util_Log(JNIEnv* env);
 extern int register_android_util_MemoryIntArray(JNIEnv* env);
@@ -1441,7 +1440,6 @@
     REG_JNI(register_android_util_EventLog),
     REG_JNI(register_android_util_Log),
     REG_JNI(register_android_util_MemoryIntArray),
-    REG_JNI(register_android_util_StatsLog),
     REG_JNI(register_android_util_StatsLogInternal),
     REG_JNI(register_android_app_admin_SecurityLog),
     REG_JNI(register_android_content_AssetManager),
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 181a32d..3a1b63d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4858,19 +4858,6 @@
     <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES"
                 android:protectionLevel="signature|installer" />
 
-    <!-- Allows an app to log compat change usage.
-         @hide  <p>Not for use by third-party applications.</p> -->
-    <permission android:name="android.permission.LOG_COMPAT_CHANGE"
-                android:protectionLevel="signature" />
-    <!-- Allows an app to read compat change config.
-         @hide  <p>Not for use by third-party applications.</p> -->
-    <permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"
-                android:protectionLevel="signature" />
-    <!-- Allows an app to override compat change config.
-         @hide  <p>Not for use by third-party applications.</p> -->
-    <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"
-                android:protectionLevel="signature" />
-
     <!-- Allows input events to be monitored. Very dangerous!  @hide -->
     <permission android:name="android.permission.MONITOR_INPUT"
                 android:protectionLevel="signature" />
diff --git a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java b/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
index 8a22aca..a027f9e 100644
--- a/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
+++ b/core/tests/coretests/BstatsTestApp/src/com/android/coretests/apps/bstatstestapp/TestService.java
@@ -22,12 +22,12 @@
 import android.app.Service;
 import android.content.Intent;
 import android.graphics.Color;
-import android.graphics.Point;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.Size;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -108,16 +108,15 @@
         @Override
         public void showApplicationOverlay() throws RemoteException {
             final WindowManager wm = TestService.this.getSystemService(WindowManager.class);
-            final Point size = new Point();
-            wm.getDefaultDisplay().getSize(size);
+            final Size size = wm.getCurrentWindowMetrics().getSize();
 
             final WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(
                     WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                     WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                             | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                             | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
-            wmlp.width = size.x / 2;
-            wmlp.height = size.y / 2;
+            wmlp.width = size.getWidth() / 2;
+            wmlp.height = size.getHeight() / 2;
             wmlp.gravity = Gravity.CENTER | Gravity.LEFT;
             wmlp.setTitle(TAG);
 
diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java
index b1a54dc..f074233 100644
--- a/core/tests/coretests/src/android/content/ContextTest.java
+++ b/core/tests/coretests/src/android/content/ContextTest.java
@@ -48,6 +48,7 @@
         assertEquals(testContext.getDisplay().getDisplayId(), testContext.getDisplayId());
     }
 
+    // TODO(b/128338354): Re-visit this test after introducing WindowContext
     @Test
     public void testDisplayIdForDefaultDisplayContext() {
         final Context testContext =
diff --git a/core/tests/coretests/src/android/util/GridScenario.java b/core/tests/coretests/src/android/util/GridScenario.java
index 0f1730e..4809a21 100644
--- a/core/tests/coretests/src/android/util/GridScenario.java
+++ b/core/tests/coretests/src/android/util/GridScenario.java
@@ -233,7 +233,7 @@
         // turn off title bar
         requestWindowFeature(Window.FEATURE_NO_TITLE);
 
-        mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();
+        mScreenHeight = getWindowManager().getCurrentWindowMetrics().getSize().getHeight();
 
         final Params params = new Params();
         init(params);
diff --git a/core/tests/coretests/src/android/util/ListScenario.java b/core/tests/coretests/src/android/util/ListScenario.java
index 129484a..d4e5a43 100644
--- a/core/tests/coretests/src/android/util/ListScenario.java
+++ b/core/tests/coretests/src/android/util/ListScenario.java
@@ -306,7 +306,7 @@
         requestWindowFeature(Window.FEATURE_NO_TITLE);
 
 
-        mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();
+        mScreenHeight = getWindowManager().getCurrentWindowMetrics().getSize().getHeight();
 
         final Params params = createParams();
         init(params);
diff --git a/core/tests/coretests/src/android/util/ScrollViewScenario.java b/core/tests/coretests/src/android/util/ScrollViewScenario.java
index e9eb978..2c0aa73 100644
--- a/core/tests/coretests/src/android/util/ScrollViewScenario.java
+++ b/core/tests/coretests/src/android/util/ScrollViewScenario.java
@@ -239,7 +239,7 @@
 
         // for test stability, turn off title bar
         requestWindowFeature(Window.FEATURE_NO_TITLE);
-        int screenHeight = getWindowManager().getDefaultDisplay().getHeight()
+        int screenHeight = getWindowManager().getCurrentWindowMetrics().getSize().getHeight()
                 - 25;
         mLinearLayout = new LinearLayout(this);
         mLinearLayout.setOrientation(LinearLayout.VERTICAL);
diff --git a/core/tests/coretests/src/android/view/BigCache.java b/core/tests/coretests/src/android/view/BigCache.java
index 6a1bcaa..e465a85 100644
--- a/core/tests/coretests/src/android/view/BigCache.java
+++ b/core/tests/coretests/src/android/view/BigCache.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.util.Size;
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
 
@@ -38,9 +39,9 @@
                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
 
         final int cacheSize = ViewConfiguration.getMaximumDrawingCacheSize();
-        final Display display = getWindowManager().getDefaultDisplay();
-        final int screenWidth = display.getWidth();
-        final int screenHeight = display.getHeight();
+        final Size windowSize = getWindowManager().getCurrentWindowMetrics().getSize();
+        final int screenWidth = windowSize.getWidth();
+        final int screenHeight = windowSize.getHeight();
 
         final View tiny = new View(this);
         tiny.setId(R.id.a);
diff --git a/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java b/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java
index f63a454..039387c 100644
--- a/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java
+++ b/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java
@@ -22,8 +22,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.content.Context;
-import android.util.DisplayMetrics;
+import android.util.Size;
 import android.widget.TextView;
 
 import androidx.test.filters.LargeTest;
@@ -54,25 +53,23 @@
         final float initialScaleFactor = 1.0f;
         assertEquals(initialScaleFactor, mScaleGestureActivity.getScaleFactor(), 0f);
 
-        // Specify start and end coordinates, irrespective of device display size.
-        final DisplayMetrics dm = new DisplayMetrics();
-        final WindowManager wm = (WindowManager) (mScaleGestureActivity.getApplicationContext())
-                .getSystemService(Context.WINDOW_SERVICE);
-        wm.getDefaultDisplay().getMetrics(dm);
-        final int displayWidth = dm.widthPixels;
-        final int displayHeight = dm.heightPixels;
+        // Specify start and end coordinates with respect to the window size.
+        final WindowManager wm = mScaleGestureActivity.getSystemService(WindowManager.class);
+        final Size windowSize = wm.getCurrentWindowMetrics().getSize();
+        final int windowWidth = windowSize.getWidth();
+        final int windowHeight = windowSize.getHeight();
 
         // Obtain coordinates to perform pinch and zoom from the center, to 75% of the display.
-        final int centerX = displayWidth / 2;
-        final int centerY = displayHeight / 2;
+        final int centerX = windowWidth / 2;
+        final int centerY = windowHeight / 2;
 
         // Offset center coordinates by one, so that the two starting points are different.
         final float[] firstFingerStartCoords = new float[] {centerX + 1.0f, centerY - 1.0f};
         final float[] firstFingerEndCoords =
-        new float[] {0.75f * displayWidth, 0.25f * displayHeight};
+        new float[] {0.75f * windowWidth, 0.25f * windowHeight};
         final float[] secondFingerStartCoords = new float[] {centerX - 1.0f, centerY + 1.0f};
         final float[] secondFingerEndCoords =
-        new float[] {0.25f * displayWidth, 0.75f * displayHeight};
+        new float[] {0.25f * windowWidth, 0.75f * windowHeight};
 
         onView(withId(R.id.article)).perform(new PinchZoomAction(firstFingerStartCoords,
                 firstFingerEndCoords, secondFingerStartCoords, secondFingerEndCoords,
diff --git a/core/tests/coretests/src/android/view/inputmethod/InputMethodManagerTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodManagerTest.java
index 9f259a8..d705724 100644
--- a/core/tests/coretests/src/android/view/inputmethod/InputMethodManagerTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodManagerTest.java
@@ -16,11 +16,13 @@
 
 package android.view.inputmethod;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 import android.content.Context;
-import android.view.WindowManager;
+import android.hardware.display.DisplayManager;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -43,9 +45,9 @@
         final Context testContext = InstrumentationRegistry.getInstrumentation()
                 .getTargetContext();
 
-        final WindowManager wm = testContext.getSystemService(WindowManager.class);
+        final DisplayManager dm = testContext.getSystemService(DisplayManager.class);
         final Context defaultDisplayContext =
-                testContext.createDisplayContext(wm.getDefaultDisplay());
+                testContext.createDisplayContext(dm.getDisplay(DEFAULT_DISPLAY));
         final InputMethodManager imm =
                 defaultDisplayContext.getSystemService(InputMethodManager.class);
         assertEquals("InputMethodManager.getInstance() always returns the instance for the default"
diff --git a/core/tests/coretests/src/android/view/menu/ContextMenuTest.java b/core/tests/coretests/src/android/view/menu/ContextMenuTest.java
index ba85d76..d5825e2 100644
--- a/core/tests/coretests/src/android/view/menu/ContextMenuTest.java
+++ b/core/tests/coretests/src/android/view/menu/ContextMenuTest.java
@@ -16,11 +16,9 @@
 
 package android.view.menu;
 
-import android.content.Context;
-import android.graphics.Point;
 import android.test.ActivityInstrumentationTestCase;
 import android.util.PollingCheck;
-import android.view.Display;
+import android.util.Size;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.espresso.ContextMenuUtils;
@@ -82,12 +80,9 @@
      * Returns the minimum of the default display's width and height.
      */
     private int getMinScreenDimension() {
-        final WindowManager windowManager = (WindowManager) getActivity().getSystemService(
-                Context.WINDOW_SERVICE);
-        final Display display = windowManager.getDefaultDisplay();
-        final Point displaySize = new Point();
-        display.getRealSize(displaySize);
-        return Math.min(displaySize.x, displaySize.y);
+        final WindowManager windowManager = getActivity().getSystemService(WindowManager.class);
+        final Size maxWindowSize = windowManager.getMaximumWindowMetrics().getSize();
+        return Math.min(maxWindowSize.getWidth(), maxWindowSize.getHeight());
     }
 
     /**
diff --git a/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java b/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java
index 73e4ea8..8e90a82 100644
--- a/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java
+++ b/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java
@@ -17,7 +17,6 @@
 package android.widget.focus;
 
 import android.app.Activity;
-import android.graphics.Point;
 import android.os.Bundle;
 import android.util.InternalSelectionView;
 import android.view.View;
@@ -112,9 +111,7 @@
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        Point size = new Point();
-        getWindowManager().getDefaultDisplay().getSize(size);
-        mScreenHeight = size.y;
+        mScreenHeight = getWindowManager().getCurrentWindowMetrics().getSize().getHeight();
 
         Bundle extras = getIntent().getExtras();
         if (extras != null) {
diff --git a/core/tests/coretests/src/android/widget/gridview/touch/GridTouchVerticalSpacingStackFromBottomTest.java b/core/tests/coretests/src/android/widget/gridview/touch/GridTouchVerticalSpacingStackFromBottomTest.java
index 0d3092c..fd1dbfc 100644
--- a/core/tests/coretests/src/android/widget/gridview/touch/GridTouchVerticalSpacingStackFromBottomTest.java
+++ b/core/tests/coretests/src/android/widget/gridview/touch/GridTouchVerticalSpacingStackFromBottomTest.java
@@ -106,9 +106,10 @@
 
         int firstTop = firstChild.getTop();
 
+        int windowHeight = mActivity.getWindowManager().getCurrentWindowMetrics().getSize()
+                .getHeight();
         int distance = TouchUtils.dragViewBy(this, firstChild, 
-                Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 
-                (int) (mActivity.getWindowManager().getDefaultDisplay().getHeight() * 0.75f));
+                Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, (int) (windowHeight * 0.75f));
         
         assertEquals("View scrolled to wrong position", firstTop
                 + (distance - mViewConfig.getScaledTouchSlop() - 1), firstChild.getTop());
diff --git a/core/tests/coretests/src/android/widget/listview/AdjacentListsWithAdjacentISVsInside.java b/core/tests/coretests/src/android/widget/listview/AdjacentListsWithAdjacentISVsInside.java
index 9e49719..e6195b1 100644
--- a/core/tests/coretests/src/android/widget/listview/AdjacentListsWithAdjacentISVsInside.java
+++ b/core/tests/coretests/src/android/widget/listview/AdjacentListsWithAdjacentISVsInside.java
@@ -65,7 +65,8 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        final int desiredHeight = (int) (0.8 * getWindowManager().getDefaultDisplay().getHeight());
+        final int desiredHeight =
+                (int) (0.8 * getWindowManager().getCurrentWindowMetrics().getSize().getHeight());
 
         mLeftListView = new ListView(this);
         mLeftListView.setAdapter(new AdjacentISVAdapter(desiredHeight));
diff --git a/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java b/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
index cd70608..cdcf23f 100644
--- a/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/DecorContextTest.java
@@ -26,7 +26,6 @@
 import android.view.Display;
 import android.view.DisplayAdjustments;
 import android.view.DisplayInfo;
-import android.view.WindowManager;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -71,8 +70,7 @@
 
     private static void assertDecorContextDisplay(int expectedDisplayId,
             DecorContext decorContext) {
-        WindowManager wm = (WindowManager) decorContext.getSystemService(Context.WINDOW_SERVICE);
-        Display associatedDisplay = wm.getDefaultDisplay();
+        Display associatedDisplay = decorContext.getDisplay();
         assertEquals(expectedDisplayId, associatedDisplay.getDisplayId());
     }
 }
diff --git a/data/etc/car/com.android.car.secondaryhome.xml b/data/etc/car/com.android.car.secondaryhome.xml
new file mode 100644
index 0000000..c74b86e
--- /dev/null
+++ b/data/etc/car/com.android.car.secondaryhome.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<permissions>
+    <privapp-permissions package="com.android.car.secondaryhome">
+        <!-- Required to launch app in ActivityView -->
+        <permission name="android.permission.ACTIVITY_EMBEDDING"/>
+        <!-- Required to send notification to current user-->
+        <permission name="android.permission.MANAGE_USERS"/>
+    </privapp-permissions>
+</permissions>
diff --git a/libs/hwui/pipeline/skia/ATraceMemoryDump.cpp b/libs/hwui/pipeline/skia/ATraceMemoryDump.cpp
index 551bdc6..234f42d 100644
--- a/libs/hwui/pipeline/skia/ATraceMemoryDump.cpp
+++ b/libs/hwui/pipeline/skia/ATraceMemoryDump.cpp
@@ -39,14 +39,13 @@
  * ATraceMemoryDump calculates memory category first by looking at the "type" string passed to
  * dumpStringValue and then by looking at "backingType" passed to setMemoryBacking.
  * Only GPU Texture memory is tracked separately and everything else is grouped as one
- * "GPU Memory" category.
+ * "Misc Memory" category.
  */
 static std::unordered_map<const char*, const char*> sResourceMap = {
         {"malloc", "HWUI CPU Memory"},          // taken from setMemoryBacking(backingType)
         {"gl_texture", "HWUI Texture Memory"},  // taken from setMemoryBacking(backingType)
-        {"Texture",
-         "HWUI Texture Memory"},  // taken from dumpStringValue(value, valueName="type")
-        // Uncomment categories below to split "GPU Memory" into more brackets for debugging.
+        {"Texture", "HWUI Texture Memory"},  // taken from dumpStringValue(value, valueName="type")
+        // Uncomment categories below to split "Misc Memory" into more brackets for debugging.
         /*{"vk_buffer", "vk_buffer"},
         {"gl_renderbuffer", "gl_renderbuffer"},
         {"gl_buffer", "gl_buffer"},
@@ -169,8 +168,8 @@
     mLastDumpValue = 0;
     mLastPurgeableDumpValue = INVALID_MEMORY_SIZE;
     mLastDumpName = dumpName;
-    // Categories not listed in sResourceMap are reported as "GPU memory"
-    mCategory = "HWUI GPU Memory";
+    // Categories not listed in sResourceMap are reported as "Misc Memory"
+    mCategory = "HWUI Misc Memory";
 }
 
 } /* namespace skiapipeline */
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java b/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java
index 074188e..adf4d3d 100644
--- a/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java
+++ b/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java
@@ -157,9 +157,7 @@
             Handler handler = eventHandler.handler();
             if (handler != null) {
                 Message m = handler.obtainMessage(what, arg1, arg2, obj);
-                if (what != AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER) {
-                    handler.removeMessages(what);
-                }
+                // Do not remove previous messages, as we would lose notification of group changes
                 handler.sendMessage(m);
             }
         }
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index f3c071a0..a828e2d 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -722,6 +722,7 @@
                 return MtpConstants.RESPONSE_OK;
             case MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE:
                 // use screen size as max image size
+                // TODO(b/147721765): Add support for foldables/multi-display devices.
                 Display display = ((WindowManager) mContext.getSystemService(
                         Context.WINDOW_SERVICE)).getDefaultDisplay();
                 int width = display.getMaximumSizeDimension();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
index 0ae640d..2522095 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
@@ -58,7 +58,6 @@
 import android.util.Log;
 import android.util.Pair;
 import android.util.Size;
-import android.view.Display;
 import android.view.Surface;
 import android.view.WindowManager;
 
@@ -2211,14 +2210,14 @@
     }
 
     public static Size getPreviewSizeBound(WindowManager windowManager, Size bound) {
-        Display display = windowManager.getDefaultDisplay();
+        Size windowSize = windowManager.getCurrentWindowMetrics().getSize();
 
-        int width = display.getWidth();
-        int height = display.getHeight();
+        int width = windowSize.getWidth();
+        int height = windowSize.getHeight();
 
         if (height > width) {
             height = width;
-            width = display.getHeight();
+            width = windowSize.getHeight();
         }
 
         if (bound.getWidth() <= width &&
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 0c6f507..34ab7a0 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -64,6 +64,7 @@
         "libgui",
         "libharfbuzz_ng",  // Only for including hb.h via minikin
         "libsensor",
+        "libstats_jni",
         "libandroid_runtime",
         "libminikin",
         "libnetd_client",
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 97b861b..a8f1d2c 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -23,6 +23,8 @@
     AChoreographer_postFrameCallbackDelayed; # introduced=24
     AChoreographer_postFrameCallback64; # introduced=29
     AChoreographer_postFrameCallbackDelayed64; # introduced=29
+    AChoreographer_registerRefreshRateCallback; # introduced=30
+    AChoreographer_unregisterRefreshRateCallback; # introduced=30
     AConfiguration_copy;
     AConfiguration_delete;
     AConfiguration_diff;
diff --git a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java
index c9e0d0a..d4eb2a9 100644
--- a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java
@@ -16,6 +16,9 @@
 
 package com.android.fakeoemfeatures;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AlertDialog;
@@ -25,9 +28,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.hardware.display.DisplayManager;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.util.Size;
 import android.util.Slog;
 import android.view.Display;
 import android.view.ViewGroup;
@@ -94,8 +99,13 @@
             return;
         }
 
-        final WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
-        final Display display = wm.getDefaultDisplay();
+        // Construct an instance of WindowManager to add the window of TYPE_APPLICATION_OVERLAY to
+        // the default display.
+        final DisplayManager dm = getSystemService(DisplayManager.class);
+        final Display defaultDisplay = dm.getDisplay(DEFAULT_DISPLAY);
+        final Context windowContext = createDisplayContext(defaultDisplay)
+                .createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
+        final WindowManager wm = windowContext.getSystemService(WindowManager.class);
 
         // Check to make sure we are not running on a user build.  If this
         // is a user build, WARN!  Do not want!
@@ -108,14 +118,14 @@
             builder.setCancelable(false);
             builder.setPositiveButton("I understand", null);
             Dialog dialog = builder.create();
-            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
+            dialog.getWindow().setType(TYPE_APPLICATION_OVERLAY);
             dialog.show();
         }
 
         // Make a fake window that is always around eating graphics resources.
         FakeView view = new FakeView(this);
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+                TYPE_APPLICATION_OVERLAY,
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
@@ -124,7 +134,8 @@
         }
         lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
         lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
-        int maxSize = display.getMaximumSizeDimension();
+        Size maxWindowSize = wm.getMaximumWindowMetrics().getSize();
+        int maxSize = Math.max(maxWindowSize.getWidth(), maxWindowSize.getHeight());
         maxSize *= 2;
         lp.x = maxSize;
         lp.y = maxSize;
diff --git a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeBackgroundService.java b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeBackgroundService.java
index ff09000..df00eee 100644
--- a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeBackgroundService.java
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeBackgroundService.java
@@ -16,6 +16,9 @@
 
 package com.android.fakeoemfeatures;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
 import java.util.ArrayList;
 import java.util.Random;
 
@@ -23,9 +26,11 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
+import android.hardware.display.DisplayManager;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.util.Size;
 import android.view.Display;
 import android.view.ViewGroup;
 import android.view.WindowManager;
@@ -68,13 +73,15 @@
         super.onCreate();
         mHandler.sendEmptyMessageDelayed(MSG_TICK, TICK_DELAY);
 
-        final WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
-        final Display display = wm.getDefaultDisplay();
+        final DisplayManager dm = getSystemService(DisplayManager.class);
+        final Display display = dm.getDisplay(DEFAULT_DISPLAY);
+        final Context windowContext = createDisplayContext(display)
+                .createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
 
         // Make a fake window that is always around eating graphics resources.
-        FakeView view = new FakeView(this);
-        Dialog dialog = new Dialog(this, android.R.style.Theme_Holo_Dialog);
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
+        FakeView view = new FakeView(windowContext);
+        Dialog dialog = new Dialog(windowContext, android.R.style.Theme_Holo_Dialog);
+        dialog.getWindow().setType(TYPE_APPLICATION_OVERLAY);
         dialog.getWindow().setFlags(
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
@@ -89,7 +96,11 @@
         dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.MATCH_PARENT);
         WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
-        int maxSize = display.getMaximumSizeDimension();
+        // Create an instance of WindowManager that is adjusted to the area of the display dedicated
+        // for windows with type TYPE_APPLICATION_OVERLAY.
+        final WindowManager wm = windowContext.getSystemService(WindowManager.class);
+        Size maxWindowSize = wm.getMaximumWindowMetrics().getSize();
+        int maxSize = Math.max(maxWindowSize.getWidth(), maxWindowSize.getHeight());
         maxSize *= 2;
         lp.x = maxSize;
         lp.y = maxSize;
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
index aac7fc3..d48aa24 100644
--- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -402,7 +402,7 @@
         private static List<String> extractTimeZoneIds(List<TimeZoneMapping> timeZoneMappings) {
             final List<String> zoneIds = new ArrayList<>(timeZoneMappings.size());
             for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
-                zoneIds.add(timeZoneMapping.timeZoneId);
+                zoneIds.add(timeZoneMapping.getTimeZoneId());
             }
             return Collections.unmodifiableList(zoneIds);
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 84dde05..44e70f4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -654,7 +654,7 @@
                 }
             }
         }
-        return oldMetering == mIsScoredNetworkMetered;
+        return oldMetering != mIsScoredNetworkMetered;
     }
 
     /**
@@ -1170,8 +1170,8 @@
             } else { // In range, not disabled.
                 if (mConfig != null) { // Is saved network
                     // Last attempt to connect to this failed. Show reason why
-                    switch (mConfig.recentFailure.getAssociationStatus()) {
-                        case WifiConfiguration.RecentFailure.STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
+                    switch (mConfig.getRecentFailureReason()) {
+                        case WifiConfiguration.RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA:
                             summary.append(mContext.getString(
                                     R.string.wifi_ap_unable_to_handle_new_sta));
                             break;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index db18213a..9934e59 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -41,13 +41,13 @@
 import android.util.Base64;
 import android.util.Slog;
 import android.util.SparseIntArray;
-import android.util.StatsLog;
 import android.util.TimeUtils;
 import android.util.Xml;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FrameworkStatsLog;
 
 import libcore.io.IoUtils;
 
@@ -429,8 +429,9 @@
             mSettings.put(name, newState);
         }
 
-        StatsLog.write(StatsLog.SETTING_CHANGED, name, value, newState.value, oldValue, tag,
-            makeDefault, getUserIdFromKey(mKey), StatsLog.SETTING_CHANGED__REASON__UPDATED);
+        FrameworkStatsLog.write(FrameworkStatsLog.SETTING_CHANGED, name, value, newState.value,
+                oldValue, tag, makeDefault, getUserIdFromKey(mKey),
+                FrameworkStatsLog.SETTING_CHANGED__REASON__UPDATED);
 
         addHistoricalOperationLocked(HISTORICAL_OPERATION_UPDATE, newState);
 
@@ -489,9 +490,9 @@
             if (key.startsWith(prefix) && !keyValues.containsKey(key)) {
                 Setting oldState = mSettings.remove(key);
 
-                StatsLog.write(StatsLog.SETTING_CHANGED, key, /* value= */ "", /* newValue= */ "",
-                        oldState.value, /* tag */ "", false, getUserIdFromKey(mKey),
-                        StatsLog.SETTING_CHANGED__REASON__DELETED);
+                FrameworkStatsLog.write(FrameworkStatsLog.SETTING_CHANGED, key,
+                        /* value= */ "", /* newValue= */ "", oldState.value, /* tag */ "", false,
+                        getUserIdFromKey(mKey), FrameworkStatsLog.SETTING_CHANGED__REASON__DELETED);
                 addHistoricalOperationLocked(HISTORICAL_OPERATION_DELETE, oldState);
                 changedKeys.add(key); // key was removed
             }
@@ -516,9 +517,9 @@
                 continue;
             }
 
-            StatsLog.write(StatsLog.SETTING_CHANGED, key, value, state.value, oldValue,
-                    /* tag */ null, /* make default */ false,
-                    getUserIdFromKey(mKey), StatsLog.SETTING_CHANGED__REASON__UPDATED);
+            FrameworkStatsLog.write(FrameworkStatsLog.SETTING_CHANGED, key, value, state.value,
+                    oldValue, /* tag */ null, /* make default */ false,
+                    getUserIdFromKey(mKey), FrameworkStatsLog.SETTING_CHANGED__REASON__UPDATED);
             addHistoricalOperationLocked(HISTORICAL_OPERATION_UPDATE, state);
         }
 
@@ -544,9 +545,9 @@
 
         Setting oldState = mSettings.remove(name);
 
-        StatsLog.write(StatsLog.SETTING_CHANGED, name, /* value= */ "", /* newValue= */ "",
-            oldState.value, /* tag */ "", false, getUserIdFromKey(mKey),
-            StatsLog.SETTING_CHANGED__REASON__DELETED);
+        FrameworkStatsLog.write(FrameworkStatsLog.SETTING_CHANGED, name, /* value= */ "",
+                /* newValue= */ "", oldState.value, /* tag */ "", false, getUserIdFromKey(mKey),
+                FrameworkStatsLog.SETTING_CHANGED__REASON__DELETED);
 
         updateMemoryUsagePerPackageLocked(oldState.packageName, oldState.value,
                 null, oldState.defaultValue, null);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 7d2b85d..84d9bb6 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -219,6 +219,9 @@
     <!-- Permission required for CTS test - CrossProfileAppsHostSideTest -->
     <uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/>
 
+    <!-- permissions required for CTS test - PhoneStateListenerTest -->
+    <uses-permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH" />
+
     <!-- Permission required for CTS test - UiModeManagerTest -->
     <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 4e2f7d4..6a04583 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1883,9 +1883,8 @@
         final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
         final int user = getCurrentUser();
         final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
-        final boolean isLockOutOrLockDown =
-                containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_LOCKOUT)
-                        || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
+        final boolean isLockDown =
+                containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
                         || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
         final boolean isEncryptedOrTimedOut =
                 containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
@@ -1899,9 +1898,9 @@
         boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;
 
         // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
-        // Lockout/lockdown modes shouldn't scan, since they are more explicit.
+        // Lock-down mode shouldn't scan, since it is more explicit.
         boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
-                && !isLockOutOrLockDown;
+                && !isLockDown;
 
         // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index e954163..a26cce0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -414,7 +414,7 @@
         mNotificationEntryManager.addNotificationEntryListener(
                 new NotificationEntryListener() {
                     @Override
-                    public void onNotificationAdded(NotificationEntry entry) {
+                    public void onPendingEntryAdded(NotificationEntry entry) {
                         onEntryAdded(entry);
                     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index e6082dd..e7e1ba8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -106,7 +106,7 @@
 
         // Initialize screenshot notification smart actions provider.
         mSmartActionsEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, false);
+                SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, true);
         if (mSmartActionsEnabled) {
             mSmartActionsProvider =
                     SystemUIFactory.getInstance()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 795cbb9..7e4ba92 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -437,14 +437,14 @@
     }
 
     @Test
-    public void testIgnoresAuth_whenLockout() {
+    public void testTriesToAuthenticate_whenLockout() {
         mKeyguardUpdateMonitor.dispatchStartedWakingUp();
         mTestableLooper.processAllMessages();
         when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
                 KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT);
 
         mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
-        verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
     }
 
     @Test
diff --git a/packages/Tethering/common/TetheringLib/jarjar-rules.txt b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
index 35e0f88..1403bba 100644
--- a/packages/Tethering/common/TetheringLib/jarjar-rules.txt
+++ b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
@@ -1 +1,2 @@
 rule android.annotation.** com.android.networkstack.tethering.annotation.@1
+rule com.android.internal.annotations.** com.android.networkstack.tethering.annotation.@1
\ No newline at end of file
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
index 37ce1d57..53a358f 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
@@ -30,6 +30,9 @@
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -37,6 +40,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
+import java.util.function.Supplier;
 
 /**
  * This class provides the APIs to control the tethering service.
@@ -50,17 +54,23 @@
 public class TetheringManager {
     private static final String TAG = TetheringManager.class.getSimpleName();
     private static final int DEFAULT_TIMEOUT_MS = 60_000;
+    private static final long CONNECTOR_POLL_INTERVAL_MILLIS = 200L;
 
-    private static TetheringManager sInstance;
+    @GuardedBy("mConnectorWaitQueue")
+    @Nullable
+    private ITetheringConnector mConnector;
+    @GuardedBy("mConnectorWaitQueue")
+    @NonNull
+    private final List<ConnectorConsumer> mConnectorWaitQueue = new ArrayList<>();
+    private final Supplier<IBinder> mConnectorSupplier;
 
-    private final ITetheringConnector mConnector;
     private final TetheringCallbackInternal mCallback;
     private final Context mContext;
     private final ArrayMap<TetheringEventCallback, ITetheringEventCallback>
             mTetheringEventCallbacks = new ArrayMap<>();
 
-    private TetheringConfigurationParcel mTetheringConfiguration;
-    private TetherStatesParcel mTetherStatesParcel;
+    private volatile TetheringConfigurationParcel mTetheringConfiguration;
+    private volatile TetherStatesParcel mTetherStatesParcel;
 
     /**
      * Broadcast Action: A tetherable connection has come or gone.
@@ -162,29 +172,139 @@
     /**
      * Create a TetheringManager object for interacting with the tethering service.
      *
+     * @param context Context for the manager.
+     * @param connectorSupplier Supplier for the manager connector; may return null while the
+     *                          service is not connected.
      * {@hide}
      */
-    public TetheringManager(@NonNull final Context context, @NonNull final IBinder service) {
+    public TetheringManager(@NonNull final Context context,
+            @NonNull Supplier<IBinder> connectorSupplier) {
         mContext = context;
-        mConnector = ITetheringConnector.Stub.asInterface(service);
         mCallback = new TetheringCallbackInternal();
+        mConnectorSupplier = connectorSupplier;
 
         final String pkgName = mContext.getOpPackageName();
+
+        final IBinder connector = mConnectorSupplier.get();
+        // If the connector is available on start, do not start a polling thread. This introduces
+        // differences in the thread that sends the oneway binder calls to the service between the
+        // first few seconds after boot and later, but it avoids always having differences between
+        // the first usage of TetheringManager from a process and subsequent usages (so the
+        // difference is only on boot). On boot binder calls may be queued until the service comes
+        // up and be sent from a worker thread; later, they are always sent from the caller thread.
+        // Considering that it's just oneway binder calls, and ordering is preserved, this seems
+        // better than inconsistent behavior persisting after boot.
+        if (connector != null) {
+            mConnector = ITetheringConnector.Stub.asInterface(connector);
+        } else {
+            startPollingForConnector();
+        }
+
         Log.i(TAG, "registerTetheringEventCallback:" + pkgName);
+        getConnector(c -> c.registerTetheringEventCallback(mCallback, pkgName));
+    }
+
+    private void startPollingForConnector() {
+        new Thread(() -> {
+            while (true) {
+                try {
+                    Thread.sleep(200);
+                } catch (InterruptedException e) {
+                    // Not much to do here, the system needs to wait for the connector
+                }
+
+                final IBinder connector = mConnectorSupplier.get();
+                if (connector != null) {
+                    onTetheringConnected(ITetheringConnector.Stub.asInterface(connector));
+                    return;
+                }
+            }
+        }).start();
+    }
+
+    private interface ConnectorConsumer {
+        void onConnectorAvailable(ITetheringConnector connector) throws RemoteException;
+    }
+
+    private void onTetheringConnected(ITetheringConnector connector) {
+        // Process the connector wait queue in order, including any items that are added
+        // while processing.
+        //
+        // 1. Copy the queue to a local variable under lock.
+        // 2. Drain the local queue with the lock released (otherwise, enqueuing future commands
+        //    would block on the lock).
+        // 3. Acquire the lock again. If any new tasks were queued during step 2, goto 1.
+        //    If not, set mConnector to non-null so future tasks are run immediately, not queued.
+        //
+        // For this to work, all calls to the tethering service must use getConnector(), which
+        // ensures that tasks are added to the queue with the lock held.
+        //
+        // Once mConnector is set to non-null, it will never be null again. If the network stack
+        // process crashes, no recovery is possible.
+        // TODO: evaluate whether it is possible to recover from network stack process crashes
+        // (though in most cases the system will have crashed when the network stack process
+        // crashes).
+        do {
+            final List<ConnectorConsumer> localWaitQueue;
+            synchronized (mConnectorWaitQueue) {
+                localWaitQueue = new ArrayList<>(mConnectorWaitQueue);
+                mConnectorWaitQueue.clear();
+            }
+
+            // Allow more tasks to be added at the end without blocking while draining the queue.
+            for (ConnectorConsumer task : localWaitQueue) {
+                try {
+                    task.onConnectorAvailable(connector);
+                } catch (RemoteException e) {
+                    // Most likely the network stack process crashed, which is likely to crash the
+                    // system. Keep processing other requests but report the error loudly.
+                    Log.wtf(TAG, "Error processing request for the tethering connector", e);
+                }
+            }
+
+            synchronized (mConnectorWaitQueue) {
+                if (mConnectorWaitQueue.size() == 0) {
+                    mConnector = connector;
+                    return;
+                }
+            }
+        } while (true);
+    }
+
+    /**
+     * Asynchronously get the ITetheringConnector to execute some operation.
+     *
+     * <p>If the connector is already available, the operation will be executed on the caller's
+     * thread. Otherwise it will be queued and executed on a worker thread. The operation should be
+     * limited to performing oneway binder calls to minimize differences due to threading.
+     */
+    private void getConnector(ConnectorConsumer consumer) {
+        final ITetheringConnector connector;
+        synchronized (mConnectorWaitQueue) {
+            connector = mConnector;
+            if (connector == null) {
+                mConnectorWaitQueue.add(consumer);
+                return;
+            }
+        }
+
         try {
-            mConnector.registerTetheringEventCallback(mCallback, pkgName);
+            consumer.onConnectorAvailable(connector);
         } catch (RemoteException e) {
             throw new IllegalStateException(e);
         }
     }
 
     private interface RequestHelper {
-        void runRequest(IIntResultListener listener);
+        void runRequest(ITetheringConnector connector, IIntResultListener listener);
     }
 
+    // Used to dispatch legacy ConnectivityManager methods that expect tethering to be able to
+    // return results and perform operations synchronously.
+    // TODO: remove once there are no callers of these legacy methods.
     private class RequestDispatcher {
         private final ConditionVariable mWaiting;
-        public int mRemoteResult;
+        public volatile int mRemoteResult;
 
         private final IIntResultListener mListener = new IIntResultListener.Stub() {
                 @Override
@@ -199,7 +319,7 @@
         }
 
         int waitForResult(final RequestHelper request) {
-            request.runRequest(mListener);
+            getConnector(c -> request.runRequest(c, mListener));
             if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
                 throw new IllegalStateException("Callback timeout");
             }
@@ -222,7 +342,7 @@
     }
 
     private class TetheringCallbackInternal extends ITetheringEventCallback.Stub {
-        private int mError = TETHER_ERROR_NO_ERROR;
+        private volatile int mError = TETHER_ERROR_NO_ERROR;
         private final ConditionVariable mWaitForCallback = new ConditionVariable();
 
         @Override
@@ -280,9 +400,9 @@
         Log.i(TAG, "tether caller:" + callerPkg);
         final RequestDispatcher dispatcher = new RequestDispatcher();
 
-        return dispatcher.waitForResult(listener -> {
+        return dispatcher.waitForResult((connector, listener) -> {
             try {
-                mConnector.tether(iface, callerPkg, listener);
+                connector.tether(iface, callerPkg, listener);
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
@@ -304,9 +424,9 @@
 
         final RequestDispatcher dispatcher = new RequestDispatcher();
 
-        return dispatcher.waitForResult(listener -> {
+        return dispatcher.waitForResult((connector, listener) -> {
             try {
-                mConnector.untether(iface, callerPkg, listener);
+                connector.untether(iface, callerPkg, listener);
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
@@ -330,9 +450,9 @@
 
         final RequestDispatcher dispatcher = new RequestDispatcher();
 
-        return dispatcher.waitForResult(listener -> {
+        return dispatcher.waitForResult((connector, listener) -> {
             try {
-                mConnector.setUsbTethering(enable, callerPkg, listener);
+                connector.setUsbTethering(enable, callerPkg, listener);
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
@@ -467,11 +587,7 @@
                 });
             }
         };
-        try {
-            mConnector.startTethering(request.getParcel(), callerPkg, listener);
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e);
-        }
+        getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener));
     }
 
     /**
@@ -509,15 +625,15 @@
         final String callerPkg = mContext.getOpPackageName();
         Log.i(TAG, "stopTethering caller:" + callerPkg);
 
-        final RequestDispatcher dispatcher = new RequestDispatcher();
-
-        dispatcher.waitForResult(listener -> {
-            try {
-                mConnector.stopTethering(type, callerPkg, listener);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
+        getConnector(c -> c.stopTethering(type, callerPkg, new IIntResultListener.Stub() {
+            @Override
+            public void onResult(int resultCode) {
+                // TODO: provide an API to obtain result
+                // This has never been possible as stopTethering has always been void and never
+                // taken a callback object. The only indication that callers have is if the call
+                // results in a TETHER_STATE_CHANGE broadcast.
             }
-        });
+        }));
     }
 
     /**
@@ -591,12 +707,8 @@
         final String callerPkg = mContext.getOpPackageName();
         Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg);
 
-        try {
-            mConnector.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi,
-                    callerPkg);
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e);
-        }
+        getConnector(c -> c.requestLatestTetheringEntitlementResult(
+                type, receiver, showEntitlementUi, callerPkg));
     }
 
     /**
@@ -832,11 +944,7 @@
                     });
                 }
             };
-            try {
-                mConnector.registerTetheringEventCallback(remoteCallback, callerPkg);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
-            }
+            getConnector(c -> c.registerTetheringEventCallback(remoteCallback, callerPkg));
             mTetheringEventCallbacks.put(callback, remoteCallback);
         }
     }
@@ -860,11 +968,8 @@
             if (remoteCallback == null) {
                 throw new IllegalArgumentException("callback was not registered.");
             }
-            try {
-                mConnector.unregisterTetheringEventCallback(remoteCallback, callerPkg);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
-            }
+
+            getConnector(c -> c.unregisterTetheringEventCallback(remoteCallback, callerPkg));
         }
     }
 
@@ -1002,9 +1107,9 @@
         final String callerPkg = mContext.getOpPackageName();
 
         final RequestDispatcher dispatcher = new RequestDispatcher();
-        final int ret = dispatcher.waitForResult(listener -> {
+        final int ret = dispatcher.waitForResult((connector, listener) -> {
             try {
-                mConnector.isTetheringSupported(callerPkg, listener);
+                connector.isTetheringSupported(callerPkg, listener);
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
@@ -1027,13 +1132,14 @@
         final String callerPkg = mContext.getOpPackageName();
         Log.i(TAG, "stopAllTethering caller:" + callerPkg);
 
-        final RequestDispatcher dispatcher = new RequestDispatcher();
-        dispatcher.waitForResult(listener -> {
-            try {
-                mConnector.stopAllTethering(callerPkg, listener);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
+        getConnector(c -> c.stopAllTethering(callerPkg, new IIntResultListener.Stub() {
+            @Override
+            public void onResult(int resultCode) {
+                // TODO: add an API parameter to send result to caller.
+                // This has never been possible as stopAllTethering has always been void and never
+                // taken a callback object. The only indication that callers have is if the call
+                // results in a TETHER_STATE_CHANGE broadcast.
             }
-        });
+        }));
     }
 }
diff --git a/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java
index 9501073..fcb113e 100644
--- a/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java
+++ b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java
@@ -26,7 +26,6 @@
 import android.util.Pools.Pool;
 import android.util.Pools.SynchronizedPool;
 import android.view.View;
-import android.view.WindowManager;
 
 import com.android.gallery3d.common.Utils;
 import com.android.gallery3d.glrenderer.BasicTexture;
@@ -164,9 +163,7 @@
 
     private static boolean isHighResolution(Context context) {
         DisplayMetrics metrics = new DisplayMetrics();
-        WindowManager wm = (WindowManager)
-                context.getSystemService(Context.WINDOW_SERVICE);
-        wm.getDefaultDisplay().getMetrics(metrics);
+        context.getDisplay().getMetrics(metrics);
         return metrics.heightPixels > 2048 ||  metrics.widthPixels > 2048;
     }
 
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
index f878b4d..6112da5 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -37,9 +37,9 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.util.Log;
+import android.util.Size;
 import android.view.Display;
 import android.view.View;
-import android.view.WindowManager;
 import android.widget.Toast;
 
 import com.android.gallery3d.common.Utils;
@@ -231,18 +231,18 @@
         return x * aspectRatio + y;
     }
 
-    static protected Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
+    static protected Point getDefaultWallpaperSize(Resources res, Display display) {
         if (sDefaultWallpaperSize == null) {
             Point minDims = new Point();
             Point maxDims = new Point();
-            windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
+            display.getCurrentSizeRange(minDims, maxDims);
 
             int maxDim = Math.max(maxDims.x, maxDims.y);
             int minDim = Math.max(minDims.x, minDims.y);
 
             if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
                 Point realSize = new Point();
-                windowManager.getDefaultDisplay().getRealSize(realSize);
+                display.getRealSize(realSize);
                 maxDim = Math.max(realSize.x, realSize.y);
                 minDim = Math.min(realSize.x, realSize.y);
             }
@@ -331,8 +331,7 @@
         // this device
         int rotation = getRotationFromExif(res, resId);
         Point inSize = mCropView.getSourceDimensions();
-        Point outSize = getDefaultWallpaperSize(getResources(),
-                getWindowManager());
+        Point outSize = getDefaultWallpaperSize(getResources(), getDisplay());
         RectF crop = getMaxCropRect(
                 inSize.x, inSize.y, outSize.x, outSize.y, false);
         Runnable onEndCrop = new Runnable() {
@@ -359,14 +358,11 @@
         // Get the crop
         boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
 
-        Display d = getWindowManager().getDefaultDisplay();
-
-        Point displaySize = new Point();
-        d.getSize(displaySize);
-        boolean isPortrait = displaySize.x < displaySize.y;
+        Size windowSize = getWindowManager().getCurrentWindowMetrics().getSize();
+        boolean isPortrait = windowSize.getWidth() < windowSize.getHeight();
 
         Point defaultWallpaperSize = getDefaultWallpaperSize(getResources(),
-                getWindowManager());
+                getDisplay());
         // Get the crop
         RectF cropRect = mCropView.getCrop();
 
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 97f27ca..7151d2b 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -98,7 +98,6 @@
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
 import android.view.View;
-import android.view.WindowManager;
 import android.widget.RemoteViews;
 
 import com.android.internal.R;
@@ -282,8 +281,7 @@
     }
 
     private void computeMaximumWidgetBitmapMemory() {
-        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        Display display = wm.getDefaultDisplay();
+        Display display = mContext.getDisplay();
         Point size = new Point();
         display.getRealSize(size);
         // Cap memory usage at 1.5 times the size of the display
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d933e9d..2982dc9 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5537,20 +5537,6 @@
         return nri.request.requestId == mDefaultRequest.requestId;
     }
 
-    // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent
-    // changes that would conflict throughout the automerger graph. Having this method temporarily
-    // helps with the process of going through with all these dependent changes across the entire
-    // tree.
-    /**
-     * Register a new agent. {@see #registerNetworkAgent} below.
-     */
-    public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
-            LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
-            int currentScore, NetworkAgentConfig networkAgentConfig) {
-        return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities,
-                currentScore, networkAgentConfig, NetworkProvider.ID_NONE);
-    }
-
     /**
      * Register a new agent with ConnectivityService to handle a network.
      *
@@ -5569,7 +5555,7 @@
      */
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
-            int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
+            NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
         enforceNetworkFactoryPermission();
 
         LinkProperties lp = new LinkProperties(linkProperties);
@@ -5577,12 +5563,10 @@
         // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
         // satisfies mDefaultRequest.
         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
-        final NetworkScore ns = new NetworkScore();
-        ns.putIntExtension(NetworkScore.LEGACY_SCORE, currentScore);
         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
                 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
-                ns, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), this,
-                mNetd, mDnsResolver, mNMS, providerId);
+                currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
+                this, mNetd, mDnsResolver, mNMS, providerId);
         // Make sure the network capabilities reflect what the agent info says.
         nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
         final String extraInfo = networkInfo.getExtraInfo();
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 36dd017..139a871 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -897,6 +897,13 @@
                     if ((events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
                             != 0) {
                         updateReportSignalStrengthDecision(r.subId);
+                        try {
+                            if (mSignalStrength[phoneId] != null) {
+                                r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
+                            }
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
                     }
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
                         try {
@@ -1326,9 +1333,10 @@
                         log("notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId
                                 + " phoneId=" + phoneId + " ss=" + signalStrength);
                     }
-                    if (r.matchPhoneStateListenerEvent(
-                                PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                    if ((r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)
+                            || r.matchPhoneStateListenerEvent(
+                                    PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH))
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG) {
                                 log("notifySignalStrengthForPhoneId: callback.onSsS r=" + r
@@ -1341,7 +1349,7 @@
                         }
                     }
                     if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) &&
-                            idMatch(r.subId, subId, phoneId)){
+                            idMatch(r.subId, subId, phoneId)) {
                         try {
                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
                             int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
@@ -2542,6 +2550,11 @@
                     android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
         }
 
+        if ((events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH, null);
+        }
+
         if ((events & READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
@@ -2657,7 +2670,8 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
+        if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0
+                || (events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) {
             try {
                 if (mSignalStrength[phoneId] != null) {
                     SignalStrength signalStrength = mSignalStrength[phoneId];
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8cf620d..08625be 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6876,6 +6876,7 @@
                 }
             }
 
+            ProcessRecord dyingProc = null;
             if (cpr != null && cpr.proc != null) {
                 providerRunning = !cpr.proc.killed;
 
@@ -6885,14 +6886,9 @@
                 // (See the commit message on I2c4ba1e87c2d47f2013befff10c49b3dc337a9a7 to see
                 // how to test this case.)
                 if (cpr.proc.killed && cpr.proc.killedByAm) {
-                    final long iden = Binder.clearCallingIdentity();
-                    try {
-                        mProcessList.killProcAndWaitIfNecessaryLocked(cpr.proc, false,
-                                cpr.uid == cpr.proc.uid || cpr.proc.isolated,
-                                "getContentProviderImpl: %s (killedByAm)", startTime);
-                    } finally {
-                        Binder.restoreCallingIdentity(iden);
-                    }
+                    Slog.wtf(TAG, cpr.proc.toString() + " was killed by AM but isn't really dead");
+                    // Now we are going to wait for the death before starting the new process.
+                    dyingProc = cpr.proc;
                 }
             }
 
@@ -6993,18 +6989,18 @@
                     // has been killed on us.  We need to wait for a new
                     // process to be started, and make sure its death
                     // doesn't kill our process.
-                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
+                    Slog.wtf(TAG, "Existing provider " + cpr.name.flattenToShortString()
                             + " is crashing; detaching " + r);
                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
-                    mProcessList.killProcAndWaitIfNecessaryLocked(cpr.proc,
-                            false, true, "getContentProviderImpl: %s", startTime);
                     if (!lastRef) {
                         // This wasn't the last ref our process had on
-                        // the provider...  we have now been killed, bail.
+                        // the provider...  we will be killed during cleaning up, bail.
                         return null;
                     }
+                    // We'll just start a new process to host the content provider
                     providerRunning = false;
                     conn = null;
+                    dyingProc = cpr.proc;
                 } else {
                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
                 }
@@ -7080,7 +7076,7 @@
                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
                 cpr = mProviderMap.getProviderByClass(comp, userId);
                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
-                final boolean firstClass = cpr == null;
+                boolean firstClass = cpr == null;
                 if (firstClass) {
                     final long ident = Binder.clearCallingIdentity();
 
@@ -7111,6 +7107,13 @@
                     } finally {
                         Binder.restoreCallingIdentity(ident);
                     }
+                } else if (dyingProc == cpr.proc) {
+                    // The old stable connection's client should be killed during proc cleaning up,
+                    // so do not re-use the old ContentProviderRecord, otherwise the new clients
+                    // could get killed unexpectedly.
+                    cpr = new ContentProviderRecord(cpr);
+                    // This is sort of "firstClass"
+                    firstClass = true;
                 }
 
                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
@@ -14270,10 +14273,19 @@
                 cpr.launchingApp = null;
                 cpr.notifyAll();
             }
-            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
+            final int userId = UserHandle.getUserId(cpr.uid);
+            // Don't remove from provider map if it doesn't match
+            // could be a new content provider is starting
+            if (mProviderMap.getProviderByClass(cpr.name, userId) == cpr) {
+                mProviderMap.removeProviderByClass(cpr.name, userId);
+            }
             String names[] = cpr.info.authority.split(";");
             for (int j = 0; j < names.length; j++) {
-                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
+                // Don't remove from provider map if it doesn't match
+                // could be a new content provider is starting
+                if (mProviderMap.getProviderByName(names[j], userId) == cpr) {
+                    mProviderMap.removeProviderByName(names[j], userId);
+                }
             }
         }
 
@@ -14368,6 +14380,10 @@
         // Remove published content providers.
         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
+            if (cpr.proc != app) {
+                // If the hosting process record isn't really us, bail out
+                continue;
+            }
             final boolean alwaysRemove = app.bad || !allowRestart;
             final boolean inLaunching = removeDyingProviderLocked(app, cpr, alwaysRemove);
             if (!alwaysRemove && inLaunching && cpr.hasConnectionOrHandle()) {
@@ -14453,6 +14469,27 @@
         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
                 null).sendToTarget();
 
+        // If this is a precede instance of another process instance
+        allowRestart = true;
+        synchronized (app) {
+            if (app.mSuccessor != null) {
+                // We don't allow restart with this ProcessRecord now,
+                // because we have created a new one already.
+                allowRestart = false;
+                // If it's persistent, add the successor to mPersistentStartingProcesses
+                if (app.isPersistent() && !app.removed) {
+                    if (mPersistentStartingProcesses.indexOf(app.mSuccessor) < 0) {
+                        mPersistentStartingProcesses.add(app.mSuccessor);
+                    }
+                }
+                // clean up the field so the successor's proc starter could proceed.
+                app.mSuccessor.mPrecedence = null;
+                app.mSuccessor = null;
+                // Notify if anyone is waiting for it.
+                app.notifyAll();
+            }
+        }
+
         // If the caller is restarting this app, then leave it in its
         // current lists and let the caller take care of it.
         if (restarting) {
@@ -14482,7 +14519,7 @@
         mAtmInternal.onCleanUpApplicationRecord(app.getWindowProcessController());
         mProcessList.noteProcessDiedLocked(app);
 
-        if (restart && !app.isolated) {
+        if (restart && allowRestart && !app.isolated) {
             // We have components that still need to be running in the
             // process, so re-launch it.
             if (index < 0) {
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 143424d..b107626 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -36,7 +36,9 @@
 import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
 import static android.app.ActivityManager.PROCESS_STATE_TOP;
 import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
 import static android.os.Process.SCHED_OTHER;
 import static android.os.Process.THREAD_GROUP_BACKGROUND;
 import static android.os.Process.THREAD_GROUP_DEFAULT;
@@ -70,7 +72,6 @@
 import android.app.ActivityManager;
 import android.app.ApplicationExitInfo;
 import android.app.usage.UsageEvents;
-import android.compat.Compatibility;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.Disabled;
 import android.compat.annotation.EnabledAfter;
@@ -82,6 +83,7 @@
 import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
@@ -93,6 +95,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.compat.IPlatformCompat;
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.wm.ActivityServiceConnectionsHolder;
@@ -210,6 +213,8 @@
     private ActiveUids mTmpUidRecords;
     private ArrayDeque<ProcessRecord> mTmpQueue;
 
+    private final IPlatformCompat mPlatformCompat;
+
     OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids) {
         this(service, processList, activeUids, createAdjusterThread());
     }
@@ -256,6 +261,8 @@
         mTmpQueue = new ArrayDeque<ProcessRecord>(mConstants.CUR_MAX_CACHED_PROCESSES << 1);
         mNumSlots = ((ProcessList.CACHED_APP_MAX_ADJ - ProcessList.CACHED_APP_MIN_ADJ + 1) >> 1)
                 / ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
+        IBinder b = ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
+        mPlatformCompat = IPlatformCompat.Stub.asInterface(b);
     }
 
     void initSettings() {
@@ -1492,8 +1499,23 @@
                                     != 0 ? TEMP_PROCESS_CAPABILITY_FOREGROUND_LOCATION : 0;
                 }
                 if (s.mAllowWhileInUsePermissionInFgs) {
-                    capabilityFromFGS |= PROCESS_CAPABILITY_FOREGROUND_CAMERA
-                            | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+                    boolean enabled = false;
+                    try {
+                        enabled = mPlatformCompat.isChangeEnabled(
+                                CAMERA_MICROPHONE_CAPABILITY_CHANGE_ID, s.appInfo);
+                    } catch (RemoteException e) {
+                    }
+                    if (enabled) {
+                        capabilityFromFGS |=
+                                (fgsType & FOREGROUND_SERVICE_TYPE_CAMERA)
+                                        != 0 ? PROCESS_CAPABILITY_FOREGROUND_CAMERA : 0;
+                        capabilityFromFGS |=
+                                (fgsType & FOREGROUND_SERVICE_TYPE_MICROPHONE)
+                                        != 0 ? PROCESS_CAPABILITY_FOREGROUND_MICROPHONE : 0;
+                    } else {
+                        capabilityFromFGS |= PROCESS_CAPABILITY_FOREGROUND_CAMERA
+                                | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+                    }
                 }
             }
 
@@ -1667,7 +1689,13 @@
                                 // Go at most to BOUND_TOP, unless requested to elevate
                                 // to client's state.
                                 clientProcState = PROCESS_STATE_BOUND_TOP;
-                                if (Compatibility.isChangeEnabled(PROCESS_CAPABILITY_CHANGE_ID)) {
+                                boolean enabled = false;
+                                try {
+                                    enabled = mPlatformCompat.isChangeEnabled(
+                                            PROCESS_CAPABILITY_CHANGE_ID, client.info);
+                                } catch (RemoteException e) {
+                                }
+                                if (enabled) {
                                     if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
                                         // TOP process passes all capabilities to the service.
                                         capability = PROCESS_CAPABILITY_ALL;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 7c36a7e..b19f2b3 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1842,26 +1842,9 @@
         if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
                     "Posting procStart msg for " + app.toShortString());
-            mService.mProcStartHandler.post(() -> {
-                try {
-                    final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
-                            entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
-                            app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
-                    synchronized (mService) {
-                        handleProcessStartedLocked(app, startResult, startSeq);
-                    }
-                } catch (RuntimeException e) {
-                    synchronized (mService) {
-                        Slog.e(ActivityManagerService.TAG, "Failure starting process "
-                                + app.processName, e);
-                        mPendingStarts.remove(startSeq);
-                        app.pendingStart = false;
-                        mService.forceStopPackageLocked(app.info.packageName,
-                                UserHandle.getAppId(app.uid),
-                                false, false, true, false, false, app.userId, "start failure");
-                    }
-                }
-            });
+            mService.mProcStartHandler.post(() -> handleProcessStart(
+                    app, entryPoint, gids, runtimeFlags, mountExternal, requiredAbi,
+                    instructionSet, invokeWith, startSeq));
             return true;
         } else {
             try {
@@ -1882,6 +1865,66 @@
         }
     }
 
+    /**
+     * Main handler routine to start the given process from the ProcStartHandler.
+     *
+     * <p>Note: this function doesn't hold the global AM lock intentionally.</p>
+     */
+    private void handleProcessStart(final ProcessRecord app, final String entryPoint,
+            final int[] gids, final int runtimeFlags, final int mountExternal,
+            final String requiredAbi, final String instructionSet,
+            final String invokeWith, final long startSeq) {
+        // If there is a precede instance of the process, wait for its death with a timeout.
+        // Use local reference since we are not using locks here
+        final ProcessRecord precedence = app.mPrecedence;
+        if (precedence != null) {
+            final int pid = precedence.pid;
+            long now = System.currentTimeMillis();
+            final long end = now + PROC_KILL_TIMEOUT;
+            try {
+                Process.waitForProcessDeath(pid, PROC_KILL_TIMEOUT);
+                // It's killed successfully, but we'd make sure the cleanup work is done.
+                synchronized (precedence) {
+                    if (app.mPrecedence != null) {
+                        now = System.currentTimeMillis();
+                        if (now < end) {
+                            try {
+                                precedence.wait(end - now);
+                            } catch (InterruptedException e) {
+                            }
+                        }
+                    }
+                    if (app.mPrecedence != null) {
+                        // The cleanup work hasn't be done yet, let's log it and continue.
+                        Slog.w(TAG, precedence + " has died, but its cleanup isn't done");
+                    }
+                }
+            } catch (Exception e) {
+                // It's still alive...
+                Slog.wtf(TAG, precedence.toString() + " refused to die, but we need to launch "
+                        + app);
+            }
+        }
+        try {
+            final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
+                    entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
+                    app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
+            synchronized (mService) {
+                handleProcessStartedLocked(app, startResult, startSeq);
+            }
+        } catch (RuntimeException e) {
+            synchronized (mService) {
+                Slog.e(ActivityManagerService.TAG, "Failure starting process "
+                        + app.processName, e);
+                mPendingStarts.remove(startSeq);
+                app.pendingStart = false;
+                mService.forceStopPackageLocked(app.info.packageName,
+                        UserHandle.getAppId(app.uid),
+                        false, false, true, false, false, app.userId, "start failure");
+            }
+        }
+    }
+
     @GuardedBy("mService")
     public void killAppZygoteIfNeededLocked(AppZygote appZygote, boolean force) {
         final ApplicationInfo appInfo = appZygote.getAppInfo();
@@ -2136,6 +2179,7 @@
                 + " app=" + app + " knownToBeDead=" + knownToBeDead
                 + " thread=" + (app != null ? app.thread : null)
                 + " pid=" + (app != null ? app.pid : -1));
+        ProcessRecord precedence = null;
         if (app != null && app.pid > 0) {
             if ((!knownToBeDead && !app.killed) || app.thread == null) {
                 // We already have the app running, or are waiting for it to
@@ -2150,9 +2194,15 @@
             // An application record is attached to a previous process,
             // clean it up now.
             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
-            // do the killing
-            killProcAndWaitIfNecessaryLocked(app, true, app.uid == info.uid || app.isolated,
-                    "startProcess: bad proc running, killing: %s", startTime);
+            checkSlow(startTime, "startProcess: bad proc running, killing");
+            ProcessList.killProcessGroup(app.uid, app.pid);
+            checkSlow(startTime, "startProcess: done killing old proc");
+
+            Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");
+            // We are not going to re-use the ProcessRecord, as we haven't dealt with the cleanup
+            // routine of it yet, but we'd set it as the precedence of the new process.
+            precedence = app;
+            app = null;
         }
 
         if (app == null) {
@@ -2166,6 +2216,10 @@
             app.crashHandler = crashHandler;
             app.isolatedEntryPoint = entryPoint;
             app.isolatedEntryPointArgs = entryPointArgs;
+            if (precedence != null) {
+                app.mPrecedence = precedence;
+                precedence.mSuccessor = app;
+            }
             checkSlow(startTime, "startProcess: done creating new process record");
         } else {
             // If this is a new package in the process, add the package to the list
@@ -2193,44 +2247,6 @@
         return success ? app : null;
     }
 
-    /**
-     * Kill (if asked to) and wait for the given process died if necessary
-     * @param app - The process record to kill
-     * @param doKill - Kill the given process record
-     * @param wait - Wait for the death of the given process
-     * @param formatString - The log message for slow operation
-     * @param startTime - The start timestamp of the operation
-     */
-    @GuardedBy("mService")
-    void killProcAndWaitIfNecessaryLocked(final ProcessRecord app, final boolean doKill,
-            final boolean wait, final String formatString, final long startTime) {
-
-        checkSlow(startTime, String.format(formatString, "before appDied"));
-
-        if (doKill) {
-            // do the killing
-            ProcessList.killProcessGroup(app.uid, app.pid);
-            noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
-                    ApplicationExitInfo.SUBREASON_UNKNOWN,
-                    String.format(formatString, ""));
-        }
-
-        // wait for the death
-        if (wait) {
-            try {
-                Process.waitForProcessDeath(app.pid, PROC_KILL_TIMEOUT);
-            } catch (Exception e) {
-                // Maybe the process goes into zombie, use an expensive API to check again.
-                if (mService.isProcessAliveLocked(app)) {
-                    Slog.w(TAG, String.format(formatString,
-                              "waiting for app killing timed out"));
-                }
-            }
-        }
-
-        checkSlow(startTime, String.format(formatString, "after appDied"));
-    }
-
     @GuardedBy("mService")
     private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
         StringBuilder sb = null;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index b0c0aae..fc33c25 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -320,6 +320,14 @@
     // set of disabled compat changes for the process (all others are enabled)
     long[] mDisabledCompatChanges;
 
+    // The precede instance of the process, which would exist when the previous process is killed
+    // but not fully dead yet; in this case, the new instance of the process should be held until
+    // this precede instance is fully dead.
+    volatile ProcessRecord mPrecedence;
+    // The succeeding instance of the process, which is going to be started after this process
+    // is killed successfully.
+    volatile ProcessRecord mSuccessor;
+
     // Cached task info for OomAdjuster
     private static final int VALUE_INVALID = -1;
     private static final int VALUE_FALSE = 0;
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
index ad20ed8..ad72166 100644
--- a/services/core/java/com/android/server/audio/RotationHelper.java
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -80,6 +80,7 @@
     static void updateOrientation() {
         // Even though we're responding to device orientation events,
         // use display rotation so audio stays in sync with video/dialogs
+        // TODO(b/148458001): Support multi-display
         int newRotation = ((WindowManager) sContext.getSystemService(
                 Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
         synchronized(sRotationLock) {
diff --git a/services/core/java/com/android/server/backup/SystemBackupAgent.java b/services/core/java/com/android/server/backup/SystemBackupAgent.java
index 1f4563b..0a30b76 100644
--- a/services/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/services/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -113,6 +113,7 @@
             throws IOException {
         // Slot in a restore helper for the older wallpaper backup schema to support restore
         // from devices still generating data in that format.
+        //TODO(b/147732386): Add multi-display support for wallpaper backup.
         addHelper(WALLPAPER_HELPER, new WallpaperBackupHelper(this,
                 new String[] { WALLPAPER_IMAGE_KEY}));
 
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index be5350f..07fc9b7 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -707,7 +707,6 @@
                 checkPermission();
             }
 
-
             if (!Utils.isValidAuthenticatorConfig(authenticators)) {
                 throw new SecurityException("Invalid authenticator configuration");
             }
@@ -720,19 +719,6 @@
             try {
                 biometricConstantsResult = checkAndGetAuthenticators(userId, bundle, opPackageName,
                         false /* checkDevicePolicyManager */).second;
-                if (biometricConstantsResult != BiometricConstants.BIOMETRIC_SUCCESS
-                        && Utils.isDeviceCredentialAllowed(bundle)) {
-                    // If there's an issue with biometrics, but device credential is allowed and
-                    // set up, return SUCCESS. If device credential isn't set up either, return
-                    // ERROR_NO_DEVICE_CREDENTIAL.
-                    if (mTrustManager.isDeviceSecure(userId)) {
-                        biometricConstantsResult = BiometricConstants.BIOMETRIC_SUCCESS;
-                    } else {
-                        biometricConstantsResult =
-                                BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL;
-                    }
-                }
-
             } catch (RemoteException e) {
                 Slog.e(TAG, "Remote exception", e);
             } finally {
@@ -1022,9 +1008,8 @@
     }
 
     /**
-     * Checks if there are any available biometrics, and returns the modality. This method also
-     * returns errors through the callback (no biometric feature, hardware not detected, no
-     * templates enrolled, etc). This service must not start authentication if errors are sent.
+     * Depending on the requested authentication (credential/biometric combination), checks their
+     * availability.
      *
      * @param userId the user to check for
      * @param bundle passed from {@link BiometricPrompt}
@@ -1037,24 +1022,27 @@
      * {@link BiometricAuthenticator#TYPE_FACE}
      * and the error containing one of the {@link BiometricConstants} errors.
      *
-     * TODO(kchyn): Update this to handle DEVICE_CREDENTIAL better, reduce duplicate code in callers
+     * TODO(kchyn) should return Pair<Integer, Integer> with `first` being an actual bitfield
+     * taking BiometricAuthenticator#TYPE_CREDENTIAL as well.
+     *
      */
     private Pair<Integer, Integer> checkAndGetAuthenticators(int userId, Bundle bundle,
             String opPackageName, boolean checkDevicePolicyManager) throws RemoteException {
-        if (!Utils.isBiometricAllowed(bundle)
-                && Utils.isDeviceCredentialAllowed(bundle)
-                && !mTrustManager.isDeviceSecure(userId)) {
-            // If only device credential is being checked, and the user doesn't have one set up
-            return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL);
-        }
 
-        // Assuming that authenticators are listed in priority-order, the rest of this function
-        // will attempt to find the first authenticator that's as strong or stronger than the
-        // requested strength, available, enrolled, and enabled. The tricky part is returning the
-        // correct error. Error strings that are modality-specific should also respect the
+        final boolean biometricRequested = Utils.isBiometricAllowed(bundle);
+        final boolean credentialRequested = Utils.isDeviceCredentialAllowed(bundle);
+
+        final boolean biometricOk;
+        final boolean credentialOk = mTrustManager.isDeviceSecure(userId);
+
+        // Assuming that biometric authenticators are listed in priority-order, the rest of this
+        // function will attempt to find the first authenticator that's as strong or stronger than
+        // the requested strength, available, enrolled, and enabled. The tricky part is returning
+        // the correct error. Error strings that are modality-specific should also respect the
         // priority-order.
 
-        // Find first authenticator that's strong enough, detected, enrolled, and enabled.
+        // Find first biometric authenticator that's strong enough, detected, enrolled, and enabled.
+        boolean disabledByDevicePolicy = false;
         boolean hasSufficientStrength = false;
         boolean isHardwareDetected = false;
         boolean hasTemplatesEnrolled = false;
@@ -1065,52 +1053,96 @@
         for (AuthenticatorWrapper authenticator : mAuthenticators) {
             final int actualStrength = authenticator.getActualStrength();
             final int requestedStrength = Utils.getPublicBiometricStrength(bundle);
-            if (Utils.isAtLeastStrength(actualStrength, requestedStrength)) {
-                hasSufficientStrength = true;
-                modality = authenticator.modality;
-                if (authenticator.impl.isHardwareDetected(opPackageName)) {
-                    isHardwareDetected = true;
-                    if (firstHwAvailable == TYPE_NONE) {
-                        // Store the first one since we want to return the error in correct
-                        // priority order.
-                        firstHwAvailable = modality;
-                    }
-                    if (authenticator.impl.hasEnrolledTemplates(userId, opPackageName)) {
-                        hasTemplatesEnrolled = true;
-                        // If the device policy manager disables a specific biometric, skip it.
-                        if (checkDevicePolicyManager &&
-                                isBiometricDisabledByDevicePolicy(modality, userId)) {
-                            continue;
-                        }
-                        if (isEnabledForApp(modality, userId)) {
-                            enabledForApps = true;
-                            break;
-                        }
-                    }
-                }
+
+            if (isBiometricDisabledByDevicePolicy(authenticator.modality, userId)) {
+                disabledByDevicePolicy = true;
+                continue;
             }
+            disabledByDevicePolicy = false;
+
+            if (!Utils.isAtLeastStrength(actualStrength, requestedStrength)) {
+                continue;
+            }
+            hasSufficientStrength = true;
+
+            if (!authenticator.impl.isHardwareDetected(opPackageName)) {
+                continue;
+            }
+            isHardwareDetected = true;
+
+            if (firstHwAvailable == TYPE_NONE) {
+                // Store the first one since we want to return the error in correct
+                // priority order.
+                firstHwAvailable = authenticator.modality;
+            }
+
+            if (!authenticator.impl.hasEnrolledTemplates(userId, opPackageName)) {
+                continue;
+            }
+            hasTemplatesEnrolled = true;
+
+            if (!isEnabledForApp(authenticator.modality, userId)) {
+                continue;
+            }
+            enabledForApps = true;
+            modality = authenticator.modality;
+            break;
         }
 
+        biometricOk = !disabledByDevicePolicy
+                && hasSufficientStrength && isHardwareDetected
+                && hasTemplatesEnrolled && enabledForApps;
+
         Slog.d(TAG, "checkAndGetAuthenticators: user=" + userId
                 + " checkDevicePolicyManager=" + checkDevicePolicyManager
                 + " isHardwareDetected=" + isHardwareDetected
                 + " hasTemplatesEnrolled=" + hasTemplatesEnrolled
-                + " enabledForApps=" + enabledForApps);
+                + " enabledForApps=" + enabledForApps
+                + " disabledByDevicePolicy=" + disabledByDevicePolicy);
 
-        // Check error conditions
-        if (!hasSufficientStrength) {
-            return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT);
-        } else if (!isHardwareDetected) {
-            return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
-        } else if (!hasTemplatesEnrolled) {
-            // Return the modality here so the correct error string can be sent. This error is
-            // preferred over !enabledForApps
-            return new Pair<>(firstHwAvailable, BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS);
-        } else if (!enabledForApps) {
+        if (biometricRequested && credentialRequested) {
+            if (credentialOk || biometricOk) {
+                if (!biometricOk) {
+                    // If there's a problem with biometrics but device credential is
+                    // allowed, only show credential UI.
+                    bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED,
+                            Authenticators.DEVICE_CREDENTIAL);
+                }
+                return new Pair<>(modality, BiometricConstants.BIOMETRIC_SUCCESS);
+            } else {
+                return new Pair<>(firstHwAvailable,
+                        BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS);
+            }
+        } else if (biometricRequested) {
+            if (biometricOk) {
+                return new Pair<>(modality, BiometricConstants.BIOMETRIC_SUCCESS);
+            } else if (disabledByDevicePolicy) {
+                return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
+            } else if (!hasSufficientStrength) {
+                return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT);
+            } else if (!isHardwareDetected) {
+                return new Pair<>(firstHwAvailable,
+                        BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
+            } else if (!hasTemplatesEnrolled) {
+                return new Pair<>(firstHwAvailable,
+                        BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS);
+            } else if (!enabledForApps) {
+                return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
+            } else {
+                Slog.e(TAG, "Unexpected case");
+                return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
+            }
+        } else if (credentialRequested) {
+            if (credentialOk) {
+                return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_SUCCESS);
+            } else {
+                return new Pair<>(TYPE_NONE,
+                        BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL);
+            }
+        } else {
+            Slog.e(TAG, "No authenticators requested");
             return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
         }
-
-        return new Pair<>(modality, BiometricConstants.BIOMETRIC_SUCCESS);
     }
 
     private boolean isEnabledForApp(int modality, int userId) {
@@ -1549,41 +1581,19 @@
             int callingUid, int callingPid, int callingUserId) {
 
         mHandler.post(() -> {
-            int modality = TYPE_NONE;
-            int result;
-
             try {
                 final boolean checkDevicePolicyManager = bundle.getBoolean(
                         BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, false);
                 final Pair<Integer, Integer> pair = checkAndGetAuthenticators(userId, bundle,
                         opPackageName, checkDevicePolicyManager);
-                modality = pair.first;
-                result = pair.second;
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Remote exception", e);
-                result = BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
-            }
+                final int modality = pair.first;
+                final int result = pair.second;
 
-            try {
-                if (result == BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL) {
-                    // If the app allowed device credential but the user hasn't set it up yet,
-                    // return this error.
-                    receiver.onError(modality, result, 0 /* vendorCode */);
-                } else if (result != BiometricConstants.BIOMETRIC_SUCCESS) {
-                    if (Utils.isDeviceCredentialAllowed(bundle)) {
-                        // If there's a problem with biometrics but device credential is allowed,
-                        // only show credential UI.
-                        bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED,
-                                Authenticators.DEVICE_CREDENTIAL);
-                        authenticateInternal(token, sessionId, userId, receiver, opPackageName,
-                                bundle, callingUid, callingPid, callingUserId, modality);
-                    } else {
-                        receiver.onError(modality, result, 0 /* vendorCode */);
-                    }
+                if (result == BiometricConstants.BIOMETRIC_SUCCESS) {
+                    authenticateInternal(token, sessionId, userId, receiver, opPackageName,
+                            bundle, callingUid, callingPid, callingUserId, modality);
                 } else {
-                    // BIOMETRIC_SUCCESS, proceed to authentication
-                    authenticateInternal(token, sessionId, userId, receiver, opPackageName, bundle,
-                            callingUid, callingPid, callingUserId, modality);
+                    receiver.onError(modality, result, 0 /* vendorCode */);
                 }
             } catch (RemoteException e) {
                 Slog.e(TAG, "Remote exception", e);
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index a0573db..b512475 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -962,9 +962,10 @@
         @Override
         public void onLockoutChanged(long duration) {
             Slog.d(TAG, "onLockoutChanged: " + duration);
+
             if (duration == 0) {
                 mCurrentUserLockoutMode = AuthenticationClient.LOCKOUT_NONE;
-            } else if (duration == Long.MAX_VALUE) {
+            } else if (duration == -1 || duration == Long.MAX_VALUE) {
                 mCurrentUserLockoutMode = AuthenticationClient.LOCKOUT_PERMANENT;
             } else {
                 mCurrentUserLockoutMode = AuthenticationClient.LOCKOUT_TIMED;
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 8d26176..7f7c9c4 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -35,6 +35,7 @@
 import com.android.internal.compat.OverrideAllowedState;
 import com.android.server.compat.config.Change;
 import com.android.server.compat.config.XmlParser;
+import com.android.server.pm.ApexManager;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -45,6 +46,7 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import javax.xml.datatype.DatatypeConfigurationException;
@@ -369,12 +371,18 @@
                 Environment.getRootDirectory(), "etc", "compatconfig"));
         config.initConfigFromLib(Environment.buildPath(
                 Environment.getRootDirectory(), "system_ext", "etc", "compatconfig"));
+
+        List<ApexManager.ActiveApexInfo> apexes = ApexManager.getInstance().getActiveApexInfos();
+        for (ApexManager.ActiveApexInfo apex : apexes) {
+            config.initConfigFromLib(Environment.buildPath(
+                    apex.apexDirectory, "etc", "compatconfig"));
+        }
         return config;
     }
 
     void initConfigFromLib(File libraryDir) {
         if (!libraryDir.exists() || !libraryDir.isDirectory()) {
-            Slog.e(TAG, "No directory " + libraryDir + ", skipping");
+            Slog.d(TAG, "No directory " + libraryDir + ", skipping");
             return;
         }
         for (File f : libraryDir.listFiles()) {
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 4d5af9a..bb8b12e 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -16,11 +16,6 @@
 
 package com.android.server.compat;
 
-import static android.Manifest.permission.LOG_COMPAT_CHANGE;
-import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
-import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
 import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.content.Context;
@@ -73,14 +68,12 @@
 
     @Override
     public void reportChange(long changeId, ApplicationInfo appInfo) {
-        checkCompatChangeLogPermission();
         reportChange(changeId, appInfo.uid,
                 StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
     }
 
     @Override
     public void reportChangeByPackageName(long changeId, String packageName, int userId) {
-        checkCompatChangeLogPermission();
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo == null) {
             return;
@@ -90,13 +83,11 @@
 
     @Override
     public void reportChangeByUid(long changeId, int uid) {
-        checkCompatChangeLogPermission();
         reportChange(changeId, uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
     }
 
     @Override
     public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
-        checkCompatChangeReadPermission();
         if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
             reportChange(changeId, appInfo.uid,
                     StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED);
@@ -109,7 +100,6 @@
 
     @Override
     public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
-        checkCompatChangeReadPermission();
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo == null) {
             return true;
@@ -119,7 +109,6 @@
 
     @Override
     public boolean isChangeEnabledByUid(long changeId, int uid) {
-        checkCompatChangeReadPermission();
         String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
         if (packages == null || packages.length == 0) {
             return true;
@@ -152,7 +141,6 @@
     @Override
     public void setOverrides(CompatibilityChangeConfig overrides, String packageName)
             throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         mCompatConfig.addOverrides(overrides, packageName);
         killPackage(packageName);
     }
@@ -160,13 +148,11 @@
     @Override
     public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName)
             throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         mCompatConfig.addOverrides(overrides, packageName);
     }
 
     @Override
     public void clearOverrides(String packageName) throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         mCompatConfig.removePackageOverrides(packageName);
         killPackage(packageName);
     }
@@ -174,14 +160,12 @@
     @Override
     public void clearOverridesForTest(String packageName)
             throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         mCompatConfig.removePackageOverrides(packageName);
     }
 
     @Override
     public boolean clearOverride(long changeId, String packageName)
             throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         boolean existed = mCompatConfig.removeOverride(changeId, packageName);
         killPackage(packageName);
         return existed;
@@ -189,13 +173,11 @@
 
     @Override
     public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
-        checkCompatChangeReadPermission();
         return mCompatConfig.getAppConfig(appInfo);
     }
 
     @Override
     public CompatibilityChangeInfo[] listAllChanges() {
-        checkCompatChangeReadPermission();
         return mCompatConfig.dumpChanges();
     }
 
@@ -234,7 +216,6 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        checkCompatChangeReadPermission();
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
         mCompatConfig.dumpConfig(pw);
     }
@@ -292,25 +273,4 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
-
-    private void checkCompatChangeLogPermission() throws SecurityException {
-        if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot log compat change usage");
-        }
-    }
-
-    private void checkCompatChangeReadPermission() throws SecurityException {
-        if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot read compat change");
-        }
-    }
-
-    private void checkCompatChangeOverridePermission() throws SecurityException {
-        if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot override compat change");
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index d66aec5..3cfe916 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -483,7 +483,7 @@
             return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
         }
 
-        int score = mNetworkScore.getIntExtension(NetworkScore.LEGACY_SCORE);
+        int score = mNetworkScore.getLegacyScore();
         if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
             score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
         }
diff --git a/services/core/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
index 0fdf2da..49f0d35 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayWindow.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
@@ -109,7 +109,8 @@
         mWindowManager = (WindowManager)context.getSystemService(
                 Context.WINDOW_SERVICE);
 
-        mDefaultDisplay = mWindowManager.getDefaultDisplay();
+        // TODO(b/148458868): Support multi-display
+        mDefaultDisplay = mContext.getDisplay();
         updateDefaultDisplayInfo();
 
         resize(width, height, densityDpi, false /* doLayout */);
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 90afeff..4ff37a2 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -95,6 +95,7 @@
      * Returns an instance of either {@link ApexManagerImpl} or {@link ApexManagerFlattenedApex}
      * depending on whether this device supports APEX, i.e. {@link ApexProperties#updatable()}
      * evaluates to {@code true}.
+     * @hide
      */
     public static ApexManager getInstance() {
         return sApexManagerSingleton.get();
@@ -102,8 +103,9 @@
 
     /**
      * Minimal information about APEX mount points and the original APEX package they refer to.
+     * @hide
      */
-    static class ActiveApexInfo {
+    public static class ActiveApexInfo {
         @Nullable public final String apexModuleName;
         public final File apexDirectory;
         public final File preInstalledApexPath;
@@ -130,8 +132,10 @@
 
     /**
      * Returns {@link ActiveApexInfo} records relative to all active APEX packages.
+     *
+     * @hide
      */
-    abstract List<ActiveApexInfo> getActiveApexInfos();
+    public abstract List<ActiveApexInfo> getActiveApexInfos();
 
     abstract void systemReady(Context context);
 
@@ -362,7 +366,7 @@
         }
 
         @Override
-        List<ActiveApexInfo> getActiveApexInfos() {
+        public List<ActiveApexInfo> getActiveApexInfos() {
             synchronized (mLock) {
                 if (mActiveApexInfosCache == null) {
                     try {
@@ -798,7 +802,7 @@
      */
     private static final class ApexManagerFlattenedApex extends ApexManager {
         @Override
-        List<ActiveApexInfo> getActiveApexInfos() {
+        public List<ActiveApexInfo> getActiveApexInfos() {
             // There is no apexd running in case of flattened apex
             // We look up the /apex directory and identify the active APEX modules from there.
             // As "preinstalled" path, we just report /system since in the case of flattened APEX
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 7f73bae..89f24d8 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -613,6 +613,7 @@
             } finally {
                 Trace.endSection();
             }
+
             if (callingPkgSetting != null) {
                 if (callingPkgInstruments(callingPkgSetting, targetPkgSetting, targetName)) {
                     return false;
@@ -626,28 +627,34 @@
                 }
             }
 
-            if (callingSharedPkgSettings != null) {
-                int size = callingSharedPkgSettings.size();
-                for (int index = 0; index < size; index++) {
-                    PackageSetting pkgSetting = callingSharedPkgSettings.valueAt(index);
-                    if (mOverlayReferenceMapper.isValidActor(targetName, pkgSetting.name)) {
+            try {
+                Trace.beginSection("mOverlayReferenceMapper");
+                if (callingSharedPkgSettings != null) {
+                    int size = callingSharedPkgSettings.size();
+                    for (int index = 0; index < size; index++) {
+                        PackageSetting pkgSetting = callingSharedPkgSettings.valueAt(index);
+                        if (mOverlayReferenceMapper.isValidActor(targetName, pkgSetting.name)) {
+                            if (DEBUG_LOGGING) {
+                                log(callingPkgSetting, targetPkgSetting,
+                                        "matches shared user of package that acts on target of "
+                                                + "overlay");
+                            }
+                            return false;
+                        }
+                    }
+                } else {
+                    if (mOverlayReferenceMapper.isValidActor(targetName, callingPkgSetting.name)) {
                         if (DEBUG_LOGGING) {
-                            log(callingPkgSetting, targetPkgSetting,
-                                    "matches shared user of package that acts on target of "
-                                            + "overlay");
+                            log(callingPkgSetting, targetPkgSetting, "acts on target of overlay");
                         }
                         return false;
                     }
                 }
-            } else {
-                if (mOverlayReferenceMapper.isValidActor(targetName, callingPkgSetting.name)) {
-                    if (DEBUG_LOGGING) {
-                        log(callingPkgSetting, targetPkgSetting, "acts on target of overlay");
-                    }
-                    return false;
-                }
+            } finally {
+                Trace.endSection();
             }
 
+
             return true;
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index c712431..ba7583f 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -36,9 +36,9 @@
 import android.os.storage.StorageManager;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.StatsLog;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
 import com.android.server.PinnerService;
 import com.android.server.pm.dex.DexManager;
@@ -444,7 +444,7 @@
         }
 
         if (dex_opt_performed) {
-            StatsLog.write(StatsLog.APP_DOWNGRADED, pkg, package_size_before,
+            FrameworkStatsLog.write(FrameworkStatsLog.APP_DOWNGRADED, pkg, package_size_before,
                     getPackageSize(pm, pkg), /*aggressive=*/ false);
         }
         return dex_opt_performed;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 02ec472..93a0506 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -288,7 +288,6 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
-import android.util.StatsLog;
 import android.util.TimingsTraceLog;
 import android.util.Xml;
 import android.util.apk.ApkSignatureVerifier;
@@ -310,6 +309,7 @@
 import com.android.internal.util.ConcurrentUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.AttributeCache;
@@ -2163,7 +2163,8 @@
                                 getPackageExternalStorageType(volume, isExternal(res.pkg));
                         // If the package was installed externally, log it.
                         if (packageExternalStorageType != StorageEnums.UNKNOWN) {
-                            StatsLog.write(StatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
+                            FrameworkStatsLog.write(
+                                    FrameworkStatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
                                     packageExternalStorageType, res.pkg.getPackageName());
                         }
                     }
@@ -19706,9 +19707,7 @@
         if (packageName == null) {
             return null;
         }
-        if (getPackageInfo(packageName, MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE
-                        | MATCH_DIRECT_BOOT_UNAWARE | MATCH_DISABLED_COMPONENTS,
-                UserHandle.getCallingUserId()) == null) {
+        if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
             return null;
         }
         return packageName;
@@ -22179,13 +22178,15 @@
 
         if (!isPreviousLocationExternal && isExternal(pkg)) {
             // Move from internal to external storage.
-            StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType,
-                    StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
+            FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
+                    packageExternalStorageType,
+                    FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
                     packageName);
         } else if (isPreviousLocationExternal && !isExternal(pkg)) {
             // Move from external to internal storage.
-            StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType,
-                    StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
+            FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
+                    packageExternalStorageType,
+                    FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
                     packageName);
         }
     }
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index cdf8ea3..bbd1ae6 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -198,7 +198,7 @@
                     Slog.w(TAG, "Failed to read staged distro.", e);
                 }
             }
-            return new RulesState(baseVersion.rulesVersion, DISTRO_FORMAT_VERSION_SUPPORTED,
+            return new RulesState(baseVersion.getRulesVersion(), DISTRO_FORMAT_VERSION_SUPPORTED,
                     operationInProgress, stagedOperationStatus, stagedDistroRulesVersion,
                     distroStatus, installedDistroRulesVersion);
         }
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index d746691..61a33b4 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -361,7 +361,7 @@
         private final Region mTempRegion3 = new Region();
         private final Region mTempRegion4 = new Region();
 
-        private final Context mContext;
+        private final Context mDisplayContext;
         private final WindowManagerService mService;
         private final MagnifiedViewport mMagnifedViewport;
         private final Handler mHandler;
@@ -378,14 +378,14 @@
                 DisplayContent displayContent,
                 Display display,
                 MagnificationCallbacks callbacks) {
-            mContext = windowManagerService.mContext;
+            mDisplayContext = windowManagerService.mContext.createDisplayContext(display);
             mService = windowManagerService;
             mCallbacks = callbacks;
             mDisplayContent = displayContent;
             mDisplay = display;
             mHandler = new MyHandler(mService.mH.getLooper());
             mMagnifedViewport = new MagnifiedViewport();
-            mLongAnimationDuration = mContext.getResources().getInteger(
+            mLongAnimationDuration = mDisplayContext.getResources().getInteger(
                     com.android.internal.R.integer.config_longAnimTime);
         }
 
@@ -568,8 +568,6 @@
 
             private final MagnificationSpec mMagnificationSpec = MagnificationSpec.obtain();
 
-            private final WindowManager mWindowManager;
-
             private final float mBorderWidth;
             private final int mHalfBorderWidth;
             private final int mDrawBorderInset;
@@ -580,14 +578,13 @@
             private int mTempLayer = 0;
 
             public MagnifiedViewport() {
-                mWindowManager = (WindowManager) mContext.getSystemService(Service.WINDOW_SERVICE);
-                mBorderWidth = mContext.getResources().getDimension(
+                mBorderWidth = mDisplayContext.getResources().getDimension(
                         com.android.internal.R.dimen.accessibility_magnification_indicator_width);
                 mHalfBorderWidth = (int) Math.ceil(mBorderWidth / 2);
                 mDrawBorderInset = (int) mBorderWidth / 2;
-                mWindow = new ViewportWindow(mContext);
+                mWindow = new ViewportWindow(mDisplayContext);
 
-                if (mContext.getResources().getConfiguration().isScreenRound()) {
+                if (mDisplayContext.getResources().getConfiguration().isScreenRound()) {
                     mCircularPath = new Path();
                     mDisplay.getRealSize(mTempPoint);
                     final int centerXY = mTempPoint.x / 2;
@@ -916,7 +913,7 @@
 
                 public void updateSize(SurfaceControl.Transaction t) {
                     synchronized (mService.mGlobalLock) {
-                        mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
+                        mDisplay.getRealSize(mTempPoint);
                         t.setBufferSize(mSurfaceControl, mTempPoint.x, mTempPoint.y);
                         invalidate(mDirtyRect);
                     }
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index dda11f9..b05c250 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3074,7 +3074,11 @@
         mStackSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this);
         waitingToShow = false;
 
-        boolean delayed = isAnimating(TRANSITION | CHILDREN);
+        // Defer removal of this activity when either a child is animating, or app transition is on
+        // going. App transition animation might be applied on the parent stack not on the activity,
+        // but the actual frame buffer is associated with the activity, so we have to keep the
+        // activity while a parent is animating.
+        boolean delayed = isAnimating(TRANSITION | PARENTS | CHILDREN);
         if (getDisplayContent().mClosingApps.contains(this)) {
             delayed = true;
         } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 362e781..a513ef8 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1711,6 +1711,7 @@
              * invisible as well and added to the stopping list.  After which we process the
              * stopping list by handling the idle.
              */
+            stack.cancelAnimation();
             stack.mForceHidden = true;
             stack.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
             stack.mForceHidden = false;
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 3927d5f..0798a91 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -431,6 +431,8 @@
         while (!candidates.isEmpty()) {
             final WindowContainer current = candidates.removeFirst();
             final WindowContainer parent = current.getParent();
+            siblings.clear();
+            siblings.add(current);
             boolean canPromote = true;
 
             if (parent == null) {
@@ -468,12 +470,11 @@
                 //
                 // [Task] +- [ActivityRecord1] (visible, in opening apps)
                 //        +- [ActivityRecord2] (visible, not in opening apps)
-                siblings.clear();
                 for (int j = 0; j < parent.getChildCount(); ++j) {
                     final WindowContainer sibling = parent.getChildAt(j);
-                    if (sibling == current || candidates.remove(sibling)) {
+                    if (candidates.remove(sibling)) {
                         siblings.add(sibling);
-                    } else if (sibling.isVisible()) {
+                    } else if (sibling != current && sibling.isVisible()) {
                         canPromote = false;
                     }
                 }
diff --git a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
index ef6f847..2f02ffb 100644
--- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java
@@ -275,7 +275,7 @@
             super.onAttachedToWindow();
 
             DisplayMetrics metrics = new DisplayMetrics();
-            getWindowManager().getDefaultDisplay().getMetrics(metrics);
+            mContext.getDisplay().getMetrics(metrics);
             float density = metrics.density;
 
             getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index e47eaee..f4e4245 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -36,7 +36,6 @@
 import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-
 import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
 import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;
 import static com.android.internal.policy.DecorView.getColorViewLeftInset;
@@ -188,8 +187,9 @@
                 return null;
             }
             sysUiVis = topFullscreenOpaqueWindow.getSystemUiVisibility();
-            windowFlags = topFullscreenOpaqueWindow.getAttrs().flags;
-            windowPrivateFlags = topFullscreenOpaqueWindow.getAttrs().privateFlags;
+            WindowManager.LayoutParams attrs = topFullscreenOpaqueWindow.mAttrs;
+            windowFlags = attrs.flags;
+            windowPrivateFlags = attrs.privateFlags;
 
             layoutParams.packageName = mainWindow.getAttrs().packageName;
             layoutParams.windowAnimations = mainWindow.getAttrs().windowAnimations;
@@ -204,6 +204,14 @@
             layoutParams.width = LayoutParams.MATCH_PARENT;
             layoutParams.height = LayoutParams.MATCH_PARENT;
             layoutParams.systemUiVisibility = sysUiVis;
+            layoutParams.insetsFlags.behavior
+                    = topFullscreenOpaqueWindow.mAttrs.insetsFlags.behavior;
+            layoutParams.insetsFlags.appearance
+                    = topFullscreenOpaqueWindow.mAttrs.insetsFlags.appearance;
+            layoutParams.setFitInsetsTypes(attrs.getFitInsetsTypes());
+            layoutParams.setFitInsetsSides(attrs.getFitInsetsSides());
+            layoutParams.setFitInsetsIgnoringVisibility(attrs.isFitInsetsIgnoringVisibility());
+
             layoutParams.setTitle(String.format(TITLE_FORMAT, task.mTaskId));
 
             final TaskDescription td = task.getTaskDescription();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 229bd2f..7f84567 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2536,11 +2536,12 @@
 
     @Override
     public void addWindowToken(IBinder binder, int type, int displayId) {
-        addWindowContextToken(binder, type, displayId, null);
+        addWindowTokenWithOptions(binder, type, displayId, null /* options */,
+                null /* packageName */);
     }
 
-    @Override
-    public int addWindowContextToken(IBinder binder, int type, int displayId, String packageName) {
+    public int addWindowTokenWithOptions(IBinder binder, int type, int displayId, Bundle options,
+            String packageName) {
         final boolean callerCanManageAppTokens =
                 checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()");
         if (!callerCanManageAppTokens) {
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index 78b64ca..67254b8 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -14,6 +14,12 @@
  * limitations under the License.
  */
 
+#include <dlfcn.h>
+#include <pthread.h>
+
+#include <chrono>
+#include <thread>
+
 #include <jni.h>
 #include <nativehelper/JNIHelp.h>
 
@@ -25,12 +31,17 @@
 #include <sensorservicehidl/SensorManager.h>
 
 #include <bionic/malloc.h>
+#include <bionic/reserved_signals.h>
 
+#include <android-base/properties.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
 #include <utils/AndroidThreads.h>
 
+using android::base::GetIntProperty;
+using namespace std::chrono_literals;
+
 namespace android {
 
 static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
@@ -68,7 +79,50 @@
 
 static void android_server_SystemServer_initZygoteChildHeapProfiling(JNIEnv* /* env */,
                                                                      jobject /* clazz */) {
-   android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0);
+    android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0);
+}
+
+static int get_current_max_fd() {
+    // Not actually guaranteed to be the max, but close enough for our purposes.
+    int fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
+    LOG_ALWAYS_FATAL_IF(fd == -1, "failed to open /dev/null: %s", strerror(errno));
+    close(fd);
+    return fd;
+}
+
+static const char kFdLeakEnableThresholdProperty[] = "persist.sys.debug.fdtrack_enable_threshold";
+static const char kFdLeakAbortThresholdProperty[] = "persist.sys.debug.fdtrack_abort_threshold";
+static const char kFdLeakCheckIntervalProperty[] = "persist.sys.debug.fdtrack_interval";
+
+static void android_server_SystemServer_spawnFdLeakCheckThread(JNIEnv*, jobject) {
+    std::thread([]() {
+        pthread_setname_np(pthread_self(), "FdLeakCheckThread");
+        bool loaded = false;
+        while (true) {
+            const int enable_threshold = GetIntProperty(kFdLeakEnableThresholdProperty, 1024);
+            const int abort_threshold = GetIntProperty(kFdLeakAbortThresholdProperty, 2048);
+            const int check_interval = GetIntProperty(kFdLeakCheckIntervalProperty, 120);
+            int max_fd = get_current_max_fd();
+            if (max_fd > enable_threshold && !loaded) {
+                loaded = true;
+                ALOGE("fd count above threshold of %d, starting fd backtraces", enable_threshold);
+                if (dlopen("libfdtrack.so", RTLD_GLOBAL) == nullptr) {
+                    ALOGE("failed to load libfdtrack.so: %s", dlerror());
+                }
+            } else if (max_fd > abort_threshold) {
+                raise(BIONIC_SIGNAL_FDTRACK);
+
+                // Wait for a bit to allow fdtrack to dump backtraces to logcat.
+                std::this_thread::sleep_for(5s);
+
+                LOG_ALWAYS_FATAL(
+                    "b/140703823: aborting due to fd leak: check logs for fd "
+                    "backtraces");
+            }
+
+            std::this_thread::sleep_for(std::chrono::seconds(check_interval));
+        }
+    }).detach();
 }
 
 /*
@@ -80,6 +134,9 @@
     { "startHidlServices", "()V", (void*) android_server_SystemServer_startHidlServices },
     { "initZygoteChildHeapProfiling", "()V",
       (void*) android_server_SystemServer_initZygoteChildHeapProfiling },
+    { "spawnFdLeakCheckThread", "()V",
+      (void*) android_server_SystemServer_spawnFdLeakCheckThread },
+
 };
 
 int register_android_server_SystemServer(JNIEnv* env)
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4f5c1ab..2a6b029 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -72,7 +72,6 @@
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.StatsLog;
-import android.view.WindowManager;
 import android.view.contentcapture.ContentCaptureManager;
 
 import com.android.internal.R;
@@ -366,6 +365,12 @@
      */
     private static native void initZygoteChildHeapProfiling();
 
+
+    /**
+     * Spawn a thread that monitors for fd leaks.
+     */
+    private static native void spawnFdLeakCheckThread();
+
     /**
      * The main entry point from zygote.
      */
@@ -500,6 +505,11 @@
                 initZygoteChildHeapProfiling();
             }
 
+            // Debug builds - spawn a thread to monitor for fd leaks.
+            if (Build.IS_DEBUGGABLE) {
+                spawnFdLeakCheckThread();
+            }
+
             // Check whether we failed to shut down last time we tried.
             // This call may not return.
             performPendingShutdown();
@@ -2083,8 +2093,7 @@
         // propagate to it.
         final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
         DisplayMetrics metrics = new DisplayMetrics();
-        WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        w.getDefaultDisplay().getMetrics(metrics);
+        context.getDisplay().getMetrics(metrics);
         context.getResources().updateConfiguration(config, metrics);
 
         // The system context's theme may be configuration-dependent.
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index b7c9001..d2ddff3 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -66,8 +66,6 @@
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.SUSPEND_APPS"/>
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
-    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
-    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
     <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
     <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index bec265e..156cd6e 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -421,6 +421,7 @@
     public void testAuthenticate_noBiometrics_credentialAllowed() throws Exception {
         setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
         when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
+        when(mTrustManager.isDeviceSecure(anyInt())).thenReturn(true);
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
                 true /* requireConfirmation */,
                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
@@ -467,6 +468,22 @@
     }
 
     @Test
+    public void testAuthenticate_no_Biometrics_noCredential() throws Exception {
+        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
+        when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
+        when(mTrustManager.isDeviceSecure(anyInt())).thenReturn(false);
+
+        invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
+                true /* requireConfirmation */,
+                Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_STRONG);
+        waitForIdle();
+
+        verify(mReceiver1).onError(anyInt() /* modality */,
+                eq(BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS)/* error */,
+                eq(0) /* vendorCode */);
+    }
+
+    @Test
     public void testRejectFace_whenAuthenticating_notifiesSystemUIAndClient_thenPaused()
             throws Exception {
         setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
@@ -1216,7 +1233,8 @@
         when(mDevicePolicyManager
                 .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
                 .thenReturn(~DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
-        invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1);
+        invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
+                Authenticators.BIOMETRIC_STRONG);
         waitForIdle();
         assertEquals(mBiometricService.mPendingAuthSession.mState,
                 BiometricService.STATE_AUTH_CALLED);
@@ -1233,7 +1251,8 @@
         when(mDevicePolicyManager
                 .getKeyguardDisabledFeatures(any() /* admin*/, anyInt() /* userHandle */))
                 .thenReturn(~DevicePolicyManager.KEYGUARD_DISABLE_FACE);
-        invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1);
+        invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
+                Authenticators.BIOMETRIC_STRONG);
         waitForIdle();
         assertEquals(mBiometricService.mPendingAuthSession.mState,
                 BiometricService.STATE_AUTH_CALLED);
@@ -1247,27 +1266,24 @@
     public void testWorkAuthentication_fingerprintFailsIfDisabledByDevicePolicyManager()
             throws Exception {
         setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        when(mTrustManager.isDeviceSecure(anyInt())).thenReturn(true);
         when(mDevicePolicyManager
                 .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
-        invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1);
-        waitForIdle();
-        assertNotNull(mBiometricService.mCurrentAuthSession);
-        assertEquals(mBiometricService.mCurrentAuthSession.mState,
-                BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL);
-    }
 
-    @Test
-    public void testWorkAuthentication_faceFailsIfDisabledByDevicePolicyManager() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
-        when(mDevicePolicyManager
-                .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
-                .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FACE);
-        invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1);
+        invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
+                Authenticators.BIOMETRIC_STRONG);
+        waitForIdle();
+        verify(mReceiver1).onError(eq(BiometricAuthenticator.TYPE_NONE),
+                eq(BiometricPrompt.BIOMETRIC_ERROR_HW_UNAVAILABLE), eq(0) /* vendorCode */);
+
+        invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver2,
+                Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL);
         waitForIdle();
         assertNotNull(mBiometricService.mCurrentAuthSession);
         assertEquals(mBiometricService.mCurrentAuthSession.mState,
                 BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL);
+        verify(mReceiver2, never()).onError(anyInt(), anyInt(), anyInt());
     }
 
     // Helper methods
@@ -1376,33 +1392,35 @@
                 0 /* userId */,
                 receiver,
                 TEST_PACKAGE_NAME /* packageName */,
-                createTestBiometricPromptBundle(requireConfirmation, authenticators));
+                createTestBiometricPromptBundle(requireConfirmation, authenticators,
+                        false /* checkDevicePolicy */));
     }
 
     private static void invokeAuthenticateForWorkApp(IBiometricService.Stub service,
-            IBiometricServiceReceiver receiver) throws Exception {
-        final Bundle bundle = new Bundle();
-        bundle.putBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, true);
-        bundle.putBoolean(BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true);
-        bundle.putBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL, true);
+            IBiometricServiceReceiver receiver, Integer authenticators) throws Exception {
         service.authenticate(
                 new Binder() /* token */,
                 0 /* sessionId */,
                 0 /* userId */,
                 receiver,
                 TEST_PACKAGE_NAME /* packageName */,
-                bundle);
+                createTestBiometricPromptBundle(false /* requireConfirmation */, authenticators,
+                        true /* checkDevicePolicy */));
     }
 
     private static Bundle createTestBiometricPromptBundle(
             boolean requireConfirmation,
-            Integer authenticators) {
+            Integer authenticators,
+            boolean checkDevicePolicy) {
         final Bundle bundle = new Bundle();
         bundle.putBoolean(BiometricPrompt.KEY_REQUIRE_CONFIRMATION, requireConfirmation);
 
         if (authenticators != null) {
             bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
         }
+        if (checkDevicePolicy) {
+            bundle.putBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, true);
+        }
         return bundle;
     }
 
diff --git a/telephony/java/android/service/carrier/CarrierIdentifier.java b/telephony/java/android/service/carrier/CarrierIdentifier.java
index 7957c25..bc0f909 100644
--- a/telephony/java/android/service/carrier/CarrierIdentifier.java
+++ b/telephony/java/android/service/carrier/CarrierIdentifier.java
@@ -20,10 +20,10 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
-import com.android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.telephony.Rlog;
 
 import java.util.Objects;
 
diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java
index 097041f..ffdb23f 100644
--- a/telephony/java/android/telephony/AnomalyReporter.java
+++ b/telephony/java/android/telephony/AnomalyReporter.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.content.Context;
@@ -27,6 +25,7 @@
 import android.os.ParcelUuid;
 
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/telephony/java/android/telephony/BarringInfo.java b/telephony/java/android/telephony/BarringInfo.java
index 5419c3c..9baa66f 100644
--- a/telephony/java/android/telephony/BarringInfo.java
+++ b/telephony/java/android/telephony/BarringInfo.java
@@ -238,6 +238,12 @@
         }
     }
 
+    private static final BarringServiceInfo BARRING_SERVICE_INFO_UNKNOWN =
+            new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_UNKNOWN);
+
+    private static final BarringServiceInfo BARRING_SERVICE_INFO_UNBARRED =
+            new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_NONE);
+
     private CellIdentity mCellIdentity;
 
     // A SparseArray potentially mapping each BarringService type to a BarringServiceInfo config
@@ -298,17 +304,6 @@
     }
 
     /**
-     * Return whether a service is currently barred based on the BarringInfo
-     *
-     * @param service the service to be checked.
-     * @return true if the service is currently being barred, otherwise false
-     */
-    public boolean isServiceBarred(@BarringServiceType int service) {
-        BarringServiceInfo bsi = mBarringServiceInfos.get(service);
-        return bsi != null && (bsi.isBarred());
-    }
-
-    /**
      * Get the BarringServiceInfo for a specified service.
      *
      * @return a BarringServiceInfo struct describing the current barring status for a service
@@ -319,9 +314,8 @@
         // type as UNKNOWN; if the modem reports barring info but doesn't report for a particular
         // service then we can safely assume that the service isn't barred (for instance because
         // that particular service isn't applicable to the current RAN).
-        return (bsi != null) ? bsi : new BarringServiceInfo(
-                mBarringServiceInfos.size() > 0 ? BarringServiceInfo.BARRING_TYPE_NONE :
-                        BarringServiceInfo.BARRING_TYPE_UNKNOWN);
+        return (bsi != null) ? bsi : mBarringServiceInfos.size() > 0
+                ? BARRING_SERVICE_INFO_UNBARRED : BARRING_SERVICE_INFO_UNKNOWN;
     }
 
     /** @hide */
diff --git a/telephony/java/android/telephony/CbGeoUtils.java b/telephony/java/android/telephony/CbGeoUtils.java
index 719ba8d..c0ae99e 100644
--- a/telephony/java/android/telephony/CbGeoUtils.java
+++ b/telephony/java/android/telephony/CbGeoUtils.java
@@ -16,13 +16,12 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.util.TelephonyUtils;
+import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index acb21f4..0edb4a4 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 /**
  * A {@link CellInfo} representing a CDMA cell that provides identity and measurement info.
  */
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index 79a9d44..2dddd3f 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -16,13 +16,13 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 /**
  * A {@link CellInfo} representing a GSM cell that provides identity and measurement info.
  */
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index fed3ebf..a57c7cd 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 import java.util.Objects;
 
 /**
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
index 58ff8c9..d2cc9c6c 100644
--- a/telephony/java/android/telephony/CellInfoTdscdma.java
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -16,12 +16,12 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 import java.util.Objects;
 
 /**
diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java
index 33f6a55..3f792d1 100644
--- a/telephony/java/android/telephony/CellInfoWcdma.java
+++ b/telephony/java/android/telephony/CellInfoWcdma.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.telephony.Rlog;
 
 import java.util.Objects;
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index cab3b0c..1c92705b 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -20,6 +20,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
+
 import com.android.telephony.Rlog;
 
 import java.util.Objects;
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index 28052aa..76d2df9 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntRange;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -25,6 +23,8 @@
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.telephony.Rlog;
+
 import java.util.Objects;
 
 /**
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 2ef2a52..6d6eaa4 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntRange;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.telephony.Rlog;
+
 import java.util.Arrays;
 import java.util.Objects;
 
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index f4c13ff..e3d03a3 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
diff --git a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
index 3bd9d58..e96f200 100644
--- a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.telephony.Rlog;
+
 import java.util.Objects;
 
 /**
diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
index 535e952..8b14b74 100644
--- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntRange;
 import android.annotation.StringDef;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -26,6 +24,8 @@
 import android.os.PersistableBundle;
 import android.text.TextUtils;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
diff --git a/telephony/java/android/telephony/NetworkScan.java b/telephony/java/android/telephony/NetworkScan.java
index a6dedf7..adf31ed 100644
--- a/telephony/java/android/telephony/NetworkScan.java
+++ b/telephony/java/android/telephony/NetworkScan.java
@@ -16,12 +16,11 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntDef;
 import android.os.RemoteException;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index 844289c..87d94bfd 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -34,6 +32,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/telephony/java/android/telephony/NetworkServiceCallback.java b/telephony/java/android/telephony/NetworkServiceCallback.java
index 214ab41..e8e73ee 100644
--- a/telephony/java/android/telephony/NetworkServiceCallback.java
+++ b/telephony/java/android/telephony/NetworkServiceCallback.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.RemoteException;
 import android.telephony.NetworkService.NetworkServiceProvider;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 0074772..ec99408 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -45,6 +43,7 @@
 import com.android.i18n.phonenumbers.PhoneNumberUtil;
 import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
 import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index 094b8b0..54c22ae 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -135,11 +135,12 @@
     }
 
     /**
-     * To check the SDK version for {@code PreciseDataConnectionState#getDataConnectionState}.
+     * Used for checking if the SDK version for
+     * {@code PreciseDataConnectionState#getDataConnectionState} is above Q.
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
-    private static final long GET_DATA_CONNECTION_STATE_CODE_CHANGE = 147600208L;
+    private static final long GET_DATA_CONNECTION_STATE_R_VERSION = 148535736L;
 
     /**
      * Returns the state of data connection that supported the apn types returned by
@@ -152,7 +153,7 @@
     @SystemApi
     public @DataState int getDataConnectionState() {
         if (mState == TelephonyManager.DATA_DISCONNECTING
-                && !Compatibility.isChangeEnabled(GET_DATA_CONNECTION_STATE_CODE_CHANGE)) {
+                && !Compatibility.isChangeEnabled(GET_DATA_CONNECTION_STATE_R_VERSION)) {
             return TelephonyManager.DATA_CONNECTED;
         }
 
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 5b09cd9..a5a1ebc 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1925,6 +1925,8 @@
 
     /**
      * Get the network registration state for the transport type and network domain.
+     * If multiple domains are in the input bitmask, only the first one from
+     * networkRegistrationInfo.getDomain() will be returned.
      *
      * @param domain The network {@link NetworkRegistrationInfo.Domain domain}
      * @param transportType The transport type
@@ -2072,11 +2074,18 @@
     public boolean isIwlanPreferred() {
         return mIsIwlanPreferred;
     }
-     /**
-     * @return {@code true}Returns True whenever the modem is searching for service.
-     * To check both CS and PS domain
-     */
 
+    /**
+     * This indicates whether the device is searching for service.
+     *
+     * This API reports the modem searching status for
+     * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} (cellular) service in either
+     * {@link NetworkRegistrationInfo#DOMAIN_CS} or {@link NetworkRegistrationInfo#DOMAIN_PS}.
+     * This API will not report searching status for
+     * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}.
+     *
+     * @return {@code true} whenever the modem is searching for service.
+     */
     public boolean isSearching() {
         NetworkRegistrationInfo psRegState = getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 7a30f14..6d82e51 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
 
 import android.Manifest;
@@ -40,13 +38,13 @@
 import com.android.internal.telephony.SmsMessageBase;
 import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
 import com.android.internal.telephony.cdma.sms.UserData;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 
-
 /**
  * A Short Message Service message.
  * @see android.provider.Telephony.Sms.Intents#getMessagesFromIntent
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index c24eeb7..832771d 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -40,6 +38,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.util.TelephonyUtils;
+import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 26dc5f0..6723522 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5562,11 +5562,11 @@
     public static final int DATA_DISCONNECTING = 4;
 
     /**
-     * To check the SDK version for {@link TelephonyManager#getDataState}.
+     * Used for checking if the SDK version for {@link TelephonyManager#getDataState} is above Q.
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
-    private static final long GET_DATA_STATE_CODE_CHANGE = 147600208L;
+    private static final long GET_DATA_STATE_R_VERSION = 148534348L;
 
     /**
      * Returns a constant indicating the current data connection state
@@ -5586,7 +5586,7 @@
             int state = telephony.getDataStateForSubId(
                     getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
             if (state == TelephonyManager.DATA_DISCONNECTING
-                    && !Compatibility.isChangeEnabled(GET_DATA_STATE_CODE_CHANGE)) {
+                    && !Compatibility.isChangeEnabled(GET_DATA_STATE_R_VERSION)) {
                 return TelephonyManager.DATA_CONNECTED;
             }
 
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index a1d40e8..cdff651 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.Nullable;
@@ -33,6 +31,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.telephony.Rlog;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
index 81a09c6..3e948fc 100644
--- a/telephony/java/android/telephony/UiccAccessRule.java
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -15,8 +15,6 @@
  */
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -28,6 +26,7 @@
 import android.text.TextUtils;
 
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.telephony.Rlog;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
diff --git a/telephony/java/android/telephony/VoLteServiceState.java b/telephony/java/android/telephony/VoLteServiceState.java
index d4a27d9..27187e6 100644
--- a/telephony/java/android/telephony/VoLteServiceState.java
+++ b/telephony/java/android/telephony/VoLteServiceState.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 /**
  * Contains LTE network state related information.
  * @deprecated Only contains SRVCC state, which isn't specific to LTE handovers. For SRVCC
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index bff12b6..6c4e7ce 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -31,10 +31,10 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.AccessNetworkConstants;
-import com.android.telephony.Rlog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index d33d3f9..72b68e4 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -22,9 +22,10 @@
 import android.annotation.SystemApi;
 import android.net.LinkProperties;
 import android.os.RemoteException;
-import com.android.telephony.Rlog;
 import android.telephony.data.DataService.DataServiceProvider;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
index 8220b16..05971c4 100644
--- a/telephony/java/android/telephony/data/QualifiedNetworksService.java
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -28,10 +28,10 @@
 import android.os.RemoteException;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.Annotation.ApnType;
-import com.android.telephony.Rlog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.telephony.Rlog;
 
 import java.util.List;
 
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index cd3fc95..d9d5c14 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -25,6 +25,7 @@
 import android.os.Parcelable;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
+
 import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java
index abfee61..21bef00 100644
--- a/telephony/java/android/telephony/ims/ImsConferenceState.java
+++ b/telephony/java/android/telephony/ims/ImsConferenceState.java
@@ -24,8 +24,8 @@
 import android.os.Parcelable;
 import android.telecom.Call;
 import android.telecom.Connection;
+
 import com.android.telephony.Rlog;
-import android.util.Log;
 
 import java.util.HashMap;
 import java.util.Iterator;
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index 136a83e..7d73165 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -24,6 +24,7 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java
index 2d2e638..70bf0c5 100644
--- a/telephony/java/android/telephony/ims/ImsSsData.java
+++ b/telephony/java/android/telephony/ims/ImsSsData.java
@@ -22,6 +22,7 @@
 import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java
index 0f6ce13..96f77d8 100644
--- a/telephony/java/com/android/ims/ImsConfig.java
+++ b/telephony/java/com/android/ims/ImsConfig.java
@@ -19,13 +19,13 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
-import com.android.telephony.Rlog;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsConfigCallback;
 
 import com.android.internal.telephony.util.HandlerExecutor;
+import com.android.telephony.Rlog;
 
 import java.util.concurrent.Executor;
 
diff --git a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
index 8e86ff7..3bd8cdd 100644
--- a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
+++ b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
@@ -19,12 +19,12 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
-import com.android.telephony.Rlog;
 import android.util.SparseIntArray;
 
 import com.android.internal.telephony.cdma.sms.UserData;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.internal.telephony.util.XmlUtils;
+import com.android.telephony.Rlog;
 
 public class Sms7BitEncodingTranslator {
     private static final String TAG = "Sms7BitEncodingTranslator";
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index d0c8024..6ed0be2 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -20,7 +20,6 @@
 import android.content.res.Resources;
 import android.sysprop.TelephonyProperties;
 import android.telephony.PhoneNumberUtils;
-import com.android.telephony.Rlog;
 import android.telephony.SmsCbLocation;
 import android.telephony.SmsCbMessage;
 import android.telephony.cdma.CdmaSmsCbProgramData;
@@ -41,6 +40,7 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.util.BitwiseInputStream;
 import com.android.internal.util.HexDump;
+import com.android.telephony.Rlog;
 
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
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 6ad6dd1..6dc1e0e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -18,7 +18,6 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
-import com.android.telephony.Rlog;
 import android.telephony.SmsCbCmasInfo;
 import android.telephony.cdma.CdmaSmsCbProgramData;
 import android.telephony.cdma.CdmaSmsCbProgramResults;
@@ -31,6 +30,7 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.util.BitwiseInputStream;
 import com.android.internal.util.BitwiseOutputStream;
+import com.android.telephony.Rlog;
 
 import java.io.ByteArrayOutputStream;
 import java.time.Instant;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index c91ea69..08580012 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -28,7 +28,6 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.telephony.PhoneNumberUtils;
-import com.android.telephony.Rlog;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.EncodeException;
@@ -38,6 +37,7 @@
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.SmsMessageBase;
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.telephony.Rlog;
 
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
index 0dc7401..1d13692 100644
--- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
@@ -21,10 +21,10 @@
 import android.content.res.Resources.NotFoundException;
 import android.graphics.Bitmap;
 import android.graphics.Color;
-import com.android.telephony.Rlog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.GsmAlphabet;
+import com.android.telephony.Rlog;
 
 import java.io.UnsupportedEncodingException;
 import java.util.List;
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index 36074ed..359c448 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -812,7 +812,7 @@
     }
 
     @Override
-    public @NonNull Context createWindowContext(int type) {
+    public @NonNull Context createWindowContext(int type, Bundle options) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/test-runner/src/android/test/TouchUtils.java b/test-runner/src/android/test/TouchUtils.java
index 28dc7b2..bb4e00b 100644
--- a/test-runner/src/android/test/TouchUtils.java
+++ b/test-runner/src/android/test/TouchUtils.java
@@ -222,7 +222,8 @@
      */
     public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v,
             int stepCount) {
-        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
+        int screenHeight =
+                activity.getWindowManager().getCurrentWindowMetrics().getSize().getHeight();
 
         int[] xy = new int[2];
         v.getLocationOnScreen(xy);
diff --git a/tests/GamePerformance/src/android/gameperformance/BaseTest.java b/tests/GamePerformance/src/android/gameperformance/BaseTest.java
index b0640b44..e705756 100644
--- a/tests/GamePerformance/src/android/gameperformance/BaseTest.java
+++ b/tests/GamePerformance/src/android/gameperformance/BaseTest.java
@@ -21,7 +21,6 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.util.Log;
-import android.view.WindowManager;
 
 /**
  * Base class for a test that performs bisection to determine maximum
@@ -55,9 +54,7 @@
 
     public BaseTest(@NonNull GamePerformanceActivity activity) {
         mActivity = activity;
-        final WindowManager windowManager =
-                (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
-        mRefreshRate = windowManager.getDefaultDisplay().getRefreshRate();
+        mRefreshRate = activity.getDisplay().getRefreshRate();
     }
 
     @NonNull
diff --git a/tests/GamePerformance/src/android/gameperformance/CustomControlView.java b/tests/GamePerformance/src/android/gameperformance/CustomControlView.java
index 219085a..e63736b 100644
--- a/tests/GamePerformance/src/android/gameperformance/CustomControlView.java
+++ b/tests/GamePerformance/src/android/gameperformance/CustomControlView.java
@@ -25,18 +25,16 @@
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.Canvas;
+import android.graphics.Point;
 import android.graphics.drawable.AnimationDrawable;
-import android.util.Log;
-import android.view.WindowManager;
 import android.widget.AbsoluteLayout;
 import android.widget.ImageView;
-import android.widget.RelativeLayout;
 
 /**
  * View that holds requested number of UI controls as ImageView with an infinite animation.
  */
 public class CustomControlView extends AbsoluteLayout {
-    private final static int CONTROL_DIMENTION = 48;
+    private final static int CONTROL_DIMENSION = 48;
 
     private final int mPerRowControlCount;
     private List<Long> mFrameTimes = new ArrayList<>();
@@ -44,8 +42,9 @@
     public CustomControlView(@NonNull Context context) {
         super(context);
 
-        final WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-        mPerRowControlCount = windowManager.getDefaultDisplay().getWidth() / CONTROL_DIMENTION;
+        final Point size = new Point();
+        context.getDisplay().getSize(size);
+        mPerRowControlCount = size.x / CONTROL_DIMENSION;
     }
 
     /**
@@ -76,11 +75,11 @@
                     for (int i = 0; i < controlCount; ++i) {
                         final ImageView image = (i == 0) ?
                                 new ReferenceImageView(activity) : new ImageView(activity);
-                        final int x = (i % mPerRowControlCount) * CONTROL_DIMENTION;
-                        final int y = (i / mPerRowControlCount) * CONTROL_DIMENTION;
+                        final int x = (i % mPerRowControlCount) * CONTROL_DIMENSION;
+                        final int y = (i / mPerRowControlCount) * CONTROL_DIMENSION;
                         final AbsoluteLayout.LayoutParams layoutParams =
                                 new AbsoluteLayout.LayoutParams(
-                                        CONTROL_DIMENTION, CONTROL_DIMENTION, x, y);
+                                        CONTROL_DIMENSION, CONTROL_DIMENSION, x, y);
                         image.setLayoutParams(layoutParams);
                         image.setBackgroundResource(R.drawable.animation);
                         final AnimationDrawable animation =
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
index 0f4c668..6d8c43c 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java
@@ -122,7 +122,7 @@
             if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) break;
         }
         
-        int rotation = getWindowManager().getDefaultDisplay().getRotation();
+        int rotation = getDisplay().getRotation();
         int degrees = 0;
 
         switch (rotation) {
diff --git a/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java b/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java
index b863713..e255ce2 100644
--- a/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java
+++ b/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java
@@ -16,6 +16,7 @@
 
 package com.google.android.test.mirrorsurface;
 
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
 import android.app.Activity;
 import android.graphics.Canvas;
@@ -26,7 +27,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.util.DisplayMetrics;
+import android.util.Size;
 import android.view.Gravity;
 import android.view.IWindowManager;
 import android.view.MotionEvent;
@@ -48,6 +49,8 @@
     private static final int MOVE_FRAME_AMOUNT = 20;
 
     private IWindowManager mIWm;
+    // An instance of WindowManager that is adjusted for adding windows with type
+    // TYPE_APPLICATION_OVERLAY.
     private WindowManager mWm;
 
     private SurfaceControl mSurfaceControl = new SurfaceControl();
@@ -57,7 +60,7 @@
     private View mOverlayView;
     private View mArrowOverlay;
 
-    private Rect mDisplayBounds = new Rect();
+    private Rect mWindowBounds = new Rect();
 
     private EditText mScaleText;
     private EditText mDisplayFrameText;
@@ -83,21 +86,21 @@
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.activity_mirror_surface);
-        mWm = (WindowManager) getSystemService(WINDOW_SERVICE);
+        mWm = createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */)
+                .getSystemService(WindowManager.class);
         mIWm = WindowManagerGlobal.getWindowManagerService();
 
-        DisplayMetrics displayMetrics = new DisplayMetrics();
-        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
-        mDisplayBounds.set(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
+        Size windowSize = mWm.getCurrentWindowMetrics().getSize();
+        mWindowBounds.set(0, 0, windowSize.getWidth(), windowSize.getHeight());
 
         mScaleText = findViewById(R.id.scale);
         mDisplayFrameText = findViewById(R.id.displayFrame);
         mSourcePositionText = findViewById(R.id.sourcePosition);
 
-        mCurrFrame.set(0, 0, mDisplayBounds.width() / 2, mDisplayBounds.height() / 2);
+        mCurrFrame.set(0, 0, mWindowBounds.width() / 2, mWindowBounds.height() / 2);
         mCurrScale = DEFAULT_SCALE;
 
-        mDisplayId = getWindowManager().getDefaultDisplay().getDisplayId();
+        mDisplayId = getDisplay().getDisplayId();
         updateEditTexts();
 
         findViewById(R.id.mirror_button).setOnClickListener(view -> {
@@ -194,8 +197,8 @@
 
     private void createMirrorOverlay() {
         mOverlayView = new LinearLayout(this);
-        WindowManager.LayoutParams params = new WindowManager.LayoutParams(mDisplayBounds.width(),
-                mDisplayBounds.height(),
+        WindowManager.LayoutParams params = new WindowManager.LayoutParams(mWindowBounds.width(),
+                mWindowBounds.height(),
                 WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                         | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
@@ -290,7 +293,7 @@
 
     private void updateMirror(Rect displayFrame, float scale) {
         if (displayFrame.isEmpty()) {
-            Rect bounds = mDisplayBounds;
+            Rect bounds = mWindowBounds;
             int defaultCropW = Math.round(bounds.width() / 2);
             int defaultCropH = Math.round(bounds.height() / 2);
             displayFrame.set(0, 0, defaultCropW, defaultCropH);
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
index 609896e..5e9ef8e 100644
--- a/tests/PlatformCompatGating/Android.bp
+++ b/tests/PlatformCompatGating/Android.bp
@@ -18,6 +18,7 @@
     name: "PlatformCompatGating",
     // Only compile source java files in this apk.
     srcs: ["src/**/*.java"],
+    certificate: "platform",
     libs: [
         "android.test.runner",
         "android.test.base",
diff --git a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
index c00aa2a..932ec64 100644
--- a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
+++ b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
@@ -16,9 +16,7 @@
 
 package android.compat.testing;
 
-import android.Manifest;
 import android.app.Instrumentation;
-import android.app.UiAutomation;
 import android.compat.Compatibility;
 import android.compat.Compatibility.ChangeConfig;
 import android.content.Context;
@@ -85,16 +83,12 @@
         @Override
         public void evaluate() throws Throwable {
             Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-            UiAutomation uiAutomation = instrumentation.getUiAutomation();
             String packageName = instrumentation.getTargetContext().getPackageName();
             IPlatformCompat platformCompat = IPlatformCompat.Stub
                     .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
             if (platformCompat == null) {
                 throw new IllegalStateException("Could not get IPlatformCompat service!");
             }
-            uiAutomation.adoptShellPermissionIdentity(
-                    Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
-                    Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG);
             Compatibility.setOverrides(mConfig);
             try {
                 platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
@@ -107,7 +101,6 @@
             } catch (RemoteException e) {
                 throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
             } finally {
-                uiAutomation.dropShellPermissionIdentity();
                 Compatibility.clearOverrides();
             }
         }
diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionMeasuringActivity.java b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionMeasuringActivity.java
index 4771b6c..e0a9668 100644
--- a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionMeasuringActivity.java
+++ b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionMeasuringActivity.java
@@ -23,7 +23,6 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.MemoryInfo;
-import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
@@ -531,8 +530,7 @@
     }
 
     private void detectRefreshRate() {
-        WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
-        mRefreshRate = wm.getDefaultDisplay().getRefreshRate();
+        mRefreshRate = getDisplay().getRefreshRate();
         if (mRefreshRate < MIN_REFRESH_RATE_SUPPORTED)
             throw new RuntimeException("Unsupported display refresh rate: " + mRefreshRate);
         mTargetFPS = mRefreshRate - 2.0f;
diff --git a/tests/net/TEST_MAPPING b/tests/net/TEST_MAPPING
index a7853b6..005cbe9 100644
--- a/tests/net/TEST_MAPPING
+++ b/tests/net/TEST_MAPPING
@@ -1,7 +1,12 @@
 {
-  "postsubmit": [
+  "presubmit": [
     {
       "name": "FrameworksNetIntegrationTests"
     }
+  ],
+  "postsubmit": [
+    {
+      "name": "FrameworksNetDeflakeTest"
+    }
   ]
 }
\ No newline at end of file
diff --git a/tests/net/common/java/android/net/NetworkScoreTest.kt b/tests/net/common/java/android/net/NetworkScoreTest.kt
index 30836b7..a63d58d 100644
--- a/tests/net/common/java/android/net/NetworkScoreTest.kt
+++ b/tests/net/common/java/android/net/NetworkScoreTest.kt
@@ -16,7 +16,7 @@
 
 package android.net
 
-import android.os.Parcelable
+import android.net.NetworkScore.Metrics.BANDWIDTH_UNKNOWN
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
 import com.android.testutils.assertParcelSane
@@ -28,77 +28,49 @@
 import org.junit.runner.RunWith
 
 private const val TEST_SCORE = 80
-private const val KEY_DEFAULT_CAPABILITIES = "DEFAULT_CAPABILITIES"
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class NetworkScoreTest {
     @Test
     fun testParcelNetworkScore() {
-        val networkScore = NetworkScore()
         val defaultCap = NetworkCapabilities()
-        networkScore.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
-        assertEquals(defaultCap, networkScore.getExtension(KEY_DEFAULT_CAPABILITIES))
-        networkScore.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
-        assertEquals(TEST_SCORE, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
-        assertParcelSane(networkScore, 1)
-    }
+        val builder = NetworkScore.Builder().setLegacyScore(TEST_SCORE)
+        assertEquals(TEST_SCORE, builder.build().getLegacyScore())
+        assertParcelSane(builder.build(), 7)
 
-    @Test
-    fun testNullKeyAndValue() {
-        val networkScore = NetworkScore()
-        val defaultCap = NetworkCapabilities()
-        networkScore.putIntExtension(null, TEST_SCORE)
-        assertEquals(TEST_SCORE, networkScore.getIntExtension(null))
-        networkScore.putExtension(null, defaultCap)
-        assertEquals(defaultCap, networkScore.getExtension(null))
-        networkScore.putExtension(null, null)
-        val result: Parcelable? = networkScore.getExtension(null)
-        assertEquals(null, result)
-    }
+        builder.addPolicy(NetworkScore.POLICY_IGNORE_ON_WIFI)
+                .addPolicy(NetworkScore.POLICY_DEFAULT_SUBSCRIPTION)
+                .setLinkLayerMetrics(NetworkScore.Metrics(44 /* latency */,
+                        380 /* downlinkBandwidth */, BANDWIDTH_UNKNOWN /* uplinkBandwidth */))
+                .setEndToEndMetrics(NetworkScore.Metrics(11 /* latency */,
+                        BANDWIDTH_UNKNOWN /* downlinkBandwidth */, 100_000 /* uplinkBandwidth */))
+                .setRange(NetworkScore.RANGE_MEDIUM)
+        assertParcelSane(builder.build(), 7)
+        builder.clearPolicy(NetworkScore.POLICY_IGNORE_ON_WIFI)
+        val ns = builder.build()
+        assertParcelSane(ns, 7)
+        assertFalse(ns.hasPolicy(NetworkScore.POLICY_IGNORE_ON_WIFI))
+        assertTrue(ns.hasPolicy(NetworkScore.POLICY_DEFAULT_SUBSCRIPTION))
 
-    @Test
-    fun testRemoveExtension() {
-        val networkScore = NetworkScore()
-        val defaultCap = NetworkCapabilities()
-        networkScore.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
-        networkScore.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
-        assertEquals(defaultCap, networkScore.getExtension(KEY_DEFAULT_CAPABILITIES))
-        assertEquals(TEST_SCORE, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
-        networkScore.removeExtension(KEY_DEFAULT_CAPABILITIES)
-        networkScore.removeExtension(NetworkScore.LEGACY_SCORE)
-        val result: Parcelable? = networkScore.getExtension(KEY_DEFAULT_CAPABILITIES)
-        assertEquals(null, result)
-        assertEquals(0, networkScore.getIntExtension(NetworkScore.LEGACY_SCORE))
+        val exitingNs = ns.withExiting(true)
+        assertNotEquals(ns.isExiting, exitingNs.isExiting)
+        assertNotEquals(ns, exitingNs)
+        assertParcelSane(exitingNs, 7)
     }
 
     @Test
     fun testEqualsNetworkScore() {
-        val ns1 = NetworkScore()
-        val ns2 = NetworkScore()
-        assertTrue(ns1.equals(ns2))
-        assertEquals(ns1.hashCode(), ns2.hashCode())
+        val builder1 = NetworkScore.Builder()
+        val builder2 = NetworkScore.Builder()
+        assertTrue(builder1.build().equals(builder2.build()))
+        assertEquals(builder1.build().hashCode(), builder2.build().hashCode())
 
-        ns1.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
-        assertFalse(ns1.equals(ns2))
-        assertNotEquals(ns1.hashCode(), ns2.hashCode())
-        ns2.putIntExtension(NetworkScore.LEGACY_SCORE, TEST_SCORE)
-        assertTrue(ns1.equals(ns2))
-        assertEquals(ns1.hashCode(), ns2.hashCode())
-
-        val defaultCap = NetworkCapabilities()
-        ns1.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
-        assertFalse(ns1.equals(ns2))
-        assertNotEquals(ns1.hashCode(), ns2.hashCode())
-        ns2.putExtension(KEY_DEFAULT_CAPABILITIES, defaultCap)
-        assertTrue(ns1.equals(ns2))
-        assertEquals(ns1.hashCode(), ns2.hashCode())
-
-        ns1.putIntExtension(null, 10)
-        assertFalse(ns1.equals(ns2))
-        assertNotEquals(ns1.hashCode(), ns2.hashCode())
-        ns2.putIntExtension(null, 10)
-        assertTrue(ns1.equals(ns2))
-        assertEquals(ns1.hashCode(), ns2.hashCode())
+        builder1.setLegacyScore(TEST_SCORE)
+        assertFalse(builder1.build().equals(builder2.build()))
+        assertNotEquals(builder1.hashCode(), builder2.hashCode())
+        builder2.setLegacyScore(TEST_SCORE)
+        assertTrue(builder1.build().equals(builder2.build()))
+        assertEquals(builder1.build().hashCode(), builder2.build().hashCode())
     }
 }
diff --git a/tests/net/deflake/Android.bp b/tests/net/deflake/Android.bp
index 1c48c74..b1b0171 100644
--- a/tests/net/deflake/Android.bp
+++ b/tests/net/deflake/Android.bp
@@ -26,4 +26,5 @@
         "net-host-tests-utils",
     ],
     data: [":FrameworksNetTests"],
-}
\ No newline at end of file
+    test_suites: ["device-tests"],
+}
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index a35fb40..7ae9e95 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -40,6 +40,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkProvider;
+import android.net.NetworkScore;
 import android.net.NetworkSpecifier;
 import android.net.SocketKeepalive;
 import android.net.UidRange;
@@ -155,9 +156,13 @@
         }
     }
 
+    private NetworkScore makeNetworkScore(final int legacyScore) {
+        return new NetworkScore.Builder().setLegacyScore(legacyScore).build();
+    }
+
     public void adjustScore(int change) {
         mScore += change;
-        mNetworkAgent.sendNetworkScore(mScore);
+        mNetworkAgent.sendNetworkScore(makeNetworkScore(mScore));
     }
 
     public int getScore() {
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index e863266..25e9057 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -353,8 +353,7 @@
         NetworkCapabilities caps = new NetworkCapabilities();
         caps.addCapability(0);
         caps.addTransportType(transport);
-        NetworkScore ns = new NetworkScore();
-        ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50);
+        NetworkScore ns = new NetworkScore.Builder().setLegacyScore(50).build();
         NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
                 caps, ns, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS,
                 NetworkProvider.ID_NONE);
diff --git a/tools/hiddenapi/Android.bp b/tools/hiddenapi/Android.bp
new file mode 100644
index 0000000..e0eb06cb
--- /dev/null
+++ b/tools/hiddenapi/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+python_binary_host {
+	name: "merge_csv",
+	main: "merge_csv.py",
+	srcs: ["merge_csv.py"],
+	version: {
+		py2: {
+			enabled: false,
+		},
+		py3: {
+			enabled: true,
+			embedded_launcher: true
+		},
+	},
+}
diff --git a/tools/hiddenapi/merge_csv.py b/tools/hiddenapi/merge_csv.py
index 48c0755..9661927 100755
--- a/tools/hiddenapi/merge_csv.py
+++ b/tools/hiddenapi/merge_csv.py
@@ -21,20 +21,19 @@
 import sys
 
 csv_readers = [
-    csv.DictReader(open(csv_file, 'rb'), delimiter=',', quotechar='|')
+    csv.DictReader(open(csv_file, 'r'), delimiter=',', quotechar='|')
     for csv_file in sys.argv[1:]
 ]
 
 # Build union of all columns from source files:
 headers = set()
 for reader in csv_readers:
-  headers = headers.union(reader.fieldnames)
+    headers = headers.union(reader.fieldnames)
 
 # Concatenate all files to output:
-out = csv.DictWriter(sys.stdout, delimiter=',', quotechar='|', fieldnames = sorted(headers))
+out = csv.DictWriter(sys.stdout, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL,
+                     dialect='unix', fieldnames=sorted(headers))
 out.writeheader()
 for reader in csv_readers:
-  for row in reader:
-    out.writerow(row)
-
-
+    for row in reader:
+        out.writerow(row)
diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp
index 1259a68..a68c3a2 100644
--- a/tools/stats_log_api_gen/java_writer_q.cpp
+++ b/tools/stats_log_api_gen/java_writer_q.cpp
@@ -577,6 +577,50 @@
     }
 }
 
+// This method is called in main.cpp to generate StatsLog for modules that's compatible with
+// Q at compile-time.
+int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
+                                      const AtomDecl &attributionDecl, const string& moduleName,
+                                      const string& javaClass, const string& javaPackage,
+                                      const bool supportWorkSource) {
+    // Print prelude
+    fprintf(out, "// This file is autogenerated\n");
+    fprintf(out, "\n");
+    fprintf(out, "package %s;\n", javaPackage.c_str());
+    fprintf(out, "\n");
+    fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
+    fprintf(out, "\n");
+    fprintf(out, "import android.util.StatsLog;\n");
+    fprintf(out, "import android.os.SystemClock;\n");
+    fprintf(out, "\n");
+    fprintf(out, "\n");
+    fprintf(out, "/**\n");
+    fprintf(out, " * Utility class for logging statistics events.\n");
+    fprintf(out, " */\n");
+    fprintf(out, "public class %s {\n", javaClass.c_str());
+
+    write_java_q_logging_constants(out, "    ");
+
+    write_java_atom_codes(out, atoms, moduleName);
+
+    write_java_enum_values(out, atoms, moduleName);
+
+    int errors = 0;
+    // Print write methods
+    fprintf(out, "    // Write methods\n");
+    errors += write_java_methods_q_schema(out, atoms.signatures_to_modules, attributionDecl,
+            moduleName, "    ");
+    errors += write_java_non_chained_methods(out, atoms.non_chained_signatures_to_modules,
+            moduleName);
+    if (supportWorkSource) {
+        errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName);
+    }
+
+    fprintf(out, "}\n");
+
+    return errors;
+}
+
 #if defined(STATS_SCHEMA_LEGACY)
 static void write_java_method(
         FILE* out,
@@ -639,48 +683,6 @@
 
     return 0;
 }
-
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
-                                      const AtomDecl &attributionDecl, const string& moduleName,
-                                      const string& javaClass, const string& javaPackage,
-                                      const bool supportWorkSource) {
-    // Print prelude
-    fprintf(out, "// This file is autogenerated\n");
-    fprintf(out, "\n");
-    fprintf(out, "package %s;\n", javaPackage.c_str());
-    fprintf(out, "\n");
-    fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
-    fprintf(out, "\n");
-    fprintf(out, "import android.util.StatsLog;\n");
-    fprintf(out, "import android.os.SystemClock;\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "/**\n");
-    fprintf(out, " * Utility class for logging statistics events.\n");
-    fprintf(out, " */\n");
-    fprintf(out, "public class %s {\n", javaClass.c_str());
-
-    write_java_q_logging_constants(out, "    ");
-
-    write_java_atom_codes(out, atoms, moduleName);
-
-    write_java_enum_values(out, atoms, moduleName);
-
-    int errors = 0;
-    // Print write methods
-    fprintf(out, "    // Write methods\n");
-    errors += write_java_methods_q_schema(out, atoms.signatures_to_modules, attributionDecl,
-            moduleName, "    ");
-    errors += write_java_non_chained_methods(out, atoms.non_chained_signatures_to_modules,
-            moduleName);
-    if (supportWorkSource) {
-        errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName);
-    }
-
-    fprintf(out, "}\n");
-
-    return errors;
-}
 #endif
 
 }  // namespace stats_log_api_gen
diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h
index 36df1d8..7d734df 100644
--- a/tools/stats_log_api_gen/java_writer_q.h
+++ b/tools/stats_log_api_gen/java_writer_q.h
@@ -45,13 +45,13 @@
         const int requiredHelpers,
         const string& indent);
 
-#if defined(STATS_SCHEMA_LEGACY)
-int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
-                           const bool supportWorkSource);
-
 int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
         const AtomDecl &attributionDecl, const string& moduleName, const string& javaClass,
         const string& javaPackage, const bool supportWorkSource);
+
+#if defined(STATS_SCHEMA_LEGACY)
+int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+                           const bool supportWorkSource);
 #endif
 }  // namespace stats_log_api_gen
 }  // namespace android
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 6089532..ddbf22c 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -511,8 +511,10 @@
     fprintf(stderr, "  --javaClass CLASS    the class name of the java class.\n");
     fprintf(stderr, "                       Optional for Java with module.\n");
     fprintf(stderr, "                       Default is \"StatsLogInternal\"\n");
-    fprintf(stderr, "  --supportQ           Include support for Android Q.\n");
+    fprintf(stderr, "  --supportQ           Include runtime support for Android Q.\n");
     fprintf(stderr, "  --worksource         Include support for logging WorkSource objects.\n");
+    fprintf(stderr, "  --compileQ           Include compile-time support for Android Q "
+            "(Java only).\n");
 }
 
 /**
@@ -536,6 +538,7 @@
     string javaClass = DEFAULT_JAVA_CLASS;
     bool supportQ = false;
     bool supportWorkSource = false;
+    bool compileQ = false;
 
     int index = 1;
     while (index < argc) {
@@ -630,6 +633,8 @@
             supportQ = true;
         } else if (0 == strcmp("--worksource", argv[index])) {
             supportWorkSource = true;
+        } else if (0 == strcmp("--compileQ", argv[index])) {
+            compileQ = true;
         }
 
         index++;
@@ -645,12 +650,18 @@
         return 1;
     }
 
-    if (DEFAULT_MODULE_NAME == moduleName && supportQ) {
+    if (DEFAULT_MODULE_NAME == moduleName && (supportQ || compileQ)) {
         // Support for Q schema is not needed for default module.
         fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str());
         return 1;
     }
 
+    if (supportQ && compileQ) {
+        // Runtime Q support is redundant if compile-time Q support is required.
+        fprintf(stderr, "Cannot specify compileQ and supportQ simultaneously.\n");
+        return 1;
+    }
+
     // Collate the parameters
     Atoms atoms;
     int errorCount = collate_atoms(Atom::descriptor(), &atoms);
@@ -748,9 +759,15 @@
             javaClass = "StatsLogInternal";
             javaPackage = "android.util";
         }
-        errorCount = android::stats_log_api_gen::write_stats_log_java(
-                out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ,
-                supportWorkSource);
+        if (compileQ) {
+            errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
+                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage,
+                    supportWorkSource);
+        } else {
+            errorCount = android::stats_log_api_gen::write_stats_log_java(
+                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ,
+                    supportWorkSource);
+        }
 #endif
 
         fclose(out);
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 0ef224a..8d95cb0 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -373,6 +373,7 @@
      * ECDHE_ECDSA
      * ECDHE_RSA
      * </pre>
+     * @hide
      */
     public static class SuiteBCipher {
         private SuiteBCipher() { }
@@ -715,8 +716,8 @@
     public BitSet allowedGroupManagementCiphers;
     /**
      * The set of SuiteB ciphers supported by this configuration.
-     * To be used for WPA3-Enterprise mode.
-     * See {@link SuiteBCipher} for descriptions of the values.
+     * To be used for WPA3-Enterprise mode. Set automatically by the framework based on the
+     * certificate type that is used in this configuration.
      */
     @NonNull
     public BitSet allowedSuiteBCiphers;
@@ -1929,54 +1930,38 @@
     private NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus();
 
     /**
-     * @hide
      * This class is intended to store extra failure reason information for the most recent
      * connection attempt, so that it may be surfaced to the settings UI
+     * @hide
      */
-    @SystemApi
+    // TODO(b/148626966): called by SUW via reflection, remove once SUW is updated
     public static class RecentFailure {
 
         private RecentFailure() {}
 
-        /** @hide */
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(value = {NONE, STATUS_AP_UNABLE_TO_HANDLE_NEW_STA})
-        public @interface AssociationStatus {}
-
-        /**
-         * No recent failure, or no specific reason given for the recent connection failure
-         */
-        public static final int NONE = 0;
-        /**
-         * Connection to this network recently failed due to Association Rejection Status 17
-         * (AP is full)
-         */
-        public static final int STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17;
         /**
          * Association Rejection Status code (NONE for success/non-association-rejection-fail)
          */
-        @AssociationStatus
-        private int mAssociationStatus = NONE;
+        @RecentFailureReason
+        private int mAssociationStatus = RECENT_FAILURE_NONE;
 
         /**
          * @param status the association status code for the recent failure
-         * @hide
          */
-        public void setAssociationStatus(@AssociationStatus int status) {
+        public void setAssociationStatus(@RecentFailureReason int status) {
             mAssociationStatus = status;
         }
         /**
          * Sets the RecentFailure to NONE
-         * @hide
          */
         public void clear() {
-            mAssociationStatus = NONE;
+            mAssociationStatus = RECENT_FAILURE_NONE;
         }
         /**
-         * Get the recent failure code. One of {@link #NONE} or
-         * {@link #STATUS_AP_UNABLE_TO_HANDLE_NEW_STA}.
+         * Get the recent failure code. One of {@link #RECENT_FAILURE_NONE} or
+         * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}.
          */
-        @AssociationStatus
+        @RecentFailureReason
         public int getAssociationStatus() {
             return mAssociationStatus;
         }
@@ -1986,10 +1971,47 @@
      * RecentFailure member
      * @hide
      */
+    // TODO(b/148626966): called by SUW via reflection, once SUW is updated, make private and
+    //  rename to mRecentFailure
     @NonNull
-    @SystemApi
     public final RecentFailure recentFailure = new RecentFailure();
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "RECENT_FAILURE_", value = {
+            RECENT_FAILURE_NONE,
+            RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA})
+    public @interface RecentFailureReason {}
+
+    /**
+     * No recent failure, or no specific reason given for the recent connection failure
+     * @hide
+     */
+    @SystemApi
+    public static final int RECENT_FAILURE_NONE = 0;
+    /**
+     * Connection to this network recently failed due to Association Rejection Status 17
+     * (AP is full)
+     * @hide
+     */
+    @SystemApi
+    public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17;
+
+    /**
+     * Get the failure reason for the most recent connection attempt, or
+     * {@link #RECENT_FAILURE_NONE} if there was no failure.
+     *
+     * Failure reasons include:
+     * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}
+     *
+     * @hide
+     */
+    @RecentFailureReason
+    @SystemApi
+    public int getRecentFailureReason() {
+        return recentFailure.getAssociationStatus();
+    }
+
     /**
      * Get the network selection status.
      * @hide
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index 3a0d080..756d679 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -19,6 +19,7 @@
 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
 import static android.net.wifi.WifiConfiguration.MeteredOverride;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.wifi.hotspot2.pps.Credential;
@@ -895,4 +896,18 @@
     public boolean isOsuProvisioned() {
         return getUpdateIdentifier() != Integer.MIN_VALUE;
     }
+
+    /**
+     * Get a unique identifier for a PasspointConfiguration object.
+     *
+     * @return A unique identifier
+     * @throws IllegalStateException if Credential or HomeSP nodes are not initialized
+     */
+    public @NonNull String getUniqueId() throws IllegalStateException {
+        if (mCredential == null || mHomeSp == null || TextUtils.isEmpty(mHomeSp.getFqdn())) {
+            throw new IllegalStateException("Credential or HomeSP are not initialized");
+        }
+
+        return mHomeSp.getFqdn();
+    }
 }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index 9562f95..36c7213 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -137,12 +137,12 @@
 
     /** @hide */
     @UnsupportedAppUsage
-    public int netId = WifiP2pGroup.PERSISTENT_NET_ID;
+    public int netId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
 
     /**
      * Get the network ID of this P2P configuration.
-     * @return either a non-negative network ID, or one of {@link WifiP2pGroup#PERSISTENT_NET_ID} or
-     * {@link WifiP2pGroup#TEMPORARY_NET_ID}.
+     * @return either a non-negative network ID, or one of
+     * {@link WifiP2pGroup#NETWORK_ID_PERSISTENT} or {@link WifiP2pGroup#NETWORK_ID_TEMPORARY}.
      */
     public int getNetworkId() {
         return netId;
@@ -280,7 +280,7 @@
         private String mPassphrase = "";
         private int mGroupOperatingBand = GROUP_OWNER_BAND_AUTO;
         private int mGroupOperatingFrequency = GROUP_OWNER_BAND_AUTO;
-        private int mNetId = WifiP2pGroup.TEMPORARY_NET_ID;
+        private int mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;
 
         /**
          * Specify the peer's MAC address. If not set, the device will
@@ -460,9 +460,9 @@
          */
         public @NonNull Builder enablePersistentMode(boolean persistent) {
             if (persistent) {
-                mNetId = WifiP2pGroup.PERSISTENT_NET_ID;
+                mNetId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
             } else {
-                mNetId = WifiP2pGroup.TEMPORARY_NET_ID;
+                mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;
             }
             return this;
         }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
index 21f6704..e497b22 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -41,7 +41,15 @@
      * The temporary network id.
      * @see #getNetworkId()
      */
-    public static final int TEMPORARY_NET_ID = -1;
+    public static final int NETWORK_ID_TEMPORARY = -1;
+
+    /**
+     * The temporary network id.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static final int TEMPORARY_NET_ID = NETWORK_ID_TEMPORARY;
 
     /**
      * The persistent network id.
@@ -49,7 +57,7 @@
      * Otherwise, create a new persistent profile.
      * @see #getNetworkId()
      */
-    public static final int PERSISTENT_NET_ID = -2;
+    public static final int NETWORK_ID_PERSISTENT = -2;
 
     /** The network name */
     private String mNetworkName;
@@ -130,13 +138,13 @@
             mPassphrase = match.group(4);
             mOwner = new WifiP2pDevice(match.group(5));
             if (match.group(6) != null) {
-                mNetId = PERSISTENT_NET_ID;
+                mNetId = NETWORK_ID_PERSISTENT;
             } else {
-                mNetId = TEMPORARY_NET_ID;
+                mNetId = NETWORK_ID_TEMPORARY;
             }
         } else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) {
             String sa = null;
-            mNetId = PERSISTENT_NET_ID;
+            mNetId = NETWORK_ID_PERSISTENT;
             for (String token : tokens) {
                 String[] nameValue = token.split("=");
                 if (nameValue.length != 2) continue;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 3459c94..0fe0675 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -1293,7 +1293,7 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
     public void createGroup(Channel c, ActionListener listener) {
         checkChannel(c);
-        c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.PERSISTENT_NET_ID,
+        c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PERSISTENT,
                 c.putListener(listener));
     }
 
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
index 654154d..e78c5bf 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -18,6 +18,7 @@
 
 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -364,4 +365,54 @@
         assertTrue(config.validateForR2());
         assertTrue(config.isOsuProvisioned());
     }
+
+    /**
+     * Verify that the unique identifier generated is correct.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUniqueId() throws Exception {
+        PasspointConfiguration config = PasspointTestUtils.createConfig();
+        String uniqueId;
+        uniqueId = config.getUniqueId();
+        assertEquals(uniqueId, config.getHomeSp().getFqdn());
+    }
+
+    /**
+     * Verify that the unique identifier API generates an exception if HomeSP is not initialized.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUniqueIdExceptionWithEmptyHomeSp() throws Exception {
+        PasspointConfiguration config = PasspointTestUtils.createConfig();
+        config.setHomeSp(null);
+        boolean exceptionCaught = false;
+        try {
+            String uniqueId = config.getUniqueId();
+        } catch (IllegalStateException e) {
+            exceptionCaught = true;
+        }
+        assertTrue(exceptionCaught);
+    }
+
+    /**
+     * Verify that the unique identifier API generates an exception if Credential is not
+     * initialized.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUniqueIdExceptionWithEmptyCredential() throws Exception {
+        PasspointConfiguration config = PasspointTestUtils.createConfig();
+        config.setCredential(null);
+        boolean exceptionCaught = false;
+        try {
+            String uniqueId = config.getUniqueId();
+        } catch (IllegalStateException e) {
+            exceptionCaught = true;
+        }
+        assertTrue(exceptionCaught);
+    }
 }