12e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson/*
22e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * Copyright (C) 2011 The Android Open Source Project
32e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson *
42e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * Licensed under the Apache License, Version 2.0 (the "License");
52e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * you may not use this file except in compliance with the License.
62e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * You may obtain a copy of the License at
72e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson *
82e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson *      http://www.apache.org/licenses/LICENSE-2.0
92e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson *
102e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * Unless required by applicable law or agreed to in writing, software
112e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * distributed under the License is distributed on an "AS IS" BASIS,
122e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * See the License for the specific language governing permissions and
142e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson * limitations under the License.
152e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson */
162e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
172e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonpackage com.android.systemui.statusbar;
182e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
192e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.content.Context;
20dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggiimport android.content.res.ColorStateList;
21dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggiimport android.graphics.Color;
22dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggiimport android.graphics.PorterDuff;
23a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynnimport android.graphics.drawable.Animatable;
24a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynnimport android.graphics.drawable.Drawable;
25b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport android.telephony.SubscriptionInfo;
265e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monkimport android.util.ArraySet;
272e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.util.AttributeSet;
28cd686b5b6d4166b510df8e32138479a9559bc117John Spurlockimport android.util.Log;
29b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport android.view.LayoutInflater;
302e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.view.View;
312e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.view.ViewGroup;
322f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlockimport android.view.accessibility.AccessibilityEvent;
332e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.widget.ImageView;
342e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.widget.LinearLayout;
352e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
362e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport com.android.systemui.R;
373b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monkimport com.android.systemui.statusbar.phone.StatusBarIconController;
3807b75fe65dcb5b8add8246654c65f95f1191933eJason Monkimport com.android.systemui.statusbar.policy.NetworkController.IconState;
39af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.NetworkControllerImpl;
403128f12f216ef481b5d03892b35706cfeec26d7cJason Monkimport com.android.systemui.statusbar.policy.SecurityController;
415e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monkimport com.android.systemui.tuner.TunerService;
425e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monkimport com.android.systemui.tuner.TunerService.Tunable;
432e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
44b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport java.util.ArrayList;
45b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport java.util.List;
46b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
475ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler// Intimately tied to the design of res/layout/signal_cluster_view.xml
482e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonpublic class SignalClusterView
492f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock        extends LinearLayout
5007b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        implements NetworkControllerImpl.SignalCallback,
515e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk        SecurityController.SecurityControllerCallback, Tunable {
522e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
5328f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    static final String TAG = "SignalClusterView";
54b3eb89190c4bb4ebbe676328cd37830d50e6ed3eJohn Spurlock    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
552f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock
563b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    private static final String SLOT_AIRPLANE = "airplane";
573b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    private static final String SLOT_MOBILE = "mobile";
583b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    private static final String SLOT_WIFI = "wifi";
593b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    private static final String SLOT_ETHERNET = "ethernet";
603b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk
61af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock    NetworkControllerImpl mNC;
623128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    SecurityController mSC;
632e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
64b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private boolean mNoSimsVisible = false;
653128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    private boolean mVpnVisible = false;
66d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti    private boolean mEthernetVisible = false;
67d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti    private int mEthernetIconId = 0;
6806302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi    private int mLastEthernetIconId = -1;
6928f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    private boolean mWifiVisible = false;
70fcc901c10bffdfb9c6b31e676dec36b47d949979John Spurlock    private int mWifiStrengthId = 0;
7106302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi    private int mLastWifiStrengthId = -1;
725ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler    private boolean mIsAirplaneMode = false;
73061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn    private int mAirplaneIconId = 0;
7406302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi    private int mLastAirplaneIconId = -1;
7507b75fe65dcb5b8add8246654c65f95f1191933eJason Monk    private String mAirplaneContentDescription;
76b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private String mWifiDescription;
77d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti    private String mEthernetDescription;
78b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private ArrayList<PhoneState> mPhoneStates = new ArrayList<PhoneState>();
79dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    private int mIconTint = Color.WHITE;
805443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi    private float mDarkIntensity;
8128f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
82d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti    ViewGroup mEthernetGroup, mWifiGroup;
831b5eb97ae651cd1e70009d3f9bbe91da804a457aAdrian Roos    View mNoSimsCombo;
84d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti    ImageView mVpn, mEthernet, mWifi, mAirplane, mNoSims, mEthernetDark, mWifiDark, mNoSimsDark;
855172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi    View mWifiAirplaneSpacer;
86c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    View mWifiSignalSpacer;
87b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    LinearLayout mMobileSignalGroup;
88c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi
89c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    private int mWideTypeIconStartPadding;
90b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private int mSecondaryTelephonyPadding;
916d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi    private int mEndPadding;
926d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi    private int mEndPaddingNothingVisible;
932e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
943b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    private boolean mBlockAirplane;
953b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    private boolean mBlockMobile;
963b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    private boolean mBlockWifi;
973b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    private boolean mBlockEthernet;
983b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk
992e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    public SignalClusterView(Context context) {
1002e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        this(context, null);
1012e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
1022e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
1032e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    public SignalClusterView(Context context, AttributeSet attrs) {
1042e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        this(context, attrs, 0);
1052e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
1062e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
1072e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    public SignalClusterView(Context context, AttributeSet attrs, int defStyle) {
1082e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        super(context, attrs, defStyle);
1093b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk    }
1103b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk
1115e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk    @Override
1125e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk    public void onTuningChanged(String key, String newValue) {
1135e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk        if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
1145e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk            return;
1155e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk        }
1165e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk        ArraySet<String> blockList = StatusBarIconController.getIconBlacklist(newValue);
117f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk        boolean blockAirplane = blockList.contains(SLOT_AIRPLANE);
118f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk        boolean blockMobile = blockList.contains(SLOT_MOBILE);
119f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk        boolean blockWifi = blockList.contains(SLOT_WIFI);
120f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk        boolean blockEthernet = blockList.contains(SLOT_ETHERNET);
121f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk
122f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk        if (blockAirplane != mBlockAirplane || blockMobile != mBlockMobile
123f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk                || blockEthernet != mBlockEthernet || blockWifi != mBlockWifi) {
124f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk            mBlockAirplane = blockAirplane;
125f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk            mBlockMobile = blockMobile;
126f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk            mBlockEthernet = blockEthernet;
127f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk            mBlockWifi = blockWifi;
128f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk            // Re-register to get new callbacks.
129f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk            mNC.removeSignalCallback(this);
130f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk            mNC.addSignalCallback(this);
131f3d1715cc9fdd61ff23d551cd7c0aa6e87651ac2Jason Monk        }
1322e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
1332e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
134af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock    public void setNetworkController(NetworkControllerImpl nc) {
135cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock        if (DEBUG) Log.d(TAG, "NetworkController=" + nc);
1362e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        mNC = nc;
1372e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
1382e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
1393128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    public void setSecurityController(SecurityController sc) {
1403128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        if (DEBUG) Log.d(TAG, "SecurityController=" + sc);
1413128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mSC = sc;
1423128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mSC.addCallback(this);
1433128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mVpnVisible = mSC.isVpnEnabled();
1443128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    }
1453128f12f216ef481b5d03892b35706cfeec26d7cJason Monk
1462e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    @Override
147c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    protected void onFinishInflate() {
148c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        super.onFinishInflate();
149c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        mWideTypeIconStartPadding = getContext().getResources().getDimensionPixelSize(
150c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi                R.dimen.wide_type_icon_start_padding);
151b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mSecondaryTelephonyPadding = getContext().getResources().getDimensionPixelSize(
152b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                R.dimen.secondary_telephony_padding);
1536d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi        mEndPadding = getContext().getResources().getDimensionPixelSize(
1546d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi                R.dimen.signal_cluster_battery_padding);
1556d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi        mEndPaddingNothingVisible = getContext().getResources().getDimensionPixelSize(
1566d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi                R.dimen.no_signal_cluster_battery_padding);
157c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    }
158c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi
159c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    @Override
1602e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    protected void onAttachedToWindow() {
1612e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        super.onAttachedToWindow();
1622e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
1633128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mVpn            = (ImageView) findViewById(R.id.vpn);
164d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        mEthernetGroup  = (ViewGroup) findViewById(R.id.ethernet_combo);
165d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        mEthernet       = (ImageView) findViewById(R.id.ethernet);
166d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        mEthernetDark   = (ImageView) findViewById(R.id.ethernet_dark);
1672e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        mWifiGroup      = (ViewGroup) findViewById(R.id.wifi_combo);
1682e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        mWifi           = (ImageView) findViewById(R.id.wifi_signal);
1695443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        mWifiDark       = (ImageView) findViewById(R.id.wifi_signal_dark);
170061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        mAirplane       = (ImageView) findViewById(R.id.airplane);
171b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mNoSims         = (ImageView) findViewById(R.id.no_sims);
1725443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        mNoSimsDark     = (ImageView) findViewById(R.id.no_sims_dark);
1731b5eb97ae651cd1e70009d3f9bbe91da804a457aAdrian Roos        mNoSimsCombo    =             findViewById(R.id.no_sims_combo);
1745172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi        mWifiAirplaneSpacer =         findViewById(R.id.wifi_airplane_spacer);
175c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        mWifiSignalSpacer =           findViewById(R.id.wifi_signal_spacer);
176b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mMobileSignalGroup = (LinearLayout) findViewById(R.id.mobile_signal_group);
177b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
178b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileSignalGroup.addView(state.mMobileGroup);
179b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
1805e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk        TunerService.get(mContext).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
18128f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
18228f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        apply();
183dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        applyIconTint();
1842e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
1852e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
1862e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    @Override
1872e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    protected void onDetachedFromWindow() {
1883128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mVpn            = null;
189d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        mEthernetGroup  = null;
190d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        mEthernet       = null;
19128f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        mWifiGroup      = null;
19228f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        mWifi           = null;
193061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        mAirplane       = null;
194b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mMobileSignalGroup.removeAllViews();
195b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mMobileSignalGroup = null;
1965e745172d93fcd4a90e0c8b216941a10a9994de8Jason Monk        TunerService.get(mContext).removeTunable(this);
19728f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
1982e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        super.onDetachedFromWindow();
1992e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
2002e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
2013128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    // From SecurityController.
2023128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    @Override
2033128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    public void onStateChanged() {
2043128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        post(new Runnable() {
2053128f12f216ef481b5d03892b35706cfeec26d7cJason Monk            @Override
2063128f12f216ef481b5d03892b35706cfeec26d7cJason Monk            public void run() {
2073128f12f216ef481b5d03892b35706cfeec26d7cJason Monk                mVpnVisible = mSC.isVpnEnabled();
2083128f12f216ef481b5d03892b35706cfeec26d7cJason Monk                apply();
2093128f12f216ef481b5d03892b35706cfeec26d7cJason Monk            }
2103128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        });
2113128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    }
2123128f12f216ef481b5d03892b35706cfeec26d7cJason Monk
213061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn    @Override
21407b75fe65dcb5b8add8246654c65f95f1191933eJason Monk    public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
21507b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            boolean activityIn, boolean activityOut, String description) {
2163b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk        mWifiVisible = statusIcon.visible && !mBlockWifi;
21707b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        mWifiStrengthId = statusIcon.icon;
21807b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        mWifiDescription = statusIcon.contentDescription;
21928f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
22028f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        apply();
22128f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    }
22228f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
223061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn    @Override
2242fdbe128209f02725c645f29bff941efe865da56Andrew Flynn    public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
2252fdbe128209f02725c645f29bff941efe865da56Andrew Flynn            int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
2262fdbe128209f02725c645f29bff941efe865da56Andrew Flynn            String description, boolean isWide, int subId) {
2278fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk        PhoneState state = getState(subId);
2288fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk        if (state == null) {
2298fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk            return;
2308fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk        }
2313b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk        state.mMobileVisible = statusIcon.visible && !mBlockMobile;
23207b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        state.mMobileStrengthId = statusIcon.icon;
23307b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        state.mMobileTypeId = statusType;
23407b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        state.mMobileDescription = statusIcon.contentDescription;
235b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        state.mMobileTypeDescription = typeContentDescription;
23607b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        state.mIsMobileTypeIconWide = statusType != 0 && isWide;
23728f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
23828f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        apply();
23928f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    }
24028f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
241061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn    @Override
24207b75fe65dcb5b8add8246654c65f95f1191933eJason Monk    public void setEthernetIndicators(IconState state) {
2433b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk        mEthernetVisible = state.visible && !mBlockEthernet;
24407b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        mEthernetIconId = state.icon;
24507b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        mEthernetDescription = state.contentDescription;
246d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti
247d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        apply();
248d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti    }
249d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti
250d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti    @Override
251b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    public void setNoSims(boolean show) {
2523b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk        mNoSimsVisible = show && !mBlockMobile;
25364f4f9887ad1e27b05c2fabdb229ef2adf50805bJason Monk        apply();
254b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
255b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
256b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    @Override
257b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    public void setSubs(List<SubscriptionInfo> subs) {
258f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk        if (hasCorrectSubs(subs)) {
259f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk            return;
260f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk        }
261b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        // Clear out all old subIds.
262b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mPhoneStates.clear();
263b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        if (mMobileSignalGroup != null) {
264b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileSignalGroup.removeAllViews();
265b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
266b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        final int n = subs.size();
267b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (int i = 0; i < n; i++) {
268b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            inflatePhoneState(subs.get(i).getSubscriptionId());
269b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
270dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        if (isAttachedToWindow()) {
271dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi            applyIconTint();
272dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        }
273b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
274b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
275f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk    private boolean hasCorrectSubs(List<SubscriptionInfo> subs) {
276f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk        final int N = subs.size();
277f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk        if (N != mPhoneStates.size()) {
278f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk            return false;
279f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk        }
280f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk        for (int i = 0; i < N; i++) {
281f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk            if (mPhoneStates.get(i).mSubId != subs.get(i).getSubscriptionId()) {
282f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk                return false;
283f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk            }
284f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk        }
285f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk        return true;
286f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk    }
287f535cf0413ef9b9f36a2fe4336b35abe241a97d9Jason Monk
2888fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk    private PhoneState getState(int subId) {
289b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
290b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (state.mSubId == subId) {
291b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                return state;
292b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
293b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
2948fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk        Log.e(TAG, "Unexpected subscription " + subId);
2958fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk        return null;
296b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
297b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
298b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private PhoneState inflatePhoneState(int subId) {
299b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        PhoneState state = new PhoneState(subId, mContext);
300b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        if (mMobileSignalGroup != null) {
301b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileSignalGroup.addView(state.mMobileGroup);
302b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
303b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mPhoneStates.add(state);
304b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        return state;
305b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
306b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
307b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    @Override
30807b75fe65dcb5b8add8246654c65f95f1191933eJason Monk    public void setIsAirplaneMode(IconState icon) {
3093b230077dc53c1f83aa6e9b70585148d8193dd82Jason Monk        mIsAirplaneMode = icon.visible && !mBlockAirplane;
31007b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        mAirplaneIconId = icon.icon;
31107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        mAirplaneContentDescription = icon.contentDescription;
312061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn
313061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        apply();
3145ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler    }
3155ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler
3162f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock    @Override
31707b75fe65dcb5b8add8246654c65f95f1191933eJason Monk    public void setMobileDataEnabled(boolean enabled) {
31807b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        // Don't care.
31907b75fe65dcb5b8add8246654c65f95f1191933eJason Monk    }
32007b75fe65dcb5b8add8246654c65f95f1191933eJason Monk
32107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk    @Override
322a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
3232f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock        // Standard group layout onPopulateAccessibilityEvent() implementations
3242f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock        // ignore content description, so populate manually
325d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        if (mEthernetVisible && mEthernetGroup != null &&
326d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti                mEthernetGroup.getContentDescription() != null)
327d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti            event.getText().add(mEthernetGroup.getContentDescription());
32824e028e0ec533cb7304296118a73bdc03870d10dDaniel Sandler        if (mWifiVisible && mWifiGroup != null && mWifiGroup.getContentDescription() != null)
3292f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock            event.getText().add(mWifiGroup.getContentDescription());
330b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
331b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            state.populateAccessibilityEvent(event);
332b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
333a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        return super.dispatchPopulateAccessibilityEventInternal(event);
3342f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock    }
3352f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock
3364662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio    @Override
3374662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio    public void onRtlPropertiesChanged(int layoutDirection) {
3384662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        super.onRtlPropertiesChanged(layoutDirection);
3394662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
340d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        if (mEthernet != null) {
341d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti            mEthernet.setImageDrawable(null);
34206302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            mEthernetDark.setImageDrawable(null);
34306302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            mLastEthernetIconId = -1;
344d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        }
345d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti
3464662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        if (mWifi != null) {
3474662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio            mWifi.setImageDrawable(null);
34806302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            mWifiDark.setImageDrawable(null);
34906302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            mLastWifiStrengthId = -1;
3504662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        }
3514662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
352b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
353b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (state.mMobile != null) {
354b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                state.mMobile.setImageDrawable(null);
355b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
356b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (state.mMobileType != null) {
357b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                state.mMobileType.setImageDrawable(null);
358b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
3594662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        }
3604662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
36106302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi        if (mAirplane != null) {
3624662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio            mAirplane.setImageDrawable(null);
36306302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            mLastAirplaneIconId = -1;
3644662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        }
3654662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
3664662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        apply();
3674662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio    }
3684662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
3690d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi    @Override
3700d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi    public boolean hasOverlappingRendering() {
3710d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi        return false;
3720d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi    }
3730d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi
37428f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    // Run after each indicator change.
37528f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    private void apply() {
3762e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        if (mWifiGroup == null) return;
3772e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
3783128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mVpn.setVisibility(mVpnVisible ? View.VISIBLE : View.GONE);
3793128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        if (DEBUG) Log.d(TAG, String.format("vpn: %s", mVpnVisible ? "VISIBLE" : "GONE"));
380d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti
381d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        if (mEthernetVisible) {
38206302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            if (mLastEthernetIconId != mEthernetIconId) {
38306302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi                mEthernet.setImageResource(mEthernetIconId);
38406302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi                mEthernetDark.setImageResource(mEthernetIconId);
38506302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi                mLastEthernetIconId = mEthernetIconId;
38606302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            }
387d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti            mEthernetGroup.setContentDescription(mEthernetDescription);
388d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti            mEthernetGroup.setVisibility(View.VISIBLE);
389d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        } else {
390d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti            mEthernetGroup.setVisibility(View.GONE);
391d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        }
392d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti
393d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        if (DEBUG) Log.d(TAG,
394d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti                String.format("ethernet: %s",
395d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti                    (mEthernetVisible ? "VISIBLE" : "GONE")));
396d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti
397d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti
39828f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        if (mWifiVisible) {
39906302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            if (mWifiStrengthId != mLastWifiStrengthId) {
40006302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi                mWifi.setImageResource(mWifiStrengthId);
40106302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi                mWifiDark.setImageResource(mWifiStrengthId);
40206302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi                mLastWifiStrengthId = mWifiStrengthId;
40306302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            }
404bcf6ef0b82c1daea43e03b8ad5af319ed324242aDaniel Sandler            mWifiGroup.setContentDescription(mWifiDescription);
405cda096ebf3fac67daf36e775547c2a337374927bFabrice Di Meglio            mWifiGroup.setVisibility(View.VISIBLE);
4062e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        } else {
4072e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson            mWifiGroup.setVisibility(View.GONE);
4082e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        }
4092e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
410cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock        if (DEBUG) Log.d(TAG,
411fcc901c10bffdfb9c6b31e676dec36b47d949979John Spurlock                String.format("wifi: %s sig=%d",
41228f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler                    (mWifiVisible ? "VISIBLE" : "GONE"),
413fcc901c10bffdfb9c6b31e676dec36b47d949979John Spurlock                    mWifiStrengthId));
4142e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
415b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        boolean anyMobileVisible = false;
416e912c9cc39807f95815400981ed27d121e8b293aDan Sandler        int firstMobileTypeId = 0;
417b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
418b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (state.apply(anyMobileVisible)) {
419e912c9cc39807f95815400981ed27d121e8b293aDan Sandler                if (!anyMobileVisible) {
420e912c9cc39807f95815400981ed27d121e8b293aDan Sandler                    firstMobileTypeId = state.mMobileTypeId;
421e912c9cc39807f95815400981ed27d121e8b293aDan Sandler                    anyMobileVisible = true;
422e912c9cc39807f95815400981ed27d121e8b293aDan Sandler                }
423b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
4242e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        }
42528f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
426061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        if (mIsAirplaneMode) {
42706302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            if (mLastAirplaneIconId != mAirplaneIconId) {
42806302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi                mAirplane.setImageResource(mAirplaneIconId);
42906302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi                mLastAirplaneIconId = mAirplaneIconId;
43006302c22969b6cf63239f990eb90e72f83d0c98eJorim Jaggi            }
43107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            mAirplane.setContentDescription(mAirplaneContentDescription);
4328afcd149970c79054a3a16377834aa0aec35eee0Fabrice Di Meglio            mAirplane.setVisibility(View.VISIBLE);
433061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        } else {
434061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn            mAirplane.setVisibility(View.GONE);
435061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        }
436061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn
4375172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi        if (mIsAirplaneMode && mWifiVisible) {
4385172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi            mWifiAirplaneSpacer.setVisibility(View.VISIBLE);
4395ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler        } else {
4405172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi            mWifiAirplaneSpacer.setVisibility(View.GONE);
4415ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler        }
4425ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler
443e912c9cc39807f95815400981ed27d121e8b293aDan Sandler        if (((anyMobileVisible && firstMobileTypeId != 0) || mNoSimsVisible) && mWifiVisible) {
444c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi            mWifiSignalSpacer.setVisibility(View.VISIBLE);
445c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        } else {
446c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi            mWifiSignalSpacer.setVisibility(View.GONE);
447c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        }
448c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi
4491b5eb97ae651cd1e70009d3f9bbe91da804a457aAdrian Roos        mNoSimsCombo.setVisibility(mNoSimsVisible ? View.VISIBLE : View.GONE);
450c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi
451b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        boolean anythingVisible = mNoSimsVisible || mWifiVisible || mIsAirplaneMode
452d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti                || anyMobileVisible || mVpnVisible || mEthernetVisible;
453b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        setPaddingRelative(0, 0, anythingVisible ? mEndPadding : mEndPaddingNothingVisible, 0);
454b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
45528f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
4565443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi    public void setIconTint(int tint, float darkIntensity) {
4575443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        boolean changed = tint != mIconTint || darkIntensity != mDarkIntensity;
458dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        mIconTint = tint;
4595443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        mDarkIntensity = darkIntensity;
460dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        if (changed && isAttachedToWindow()) {
461dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi            applyIconTint();
462dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        }
463dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    }
464dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi
465dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    private void applyIconTint() {
466dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        setTint(mVpn, mIconTint);
467dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        setTint(mAirplane, mIconTint);
4685443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        applyDarkIntensity(mDarkIntensity, mNoSims, mNoSimsDark);
4695443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        applyDarkIntensity(mDarkIntensity, mWifi, mWifiDark);
470d46bb58fa635110bf8c911107819e8bd8e8b06e2Lorenzo Colitti        applyDarkIntensity(mDarkIntensity, mEthernet, mEthernetDark);
471dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        for (int i = 0; i < mPhoneStates.size(); i++) {
4725443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi            mPhoneStates.get(i).setIconTint(mIconTint, mDarkIntensity);
473dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        }
474dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    }
475dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi
4765443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi    private void applyDarkIntensity(float darkIntensity, View lightIcon, View darkIcon) {
4775443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        lightIcon.setAlpha(1 - darkIntensity);
4785443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        darkIcon.setAlpha(darkIntensity);
4795443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi    }
4805443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi
481dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    private void setTint(ImageView v, int tint) {
482dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        v.setImageTintList(ColorStateList.valueOf(tint));
483dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    }
484dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi
485b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private class PhoneState {
486b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private final int mSubId;
487b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private boolean mMobileVisible = false;
4882fdbe128209f02725c645f29bff941efe865da56Andrew Flynn        private int mMobileStrengthId = 0, mMobileTypeId = 0;
489b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private boolean mIsMobileTypeIconWide;
490b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private String mMobileDescription, mMobileTypeDescription;
491b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
492b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private ViewGroup mMobileGroup;
4935443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        private ImageView mMobile, mMobileDark, mMobileType;
494b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
495b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        public PhoneState(int subId, Context context) {
496b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            ViewGroup root = (ViewGroup) LayoutInflater.from(context)
497b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    .inflate(R.layout.mobile_signal_group, null);
498b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            setViews(root);
499b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mSubId = subId;
500b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
5016d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi
502b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        public void setViews(ViewGroup root) {
503b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileGroup    = root;
504b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobile         = (ImageView) root.findViewById(R.id.mobile_signal);
5055443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi            mMobileDark     = (ImageView) root.findViewById(R.id.mobile_signal_dark);
506b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileType     = (ImageView) root.findViewById(R.id.mobile_type);
507b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
508b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
509b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        public boolean apply(boolean isSecondaryIcon) {
510b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (mMobileVisible && !mIsAirplaneMode) {
511b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobile.setImageResource(mMobileStrengthId);
512a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                Drawable mobileDrawable = mMobile.getDrawable();
513a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                if (mobileDrawable instanceof Animatable) {
514a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                    Animatable ad = (Animatable) mobileDrawable;
515a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                    if (!ad.isRunning()) {
516a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                        ad.start();
517a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                    }
518a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                }
519a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
5205443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi                mMobileDark.setImageResource(mMobileStrengthId);
521a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                Drawable mobileDarkDrawable = mMobileDark.getDrawable();
522a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                if (mobileDarkDrawable instanceof Animatable) {
523a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                    Animatable ad = (Animatable) mobileDarkDrawable;
524a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                    if (!ad.isRunning()) {
525a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                        ad.start();
526a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                    }
527a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                }
528a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
529b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobileType.setImageResource(mMobileTypeId);
530b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobileGroup.setContentDescription(mMobileTypeDescription
531b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                        + " " + mMobileDescription);
532b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobileGroup.setVisibility(View.VISIBLE);
533b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            } else {
534b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobileGroup.setVisibility(View.GONE);
535b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
536b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
537b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            // When this isn't next to wifi, give it some extra padding between the signals.
538b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileGroup.setPaddingRelative(isSecondaryIcon ? mSecondaryTelephonyPadding : 0,
539b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    0, 0, 0);
540b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobile.setPaddingRelative(mIsMobileTypeIconWide ? mWideTypeIconStartPadding : 0,
541b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    0, 0, 0);
5425443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi            mMobileDark.setPaddingRelative(mIsMobileTypeIconWide ? mWideTypeIconStartPadding : 0,
5435443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi                    0, 0, 0);
544b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
5452fdbe128209f02725c645f29bff941efe865da56Andrew Flynn            if (DEBUG) Log.d(TAG, String.format("mobile: %s sig=%d typ=%d",
5462fdbe128209f02725c645f29bff941efe865da56Andrew Flynn                        (mMobileVisible ? "VISIBLE" : "GONE"), mMobileStrengthId, mMobileTypeId));
547b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
548b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileType.setVisibility(mMobileTypeId != 0 ? View.VISIBLE : View.GONE);
549b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
550b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            return mMobileVisible;
551b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
552b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
553b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        public void populateAccessibilityEvent(AccessibilityEvent event) {
554b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (mMobileVisible && mMobileGroup != null
555b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    && mMobileGroup.getContentDescription() != null) {
556b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                event.getText().add(mMobileGroup.getContentDescription());
557b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
558b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
559dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi
5605443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi        public void setIconTint(int tint, float darkIntensity) {
5615443cc563cf4581a8ea9ada3b27fac7107d72099Jorim Jaggi            applyDarkIntensity(darkIntensity, mMobile, mMobileDark);
562dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi            setTint(mMobileType, tint);
563dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        }
5642e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
5652e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson}
5662e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
567