OSDN Git Service

Fix the bug of "Connecting" is rarely appearing on Wi-Fi slice
authorJason Chiu <chiujason@google.com>
Thu, 7 Mar 2019 09:42:39 +0000 (17:42 +0800)
committerJason Chiu <chiujason@google.com>
Mon, 18 Mar 2019 08:01:48 +0000 (16:01 +0800)
- AccessPoint treats connected and connecting as equal so slice doesn't
refresh in this case
- Add a new method to determine if two lists are the same in SliceBackgroundWorker
- WifiScanWorker overrides this method to check the access point states

Fixes: 123941320
Test: robotest
Change-Id: I78d610da4b6b1d40f5785ba6701fb71b987fe31c

src/com/android/settings/slices/SliceBackgroundWorker.java
src/com/android/settings/wifi/slice/WifiSlice.java
tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java

index 559aa71..f19b1df 100644 (file)
@@ -146,7 +146,7 @@ public abstract class SliceBackgroundWorker<E> implements Closeable {
                 needNotify = true;
             }
         } else {
-            needNotify = !results.equals(mCachedResults);
+            needNotify = !areListsTheSame(results, mCachedResults);
         }
 
         if (needNotify) {
@@ -155,6 +155,10 @@ public abstract class SliceBackgroundWorker<E> implements Closeable {
         }
     }
 
+    protected boolean areListsTheSame(List<E> a, List<E> b) {
+        return a.equals(b);
+    }
+
     /**
      * Notify that data was updated and attempt to sync changes to the Slice.
      */
index 8d20f7f..5b2fed4 100644 (file)
@@ -32,6 +32,7 @@ import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
 import android.net.Uri;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
@@ -355,7 +356,6 @@ public class WifiSlice implements CustomSliceable {
 
         @Override
         public void onConnectedChanged() {
-            notifySliceChange();
         }
 
         @Override
@@ -370,10 +370,43 @@ public class WifiSlice implements CustomSliceable {
             final List<AccessPoint> resultList = new ArrayList<>();
             for (AccessPoint ap : accessPoints) {
                 if (ap.isReachable()) {
-                    resultList.add(ap);
+                    resultList.add(clone(ap));
+                    if (resultList.size() >= DEFAULT_EXPANDED_ROW_COUNT) {
+                        break;
+                    }
                 }
             }
             updateResults(resultList);
         }
+
+        private AccessPoint clone(AccessPoint accessPoint) {
+            final Bundle savedState = new Bundle();
+            accessPoint.saveWifiState(savedState);
+            return new AccessPoint(mContext, savedState);
+        }
+
+        @Override
+        protected boolean areListsTheSame(List<AccessPoint> a, List<AccessPoint> b) {
+            if (!a.equals(b)) {
+                return false;
+            }
+
+            // compare access point states one by one
+            final int listSize = a.size();
+            for (int i = 0; i < listSize; i++) {
+                if (getState(a.get(i)) != getState(b.get(i))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private State getState(AccessPoint accessPoint) {
+            final NetworkInfo networkInfo = accessPoint.getNetworkInfo();
+            if (networkInfo != null) {
+                return networkInfo.getState();
+            }
+            return null;
+        }
     }
 }
index 01feb8e..75a9e11 100644 (file)
@@ -34,8 +34,10 @@ import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
 import android.net.Uri;
 import android.net.wifi.WifiManager;
+import android.os.Bundle;
 
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.slice.Slice;
@@ -61,6 +63,7 @@ import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
@@ -253,11 +256,42 @@ public class WifiSliceTest {
         verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
     }
 
+    private AccessPoint createAccessPoint(String name, State state) {
+        final NetworkInfo info = mock(NetworkInfo.class);
+        doReturn(state).when(info).getState();
+
+        final Bundle savedState = new Bundle();
+        savedState.putString("key_ssid", name);
+        savedState.putParcelable("key_networkinfo", info);
+        return new AccessPoint(mContext, savedState);
+    }
+
     @Test
-    public void onConnectedChanged_shouldNotifyChange() {
-        mWifiScanWorker.onConnectedChanged();
+    public void SliceAccessPoint_sameState_shouldBeTheSame() {
+        final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTED);
+        final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED);
 
-        verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
+        assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2)))
+                .isTrue();
+    }
+
+    @Test
+    public void SliceAccessPoint_differentState_shouldBeDifferent() {
+        final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTING);
+        final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED);
+
+        assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2)))
+                .isFalse();
+    }
+    @Test
+    public void SliceAccessPoint_differentLength_shouldBeDifferent() {
+        final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTED);
+        final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED);
+        final List<AccessPoint> list = new ArrayList<>();
+        list.add(ap1);
+        list.add(ap2);
+
+        assertThat(mWifiScanWorker.areListsTheSame(list, Arrays.asList(ap1))).isFalse();
     }
 
     @Implements(SliceBackgroundWorker.class)