Merge "Update systemui wifi icons to GM2." into qt-dev
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index af58b19..c6f6c50a 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -3515,10 +3515,10 @@
     /**
      * Process state of UID changed; if needed, will trigger
      * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
-     * {@link #updateRulesForPowerRestrictionsUL(int)}
+     * {@link #updateRulesForPowerRestrictionsUL(int)}. Returns true if the state was updated.
      */
     @GuardedBy("mUidRulesFirstLock")
-    private void updateUidStateUL(int uid, int uidState) {
+    private boolean updateUidStateUL(int uid, int uidState) {
         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
         try {
             final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
@@ -3537,15 +3537,16 @@
                     }
                     updateRulesForPowerRestrictionsUL(uid);
                 }
-                updateNetworkStats(uid, isUidStateForeground(uidState));
+                return true;
             }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
         }
+        return false;
     }
 
     @GuardedBy("mUidRulesFirstLock")
-    private void removeUidStateUL(int uid) {
+    private boolean removeUidStateUL(int uid) {
         final int index = mUidState.indexOfKey(uid);
         if (index >= 0) {
             final int oldUidState = mUidState.valueAt(index);
@@ -3560,9 +3561,10 @@
                     updateRuleForRestrictPowerUL(uid);
                 }
                 updateRulesForPowerRestrictionsUL(uid);
-                updateNetworkStats(uid, false);
+                return true;
             }
         }
+        return false;
     }
 
     // adjust stats accounting based on foreground status
@@ -4552,21 +4554,26 @@
                 }
             }
         }
