OSDN Git Service

Fix Wi-Fi DPP fragment back stack problems
authorArc Wang <arcwang@google.com>
Thu, 31 Jan 2019 03:07:38 +0000 (11:07 +0800)
committerArc Wang <arcwang@google.com>
Mon, 11 Feb 2019 03:42:21 +0000 (11:42 +0800)
1. When a Wi-Fi network connected and receiving
   intent android.settings.PROCESS_WIFI_EASY_CONNECT_QR_CODE,
   show WifiDppAddDeviceFragment from WifiDppConfiguratorActivity
   instead of WifiNetworkListFragment

2. Only handle intent when savedInstanceState is null

3. To show a fragment
   I. do nothing when a fragment is already visible on screen,
   II. pop back stack if it's in back stack, we can do this because
   current fragment transactions are arranged in an order

Bug: 124194531
Test: atest WifiQrCodeTest
      atest WifiDppConfiguratorActivityTest
      atest WifiDppEnrolleeActivityTest
      atest WifiDppQrCodeGeneratorFragmentTest
      atest WifiDppQrCodeScannerFragmentTest
      atest WifiNetworkListFragmentTest
      atest WifiDppChooseSavedWifiNetworkFragmentTest

Change-Id: I1d44eeb3bdc7bfb2ec2e4d81efaab64b066651ad

src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
src/com/android/settings/wifi/dpp/WifiDppUtils.java
src/com/android/settings/wifi/dpp/WifiNetworkListFragment.java
tests/unit/src/com/android/settings/wifi/dpp/WifiNetworkListFragmentTest.java

index 4aac538..65be11c 100644 (file)
@@ -19,6 +19,9 @@ package com.android.settings.wifi.dpp;
 import android.app.ActionBar;
 import android.app.settings.SettingsEnums;
 import android.content.Intent;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.util.Log;
@@ -31,6 +34,8 @@ import androidx.fragment.app.FragmentTransaction;
 import com.android.settings.R;
 import com.android.settings.core.InstrumentedActivity;
 
+import java.util.List;
+
 /**
  * To provision "other" device with specified Wi-Fi network.
  *
@@ -78,6 +83,7 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
 
     /** The Wi-Fi DPP QR code from intent ACTION_PROCESS_WIFI_EASY_CONNECT_QR_CODE */
     private WifiQrCode mWifiDppQrCode;
+
     /** Secret extra that allows fake networks to show in UI for testing purposes */
     private boolean mIsTest;
 
@@ -90,6 +96,9 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        setContentView(R.layout.wifi_dpp_activity);
+        mFragmentManager = getSupportFragmentManager();
+
         if (savedInstanceState != null) {
             String qrCode = savedInstanceState.getString(KEY_QR_CODE);
 
@@ -103,13 +112,10 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
 
             mWifiNetworkConfig = WifiNetworkConfig.getValidConfigOrNull(security, ssid,
                     preSharedKey, hiddenSsid, networkId);
+        } else {
+            handleIntent(getIntent());
         }
 
