diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java index 8a46c9d18c5..e3e77e86000 100644 --- a/src/com/android/settings/wifi/WifiDialogActivity.java +++ b/src/com/android/settings/wifi/WifiDialogActivity.java @@ -19,6 +19,7 @@ package com.android.settings.wifi; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.os.UserManager.DISALLOW_CONFIG_WIFI; +import android.app.KeyguardManager; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; @@ -51,6 +52,7 @@ import com.android.wifitrackerlib.WifiEntry; import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupdesign.util.ThemeHelper; +import java.lang.ref.WeakReference; import java.time.Clock; import java.time.ZoneOffset; @@ -96,10 +98,12 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog // Interval between initiating NetworkDetailsTracker scans. private static final long SCAN_INTERVAL_MILLIS = 10_000; - private WifiDialog mDialog; + @VisibleForTesting + WifiDialog mDialog; private AccessPoint mAccessPoint; - private WifiDialog2 mDialog2; + @VisibleForTesting + WifiDialog2 mDialog2; // The received intent supports a key of WifiTrackerLib or SettingsLib. private boolean mIsWifiTrackerLib; @@ -108,6 +112,7 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog private NetworkDetailsTracker mNetworkDetailsTracker; private HandlerThread mWorkerThread; private WifiManager mWifiManager; + private LockScreenMonitor mLockScreenMonitor; @Override protected void onCreate(Bundle savedInstanceState) { @@ -184,6 +189,10 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog mDialog.setOnDismissListener(this); } } + + if (mDialog2 != null || mDialog != null) { + mLockScreenMonitor = new LockScreenMonitor(this); + } } @VisibleForTesting @@ -221,6 +230,10 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog } } + if (mLockScreenMonitor != null) { + mLockScreenMonitor.release(); + mLockScreenMonitor = null; + } super.onDestroy(); } @@ -411,4 +424,45 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog } return false; } + + void dismissDialog() { + if (mDialog != null) { + mDialog.dismiss(); + mDialog = null; + } + if (mDialog2 != null) { + mDialog2.dismiss(); + mDialog2 = null; + } + } + + @VisibleForTesting + static final class LockScreenMonitor implements KeyguardManager.KeyguardLockedStateListener { + private final WeakReference mWifiDialogActivity; + private KeyguardManager mKeyguardManager; + + LockScreenMonitor(WifiDialogActivity activity) { + mWifiDialogActivity = new WeakReference<>(activity); + mKeyguardManager = activity.getSystemService(KeyguardManager.class); + mKeyguardManager.addKeyguardLockedStateListener(activity.getMainExecutor(), this); + } + + void release() { + if (mKeyguardManager == null) return; + mKeyguardManager.removeKeyguardLockedStateListener(this); + mKeyguardManager = null; + } + + @Override + public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) { + if (!isKeyguardLocked) return; + WifiDialogActivity activity = mWifiDialogActivity.get(); + if (activity == null) return; + activity.dismissDialog(); + + Log.e(TAG, "Dismiss Wi-Fi dialog to prevent leaking user data on lock screen!"); + EventLog.writeEvent(0x534e4554, "231583603", -1 /* UID */, + "Leak Wi-Fi dialog on lock screen"); + } + } } diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java index 28b7ecbf09b..c9cc02e9afb 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java @@ -33,6 +33,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.KeyguardManager; import android.content.Intent; import android.content.pm.PackageManager; import android.net.wifi.WifiConfiguration; @@ -46,7 +47,6 @@ import com.android.wifitrackerlib.WifiEntry; import com.google.android.setupcompat.util.WizardManagerHelper; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -82,6 +82,8 @@ public class WifiDialogActivityTest { Intent mResultData; @Mock WifiConfigController mController; + @Mock + KeyguardManager mKeyguardManager; WifiDialogActivity mActivity; @@ -99,6 +101,7 @@ public class WifiDialogActivityTest { mActivity = spy(Robolectric.setupActivity(WifiDialogActivity.class)); when(mActivity.getSystemService(UserManager.class)).thenReturn(mUserManager); when(mActivity.getSystemService(WifiManager.class)).thenReturn(mWifiManager); + when(mActivity.getSystemService(KeyguardManager.class)).thenReturn(mKeyguardManager); } @Test @@ -294,4 +297,35 @@ public class WifiDialogActivityTest { assertThat(result).isTrue(); } + + @Test + public void dismissDialog_hasDialog_dialogDismiss() { + mActivity.mDialog = mWifiDialog; + mActivity.mDialog2 = mWifiDialog2; + + mActivity.dismissDialog(); + + verify(mWifiDialog).dismiss(); + verify(mWifiDialog2).dismiss(); + } + + @Test + public void onKeyguardLockedStateChanged_keyguardIsNotLocked_doNotDismissDialog() { + WifiDialogActivity.LockScreenMonitor lockScreenMonitor = + new WifiDialogActivity.LockScreenMonitor(mActivity); + + lockScreenMonitor.onKeyguardLockedStateChanged(false /* isKeyguardLocked */); + + verify(mActivity, never()).dismissDialog(); + } + + @Test + public void onKeyguardLockedStateChanged_keyguardIsLocked_dismissDialog() { + WifiDialogActivity.LockScreenMonitor lockScreenMonitor = + new WifiDialogActivity.LockScreenMonitor(mActivity); + + lockScreenMonitor.onKeyguardLockedStateChanged(true /* isKeyguardLocked */); + + verify(mActivity).dismissDialog(); + } }