OSDN Git Service

Merge "Fix the bug of "Connecting" is rarely appearing on Wi-Fi slice"
[android-x86/packages-apps-Settings.git] / src / com / android / settings / wifi / slice / WifiSlice.java
index b4b94e1..1c44204 100644 (file)
@@ -26,12 +26,22 @@ import android.app.PendingIntent;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+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;
 import android.net.wifi.WifiSsid;
 import android.os.Bundle;
+import android.text.Spannable;
+import android.text.SpannableString;
 import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.core.graphics.drawable.IconCompat;
@@ -79,13 +89,15 @@ public class WifiSlice implements CustomSliceable {
 
     @Override
     public Slice getSlice() {
+        // Reload theme for switching dark mode on/off
+        mContext.getTheme().applyStyle(R.style.Theme_Settings_Home, true /* force */);
+
         final boolean isWifiEnabled = isWifiEnabled();
 
         final IconCompat icon = IconCompat.createWithResource(mContext,
                 R.drawable.ic_settings_wireless);
         final String title = mContext.getString(R.string.wifi_settings);
         final CharSequence summary = getSummary();
-        @ColorInt final int color = getSliceAccentColor();
         final PendingIntent toggleAction = getBroadcastIntent(mContext);
         final PendingIntent primaryAction = getPrimaryAction();
         final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon,
@@ -94,7 +106,7 @@ public class WifiSlice implements CustomSliceable {
                 null /* actionTitle */, isWifiEnabled);
 
         final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
-                .setAccentColor(color)
+                .setAccentColor(COLOR_NOT_TINTED)
                 .addRow(new ListBuilder.RowBuilder()
                         .setTitle(title)
                         .setSubtitle(summary)
@@ -107,10 +119,19 @@ public class WifiSlice implements CustomSliceable {
 
         final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(getUri());
         final List<AccessPoint> results = worker != null ? worker.getResults() : null;
-
-        // Need a loading text when results are not ready.
-        boolean needLoadingRow = results == null;
-        final int apCount = needLoadingRow ? 0 : results.size();
+        final int apCount = results == null ? 0 : results.size();
+
+        // Need a loading text when results are not ready or out of date.
+        boolean needLoadingRow = true;
+        int index = apCount > 0 && results.get(0).isActive() ? 1 : 0;
+        // This loop checks the existence of reachable APs to determine the validity of the current
+        // AP list.
+        for (; index < apCount; index++) {
+            if (results.get(index).isReachable()) {
+                needLoadingRow = false;
+                break;
+            }
+        }
 
         // Add AP rows
         final CharSequence placeholder = mContext.getText(R.string.summary_placeholder);
@@ -118,8 +139,7 @@ public class WifiSlice implements CustomSliceable {
             if (i < apCount) {
                 listBuilder.addRow(getAccessPointRow(results.get(i)));
             } else if (needLoadingRow) {
-                listBuilder.addRow(new ListBuilder.RowBuilder()
-                        .setTitle(mContext.getText(R.string.wifi_empty_list_wifi_on)));
+                listBuilder.addRow(getLoadingRow());
                 needLoadingRow = false;
             } else {
                 listBuilder.addRow(new ListBuilder.RowBuilder()
@@ -130,11 +150,11 @@ public class WifiSlice implements CustomSliceable {
     }
 
     private ListBuilder.RowBuilder getAccessPointRow(AccessPoint accessPoint) {
-        final CharSequence title = accessPoint.getConfigName();
+        final CharSequence title = getAccessPointName(accessPoint);
         final IconCompat levelIcon = getAccessPointLevelIcon(accessPoint);
         final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder()
                 .setTitleItem(levelIcon, ListBuilder.ICON_IMAGE)
-                .setTitle(title)
+                .setSubtitle(title)
                 .setPrimaryAction(SliceAction.create(
                         getAccessPointAction(accessPoint), levelIcon, ListBuilder.ICON_IMAGE,
                         title));
@@ -146,19 +166,40 @@ public class WifiSlice implements CustomSliceable {
         return rowBuilder;
     }
 
-    protected IconCompat getAccessPointLevelIcon(AccessPoint accessPoint) {
-        return IconCompat.createWithResource(mContext,
-                com.android.settingslib.Utils.getWifiIconResource(accessPoint.getLevel()));
+    private CharSequence getAccessPointName(AccessPoint accessPoint) {
+        final CharSequence name = accessPoint.getConfigName();
+        final Spannable span = new SpannableString(name);
+        @ColorInt final int color = Utils.getColorAttrDefaultColor(mContext,
+                android.R.attr.textColorPrimary);
+        span.setSpan(new ForegroundColorSpan(color), 0, name.length(),
+                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        return span;
     }
 
-    @ColorInt
-    protected int getSliceAccentColor() {
-        return Utils.getColorAccentDefaultColor(mContext);
+    private IconCompat getAccessPointLevelIcon(AccessPoint accessPoint) {
+        final Drawable d = mContext.getDrawable(
+                com.android.settingslib.Utils.getWifiIconResource(accessPoint.getLevel()));
+
+        @ColorInt int color;
+        if (accessPoint.isActive()) {
+            final NetworkInfo.State state = accessPoint.getNetworkInfo().getState();
+            if (state == NetworkInfo.State.CONNECTED) {
+                color = Utils.getColorAccentDefaultColor(mContext);
+            } else { // connecting
+                color = Utils.getDisabled(mContext, Utils.getColorAttrDefaultColor(mContext,
+                        android.R.attr.colorControlNormal));
+            }
+        } else {
+            color = Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorControlNormal);
+        }
+
+        d.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
+        return Utils.createIconWithDrawable(d);
     }
 
     private IconCompat getEndIcon(AccessPoint accessPoint) {
         if (accessPoint.isActive()) {
-            return IconCompat.createWithResource(mContext, R.drawable.ic_settings_accent);
+            return null;
         } else if (accessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
             return IconCompat.createWithResource(mContext, R.drawable.ic_friction_lock_closed);
         } else if (accessPoint.isMetered()) {
@@ -190,6 +231,18 @@ public class WifiSlice implements CustomSliceable {
                 intent, 0 /* flags */);
     }
 
+    private ListBuilder.RowBuilder getLoadingRow() {
+        final CharSequence title = mContext.getText(R.string.wifi_empty_list_wifi_on);
+
+        // for aligning to the Wi-Fi AP's name
+        final IconCompat emptyIcon = Utils.createIconWithDrawable(
+                new ColorDrawable(Color.TRANSPARENT));
+
+        return new ListBuilder.RowBuilder()
+                .setTitleItem(emptyIcon, ListBuilder.ICON_IMAGE)
+                .setSubtitle(title);
+    }
+
     /**
      * Update the current wifi status to the boolean value keyed by
      * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
@@ -303,7 +356,6 @@ public class WifiSlice implements CustomSliceable {
 
         @Override
         public void onConnectedChanged() {
-            notifySliceChange();
         }
 
         @Override
@@ -318,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;
+        }
     }
 }