-        setContentView(R.layout.wifi_dpp_activity);
-        mFragmentManager = getSupportFragmentManager();
-
-        handleIntent(getIntent());
-
         ActionBar actionBar = getActionBar();
         if (actionBar != null) {
             actionBar.setElevation(0);
@@ -150,7 +156,13 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
                 if (mWifiDppQrCode == null || !isDppSupported) {
                     cancelActivity = true;
                 } else {
-                    showChooseSavedWifiNetworkFragment(/* addToBackStack */ false);
+                    final WifiNetworkConfig connectedConfig = getConnectedWifiNetworkConfigOrNull();
+                    if (connectedConfig == null) {
+                        showChooseSavedWifiNetworkFragment(/* addToBackStack */ false);
+                    } else {
+                        mWifiNetworkConfig = connectedConfig;
+                        showAddDeviceFragment(/* addToBackStack */ false);
+                    }
                 }
                 break;
             default:
@@ -167,13 +179,18 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
         WifiDppQrCodeScannerFragment fragment =
                 (WifiDppQrCodeScannerFragment) mFragmentManager.findFragmentByTag(
                         WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
-        // Avoid to replace the same fragment during configuration change
-        if (fragment != null && fragment.isVisible()) {
-            return;
-        }
 
         if (fragment == null) {
             fragment = new WifiDppQrCodeScannerFragment();
+        } else {
+            if (fragment.isVisible()) {
+                return;
+            }
+
+            // When the fragment in back stack but not on top of the stack, we can simply pop
+            // stack because current fragment transactions are arranged in an order
+            mFragmentManager.popBackStackImmediate();
+            return;
         }
         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
 
@@ -189,12 +206,19 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
         WifiDppQrCodeGeneratorFragment fragment =
                 (WifiDppQrCodeGeneratorFragment) mFragmentManager.findFragmentByTag(
                         WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
-        // Avoid to replace the same fragment during configuration change
-        if (fragment != null && fragment.isVisible()) {
+
+        if (fragment == null) {
+            fragment = new WifiDppQrCodeGeneratorFragment();
+        } else {
+            if (fragment.isVisible()) {
+                return;
+            }
+
+            // When the fragment in back stack but not on top of the stack, we can simply pop
+            // stack because current fragment transactions are arranged in an order
+            mFragmentManager.popBackStackImmediate();
             return;
         }
-
-        fragment = new WifiDppQrCodeGeneratorFragment();
         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
 
         fragmentTransaction.replace(R.id.fragment_container, fragment,
@@ -206,10 +230,6 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
         WifiDppChooseSavedWifiNetworkFragment fragment =
                 (WifiDppChooseSavedWifiNetworkFragment) mFragmentManager.findFragmentByTag(
                         WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK);
-        // Avoid to replace the same fragment during configuration change
-        if (fragment != null && fragment.isVisible()) {
-            return;
-        }
 
         if (fragment == null) {
             fragment = new WifiDppChooseSavedWifiNetworkFragment();
@@ -218,6 +238,15 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
                 bundle.putBoolean(WifiDppUtils.EXTRA_TEST, true);
                 fragment.setArguments(bundle);
             }
+        } else {
+            if (fragment.isVisible()) {
+                return;
+            }
+
+            // When the fragment in back stack but not on top of the stack, we can simply pop
+            // stack because current fragment transactions are arranged in an order
+            mFragmentManager.popBackStackImmediate();
+            return;
         }
         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
 
@@ -234,14 +263,17 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
                 (WifiDppAddDeviceFragment) mFragmentManager.findFragmentByTag(
                         WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE);
 
-        // Avoid to replace the same fragment during configuration change
-        if (mFragmentManager.findFragmentByTag(
-                WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE) != null) {
-            return;
-        }
-
         if (fragment == null) {
             fragment = new WifiDppAddDeviceFragment();
+        } else {
+            if (fragment.isVisible()) {
+                return;
+            }
+
+            // When the fragment in back stack but not on top of the stack, we can simply pop
+            // stack because current fragment transactions are arranged in an order
+            mFragmentManager.popBackStackImmediate();
+            return;
         }
         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
 
@@ -359,4 +391,31 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
 
         showAddDeviceFragment(/* addToBackStack */ true);
     }
+
+    private WifiNetworkConfig getConnectedWifiNetworkConfigOrNull() {
+        final WifiManager wifiManager = getSystemService(WifiManager.class);
+        if (!wifiManager.isWifiEnabled()) {
+            return null;
+        }
+
+        final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
+        if (connectionInfo == null) {
+            return null;
+        }
+
+        final int connectionNetworkId = connectionInfo.getNetworkId();
+        final List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
+        for (WifiConfiguration wifiConfiguration : configs) {
+            if (wifiConfiguration.networkId == connectionNetworkId) {
+                return WifiNetworkConfig.getValidConfigOrNull(
+                    WifiDppUtils.getSecurityString(wifiConfiguration),
+                    wifiConfiguration.getPrintableSsid(),
+                    wifiConfiguration.preSharedKey,
+                    /* hiddenSsid */ false,
+                    wifiConfiguration.networkId);
+            }
+        }
+
+        return null;
+    }
 }
index df36ae5..143f87f 100644 (file)
@@ -100,7 +100,9 @@ public class WifiDppEnrolleeActivity extends InstrumentedActivity implements
         setContentView(R.layout.wifi_dpp_activity);
         mFragmentManager = getSupportFragmentManager();
 
-        handleIntent(getIntent());
+        if (savedInstanceState == null) {
+            handleIntent(getIntent());
+        }
 
         ActionBar actionBar = getActionBar();
         if (actionBar != null) {
@@ -122,13 +124,23 @@ public class WifiDppEnrolleeActivity extends InstrumentedActivity implements
     }
 
     private void showQrCodeScannerFragment(boolean addToBackStack, String ssid) {
-        // Avoid to replace the same fragment during configuration change
-        if (mFragmentManager.findFragmentByTag(WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER) != null) {
+        WifiDppQrCodeScannerFragment fragment =
+                (WifiDppQrCodeScannerFragment) mFragmentManager.findFragmentByTag(
+                        WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
+
+        if (fragment == null) {
+            fragment = new WifiDppQrCodeScannerFragment(ssid);
+        } else {
+            if (fragment.isVisible()) {
+                return;
+            }
+
+            // When the fragment in back stack but not on top of the stack, we can simply pop
+            // stack because current fragment transactions are arranged in an order
+            mFragmentManager.popBackStackImmediate();
             return;
         }
-
-        WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment(ssid);
-        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+        final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
 
         fragmentTransaction.replace(R.id.fragment_container, fragment,
                 WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
index 9c69032..7bc80e0 100644 (file)
@@ -18,6 +18,7 @@ package com.android.settings.wifi.dpp;
 
 import android.content.Context;
 import android.content.Intent;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.text.TextUtils;
@@ -147,6 +148,17 @@ public class WifiDppUtils {
         }
     }
 
+    static String getSecurityString(WifiConfiguration config) {
+        if (config.allowedKeyManagement.get(KeyMgmt.SAE)) {
+            return WifiQrCode.SECURITY_SAE;
+        }
+        if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
+            return WifiQrCode.SECURITY_WPA_PSK;
+        }
+        return (config.wepKeys[0] == null) ?
+                WifiQrCode.SECURITY_NO_PASSWORD : WifiQrCode.SECURITY_WEP;
+    }
+
     /**
      * Returns an intent to launch QR code generator or scanner according to the Wi-Fi network
      * security. It may return null if the security is not supported by QR code generator nor
index 89efc31..ce92f90 100644 (file)
@@ -20,7 +20,6 @@ import android.app.Activity;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
-import android.net.NetworkInfo.DetailedState;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
@@ -28,7 +27,6 @@ import android.util.Log;
 import android.view.View;
 import android.widget.Toast;
 
-import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
 
@@ -64,9 +62,6 @@ public class WifiNetworkListFragment extends SettingsPreferenceFragment implemen
     private WifiManager.ActionListener mSaveListener;
     private boolean mIsTest;
 
-    @VisibleForTesting
-    boolean mUseConnectedAccessPointDirectly;
-
     // Container Activity must implement this interface
     public interface OnChooseNetworkListener {
         public void onChooseNetwork(WifiNetworkConfig wifiNetworkConfig);
@@ -123,8 +118,6 @@ public class WifiNetworkListFragment extends SettingsPreferenceFragment implemen
                 }
             }
         };
-
-        mUseConnectedAccessPointDirectly = true;
     }
 
     @Override
@@ -310,16 +303,6 @@ public class WifiNetworkListFragment extends SettingsPreferenceFragment implemen
             if (isValidForDppConfiguration(accessPoint)) {
                 final String key = accessPoint.getKey();
 
-                // Check if this access point is already connected.
-                if (mUseConnectedAccessPointDirectly
-                        && accessPoint.getDetailedState() == DetailedState.CONNECTED) {
-                    // Uses connected access point to start DPP in Configurator-Initiator role
-                    // directly.
-                    onPreferenceTreeClick(createAccessPointPreference(accessPoint));
-                    removeCachedPrefs(mAccessPointsPreferenceCategory);
-                    return;
-                }
-
                 final AccessPointPreference pref = (AccessPointPreference) getCachedPreference(key);
                 if (pref != null) {
                     pref.setOrder(index);
index 18d62c2..c1c1d54 100644 (file)
@@ -98,7 +98,6 @@ public class WifiNetworkListFragmentTest {
     private void callOnWifiStateChanged(int state) {
         mActivityRule.getActivity().getMainThreadHandler()
                 .post(() -> mWifiNetworkListFragment.onWifiStateChanged(state));
-        mWifiNetworkListFragment.mUseConnectedAccessPointDirectly = false;
     }
 
     /** Launch the activity via an Intent with a String extra. */
@@ -173,4 +172,4 @@ public class WifiNetworkListFragmentTest {
         onView(withText(resourceString(WIFI_DISPLAY_STATUS_CONNECTED))).check(
                 matches(isDisplayed()));
     }
-}
\ No newline at end of file
+}