OSDN Git Service

Reduce jank in wifi settings
authorJason Monk <jmonk@google.com>
Mon, 29 Jun 2015 17:28:21 +0000 (13:28 -0400)
committerJason Monk <jmonk@google.com>
Mon, 29 Jun 2015 17:47:14 +0000 (13:47 -0400)
 - Fix view recycling for AccessPointPreferences by adding a dummy
   during initial inflation
 - Cut down on what is done during onBindView and refresh()
 - Try to re-use AccessPointPreferences when possible

Some jank still occurs when scan results come in, but it is less
than before.

Bug: 16518752
Change-Id: I2619303281dd50aa3864783c49738ae9f221834a

res/xml/wifi_settings.xml
src/com/android/settings/wifi/AccessPointPreference.java
src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
src/com/android/settings/wifi/WifiSettings.java

index fdde20f..99a0c4e 100644 (file)
@@ -19,4 +19,9 @@
         android:title="@string/wifi_settings"
         settings:keywords="@string/keywords_wifi">
 
+    <!-- Needed so PreferenceGroupAdapter allows AccessPointPreference to be
+         recycled. Removed in onResume -->
+    <com.android.settings.wifi.AccessPointPreference
+        android:key="dummy" />
+
 </PreferenceScreen>
index 346561a..b9612a3 100644 (file)
 package com.android.settings.wifi;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
 import android.net.wifi.WifiConfiguration;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.preference.Preference;
+import android.util.AttributeSet;
+import android.util.SparseArray;
 import android.view.View;
 import android.widget.TextView;
 
