198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler/*
298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * Copyright (C) 2016 The Android Open Source Project
398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler *
498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * you may not use this file except in compliance with the License.
698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * You may obtain a copy of the License at
798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler *
898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler *
1098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * Unless required by applicable law or agreed to in writing, software
1198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
1298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * See the License for the specific language governing permissions and
1498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler * limitations under the License
1598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler */
1698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerpackage com.android.settingslib.wifi;
1798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
1898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.content.Context;
1998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.content.pm.PackageManager;
202c096596b7042d6870fef38fc886285424653834Stephen Chenimport android.content.res.Resources;
212c096596b7042d6870fef38fc886285424653834Stephen Chenimport android.content.res.TypedArray;
2298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.graphics.drawable.Drawable;
2398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.graphics.drawable.StateListDrawable;
24ed8f5297a36ea7a21cd24a1f2b36b45031b8a50bStephen Chenimport android.net.NetworkBadging;
2598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.net.wifi.WifiConfiguration;
2698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.os.Looper;
2798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.os.UserHandle;
2860b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhangimport android.support.annotation.VisibleForTesting;
2998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.support.v7.preference.Preference;
3098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.support.v7.preference.PreferenceViewHolder;
3198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.text.TextUtils;
3298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.util.AttributeSet;
3398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.util.SparseArray;
342c096596b7042d6870fef38fc886285424653834Stephen Chenimport android.widget.ImageView;
3598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport android.widget.TextView;
36bf339f5cc5212aa3fb714a044496788308d53ac7Sundeep Ghuman
3798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerimport com.android.settingslib.R;
38bf339f5cc5212aa3fb714a044496788308d53ac7Sundeep Ghumanimport com.android.settingslib.TronUtils;
39f84e0573fc61ff36bc29b731574a11530c00538aSundeep Ghumanimport com.android.settingslib.Utils;
4098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
4198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantlerpublic class AccessPointPreference extends Preference {
4298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
4398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private static final int[] STATE_SECURED = {
4498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            R.attr.state_encrypted
4598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    };
4698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
47aed318ef076ed220ea9d9c26c52885c18f951c75Stephen Chen    private static final int[] STATE_METERED = {
48aed318ef076ed220ea9d9c26c52885c18f951c75Stephen Chen            R.attr.state_metered
49aed318ef076ed220ea9d9c26c52885c18f951c75Stephen Chen    };
50aed318ef076ed220ea9d9c26c52885c18f951c75Stephen Chen
5160b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang    private static final int[] FRICTION_ATTRS = {
5260b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            R.attr.wifi_friction
5360b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang    };
5460b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang
5560b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang    private static final int[] WIFI_CONNECTION_STRENGTH = {
5660b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            R.string.accessibility_no_wifi,
5760b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            R.string.accessibility_wifi_one_bar,
5860b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            R.string.accessibility_wifi_two_bars,
5960b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            R.string.accessibility_wifi_three_bars,
6060b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            R.string.accessibility_wifi_signal_full
6160b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang    };
6298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
632c096596b7042d6870fef38fc886285424653834Stephen Chen    private final StateListDrawable mFrictionSld;
6498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private final int mBadgePadding;
6598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private final UserBadgeCache mBadgeCache;
6698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private TextView mTitleView;
6745a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez
6898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private boolean mForSavedNetworks = false;
6998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private AccessPoint mAccessPoint;
7098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private Drawable mBadge;
7198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private int mLevel;
7298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private CharSequence mContentDescription;
7345a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez    private int mDefaultIconResId;
7455adc6b2fc524a79805e422bf0c772c2dd202838Sundeep Ghuman    private int mWifiSpeed = NetworkBadging.BADGING_NONE;
7598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
767c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman    public static String generatePreferenceKey(AccessPoint accessPoint) {
777c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman        StringBuilder builder = new StringBuilder();
787c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman
792b35b512e336a54e32b6a379f2429876b3d1f647Eric Schwarzenbach        if (TextUtils.isEmpty(accessPoint.getSsidStr())) {
807c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman            builder.append(accessPoint.getBssid());
812b35b512e336a54e32b6a379f2429876b3d1f647Eric Schwarzenbach        } else {
822b35b512e336a54e32b6a379f2429876b3d1f647Eric Schwarzenbach            builder.append(accessPoint.getSsidStr());
837c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman        }
847c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman
857c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman        builder.append(',').append(accessPoint.getSecurity());
867c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman        return builder.toString();
877c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman    }
887c32aa3039fd9eba3c09f7503ac451a0ba0b1d87Sundeep Ghuman
8998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    // Used for dummy pref.
9098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    public AccessPointPreference(Context context, AttributeSet attrs) {
9198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        super(context, attrs);
922c096596b7042d6870fef38fc886285424653834Stephen Chen        mFrictionSld = null;
9398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        mBadgePadding = 0;
9498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        mBadgeCache = null;
9598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
9698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
9798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    public AccessPointPreference(AccessPoint accessPoint, Context context, UserBadgeCache cache,
9898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            boolean forSavedNetworks) {
9998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        super(context);
1002c096596b7042d6870fef38fc886285424653834Stephen Chen        setWidgetLayoutResource(R.layout.access_point_friction_widget);
10198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        mBadgeCache = cache;
10298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        mAccessPoint = accessPoint;
10398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        mForSavedNetworks = forSavedNetworks;
10498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        mAccessPoint.setTag(this);
10598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        mLevel = -1;
10698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
1072c096596b7042d6870fef38fc886285424653834Stephen Chen        TypedArray frictionSld;
1082c096596b7042d6870fef38fc886285424653834Stephen Chen        try {
10960b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            frictionSld = context.getTheme().obtainStyledAttributes(FRICTION_ATTRS);
1102c096596b7042d6870fef38fc886285424653834Stephen Chen        } catch (Resources.NotFoundException e) {
1112c096596b7042d6870fef38fc886285424653834Stephen Chen            // Fallback for platforms that do not need friction icon resources.
1122c096596b7042d6870fef38fc886285424653834Stephen Chen            frictionSld = null;
1132c096596b7042d6870fef38fc886285424653834Stephen Chen        }
1142c096596b7042d6870fef38fc886285424653834Stephen Chen        mFrictionSld = frictionSld != null ? (StateListDrawable) frictionSld.getDrawable(0) : null;
1152c096596b7042d6870fef38fc886285424653834Stephen Chen
11698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        // Distance from the end of the title at which this AP's user badge should sit.
11798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        mBadgePadding = context.getResources()
11898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler                .getDimensionPixelSize(R.dimen.wifi_preference_badge_padding);
11998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        refresh();
12098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
12198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
12245a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez    public AccessPointPreference(AccessPoint accessPoint, Context context, UserBadgeCache cache,
12345a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez            int iconResId, boolean forSavedNetworks) {
12445a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        super(context);
1252c096596b7042d6870fef38fc886285424653834Stephen Chen        setWidgetLayoutResource(R.layout.access_point_friction_widget);
12645a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        mBadgeCache = cache;
12745a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        mAccessPoint = accessPoint;
12845a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        mForSavedNetworks = forSavedNetworks;
12945a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        mAccessPoint.setTag(this);
13045a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        mLevel = -1;
13145a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        mDefaultIconResId = iconResId;
13245a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez
1332c096596b7042d6870fef38fc886285424653834Stephen Chen        TypedArray frictionSld;
1342c096596b7042d6870fef38fc886285424653834Stephen Chen        try {
13560b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            frictionSld = context.getTheme().obtainStyledAttributes(FRICTION_ATTRS);
1362c096596b7042d6870fef38fc886285424653834Stephen Chen        } catch (Resources.NotFoundException e) {
1372c096596b7042d6870fef38fc886285424653834Stephen Chen            // Fallback for platforms that do not need friction icon resources.
1382c096596b7042d6870fef38fc886285424653834Stephen Chen            frictionSld = null;
1392c096596b7042d6870fef38fc886285424653834Stephen Chen        }
1402c096596b7042d6870fef38fc886285424653834Stephen Chen        mFrictionSld = frictionSld != null ? (StateListDrawable) frictionSld.getDrawable(0) : null;
1412c096596b7042d6870fef38fc886285424653834Stephen Chen
14245a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        // Distance from the end of the title at which this AP's user badge should sit.
14345a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        mBadgePadding = context.getResources()
14445a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez                .getDimensionPixelSize(R.dimen.wifi_preference_badge_padding);
14545a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez    }
14645a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez
14798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    public AccessPoint getAccessPoint() {
14898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        return mAccessPoint;
14998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
15098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
15198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    @Override
15298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    public void onBindViewHolder(final PreferenceViewHolder view) {
15398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        super.onBindViewHolder(view);
15498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        if (mAccessPoint == null) {
15598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            // Used for dummy pref.
15698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            return;
15798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
15898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        Drawable drawable = getIcon();
15998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        if (drawable != null) {
16098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            drawable.setLevel(mLevel);
16198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
16298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
16370efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang        mTitleView = (TextView) view.findViewById(android.R.id.title);
16498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        if (mTitleView != null) {
16598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            // Attach to the end of the title view
16698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            mTitleView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, mBadge, null);
16798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            mTitleView.setCompoundDrawablePadding(mBadgePadding);
16898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
16998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        view.itemView.setContentDescription(mContentDescription);
1702c096596b7042d6870fef38fc886285424653834Stephen Chen
1714d8781e6be372fdc7c077b450fc1446d9a7facaeSundeep Ghuman        ImageView frictionImageView = (ImageView) view.findViewById(R.id.friction_icon);
1724d8781e6be372fdc7c077b450fc1446d9a7facaeSundeep Ghuman        bindFrictionImage(frictionImageView);
17398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
17498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
17598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    protected void updateIcon(int level, Context context) {
17698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        if (level == -1) {
17745a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez            safeSetDefaultIcon();
178ed8f5297a36ea7a21cd24a1f2b36b45031b8a50bStephen Chen            return;
179ed8f5297a36ea7a21cd24a1f2b36b45031b8a50bStephen Chen        }
18053200edba1bee7fe6dc3f567fb92876780881ac2Sundeep Ghuman        TronUtils.logWifiSettingsSpeed(context, mWifiSpeed);
181271e5de583e78fea09c12984df77c927be0ad671Sundeep Ghuman
182271e5de583e78fea09c12984df77c927be0ad671Sundeep Ghuman        // TODO(b/62355275): Revert this to N code after deleting NetworkBadging API
183271e5de583e78fea09c12984df77c927be0ad671Sundeep Ghuman        Drawable drawable = NetworkBadging.getWifiIcon(
184271e5de583e78fea09c12984df77c927be0ad671Sundeep Ghuman                level, NetworkBadging.BADGING_NONE, getContext().getTheme());
185ed8f5297a36ea7a21cd24a1f2b36b45031b8a50bStephen Chen        if (!mForSavedNetworks && drawable != null) {
1866962c0cbb598873a4c291c1e3f4ed0da917a71e3Sundeep Ghuman            drawable.setTint(Utils.getColorAttr(context, android.R.attr.colorControlNormal));
187ed8f5297a36ea7a21cd24a1f2b36b45031b8a50bStephen Chen            setIcon(drawable);
18898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        } else {
189ed8f5297a36ea7a21cd24a1f2b36b45031b8a50bStephen Chen            safeSetDefaultIcon();
19098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
19198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
19298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
1932c096596b7042d6870fef38fc886285424653834Stephen Chen    /**
1942c096596b7042d6870fef38fc886285424653834Stephen Chen     * Binds the friction icon drawable using a StateListDrawable.
1952c096596b7042d6870fef38fc886285424653834Stephen Chen     *
1962c096596b7042d6870fef38fc886285424653834Stephen Chen     * <p>Friction icons will be rebound when notifyChange() is called, and therefore
1972c096596b7042d6870fef38fc886285424653834Stephen Chen     * do not need to be managed in refresh()</p>.
1982c096596b7042d6870fef38fc886285424653834Stephen Chen     */
1992c096596b7042d6870fef38fc886285424653834Stephen Chen    private void bindFrictionImage(ImageView frictionImageView) {
2002c096596b7042d6870fef38fc886285424653834Stephen Chen        if (frictionImageView == null || mFrictionSld == null) {
2012c096596b7042d6870fef38fc886285424653834Stephen Chen            return;
2022c096596b7042d6870fef38fc886285424653834Stephen Chen        }
2032c096596b7042d6870fef38fc886285424653834Stephen Chen        if (mAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
2044d8781e6be372fdc7c077b450fc1446d9a7facaeSundeep Ghuman            mFrictionSld.setState(STATE_SECURED);
20521f6868d8096ca2ff64cdb9fdc4457277d70bf07Stephen Chen        } else if (mAccessPoint.isMetered()) {
206aed318ef076ed220ea9d9c26c52885c18f951c75Stephen Chen            mFrictionSld.setState(STATE_METERED);
2072c096596b7042d6870fef38fc886285424653834Stephen Chen        }
2082c096596b7042d6870fef38fc886285424653834Stephen Chen        Drawable drawable = mFrictionSld.getCurrent();
2092c096596b7042d6870fef38fc886285424653834Stephen Chen        frictionImageView.setImageDrawable(drawable);
2102c096596b7042d6870fef38fc886285424653834Stephen Chen    }
2112c096596b7042d6870fef38fc886285424653834Stephen Chen
21245a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez    private void safeSetDefaultIcon() {
21345a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        if (mDefaultIconResId != 0) {
21445a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez            setIcon(mDefaultIconResId);
21545a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        } else {
21645a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez            setIcon(null);
21745a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez        }
21845a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez    }
21945a1594247eecf02d64f6b95b19a6843f298d0e7Salvador Martinez
22098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    protected void updateBadge(Context context) {
22198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        WifiConfiguration config = mAccessPoint.getConfig();
22298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        if (config != null) {
22398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            // Fetch badge (may be null)
22498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            // Get the badge using a cache since the PM will ask the UserManager for the list
22598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            // of profiles every time otherwise.
22698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            mBadge = mBadgeCache.getUserBadge(config.creatorUid);
22798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
22898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
22998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
23098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    /**
23198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler     * Updates the title and summary; may indirectly call notifyChanged().
23298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler     */
23398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    public void refresh() {
23470efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang        setTitle(this, mAccessPoint, mForSavedNetworks);
23598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        final Context context = getContext();
236aaa8a1b54a038424bd3e6590efe52c4fac14143bSundeep Ghuman        int level = mAccessPoint.getLevel();
23755adc6b2fc524a79805e422bf0c772c2dd202838Sundeep Ghuman        int wifiSpeed = mAccessPoint.getSpeed();
23855adc6b2fc524a79805e422bf0c772c2dd202838Sundeep Ghuman        if (level != mLevel || wifiSpeed != mWifiSpeed) {
23998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            mLevel = level;
24055adc6b2fc524a79805e422bf0c772c2dd202838Sundeep Ghuman            mWifiSpeed = wifiSpeed;
24198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            updateIcon(mLevel, context);
2428897a5044b6e2612c80fecb72de031027229c2a0Julia Reynolds            notifyChanged();
24398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
244f84e0573fc61ff36bc29b731574a11530c00538aSundeep Ghuman
24598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        updateBadge(context);
24698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
24798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        setSummary(mForSavedNetworks ? mAccessPoint.getSavedNetworkSummary()
24898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler                : mAccessPoint.getSettingsSummary());
24998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
25060b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        mContentDescription = buildContentDescription(getContext(), this /* pref */, mAccessPoint);
25198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
25298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
25398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    @Override
25498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    protected void notifyChanged() {
25598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        if (Looper.getMainLooper() != Looper.myLooper()) {
25698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            // Let our BG thread callbacks call setTitle/setSummary.
25798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            postNotifyChanged();
25898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        } else {
25998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            super.notifyChanged();
26098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
26198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
26298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
26370efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang    @VisibleForTesting
26470efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang    static void setTitle(AccessPointPreference preference, AccessPoint ap, boolean savedNetworks) {
26570efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang        if (savedNetworks) {
26670efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang            preference.setTitle(ap.getConfigName());
26770efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang        } else {
26870efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang            preference.setTitle(ap.getSsidStr());
26970efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang        }
27070efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang    }
27170efb670c8d9a09d87b465bbb1e10a1af2be3b16Fan Zhang
27260b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang    /**
27360b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang     * Helper method to generate content description string.
27460b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang     */
27560b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang    @VisibleForTesting
27660b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang    static CharSequence buildContentDescription(Context context, Preference pref, AccessPoint ap) {
27760b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        CharSequence contentDescription = pref.getTitle();
27860b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        final CharSequence summary = pref.getSummary();
27960b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        if (!TextUtils.isEmpty(summary)) {
28060b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            contentDescription = TextUtils.concat(contentDescription, ",", summary);
28160b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        }
28260b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        int level = ap.getLevel();
28360b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        if (level >= 0 && level < WIFI_CONNECTION_STRENGTH.length) {
28460b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang            contentDescription = TextUtils.concat(contentDescription, ",",
28560b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang                    context.getString(WIFI_CONNECTION_STRENGTH[level]));
28660b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        }
28760b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang        return TextUtils.concat(contentDescription, ",",
28860b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang                ap.getSecurity() == AccessPoint.SECURITY_NONE
28960b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang                        ? context.getString(R.string.accessibility_wifi_security_type_none)
29060b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang                        : context.getString(R.string.accessibility_wifi_security_type_secured));
29160b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang    }
29260b850de5e02d8b525f2f8068b5a3325a974b887Fan Zhang
29398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    public void onLevelChanged() {
29498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        postNotifyChanged();
29598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
29698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
29798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private void postNotifyChanged() {
29898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        if (mTitleView != null) {
29998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            mTitleView.post(mNotifyChanged);
30098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        } // Otherwise we haven't been bound yet, and don't need to update.
30198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
30298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
30398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    private final Runnable mNotifyChanged = new Runnable() {
30498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        @Override
30598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        public void run() {
30698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            notifyChanged();
30798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
30898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    };
30998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
31098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    public static class UserBadgeCache {
31198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        private final SparseArray<Drawable> mBadges = new SparseArray<>();
31298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        private final PackageManager mPm;
31398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
31498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        public UserBadgeCache(PackageManager pm) {
31598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            mPm = pm;
31698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
31798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler
31898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        private Drawable getUserBadge(int userId) {
31998608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            int index = mBadges.indexOfKey(userId);
32098608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            if (index < 0) {
32198608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler                Drawable badge = mPm.getUserBadgeForDensity(new UserHandle(userId), 0 /* dpi */);
32298608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler                mBadges.put(userId, badge);
32398608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler                return badge;
32498608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            }
32598608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler            return mBadges.valueAt(index);
32698608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler        }
32798608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler    }
32898608e43ebec9999a5e20d9c36b6bbb387cf56fcTony Mantler}
329