-
     };
 
     void handleUidChanged(int uid, int procState, long procStateSeq) {
         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
         try {
+            boolean updated;
             synchronized (mUidRulesFirstLock) {
                 // We received a uid state change callback, add it to the history so that it
                 // will be useful for debugging.
                 mLogger.uidStateChanged(uid, procState, procStateSeq);
                 // Now update the network policy rules as per the updated uid state.
-                updateUidStateUL(uid, procState);
+                updated = updateUidStateUL(uid, procState);
                 // Updating the network rules is done, so notify AMS about this.
                 mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
             }
+            // Do this without the lock held. handleUidChanged() and handleUidGone() are
+            // called from the handler, so there's no multi-threading issue.
+            if (updated) {
+                updateNetworkStats(uid, isUidStateForeground(procState));
+            }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
         }
@@ -4575,8 +4582,14 @@
     void handleUidGone(int uid) {
         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
         try {
+            boolean updated;
             synchronized (mUidRulesFirstLock) {
-                removeUidStateUL(uid);
+                updated = removeUidStateUL(uid);
+            }
+            // Do this without the lock held. handleUidChanged() and handleUidGone() are
+            // called from the handler, so there's no multi-threading issue.
+            if (updated) {
+                updateNetworkStats(uid, false);
             }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
diff --git a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
index 9685ff6..22978a2 100644
--- a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
@@ -30,12 +30,15 @@
 
     /** Converts this OnBlobRetrievedListener to a parcelable object */
     @NonNull
-    static IOnBlobRetrievedListener toAIDL(final OnBlobRetrievedListener listener) {
+    static IOnBlobRetrievedListener toAIDL(@NonNull final OnBlobRetrievedListener listener) {
         return new IOnBlobRetrievedListener.Stub() {
             @Override
             public void onBlobRetrieved(final StatusParcelable statusParcelable, final String l2Key,
                     final String name, final Blob blob) {
-                listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob);
+                // NonNull, but still don't crash the system server if null
+                if (null != listener) {
+                    listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob);
+                }
             }
         };
     }
diff --git a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
index 80209c5..9e7c1c8 100644
--- a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
@@ -30,12 +30,15 @@
 
     /** Converts this OnL2KeyResponseListener to a parcelable object */
     @NonNull
-    static IOnL2KeyResponseListener toAIDL(final OnL2KeyResponseListener listener) {
+    static IOnL2KeyResponseListener toAIDL(@NonNull final OnL2KeyResponseListener listener) {
         return new IOnL2KeyResponseListener.Stub() {
             @Override
             public void onL2KeyResponse(final StatusParcelable statusParcelable,
                     final String l2Key) {
-                listener.onL2KeyResponse(new Status(statusParcelable), l2Key);
+                // NonNull, but still don't crash the system server if null
+                if (null != listener) {
+                    listener.onL2KeyResponse(new Status(statusParcelable), l2Key);
+                }
             }
         };
     }
diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
index f0f6f40..59da268 100644
--- a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
@@ -31,15 +31,18 @@
     /** Converts this OnNetworkAttributesRetrievedListener to a parcelable object */
     @NonNull
     static IOnNetworkAttributesRetrievedListener toAIDL(
-            final OnNetworkAttributesRetrievedListener listener) {
+            @NonNull final OnNetworkAttributesRetrievedListener listener) {
         return new IOnNetworkAttributesRetrievedListener.Stub() {
             @Override
             public void onNetworkAttributesRetrieved(final StatusParcelable statusParcelable,
                     final String l2Key,
                     final NetworkAttributesParcelable networkAttributesParcelable) {
-                listener.onNetworkAttributesRetrieved(
-                        new Status(statusParcelable), l2Key,
-                        new NetworkAttributes(networkAttributesParcelable));
+                // NonNull, but still don't crash the system server if null
+                if (null != listener) {
+                    listener.onNetworkAttributesRetrieved(
+                            new Status(statusParcelable), l2Key,
+                            new NetworkAttributes(networkAttributesParcelable));
+                }
             }
         };
     }
diff --git a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
index ba1e0e6..0154fd2 100644
--- a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
@@ -30,14 +30,18 @@
 
     /** Converts this OnSameL3NetworkResponseListener to a parcelable object */
     @NonNull
-    static IOnSameL3NetworkResponseListener toAIDL(final OnSameL3NetworkResponseListener listener) {
+    static IOnSameL3NetworkResponseListener toAIDL(
+            @NonNull final OnSameL3NetworkResponseListener listener) {
         return new IOnSameL3NetworkResponseListener.Stub() {
             @Override
             public void onSameL3NetworkResponse(final StatusParcelable statusParcelable,
                     final SameL3NetworkResponseParcelable sameL3NetworkResponseParcelable) {
-                listener.onSameL3NetworkResponse(
-                        new Status(statusParcelable),
-                        new SameL3NetworkResponse(sameL3NetworkResponseParcelable));
+                // NonNull, but still don't crash the system server if null
+                if (null != listener) {
+                    listener.onSameL3NetworkResponse(
+                            new Status(statusParcelable),
+                            new SameL3NetworkResponse(sameL3NetworkResponseParcelable));
+                }
             }
         };
     }
diff --git a/services/net/java/android/net/ipmemorystore/OnStatusListener.java b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
index 0de1666..824b7b0 100644
--- a/services/net/java/android/net/ipmemorystore/OnStatusListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
@@ -17,6 +17,7 @@
 package android.net.ipmemorystore;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 
 /**
  * A listener for the IpMemoryStore to return a status to a client.
@@ -30,11 +31,13 @@
 
     /** Converts this OnStatusListener to a parcelable object */
     @NonNull
-    static IOnStatusListener toAIDL(final OnStatusListener listener) {
+    static IOnStatusListener toAIDL(@Nullable final OnStatusListener listener) {
         return new IOnStatusListener.Stub() {
             @Override
             public void onComplete(final StatusParcelable statusParcelable) {
-                listener.onComplete(new Status(statusParcelable));
+                if (null != listener) {
+                    listener.onComplete(new Status(statusParcelable));
+                }
             }
         };
     }
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 46d0761..231025c 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -484,9 +484,6 @@
 
     private void waitForHandlerToComplete(Handler handler, long waitTimeMs)
             throws InterruptedException {
-        if (!handler.hasMessagesOrCallbacks()) { // if nothing queued, do not wait.
-            return;
-        }
         final Object lock = new Object();
         synchronized (lock) {
             handler.post(() -> {