Merge "Wipe the data in IpMemoryStore database upon network factory reset." into qt-dev
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index fe42111..050fcfa 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -22,7 +22,6 @@
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.net.shared.InetAddressUtils;
-import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -54,7 +53,7 @@
 @TestApi
 public final class StaticIpConfiguration implements Parcelable {
     /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     @Nullable
     public LinkAddress ipAddress;
     /** @hide */
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index 8090d14..4e40ba4 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -683,9 +683,9 @@
         public void enter() {
             maybeLogEvaluationResult(
                     networkEventType(validationStage(), EvaluationResult.VALIDATED));
-            // If the user has accepted that and HTTPS probing is disabled, then mark the network
-            // as validated and partial so that settings can keep informing the user that the
-            // connection is limited.
+            // If the user has accepted partial connectivity and HTTPS probing is disabled, then
+            // mark the network as validated and partial so that settings can keep informing the
+            // user that the connection is limited.
             int result = NETWORK_VALIDATION_RESULT_VALID;
             if (!mUseHttps && mAcceptPartialConnectivity) {
                 result |= NETWORK_VALIDATION_RESULT_PARTIAL;
@@ -1054,6 +1054,11 @@
             // TODO: Consider abandoning this state after a few attempts and
             // transitioning back to EvaluatingState, to perhaps give ourselves
             // the opportunity to (re)detect a captive portal or something.
+            //
+            // TODO: distinguish between CMD_EVALUATE_PRIVATE_DNS messages that are caused by server
+            // lookup failures (which should continue to do exponential backoff) and
+            // CMD_EVALUATE_PRIVATE_DNS messages that are caused by user reconfiguration (which
+            // should be processed immediately.
             sendMessageDelayed(CMD_EVALUATE_PRIVATE_DNS, mPrivateDnsReevalDelayMs);
             mPrivateDnsReevalDelayMs *= 2;
             if (mPrivateDnsReevalDelayMs > MAX_REEVALUATE_DELAY_MS) {
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
index cc8f2c0..262641d 100644
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -941,6 +941,10 @@
             .notifyNetworkTested(intCaptor.capture(), any());
         List<Integer> intArgs = intCaptor.getAllValues();
 
+        // None of these exact values can be known in advance except for intArgs.get(0) because the
+        // HTTP and HTTPS probes race and the order in which they complete is non-deterministic.
+        // Thus, check only exact value for intArgs.get(0) and only check the validation result for
+        // the rest ones.
         assertEquals(Integer.valueOf(NETWORK_VALIDATION_PROBE_DNS
                 | NETWORK_VALIDATION_PROBE_FALLBACK | NETWORK_VALIDATION_RESULT_VALID),
                 intArgs.get(0));
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 017c1b3..107e1fbb 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -601,21 +601,6 @@
                 // Hide notification first, as tie managed profile lock takes time
                 hideEncryptionNotification(new UserHandle(userId));
 
-                // Now we have unlocked the parent user we should show notifications
-                // about any profiles that exist.
-                List<UserInfo> profiles = mUserManager.getProfiles(userId);
-                for (int i = 0; i < profiles.size(); i++) {
-                    UserInfo profile = profiles.get(i);
-                    final boolean isSecure = isUserSecure(profile.id);
-                    if (isSecure && profile.isManagedProfile()) {
-                        UserHandle userHandle = profile.getUserHandle();
-                        if (!mUserManager.isUserUnlockingOrUnlocked(userHandle) &&
-                                !mUserManager.isQuietModeEnabled(userHandle)) {
-                            showEncryptionNotificationForProfile(userHandle);
-                        }
-                    }
-                }
-
                 if (mUserManager.getUserInfo(userId).isManagedProfile()) {
                     tieManagedProfileLockIfNecessary(userId, null);
                 }
@@ -1205,6 +1190,7 @@
      */
     private void unlockUser(int userId, byte[] token, byte[] secret) {
         // TODO: make this method fully async so we can update UI with progress strings
+        final boolean alreadyUnlocked = mUserManager.isUserUnlockingOrUnlocked(userId);
         final CountDownLatch latch = new CountDownLatch(1);
         final IProgressListener listener = new IProgressListener.Stub() {
             @Override
@@ -1235,18 +1221,31 @@
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
         }
-        try {
-            if (!mUserManager.getUserInfo(userId).isManagedProfile()) {
-                final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-                for (UserInfo pi : profiles) {
-                    // Unlock managed profile with unified lock
-                    if (tiedManagedProfileReadyToUnlock(pi)) {
-                        unlockChildProfile(pi.id, false /* ignoreUserNotAuthenticated */);
-                    }
+
+        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+            return;
+        }
+
+        for (UserInfo profile : mUserManager.getProfiles(userId)) {
+            // Unlock managed profile with unified lock
+            if (tiedManagedProfileReadyToUnlock(profile)) {
+                try {
+                    unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */);
+                } catch (RemoteException e) {
+                    Log.d(TAG, "Failed to unlock child profile", e);
                 }
             }
-        } catch (RemoteException e) {
-            Log.d(TAG, "Failed to unlock child profile", e);
+            // Now we have unlocked the parent user and attempted to unlock the profile we should
+            // show notifications if the profile is still locked.
+            if (!alreadyUnlocked) {
+                long ident = clearCallingIdentity();
+                try {
+                    maybeShowEncryptionNotificationForUser(profile.id);
+                } finally {
+                    restoreCallingIdentity(ident);
+                }
+            }
+
         }
     }
 
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 6560f58..8c024a5 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -615,7 +615,7 @@
         private void onValidationRequested() {
             try {
                 if (mNmProvNotificationRequested
-                        && mNmValidationResult == VALIDATION_RESULT_VALID) {
+                        && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) {
                     mNmCallbacks.hideProvisioningNotification();
                     mNmProvNotificationRequested = false;
                 }
@@ -2781,10 +2781,10 @@
         // Bring up a network with a captive portal.
         // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        String firstRedirectUrl = "http://example.com/firstPath";
-        mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
+        String redirectUrl = "http://android.com/path";
+        mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl);
         captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
+        assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), redirectUrl);
 
         // Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
         mCm.startCaptivePortalApp(mWiFiNetworkAgent.getNetwork());
@@ -2794,7 +2794,7 @@
         // Report that the captive portal is dismissed with partial connectivity, and check that
         // callbacks are fired.
         mWiFiNetworkAgent.setNetworkPartial();
-        mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
+        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
         waitForIdle();
         captivePortalCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
                 mWiFiNetworkAgent);
@@ -2805,6 +2805,7 @@
                 false /* always */);
         waitForIdle();
         mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
+        captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
         NetworkCapabilities nc =
                 validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,