SignalClusterView.java revision dd0107a0dbe3084af8f5da005a4d96f8657f58a1
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;
23b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport android.telephony.SubscriptionInfo;
242e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.util.AttributeSet;
25cd686b5b6d4166b510df8e32138479a9559bc117John Spurlockimport android.util.Log;
26b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport android.view.LayoutInflater;
272e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.view.View;
282e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.view.ViewGroup;
292f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlockimport android.view.accessibility.AccessibilityEvent;
302e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.widget.ImageView;
312e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport android.widget.LinearLayout;
322e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
332e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport com.android.systemui.R;
34af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.NetworkControllerImpl;
353128f12f216ef481b5d03892b35706cfeec26d7cJason Monkimport com.android.systemui.statusbar.policy.SecurityController;
362e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
37b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport java.util.ArrayList;
38b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport java.util.List;
39b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
405ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler// Intimately tied to the design of res/layout/signal_cluster_view.xml
412e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonpublic class SignalClusterView
422f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock        extends LinearLayout
433128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        implements NetworkControllerImpl.SignalCluster,
443128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        SecurityController.SecurityControllerCallback {
452e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
4628f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    static final String TAG = "SignalClusterView";
47b3eb89190c4bb4ebbe676328cd37830d50e6ed3eJohn Spurlock    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
482f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock
49af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock    NetworkControllerImpl mNC;
503128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    SecurityController mSC;
512e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
52b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private boolean mNoSimsVisible = false;
533128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    private boolean mVpnVisible = false;
5428f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    private boolean mWifiVisible = false;
55fcc901c10bffdfb9c6b31e676dec36b47d949979John Spurlock    private int mWifiStrengthId = 0;
565ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler    private boolean mIsAirplaneMode = false;
57061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn    private int mAirplaneIconId = 0;
58d2263cd9db36d5f74a124c5ffaf8594ef702408fJason Monk    private int mAirplaneContentDescription;
59b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private String mWifiDescription;
60b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private ArrayList<PhoneState> mPhoneStates = new ArrayList<PhoneState>();
61dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    private int mIconTint = Color.WHITE;
6228f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
63b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    ViewGroup mWifiGroup;
64b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    ImageView mVpn, mWifi, mAirplane, mNoSims;
655172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi    View mWifiAirplaneSpacer;
66c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    View mWifiSignalSpacer;
67b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    LinearLayout mMobileSignalGroup;
68c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi
69c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    private int mWideTypeIconStartPadding;
70b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private int mSecondaryTelephonyPadding;
716d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi    private int mEndPadding;
726d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi    private int mEndPaddingNothingVisible;
732e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
742e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    public SignalClusterView(Context context) {
752e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        this(context, null);
762e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
772e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
782e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    public SignalClusterView(Context context, AttributeSet attrs) {
792e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        this(context, attrs, 0);
802e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
812e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
822e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    public SignalClusterView(Context context, AttributeSet attrs, int defStyle) {
832e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        super(context, attrs, defStyle);
842e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
852e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
86af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock    public void setNetworkController(NetworkControllerImpl nc) {
87cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock        if (DEBUG) Log.d(TAG, "NetworkController=" + nc);
882e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        mNC = nc;
892e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
902e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
913128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    public void setSecurityController(SecurityController sc) {
923128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        if (DEBUG) Log.d(TAG, "SecurityController=" + sc);
933128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mSC = sc;
943128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mSC.addCallback(this);
953128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mVpnVisible = mSC.isVpnEnabled();
963128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    }
973128f12f216ef481b5d03892b35706cfeec26d7cJason Monk
982e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    @Override
99c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    protected void onFinishInflate() {
100c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        super.onFinishInflate();
101c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        mWideTypeIconStartPadding = getContext().getResources().getDimensionPixelSize(
102c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi                R.dimen.wide_type_icon_start_padding);
103b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mSecondaryTelephonyPadding = getContext().getResources().getDimensionPixelSize(
104b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                R.dimen.secondary_telephony_padding);
1056d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi        mEndPadding = getContext().getResources().getDimensionPixelSize(
1066d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi                R.dimen.signal_cluster_battery_padding);
1076d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi        mEndPaddingNothingVisible = getContext().getResources().getDimensionPixelSize(
1086d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi                R.dimen.no_signal_cluster_battery_padding);
109c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    }
110c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi
111c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi    @Override
1122e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    protected void onAttachedToWindow() {
1132e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        super.onAttachedToWindow();
1142e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
1153128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mVpn            = (ImageView) findViewById(R.id.vpn);
1162e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        mWifiGroup      = (ViewGroup) findViewById(R.id.wifi_combo);
1172e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        mWifi           = (ImageView) findViewById(R.id.wifi_signal);
118061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        mAirplane       = (ImageView) findViewById(R.id.airplane);
119b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mNoSims         = (ImageView) findViewById(R.id.no_sims);
1205172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi        mWifiAirplaneSpacer =         findViewById(R.id.wifi_airplane_spacer);
121c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        mWifiSignalSpacer =           findViewById(R.id.wifi_signal_spacer);
122b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mMobileSignalGroup = (LinearLayout) findViewById(R.id.mobile_signal_group);
123b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
124b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileSignalGroup.addView(state.mMobileGroup);
125b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
12628f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
12728f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        apply();
128dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        applyIconTint();
1292e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
1302e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
1312e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    @Override
1322e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    protected void onDetachedFromWindow() {
1333128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mVpn            = null;
13428f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        mWifiGroup      = null;
13528f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        mWifi           = null;
136061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        mAirplane       = null;
137b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mMobileSignalGroup.removeAllViews();
138b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mMobileSignalGroup = null;
13928f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
1402e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        super.onDetachedFromWindow();
1412e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
1422e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
1433128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    // From SecurityController.
1443128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    @Override
1453128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    public void onStateChanged() {
1463128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        post(new Runnable() {
1473128f12f216ef481b5d03892b35706cfeec26d7cJason Monk            @Override
1483128f12f216ef481b5d03892b35706cfeec26d7cJason Monk            public void run() {
1493128f12f216ef481b5d03892b35706cfeec26d7cJason Monk                mVpnVisible = mSC.isVpnEnabled();
1503128f12f216ef481b5d03892b35706cfeec26d7cJason Monk                apply();
1513128f12f216ef481b5d03892b35706cfeec26d7cJason Monk            }
1523128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        });
1533128f12f216ef481b5d03892b35706cfeec26d7cJason Monk    }
1543128f12f216ef481b5d03892b35706cfeec26d7cJason Monk
155061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn    @Override
156b3eb89190c4bb4ebbe676328cd37830d50e6ed3eJohn Spurlock    public void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription) {
15728f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        mWifiVisible = visible;
15828f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        mWifiStrengthId = strengthIcon;
159bcf6ef0b82c1daea43e03b8ad5af319ed324242aDaniel Sandler        mWifiDescription = contentDescription;
16028f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
16128f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        apply();
16228f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    }
16328f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
164061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn    @Override
165b3eb89190c4bb4ebbe676328cd37830d50e6ed3eJohn Spurlock    public void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon,
166b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            String contentDescription, String typeContentDescription, boolean isTypeIconWide,
167b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            int subId) {
168b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        PhoneState state = getOrInflateState(subId);
169b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        state.mMobileVisible = visible;
170b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        state.mMobileStrengthId = strengthIcon;
171b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        state.mMobileTypeId = typeIcon;
172b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        state.mMobileDescription = contentDescription;
173b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        state.mMobileTypeDescription = typeContentDescription;
174b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        state.mIsMobileTypeIconWide = isTypeIconWide;
17528f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
17628f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        apply();
17728f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    }
17828f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
179061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn    @Override
180b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    public void setNoSims(boolean show) {
181b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mNoSimsVisible = show;
182b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
183b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
184b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    @Override
185b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    public void setSubs(List<SubscriptionInfo> subs) {
186b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        // Clear out all old subIds.
187b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mPhoneStates.clear();
188b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        if (mMobileSignalGroup != null) {
189b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileSignalGroup.removeAllViews();
190b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
191b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        final int n = subs.size();
192b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (int i = 0; i < n; i++) {
193b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            inflatePhoneState(subs.get(i).getSubscriptionId());
194b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
195dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        if (isAttachedToWindow()) {
196dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi            applyIconTint();
197dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        }
198b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
199b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
200b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private PhoneState getOrInflateState(int subId) {
201b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
202b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (state.mSubId == subId) {
203b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                return state;
204b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
205b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
206b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        return inflatePhoneState(subId);
207b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
208b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
209b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private PhoneState inflatePhoneState(int subId) {
210b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        PhoneState state = new PhoneState(subId, mContext);
211b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        if (mMobileSignalGroup != null) {
212b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileSignalGroup.addView(state.mMobileGroup);
213b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
214b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mPhoneStates.add(state);
215b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        return state;
216b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
217b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
218b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    @Override
219d2263cd9db36d5f74a124c5ffaf8594ef702408fJason Monk    public void setIsAirplaneMode(boolean is, int airplaneIconId, int contentDescription) {
2205ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler        mIsAirplaneMode = is;
221061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        mAirplaneIconId = airplaneIconId;
222d2263cd9db36d5f74a124c5ffaf8594ef702408fJason Monk        mAirplaneContentDescription = contentDescription;
223061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn
224061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        apply();
2255ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler    }
2265ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler
2272f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock    @Override
228a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette    public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
2292f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock        // Standard group layout onPopulateAccessibilityEvent() implementations
2302f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock        // ignore content description, so populate manually
23124e028e0ec533cb7304296118a73bdc03870d10dDaniel Sandler        if (mWifiVisible && mWifiGroup != null && mWifiGroup.getContentDescription() != null)
2322f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock            event.getText().add(mWifiGroup.getContentDescription());
233b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
234b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            state.populateAccessibilityEvent(event);
235b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
236a54956a0bc611b1e9b3914edc7a604b59688f6b7Alan Viverette        return super.dispatchPopulateAccessibilityEventInternal(event);
2372f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock    }
2382f7dfa7afdaada78c46bd6fd7e307656ba3dd66aJohn Spurlock
2394662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio    @Override
2404662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio    public void onRtlPropertiesChanged(int layoutDirection) {
2414662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        super.onRtlPropertiesChanged(layoutDirection);
2424662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
2434662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        if (mWifi != null) {
2444662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio            mWifi.setImageDrawable(null);
2454662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        }
2464662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
247b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
248b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (state.mMobile != null) {
249b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                state.mMobile.setImageDrawable(null);
250b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
251b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (state.mMobileType != null) {
252b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                state.mMobileType.setImageDrawable(null);
253b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
2544662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        }
2554662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
2564662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        if(mAirplane != null) {
2574662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio            mAirplane.setImageDrawable(null);
2584662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        }
2594662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
2604662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio        apply();
2614662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio    }
2624662611f3757bd9210f252c095f2bef278fa2043Fabrice Di Meglio
2630d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi    @Override
2640d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi    public boolean hasOverlappingRendering() {
2650d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi        return false;
2660d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi    }
2670d266899da8f612194a8393ec69c4fd870f2f45cJorim Jaggi
26828f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    // Run after each indicator change.
26928f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler    private void apply() {
2702e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        if (mWifiGroup == null) return;
2712e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
2723128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        mVpn.setVisibility(mVpnVisible ? View.VISIBLE : View.GONE);
2733128f12f216ef481b5d03892b35706cfeec26d7cJason Monk        if (DEBUG) Log.d(TAG, String.format("vpn: %s", mVpnVisible ? "VISIBLE" : "GONE"));
27428f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        if (mWifiVisible) {
27528f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler            mWifi.setImageResource(mWifiStrengthId);
276bcf6ef0b82c1daea43e03b8ad5af319ed324242aDaniel Sandler            mWifiGroup.setContentDescription(mWifiDescription);
277cda096ebf3fac67daf36e775547c2a337374927bFabrice Di Meglio            mWifiGroup.setVisibility(View.VISIBLE);
2782e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        } else {
2792e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson            mWifiGroup.setVisibility(View.GONE);
2802e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        }
2812e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
282cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock        if (DEBUG) Log.d(TAG,
283fcc901c10bffdfb9c6b31e676dec36b47d949979John Spurlock                String.format("wifi: %s sig=%d",
28428f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler                    (mWifiVisible ? "VISIBLE" : "GONE"),
285fcc901c10bffdfb9c6b31e676dec36b47d949979John Spurlock                    mWifiStrengthId));
2862e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
287b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        boolean anyMobileVisible = false;
288e912c9cc39807f95815400981ed27d121e8b293aDan Sandler        int firstMobileTypeId = 0;
289b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        for (PhoneState state : mPhoneStates) {
290b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (state.apply(anyMobileVisible)) {
291e912c9cc39807f95815400981ed27d121e8b293aDan Sandler                if (!anyMobileVisible) {
292e912c9cc39807f95815400981ed27d121e8b293aDan Sandler                    firstMobileTypeId = state.mMobileTypeId;
293e912c9cc39807f95815400981ed27d121e8b293aDan Sandler                    anyMobileVisible = true;
294e912c9cc39807f95815400981ed27d121e8b293aDan Sandler                }
295b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
2962e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        }
29728f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
298061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        if (mIsAirplaneMode) {
299061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn            mAirplane.setImageResource(mAirplaneIconId);
300d2263cd9db36d5f74a124c5ffaf8594ef702408fJason Monk            mAirplane.setContentDescription(mAirplaneContentDescription != 0 ?
301b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    mContext.getString(mAirplaneContentDescription) : null);
3028afcd149970c79054a3a16377834aa0aec35eee0Fabrice Di Meglio            mAirplane.setVisibility(View.VISIBLE);
303061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        } else {
304061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn            mAirplane.setVisibility(View.GONE);
305061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn        }
306061d43c2386dd8222448bb1bec017bf9a2367a4eAndrew Flynn
3075172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi        if (mIsAirplaneMode && mWifiVisible) {
3085172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi            mWifiAirplaneSpacer.setVisibility(View.VISIBLE);
3095ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler        } else {
3105172dc2f36f9c417befd0957ce2ae20f9d083a88Jorim Jaggi            mWifiAirplaneSpacer.setVisibility(View.GONE);
3115ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler        }
3125ccff81a642844138b144ad2cc339eba188812a0Daniel Sandler
313e912c9cc39807f95815400981ed27d121e8b293aDan Sandler        if (((anyMobileVisible && firstMobileTypeId != 0) || mNoSimsVisible) && mWifiVisible) {
314c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi            mWifiSignalSpacer.setVisibility(View.VISIBLE);
315c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        } else {
316c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi            mWifiSignalSpacer.setVisibility(View.GONE);
317c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi        }
318c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi
319b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        mNoSims.setVisibility(mNoSimsVisible ? View.VISIBLE : View.GONE);
320c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi
321b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        boolean anythingVisible = mNoSimsVisible || mWifiVisible || mIsAirplaneMode
322b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                || anyMobileVisible || mVpnVisible;
323b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        setPaddingRelative(0, 0, anythingVisible ? mEndPadding : mEndPaddingNothingVisible, 0);
324b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    }
32528f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler
326dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    public void setIconTint(int tint) {
327dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        boolean changed = tint != mIconTint;
328dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        mIconTint = tint;
329dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        if (changed && isAttachedToWindow()) {
330dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi            applyIconTint();
331dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        }
332dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    }
333dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi
334dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    private void applyIconTint() {
335dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        setTint(mVpn, mIconTint);
336dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        setTint(mWifi, mIconTint);
337dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        setTint(mNoSims, mIconTint);
338dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        setTint(mAirplane, mIconTint);
339dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        for (int i = 0; i < mPhoneStates.size(); i++) {
340dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi            mPhoneStates.get(i).setIconTint(mIconTint);
341dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        }
342dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    }
343dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi
344dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    private void setTint(ImageView v, int tint) {
345dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        v.setImageTintMode(PorterDuff.Mode.SRC_ATOP);
346dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        v.setImageTintList(ColorStateList.valueOf(tint));
347dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi    }
348dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi
349b574627ebc383d35cf8212ee241b191b26518a0dJason Monk    private class PhoneState {
350b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private final int mSubId;
351b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private boolean mMobileVisible = false;
352b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private int mMobileStrengthId = 0, mMobileTypeId = 0;
353b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private boolean mIsMobileTypeIconWide;
354b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private String mMobileDescription, mMobileTypeDescription;
355b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
356b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private ViewGroup mMobileGroup;
357b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        private ImageView mMobile, mMobileType;
358b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
359b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        public PhoneState(int subId, Context context) {
360b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            ViewGroup root = (ViewGroup) LayoutInflater.from(context)
361b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    .inflate(R.layout.mobile_signal_group, null);
362b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            setViews(root);
363b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mSubId = subId;
364b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
3656d035f15d5c8c67d97a4d5b6ed44f8cca0772e1fJorim Jaggi
366b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        public void setViews(ViewGroup root) {
367b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileGroup    = root;
368b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobile         = (ImageView) root.findViewById(R.id.mobile_signal);
369b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileType     = (ImageView) root.findViewById(R.id.mobile_type);
370b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
371b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
372b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        public boolean apply(boolean isSecondaryIcon) {
373b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (mMobileVisible && !mIsAirplaneMode) {
374b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobile.setImageResource(mMobileStrengthId);
375b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobileType.setImageResource(mMobileTypeId);
376b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobileGroup.setContentDescription(mMobileTypeDescription
377b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                        + " " + mMobileDescription);
378b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobileGroup.setVisibility(View.VISIBLE);
379b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            } else {
380b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                mMobileGroup.setVisibility(View.GONE);
381b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
382b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
383b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            // When this isn't next to wifi, give it some extra padding between the signals.
384b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileGroup.setPaddingRelative(isSecondaryIcon ? mSecondaryTelephonyPadding : 0,
385b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    0, 0, 0);
386b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobile.setPaddingRelative(mIsMobileTypeIconWide ? mWideTypeIconStartPadding : 0,
387b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    0, 0, 0);
388b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
389b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (DEBUG) Log.d(TAG, String.format("mobile: %s sig=%d typ=%d",
390b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                        (mMobileVisible ? "VISIBLE" : "GONE"), mMobileStrengthId, mMobileTypeId));
391b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
392b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            mMobileType.setVisibility(mMobileTypeId != 0 ? View.VISIBLE : View.GONE);
393b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
394b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            return mMobileVisible;
395b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
396b574627ebc383d35cf8212ee241b191b26518a0dJason Monk
397b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        public void populateAccessibilityEvent(AccessibilityEvent event) {
398b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            if (mMobileVisible && mMobileGroup != null
399b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                    && mMobileGroup.getContentDescription() != null) {
400b574627ebc383d35cf8212ee241b191b26518a0dJason Monk                event.getText().add(mMobileGroup.getContentDescription());
401b574627ebc383d35cf8212ee241b191b26518a0dJason Monk            }
402b574627ebc383d35cf8212ee241b191b26518a0dJason Monk        }
403dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi
404dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        public void setIconTint(int tint) {
405dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi            setTint(mMobile, tint);
406dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi            setTint(mMobileType, tint);
407dd0107a0dbe3084af8f5da005a4d96f8657f58a1Jorim Jaggi        }
4082e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson    }
4092e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson}
4102e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson
411