@@ -37,22 +40,39 @@ public class AccessPointPreference extends Preference {
 
     private static int[] wifi_signal_attributes = { R.attr.wifi_signal };
 
+    private final StateListDrawable mWifiSld;
+    private final int mBadgePadding;
+    private final UserBadgeCache mBadgeCache;
+
     private TextView mTitleView;
-    private TextView mSummaryView;
-    private boolean mShowSummary = true;
     private boolean mForSavedNetworks = false;
     private AccessPoint mAccessPoint;
     private Drawable mBadge;
-    private int mBadgePadding;
     private int mLevel;
 
-    public AccessPointPreference(AccessPoint accessPoint, Context context,
+    // Used for dummy pref.
+    public AccessPointPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mWifiSld = null;
+        mBadgePadding = 0;
+        mBadgeCache = null;
+    }
+
+    public AccessPointPreference(AccessPoint accessPoint, Context context, UserBadgeCache cache,
                                  boolean forSavedNetworks) {
         super(context);
+        mBadgeCache = cache;
         mAccessPoint = accessPoint;
         mForSavedNetworks = forSavedNetworks;
         mAccessPoint.setTag(this);
         mLevel = -1;
+
+        mWifiSld = (StateListDrawable) context.getTheme()
+                .obtainStyledAttributes(wifi_signal_attributes).getDrawable(0);
+
+        // Distance from the end of the title at which this AP's user badge should sit.
+        mBadgePadding = context.getResources()
+                .getDimensionPixelSize(R.dimen.wifi_preference_badge_padding);
         refresh();
     }
 
@@ -63,6 +83,10 @@ public class AccessPointPreference extends Preference {
     @Override
     protected void onBindView(View view) {
         super.onBindView(view);
+        if (mAccessPoint == null) {
+            // Used for dummy pref.
+            return;
+        }
         Drawable drawable = getIcon();
         if (drawable != null) {
             drawable.setLevel(mLevel);
@@ -74,11 +98,6 @@ public class AccessPointPreference extends Preference {
             mTitleView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, mBadge, null);
             mTitleView.setCompoundDrawablePadding(mBadgePadding);
         }
-
-        mSummaryView = (TextView) view.findViewById(com.android.internal.R.id.summary);
-        mSummaryView.setVisibility(mShowSummary ? View.VISIBLE : View.GONE);
-
-        updateBadge(getContext());
     }
 
     protected void updateIcon(int level, Context context) {
@@ -88,15 +107,13 @@ public class AccessPointPreference extends Preference {
             if (getIcon() == null) {
                 // To avoid a drawing race condition, we first set the state (SECURE/NONE) and then
                 // set the icon (drawable) to that state's drawable.
-                StateListDrawable sld = (StateListDrawable) context.getTheme()
-                        .obtainStyledAttributes(wifi_signal_attributes).getDrawable(0);
                 // If sld is null then we are indexing and therefore do not have access to
                 // (nor need to display) the drawable.
-                if (sld != null) {
-                    sld.setState((mAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE)
+                if (mWifiSld != null) {
+                    mWifiSld.setState((mAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE)
                             ? STATE_SECURED
                             : STATE_NONE);
-                    Drawable drawable = sld.getCurrent();
+                    Drawable drawable = mWifiSld.getCurrent();
                     if (!mForSavedNetworks) {
                         setIcon(drawable);
                     } else {
@@ -111,12 +128,9 @@ public class AccessPointPreference extends Preference {
         WifiConfiguration config = mAccessPoint.getConfig();
         if (config != null) {
             // Fetch badge (may be null)
-            UserHandle creatorUser = new UserHandle(UserHandle.getUserId(config.creatorUid));
-            mBadge = context.getPackageManager().getUserBadgeForDensity(creatorUser, 0 /* dpi */);
-
-            // Distance from the end of the title at which this AP's user badge should sit.
-            mBadgePadding = context.getResources()
-                    .getDimensionPixelSize(R.dimen.wifi_preference_badge_padding);
+            // Get the badge using a cache since the PM will ask the UserManager for the list
+            // of profiles every time otherwise.
+            mBadge = mBadgeCache.getUserBadge(config.creatorUid);
         }
     }
 
@@ -139,20 +153,8 @@ public class AccessPointPreference extends Preference {
         }
         updateBadge(context);
 
-        // Force new summary
-        setSummary(null);
-
-        String summary = mForSavedNetworks ? mAccessPoint.getSavedNetworkSummary()
-                : mAccessPoint.getSettingsSummary();
-
-        boolean showSummary = summary.length() > 0;
-        if (showSummary) {
-            setSummary(summary);
-        }
-        if (showSummary != mShowSummary) {
-            mShowSummary = showSummary;
-            notifyChanged();
-        }
+        setSummary(mForSavedNetworks ? mAccessPoint.getSavedNetworkSummary()
+                : mAccessPoint.getSettingsSummary());
     }
 
     @Override
@@ -181,4 +183,23 @@ public class AccessPointPreference extends Preference {
             notifyChanged();
         }
     };
+
+    public static class UserBadgeCache {
+        private final SparseArray<Drawable> mBadges = new SparseArray<>();
+        private final PackageManager mPm;
+
+        UserBadgeCache(PackageManager pm) {
+            mPm = pm;
+        }
+
+        private Drawable getUserBadge(int userId) {
+            int index = mBadges.indexOfKey(userId);
+            if (index < 0) {
+                Drawable badge = mPm.getUserBadgeForDensity(new UserHandle(userId), 0 /* dpi */);
+                mBadges.put(userId, badge);
+                return badge;
+            }
+            return mBadges.valueAt(index);
+        }
+    }
 }
index 9a88ee8..72abe1e 100644 (file)
 
 package com.android.settings.wifi;
 
-import android.app.AppGlobals;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
 import android.content.res.Resources;
-import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.UserHandle;
 import android.preference.Preference;
 import android.preference.PreferenceScreen;
 import android.util.Log;
@@ -39,12 +32,13 @@ import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
+import com.android.settings.wifi.AccessPointPreference.UserBadgeCache;
 import com.android.settingslib.wifi.AccessPoint;
 import com.android.settingslib.wifi.WifiTracker;
-import java.util.Collections;
-import java.util.Comparator;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 
 /**
@@ -60,6 +54,8 @@ public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment
     private Bundle mAccessPointSavedState;
     private AccessPoint mSelectedAccessPoint;
 
+    private UserBadgeCache mUserBadgeCache;
+
     // Instance state key
     private static final String SAVE_DIALOG_ACCESS_POINT_STATE = "wifi_ap_state";
 
@@ -72,6 +68,7 @@ public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.wifi_display_saved_access_points);
+        mUserBadgeCache = new UserBadgeCache(getPackageManager());
     }
 
     @Override
@@ -113,7 +110,7 @@ public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment
         final int accessPointsSize = accessPoints.size();
         for (int i = 0; i < accessPointsSize; ++i){
             AccessPointPreference preference = new AccessPointPreference(accessPoints.get(i),
-                    context, true);
+                    context, mUserBadgeCache, true);
             preference.setIcon(null);
             preferenceScreen.addPreference(preference);
         }
index 56d1b97..c32df9d 100644 (file)
@@ -78,6 +78,7 @@ import com.android.settings.location.ScanningSettings;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
+import com.android.settings.wifi.AccessPointPreference.UserBadgeCache;
 import com.android.settingslib.wifi.AccessPoint;
 import com.android.settingslib.wifi.AccessPoint.AccessPointListener;
 import com.android.settingslib.wifi.WifiTracker;
@@ -159,6 +160,8 @@ public class WifiSettings extends RestrictedSettingsFragment
 
     private HandlerThread mBgThread;
 
+    private UserBadgeCache mUserBadgeCache;
+
     /* End of "used in Wifi Setup context" */
 
     public WifiSettings() {
@@ -177,6 +180,9 @@ public class WifiSettings extends RestrictedSettingsFragment
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
+        addPreferencesFromResource(R.xml.wifi_settings);
+        mUserBadgeCache = new UserBadgeCache(getPackageManager());
+
         mBgThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
         mBgThread.start();
     }
@@ -270,8 +276,6 @@ public class WifiSettings extends RestrictedSettingsFragment
             }
         }
 
-        addPreferencesFromResource(R.xml.wifi_settings);
-
         mEmptyView = initEmptyView();
         registerForContextMenu(getListView());
         setHasOptionsMenu(true);
@@ -311,6 +315,7 @@ public class WifiSettings extends RestrictedSettingsFragment
     public void onResume() {
         final Activity activity = getActivity();
         super.onResume();
+        removePreference("dummy");
         if (mWifiEnabler != null) {
             mWifiEnabler.resume(activity);
         }
@@ -652,8 +657,12 @@ public class WifiSettings extends RestrictedSettingsFragment
                     // Ignore access points that are out of range.
                     if (accessPoint.getLevel() != -1) {
                         hasAvailableAccessPoints = true;
+                        if (accessPoint.getTag() != null) {
+                            getPreferenceScreen().addPreference((Preference) accessPoint.getTag());
+                            continue;
+                        }
                         AccessPointPreference preference = new AccessPointPreference(accessPoint,
-                                getActivity(), false);
+                                getActivity(), mUserBadgeCache, false);
 
                         if (mOpenSsid != null && mOpenSsid.equals(accessPoint.getSsidStr())
                                 && !accessPoint.isSaved()