Fix NPE when forgetting networks.

- Fixed disablement of ephemeral networks
- Exit out of the fragment when Forget is pressed

Bug: 36723238
Test: m RunSettingsRoboTests and manual testing
Change-Id: I83c09a44dbef0f02a452dc8c3163523a27bd4b63
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 85c0929..92e12b0 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -106,6 +106,7 @@
         mSignalStr = context.getResources().getStringArray(R.array.wifi_signal);
         mWifiConfig = accessPoint.getConfig();
         mWifiManager = wifiManager;
+        mWifiInfo = wifiManager.getConnectionInfo();
 
         lifecycle.addObserver(this);
     }
@@ -266,15 +267,24 @@
     }
 
     /**
+     * Returns whether the network represented by this preference can be forgotten.
+     */
+    public boolean canForgetNetwork() {
+        return mWifiInfo != null && mWifiInfo.isEphemeral() || mWifiConfig != null;
+    }
+
+    /**
      * Forgets the wifi network associated with this preference.
      */
     public void forgetNetwork() {
-        if (mWifiConfig.ephemeral) {
-            mWifiManager.disableEphemeralNetwork(mWifiConfig.SSID);
-        } else if (mWifiConfig.isPasspoint()) {
-            mWifiManager.removePasspointConfiguration(mWifiConfig.FQDN);
-        } else {
-            mWifiManager.forget(mWifiConfig.networkId, null /* action listener */);
+        if (mWifiInfo != null && mWifiInfo.isEphemeral()) {
+            mWifiManager.disableEphemeralNetwork(mWifiInfo.getSSID());
+        } else if (mWifiConfig != null) {
+            if (mWifiConfig.isPasspoint()) {
+                mWifiManager.removePasspointConfiguration(mWifiConfig.FQDN);
+            } else {
+                mWifiManager.forget(mWifiConfig.networkId, null /* action listener */);
+            }
         }
     }
 }
diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
index ade9d6a..7ebde38 100644
--- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
+++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
@@ -16,10 +16,8 @@
 package com.android.settings.wifi.details;
 
 import android.content.Context;
-import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
-import android.view.View;
 import android.widget.Button;
 
 import com.android.internal.logging.nano.MetricsProto;
@@ -63,8 +61,9 @@
 
         // Header Title set automatically from launching Preference
 
-        mForgetButton = (Button) ((LayoutPreference) findPreference(KEY_FORGET_BUTTON))
-                .findViewById(R.id.button);
+        LayoutPreference forgetPreference = ((LayoutPreference) findPreference(KEY_FORGET_BUTTON));
+        forgetPreference.setVisible(mWifiDetailPreferenceController.canForgetNetwork());
+        mForgetButton = (Button) forgetPreference.findViewById(R.id.button);
         mForgetButton.setText(R.string.forget);
         mForgetButton.setOnClickListener(view -> forgetNetwork());
     }
@@ -72,7 +71,7 @@
     private void forgetNetwork() {
         mMetricsFeatureProvider.action(getActivity(), MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
         mWifiDetailPreferenceController.forgetNetwork();
-        mForgetButton.setEnabled(false);
+        getActivity().finish();
     }
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 0a12ebf..f60c106 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -18,6 +18,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -93,14 +94,14 @@
         when(mockAccessPoint.getRssi()).thenReturn(RSSI);
         when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY);
 
+        when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED);
+        when(mockWifiInfo.getRssi()).thenReturn(RSSI);
+        when(mockWifiManager.getConnectionInfo()).thenReturn(mockWifiInfo);
+
         mController = new WifiDetailPreferenceController(
                 mockAccessPoint, mContext, mLifecycle, mockWifiManager);
 
         setupMockedPreferenceScreen();
-
-        when(mockWifiInfo.getRssi()).thenReturn(RSSI);
-        when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED);
-        when(mockWifiManager.getConnectionInfo()).thenReturn(mockWifiInfo);
     }
 
     private void setupMockedPreferenceScreen() {
@@ -143,7 +144,8 @@
     public void latestWifiInfoAndConfig_shouldBeFetchedOnResume() {
         mController.onResume();
 
-        verify(mockWifiManager).getConnectionInfo();
+        // Once in construction, once in onResume
+        verify(mockWifiManager, times(2)).getConnectionInfo();
     }
 
     @Test
@@ -193,19 +195,41 @@
     }
 
     @Test
-    public void forgetNetwork_ephemeral() {
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.SSID = "ssid";
-        // WifiConfiguration#isEphemeral will not be visible in robolectric until O is supported
-        wifiConfiguration.ephemeral = true;
-        when(mockAccessPoint.getConfig()).thenReturn(wifiConfiguration);
+    public void canForgetNetwork_noNetwork() {
+        when(mockAccessPoint.getConfig()).thenReturn(null);
 
         mController = new WifiDetailPreferenceController(
                 mockAccessPoint, mContext, mLifecycle, mockWifiManager);
 
+        assertThat(mController.canForgetNetwork()).isFalse();
+    }
+
+    @Test
+    public void canForgetNetwork_ephemeral() {
+        when(mockWifiInfo.isEphemeral()).thenReturn(true);
+        when(mockAccessPoint.getConfig()).thenReturn(null);
+
+        mController = new WifiDetailPreferenceController(
+                mockAccessPoint, mContext, mLifecycle, mockWifiManager);
+
+        assertThat(mController.canForgetNetwork()).isTrue();
+    }
+
+    @Test
+    public void canForgetNetwork_saved() {
+        assertThat(mController.canForgetNetwork()).isTrue();
+    }
+
+    @Test
+    public void forgetNetwork_ephemeral() {
+        String ssid = "ssid";
+
+        when(mockWifiInfo.isEphemeral()).thenReturn(true);
+        when(mockWifiInfo.getSSID()).thenReturn(ssid);
+
         mController.forgetNetwork();
 
-        verify(mockWifiManager).disableEphemeralNetwork(wifiConfiguration.SSID);
+        verify(mockWifiManager).disableEphemeralNetwork(ssid);
     }
 
     @Test