2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.systemui.statusbar;
19 import android.annotation.DrawableRes;
20 import android.content.Context;
21 import android.content.res.ColorStateList;
22 import android.content.res.Resources;
23 import android.graphics.Color;
24 import android.graphics.Rect;
25 import android.graphics.drawable.Animatable;
26 import android.graphics.drawable.AnimatedVectorDrawable;
27 import android.graphics.drawable.Drawable;
28 import android.telephony.SubscriptionInfo;
29 import android.util.ArraySet;
30 import android.util.AttributeSet;
31 import android.util.Log;
32 import android.util.TypedValue;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.view.ViewGroup;
36 import android.view.accessibility.AccessibilityEvent;
37 import android.widget.ImageView;
38 import android.widget.LinearLayout;
40 import com.android.systemui.R;
41 import com.android.systemui.statusbar.phone.StatusBarIconController;
42 import com.android.systemui.statusbar.policy.NetworkController.IconState;
43 import com.android.systemui.statusbar.policy.NetworkControllerImpl;
44 import com.android.systemui.statusbar.policy.SecurityController;
45 import com.android.systemui.tuner.TunerService;
46 import com.android.systemui.tuner.TunerService.Tunable;
48 import java.util.ArrayList;
49 import java.util.List;
51 // Intimately tied to the design of res/layout/signal_cluster_view.xml
52 public class SignalClusterView
54 implements NetworkControllerImpl.SignalCallback,
55 SecurityController.SecurityControllerCallback, Tunable {
57 static final String TAG = "SignalClusterView";
58 static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
60 private static final String SLOT_AIRPLANE = "airplane";
61 private static final String SLOT_MOBILE = "mobile";
62 private static final String SLOT_WIFI = "wifi";
63 private static final String SLOT_ETHERNET = "ethernet";
65 NetworkControllerImpl mNC;
66 SecurityController mSC;
68 private boolean mNoSimsVisible = false;
69 private boolean mVpnVisible = false;
70 private int mVpnIconId = 0;
71 private int mLastVpnIconId = -1;
72 private boolean mEthernetVisible = false;
73 private int mEthernetIconId = 0;
74 private int mLastEthernetIconId = -1;
75 private boolean mWifiVisible = false;
76 private int mWifiStrengthId = 0;
77 private int mLastWifiStrengthId = -1;
78 private boolean mIsAirplaneMode = false;
79 private int mAirplaneIconId = 0;
80 private int mLastAirplaneIconId = -1;
81 private String mAirplaneContentDescription;
82 private String mWifiDescription;
83 private String mEthernetDescription;
84 private ArrayList<PhoneState> mPhoneStates = new ArrayList<PhoneState>();
85 private int mIconTint = Color.WHITE;
86 private float mDarkIntensity;
87 private final Rect mTintArea = new Rect();
89 ViewGroup mEthernetGroup, mWifiGroup;
91 ImageView mVpn, mEthernet, mWifi, mAirplane, mNoSims, mEthernetDark, mWifiDark, mNoSimsDark;
92 View mWifiAirplaneSpacer;
93 View mWifiSignalSpacer;
94 LinearLayout mMobileSignalGroup;
96 private final int mMobileSignalGroupEndPadding;
97 private final int mMobileDataIconStartPadding;
98 private final int mWideTypeIconStartPadding;
99 private final int mSecondaryTelephonyPadding;
100 private final int mEndPadding;
101 private final int mEndPaddingNothingVisible;
102 private final float mIconScaleFactor;
104 private boolean mBlockAirplane;
105 private boolean mBlockMobile;
106 private boolean mBlockWifi;
107 private boolean mBlockEthernet;
109 public SignalClusterView(Context context) {
113 public SignalClusterView(Context context, AttributeSet attrs) {
114 this(context, attrs, 0);
117 public SignalClusterView(Context context, AttributeSet attrs, int defStyle) {
118 super(context, attrs, defStyle);
120 Resources res = getResources();
121 mMobileSignalGroupEndPadding =
122 res.getDimensionPixelSize(R.dimen.mobile_signal_group_end_padding);
123 mMobileDataIconStartPadding =
124 res.getDimensionPixelSize(R.dimen.mobile_data_icon_start_padding);
125 mWideTypeIconStartPadding = res.getDimensionPixelSize(R.dimen.wide_type_icon_start_padding);
126 mSecondaryTelephonyPadding = res.getDimensionPixelSize(R.dimen.secondary_telephony_padding);
127 mEndPadding = res.getDimensionPixelSize(R.dimen.signal_cluster_battery_padding);
128 mEndPaddingNothingVisible = res.getDimensionPixelSize(
129 R.dimen.no_signal_cluster_battery_padding);
131 TypedValue typedValue = new TypedValue();
132 res.getValue(R.dimen.status_bar_icon_scale_factor, typedValue, true);
133 mIconScaleFactor = typedValue.getFloat();
137 public void onTuningChanged(String key, String newValue) {
138 if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
141 ArraySet<String> blockList = StatusBarIconController.getIconBlacklist(newValue);
142 boolean blockAirplane = blockList.contains(SLOT_AIRPLANE);
143 boolean blockMobile = blockList.contains(SLOT_MOBILE);
144 boolean blockWifi = blockList.contains(SLOT_WIFI);
145 boolean blockEthernet = blockList.contains(SLOT_ETHERNET);
147 if (blockAirplane != mBlockAirplane || blockMobile != mBlockMobile
148 || blockEthernet != mBlockEthernet || blockWifi != mBlockWifi) {
149 mBlockAirplane = blockAirplane;
150 mBlockMobile = blockMobile;
151 mBlockEthernet = blockEthernet;
152 mBlockWifi = blockWifi;
153 // Re-register to get new callbacks.
154 mNC.removeSignalCallback(this);
155 mNC.addSignalCallback(this);
159 public void setNetworkController(NetworkControllerImpl nc) {
160 if (DEBUG) Log.d(TAG, "NetworkController=" + nc);
164 public void setSecurityController(SecurityController sc) {
165 if (DEBUG) Log.d(TAG, "SecurityController=" + sc);
167 mSC.addCallback(this);
168 mVpnVisible = mSC.isVpnEnabled();
169 mVpnIconId = currentVpnIconId(mSC.isVpnBranded());
173 protected void onFinishInflate() {
174 super.onFinishInflate();
176 mVpn = (ImageView) findViewById(R.id.vpn);
177 mEthernetGroup = (ViewGroup) findViewById(R.id.ethernet_combo);
178 mEthernet = (ImageView) findViewById(R.id.ethernet);
179 mEthernetDark = (ImageView) findViewById(R.id.ethernet_dark);
180 mWifiGroup = (ViewGroup) findViewById(R.id.wifi_combo);
181 mWifi = (ImageView) findViewById(R.id.wifi_signal);
182 mWifiDark = (ImageView) findViewById(R.id.wifi_signal_dark);
183 mAirplane = (ImageView) findViewById(R.id.airplane);
184 mNoSims = (ImageView) findViewById(R.id.no_sims);
185 mNoSimsDark = (ImageView) findViewById(R.id.no_sims_dark);
186 mNoSimsCombo = findViewById(R.id.no_sims_combo);
187 mWifiAirplaneSpacer = findViewById(R.id.wifi_airplane_spacer);
188 mWifiSignalSpacer = findViewById(R.id.wifi_signal_spacer);
189 mMobileSignalGroup = (LinearLayout) findViewById(R.id.mobile_signal_group);
191 maybeScaleVpnAndNoSimsIcons();
195 * Extracts the icon off of the VPN and no sims views and maybe scale them by
196 * {@link #mIconScaleFactor}. Note that the other icons are not scaled here because they are
197 * dynamic. As such, they need to be scaled each time the icon changes in {@link #apply()}.
199 private void maybeScaleVpnAndNoSimsIcons() {
200 if (mIconScaleFactor == 1.f) {
204 mVpn.setImageDrawable(new ScalingDrawableWrapper(mVpn.getDrawable(), mIconScaleFactor));
206 mNoSims.setImageDrawable(
207 new ScalingDrawableWrapper(mNoSims.getDrawable(), mIconScaleFactor));
208 mNoSimsDark.setImageDrawable(
209 new ScalingDrawableWrapper(mNoSimsDark.getDrawable(), mIconScaleFactor));
213 protected void onAttachedToWindow() {
214 super.onAttachedToWindow();
216 for (PhoneState state : mPhoneStates) {
217 mMobileSignalGroup.addView(state.mMobileGroup);
220 int endPadding = mMobileSignalGroup.getChildCount() > 0 ? mMobileSignalGroupEndPadding : 0;
221 mMobileSignalGroup.setPaddingRelative(0, 0, endPadding, 0);
223 TunerService.get(mContext).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
227 mNC.addSignalCallback(this);
231 protected void onDetachedFromWindow() {
232 mMobileSignalGroup.removeAllViews();
233 TunerService.get(mContext).removeTunable(this);
234 mSC.removeCallback(this);
235 mNC.removeSignalCallback(this);
237 super.onDetachedFromWindow();
241 protected void onLayout(boolean changed, int l, int t, int r, int b) {
242 super.onLayout(changed, l, t, r, b);
244 // Re-run all checks against the tint area for all icons
248 // From SecurityController.
250 public void onStateChanged() {
251 post(new Runnable() {
254 mVpnVisible = mSC.isVpnEnabled();
255 mVpnIconId = currentVpnIconId(mSC.isVpnBranded());
262 public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
263 boolean activityIn, boolean activityOut, String description) {
264 mWifiVisible = statusIcon.visible && !mBlockWifi;
265 mWifiStrengthId = statusIcon.icon;
266 mWifiDescription = statusIcon.contentDescription;
272 public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
273 int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
274 String description, boolean isWide, int subId) {
275 PhoneState state = getState(subId);
279 state.mMobileVisible = statusIcon.visible && !mBlockMobile;
280 state.mMobileStrengthId = statusIcon.icon;
281 state.mMobileTypeId = statusType;
282 state.mMobileDescription = statusIcon.contentDescription;
283 state.mMobileTypeDescription = typeContentDescription;
284 state.mIsMobileTypeIconWide = statusType != 0 && isWide;
290 public void setEthernetIndicators(IconState state) {
291 mEthernetVisible = state.visible && !mBlockEthernet;
292 mEthernetIconId = state.icon;
293 mEthernetDescription = state.contentDescription;
299 public void setNoSims(boolean show) {
300 mNoSimsVisible = show && !mBlockMobile;
305 public void setSubs(List<SubscriptionInfo> subs) {
306 if (hasCorrectSubs(subs)) {
309 // Clear out all old subIds.
310 for (PhoneState state : mPhoneStates) {
311 if (state.mMobile != null) {
312 state.maybeStopAnimatableDrawable(state.mMobile);
314 if (state.mMobileDark != null) {
315 state.maybeStopAnimatableDrawable(state.mMobileDark);
318 mPhoneStates.clear();
319 if (mMobileSignalGroup != null) {
320 mMobileSignalGroup.removeAllViews();
322 final int n = subs.size();
323 for (int i = 0; i < n; i++) {
324 inflatePhoneState(subs.get(i).getSubscriptionId());
326 if (isAttachedToWindow()) {
331 private boolean hasCorrectSubs(List<SubscriptionInfo> subs) {
332 final int N = subs.size();
333 if (N != mPhoneStates.size()) {
336 for (int i = 0; i < N; i++) {
337 if (mPhoneStates.get(i).mSubId != subs.get(i).getSubscriptionId()) {
344 private PhoneState getState(int subId) {
345 for (PhoneState state : mPhoneStates) {
346 if (state.mSubId == subId) {
350 Log.e(TAG, "Unexpected subscription " + subId);
354 private PhoneState inflatePhoneState(int subId) {
355 PhoneState state = new PhoneState(subId, mContext);
356 if (mMobileSignalGroup != null) {
357 mMobileSignalGroup.addView(state.mMobileGroup);
359 mPhoneStates.add(state);
364 public void setIsAirplaneMode(IconState icon) {
365 mIsAirplaneMode = icon.visible && !mBlockAirplane;
366 mAirplaneIconId = icon.icon;
367 mAirplaneContentDescription = icon.contentDescription;
373 public void setMobileDataEnabled(boolean enabled) {
378 public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
379 // Standard group layout onPopulateAccessibilityEvent() implementations
380 // ignore content description, so populate manually
381 if (mEthernetVisible && mEthernetGroup != null &&
382 mEthernetGroup.getContentDescription() != null)
383 event.getText().add(mEthernetGroup.getContentDescription());
384 if (mWifiVisible && mWifiGroup != null && mWifiGroup.getContentDescription() != null)
385 event.getText().add(mWifiGroup.getContentDescription());
386 for (PhoneState state : mPhoneStates) {
387 state.populateAccessibilityEvent(event);
389 return super.dispatchPopulateAccessibilityEventInternal(event);
393 public void onRtlPropertiesChanged(int layoutDirection) {
394 super.onRtlPropertiesChanged(layoutDirection);
396 if (mEthernet != null) {
397 mEthernet.setImageDrawable(null);
398 mEthernetDark.setImageDrawable(null);
399 mLastEthernetIconId = -1;
403 mWifi.setImageDrawable(null);
404 mWifiDark.setImageDrawable(null);
405 mLastWifiStrengthId = -1;
408 for (PhoneState state : mPhoneStates) {
409 if (state.mMobile != null) {
410 state.maybeStopAnimatableDrawable(state.mMobile);
411 state.mMobile.setImageDrawable(null);
412 state.mLastMobileStrengthId = -1;
414 if (state.mMobileDark != null) {
415 state.maybeStopAnimatableDrawable(state.mMobileDark);
416 state.mMobileDark.setImageDrawable(null);
417 state.mLastMobileStrengthId = -1;
419 if (state.mMobileType != null) {
420 state.mMobileType.setImageDrawable(null);
421 state.mLastMobileTypeId = -1;
425 if (mAirplane != null) {
426 mAirplane.setImageDrawable(null);
427 mLastAirplaneIconId = -1;
434 public boolean hasOverlappingRendering() {
438 // Run after each indicator change.
439 private void apply() {
440 if (mWifiGroup == null) return;
442 mVpn.setVisibility(mVpnVisible ? View.VISIBLE : View.GONE);
444 if (mLastVpnIconId != mVpnIconId) {
445 setIconForView(mVpn, mVpnIconId);
446 mLastVpnIconId = mVpnIconId;
448 mVpn.setVisibility(View.VISIBLE);
450 mVpn.setVisibility(View.GONE);
452 if (DEBUG) Log.d(TAG, String.format("vpn: %s", mVpnVisible ? "VISIBLE" : "GONE"));
454 if (mEthernetVisible) {
455 if (mLastEthernetIconId != mEthernetIconId) {
456 setIconForView(mEthernet, mEthernetIconId);
457 setIconForView(mEthernetDark, mEthernetIconId);
458 mLastEthernetIconId = mEthernetIconId;
460 mEthernetGroup.setContentDescription(mEthernetDescription);
461 mEthernetGroup.setVisibility(View.VISIBLE);
463 mEthernetGroup.setVisibility(View.GONE);
466 if (DEBUG) Log.d(TAG,
467 String.format("ethernet: %s",
468 (mEthernetVisible ? "VISIBLE" : "GONE")));
471 if (mWifiStrengthId != mLastWifiStrengthId) {
472 setIconForView(mWifi, mWifiStrengthId);
473 setIconForView(mWifiDark, mWifiStrengthId);
474 mLastWifiStrengthId = mWifiStrengthId;
476 mWifiGroup.setContentDescription(mWifiDescription);
477 mWifiGroup.setVisibility(View.VISIBLE);
479 mWifiGroup.setVisibility(View.GONE);
482 if (DEBUG) Log.d(TAG,
483 String.format("wifi: %s sig=%d",
484 (mWifiVisible ? "VISIBLE" : "GONE"),
487 boolean anyMobileVisible = false;
488 int firstMobileTypeId = 0;
489 for (PhoneState state : mPhoneStates) {
490 if (state.apply(anyMobileVisible)) {
491 if (!anyMobileVisible) {
492 firstMobileTypeId = state.mMobileTypeId;
493 anyMobileVisible = true;
498 if (mIsAirplaneMode) {
499 if (mLastAirplaneIconId != mAirplaneIconId) {
500 setIconForView(mAirplane, mAirplaneIconId);
501 mLastAirplaneIconId = mAirplaneIconId;
503 mAirplane.setContentDescription(mAirplaneContentDescription);
504 mAirplane.setVisibility(View.VISIBLE);
506 mAirplane.setVisibility(View.GONE);
509 if (mIsAirplaneMode && mWifiVisible) {
510 mWifiAirplaneSpacer.setVisibility(View.VISIBLE);
512 mWifiAirplaneSpacer.setVisibility(View.GONE);
515 if (((anyMobileVisible && firstMobileTypeId != 0) || mNoSimsVisible) && mWifiVisible) {
516 mWifiSignalSpacer.setVisibility(View.VISIBLE);
518 mWifiSignalSpacer.setVisibility(View.GONE);
521 mNoSimsCombo.setVisibility(mNoSimsVisible ? View.VISIBLE : View.GONE);
523 boolean anythingVisible = mNoSimsVisible || mWifiVisible || mIsAirplaneMode
524 || anyMobileVisible || mVpnVisible || mEthernetVisible;
525 setPaddingRelative(0, 0, anythingVisible ? mEndPadding : mEndPaddingNothingVisible, 0);
529 * Sets the given drawable id on the view. This method will also scale the icon by
530 * {@link #mIconScaleFactor} if appropriate.
532 private void setIconForView(ImageView imageView, @DrawableRes int iconId) {
533 // Using the imageView's context to retrieve the Drawable so that theme is preserved.
534 Drawable icon = imageView.getContext().getDrawable(iconId);
536 if (mIconScaleFactor == 1.f) {
537 imageView.setImageDrawable(icon);
539 imageView.setImageDrawable(new ScalingDrawableWrapper(icon, mIconScaleFactor));
543 public void setIconTint(int tint, float darkIntensity, Rect tintArea) {
544 boolean changed = tint != mIconTint || darkIntensity != mDarkIntensity
545 || !mTintArea.equals(tintArea);
547 mDarkIntensity = darkIntensity;
548 mTintArea.set(tintArea);
549 if (changed && isAttachedToWindow()) {
554 private void applyIconTint() {
555 setTint(mVpn, StatusBarIconController.getTint(mTintArea, mVpn, mIconTint));
556 setTint(mAirplane, StatusBarIconController.getTint(mTintArea, mAirplane, mIconTint));
558 StatusBarIconController.getDarkIntensity(mTintArea, mNoSims, mDarkIntensity),
559 mNoSims, mNoSimsDark);
561 StatusBarIconController.getDarkIntensity(mTintArea, mWifi, mDarkIntensity),
564 StatusBarIconController.getDarkIntensity(mTintArea, mEthernet, mDarkIntensity),
565 mEthernet, mEthernetDark);
566 for (int i = 0; i < mPhoneStates.size(); i++) {
567 mPhoneStates.get(i).setIconTint(mIconTint, mDarkIntensity, mTintArea);
571 private void applyDarkIntensity(float darkIntensity, View lightIcon, View darkIcon) {
572 lightIcon.setAlpha(1 - darkIntensity);
573 darkIcon.setAlpha(darkIntensity);
576 private void setTint(ImageView v, int tint) {
577 v.setImageTintList(ColorStateList.valueOf(tint));
580 private int currentVpnIconId(boolean isBranded) {
581 return isBranded ? R.drawable.stat_sys_branded_vpn : R.drawable.stat_sys_vpn_ic;
584 private class PhoneState {
585 private final int mSubId;
586 private boolean mMobileVisible = false;
587 private int mMobileStrengthId = 0, mMobileTypeId = 0;
588 private int mLastMobileStrengthId = -1;
589 private int mLastMobileTypeId = -1;
590 private boolean mIsMobileTypeIconWide;
591 private String mMobileDescription, mMobileTypeDescription;
593 private ViewGroup mMobileGroup;
594 private ImageView mMobile, mMobileDark, mMobileType;
596 public PhoneState(int subId, Context context) {
597 ViewGroup root = (ViewGroup) LayoutInflater.from(context)
598 .inflate(R.layout.mobile_signal_group, null);
603 public void setViews(ViewGroup root) {
605 mMobile = (ImageView) root.findViewById(R.id.mobile_signal);
606 mMobileDark = (ImageView) root.findViewById(R.id.mobile_signal_dark);
607 mMobileType = (ImageView) root.findViewById(R.id.mobile_type);
610 public boolean apply(boolean isSecondaryIcon) {
611 if (mMobileVisible && !mIsAirplaneMode) {
612 if (mLastMobileStrengthId != mMobileStrengthId) {
613 updateAnimatableIcon(mMobile, mMobileStrengthId);
614 updateAnimatableIcon(mMobileDark, mMobileStrengthId);
615 mLastMobileStrengthId = mMobileStrengthId;
618 if (mLastMobileTypeId != mMobileTypeId) {
619 mMobileType.setImageResource(mMobileTypeId);
620 mLastMobileTypeId = mMobileTypeId;
622 mMobileGroup.setContentDescription(mMobileTypeDescription
623 + " " + mMobileDescription);
624 mMobileGroup.setVisibility(View.VISIBLE);
626 mMobileGroup.setVisibility(View.GONE);
629 // When this isn't next to wifi, give it some extra padding between the signals.
630 mMobileGroup.setPaddingRelative(isSecondaryIcon ? mSecondaryTelephonyPadding : 0,
632 mMobile.setPaddingRelative(
633 mIsMobileTypeIconWide ? mWideTypeIconStartPadding : mMobileDataIconStartPadding,
635 mMobileDark.setPaddingRelative(
636 mIsMobileTypeIconWide ? mWideTypeIconStartPadding : mMobileDataIconStartPadding,
639 if (DEBUG) Log.d(TAG, String.format("mobile: %s sig=%d typ=%d",
640 (mMobileVisible ? "VISIBLE" : "GONE"), mMobileStrengthId, mMobileTypeId));
642 mMobileType.setVisibility(mMobileTypeId != 0 ? View.VISIBLE : View.GONE);
644 return mMobileVisible;
647 private void updateAnimatableIcon(ImageView view, int resId) {
648 maybeStopAnimatableDrawable(view);
649 setIconForView(view, resId);
650 maybeStartAnimatableDrawable(view);
653 private void maybeStopAnimatableDrawable(ImageView view) {
654 Drawable drawable = view.getDrawable();
656 // Check if the icon has been scaled. If it has retrieve the actual drawable out of the
658 if (drawable instanceof ScalingDrawableWrapper) {
659 drawable = ((ScalingDrawableWrapper) drawable).getDrawable();
662 if (drawable instanceof Animatable) {
663 Animatable ad = (Animatable) drawable;
664 if (ad.isRunning()) {
670 private void maybeStartAnimatableDrawable(ImageView view) {
671 Drawable drawable = view.getDrawable();
673 // Check if the icon has been scaled. If it has retrieve the actual drawable out of the
675 if (drawable instanceof ScalingDrawableWrapper) {
676 drawable = ((ScalingDrawableWrapper) drawable).getDrawable();
679 if (drawable instanceof Animatable) {
680 Animatable ad = (Animatable) drawable;
681 if (ad instanceof AnimatedVectorDrawable) {
682 ((AnimatedVectorDrawable) ad).forceAnimationOnUI();
684 if (!ad.isRunning()) {
690 public void populateAccessibilityEvent(AccessibilityEvent event) {
691 if (mMobileVisible && mMobileGroup != null
692 && mMobileGroup.getContentDescription() != null) {
693 event.getText().add(mMobileGroup.getContentDescription());
697 public void setIconTint(int tint, float darkIntensity, Rect tintArea) {
699 StatusBarIconController.getDarkIntensity(tintArea, mMobile, darkIntensity),
700 mMobile, mMobileDark);
701 setTint(mMobileType, StatusBarIconController.getTint(tintArea, mMobileType, tint));