From 55dd8869db9c2a66423fcbb83cb5f5db38f8fb5f Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Mon, 29 Jun 2015 13:28:21 -0400 Subject: [PATCH] Reduce jank in wifi settings - 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 | 5 ++ .../settings/wifi/AccessPointPreference.java | 89 +++++++++++++--------- .../wifi/SavedAccessPointsWifiSettings.java | 17 ++--- src/com/android/settings/wifi/WifiSettings.java | 15 +++- 4 files changed, 79 insertions(+), 47 deletions(-) diff --git a/res/xml/wifi_settings.xml b/res/xml/wifi_settings.xml index fdde20ff2b..99a0c4efa0 100644 --- a/res/xml/wifi_settings.xml +++ b/res/xml/wifi_settings.xml @@ -19,4 +19,9 @@ android:title="@string/wifi_settings" settings:keywords="@string/keywords_wifi"> + + + diff --git a/src/com/android/settings/wifi/AccessPointPreference.java b/src/com/android/settings/wifi/AccessPointPreference.java index 346561a774..b9612a36ee 100644 --- a/src/com/android/settings/wifi/AccessPointPreference.java +++ b/src/com/android/settings/wifi/AccessPointPreference.java @@ -16,12 +16,15 @@ 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 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); + } + } } diff --git a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java index 9a88ee8e32..72abe1e2b6 100644 --- a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java +++ b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java @@ -16,19 +16,12 @@ 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); } diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 56d1b97d3f..c32df9deb1 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -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() -- 2.11.0