Home | History | Annotate | Download | only in phone
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      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
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     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
     15  */
     16 
     17 package com.android.systemui.statusbar.phone;
     18 
     19 import android.animation.ArgbEvaluator;
     20 import android.animation.ValueAnimator;
     21 import android.content.Context;
     22 import android.content.res.ColorStateList;
     23 import android.content.res.Resources;
     24 import android.graphics.Color;
     25 import android.graphics.Rect;
     26 import android.graphics.drawable.Icon;
     27 import android.os.Bundle;
     28 import android.os.Handler;
     29 import android.os.SystemClock;
     30 import android.os.UserHandle;
     31 import android.text.TextUtils;
     32 import android.util.ArraySet;
     33 import android.util.TypedValue;
     34 import android.view.Gravity;
     35 import android.view.View;
     36 import android.view.ViewGroup;
     37 import android.widget.ImageView;
     38 import android.widget.LinearLayout;
     39 import android.widget.TextView;
     40 import com.android.internal.statusbar.StatusBarIcon;
     41 import com.android.systemui.BatteryMeterView;
     42 import com.android.systemui.FontSizeUtils;
     43 import com.android.systemui.Interpolators;
     44 import com.android.systemui.R;
     45 import com.android.systemui.SystemUIFactory;
     46 import com.android.systemui.statusbar.NotificationData;
     47 import com.android.systemui.statusbar.SignalClusterView;
     48 import com.android.systemui.statusbar.StatusBarIconView;
     49 import com.android.systemui.tuner.TunerService;
     50 import com.android.systemui.tuner.TunerService.Tunable;
     51 
     52 import java.io.PrintWriter;
     53 import java.util.ArrayList;
     54 
     55 /**
     56  * Controls everything regarding the icons in the status bar and on Keyguard, including, but not
     57  * limited to: notification icons, signal cluster, additional status icons, and clock in the status
     58  * bar.
     59  */
     60 public class StatusBarIconController extends StatusBarIconList implements Tunable {
     61 
     62     public static final long DEFAULT_TINT_ANIMATION_DURATION = 120;
     63     public static final String ICON_BLACKLIST = "icon_blacklist";
     64     public static final int DEFAULT_ICON_TINT = Color.WHITE;
     65 
     66     private Context mContext;
     67     private PhoneStatusBar mPhoneStatusBar;
     68     private DemoStatusIcons mDemoStatusIcons;
     69 
     70     private LinearLayout mSystemIconArea;
     71     private LinearLayout mStatusIcons;
     72     private SignalClusterView mSignalCluster;
     73     private LinearLayout mStatusIconsKeyguard;
     74 
     75     private NotificationIconAreaController mNotificationIconAreaController;
     76     private View mNotificationIconAreaInner;
     77 
     78     private BatteryMeterView mBatteryMeterView;
     79     private BatteryMeterView mBatteryMeterViewKeyguard;
     80     private TextView mClock;
     81 
     82     private int mIconSize;
     83     private int mIconHPadding;
     84 
     85     private int mIconTint = DEFAULT_ICON_TINT;
     86     private float mDarkIntensity;
     87     private final Rect mTintArea = new Rect();
     88     private static final Rect sTmpRect = new Rect();
     89     private static final int[] sTmpInt2 = new int[2];
     90 
     91     private boolean mTransitionPending;
     92     private boolean mTintChangePending;
     93     private float mPendingDarkIntensity;
     94     private ValueAnimator mTintAnimator;
     95 
     96     private int mDarkModeIconColorSingleTone;
     97     private int mLightModeIconColorSingleTone;
     98 
     99     private final Handler mHandler;
    100     private boolean mTransitionDeferring;
    101     private long mTransitionDeferringStartTime;
    102     private long mTransitionDeferringDuration;
    103 
    104     private final ArraySet<String> mIconBlacklist = new ArraySet<>();
    105 
    106     private final Runnable mTransitionDeferringDoneRunnable = new Runnable() {
    107         @Override
    108         public void run() {
    109             mTransitionDeferring = false;
    110         }
    111     };
    112 
    113     public StatusBarIconController(Context context, View statusBar, View keyguardStatusBar,
    114             PhoneStatusBar phoneStatusBar) {
    115         super(context.getResources().getStringArray(
    116                 com.android.internal.R.array.config_statusBarIcons));
    117         mContext = context;
    118         mPhoneStatusBar = phoneStatusBar;
    119         mSystemIconArea = (LinearLayout) statusBar.findViewById(R.id.system_icon_area);
    120         mStatusIcons = (LinearLayout) statusBar.findViewById(R.id.statusIcons);
    121         mSignalCluster = (SignalClusterView) statusBar.findViewById(R.id.signal_cluster);
    122 
    123         mNotificationIconAreaController = SystemUIFactory.getInstance()
    124                 .createNotificationIconAreaController(context, phoneStatusBar);
    125         mNotificationIconAreaInner =
    126                 mNotificationIconAreaController.getNotificationInnerAreaView();
    127 
    128         ViewGroup notificationIconArea =
    129                 (ViewGroup) statusBar.findViewById(R.id.notification_icon_area);
    130         notificationIconArea.addView(mNotificationIconAreaInner);
    131 
    132         mStatusIconsKeyguard = (LinearLayout) keyguardStatusBar.findViewById(R.id.statusIcons);
    133 
    134         mBatteryMeterView = (BatteryMeterView) statusBar.findViewById(R.id.battery);
    135         mBatteryMeterViewKeyguard = (BatteryMeterView) keyguardStatusBar.findViewById(R.id.battery);
    136         scaleBatteryMeterViews(context);
    137 
    138         mClock = (TextView) statusBar.findViewById(R.id.clock);
    139         mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone);
    140         mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
    141         mHandler = new Handler();
    142         loadDimens();
    143 
    144         TunerService.get(mContext).addTunable(this, ICON_BLACKLIST);
    145     }
    146 
    147     public void setSignalCluster(SignalClusterView signalCluster) {
    148         mSignalCluster = signalCluster;
    149     }
    150 
    151     /**
    152      * Looks up the scale factor for status bar icons and scales the battery view by that amount.
    153      */
    154     private void scaleBatteryMeterViews(Context context) {
    155         Resources res = context.getResources();
    156         TypedValue typedValue = new TypedValue();
    157 
    158         res.getValue(R.dimen.status_bar_icon_scale_factor, typedValue, true);
    159         float iconScaleFactor = typedValue.getFloat();
    160 
    161         int batteryHeight = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_height);
    162         int batteryWidth = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_width);
    163         int marginBottom = res.getDimensionPixelSize(R.dimen.battery_margin_bottom);
    164 
    165         LinearLayout.LayoutParams scaledLayoutParams = new LinearLayout.LayoutParams(
    166                 (int) (batteryWidth * iconScaleFactor), (int) (batteryHeight * iconScaleFactor));
    167         scaledLayoutParams.setMarginsRelative(0, 0, 0, marginBottom);
    168 
    169         mBatteryMeterView.setLayoutParams(scaledLayoutParams);
    170         mBatteryMeterViewKeyguard.setLayoutParams(scaledLayoutParams);
    171     }
    172 
    173     @Override
    174     public void onTuningChanged(String key, String newValue) {
    175         if (!ICON_BLACKLIST.equals(key)) {
    176             return;
    177         }
    178         mIconBlacklist.clear();
    179         mIconBlacklist.addAll(getIconBlacklist(newValue));
    180         ArrayList<StatusBarIconView> views = new ArrayList<StatusBarIconView>();
    181         // Get all the current views.
    182         for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
    183             views.add((StatusBarIconView) mStatusIcons.getChildAt(i));
    184         }
    185         // Remove all the icons.
    186         for (int i = views.size() - 1; i >= 0; i--) {
    187             removeIcon(views.get(i).getSlot());
    188         }
    189         // Add them all back
    190         for (int i = 0; i < views.size(); i++) {
    191             setIcon(views.get(i).getSlot(), views.get(i).getStatusBarIcon());
    192         }
    193     }
    194     private void loadDimens() {
    195         mIconSize = mContext.getResources().getDimensionPixelSize(
    196                 com.android.internal.R.dimen.status_bar_icon_size);
    197         mIconHPadding = mContext.getResources().getDimensionPixelSize(
    198                 R.dimen.status_bar_icon_padding);
    199     }
    200 
    201     private void addSystemIcon(int index, StatusBarIcon icon) {
    202         String slot = getSlot(index);
    203         int viewIndex = getViewIndex(index);
    204         boolean blocked = mIconBlacklist.contains(slot);
    205         StatusBarIconView view = new StatusBarIconView(mContext, slot, null, blocked);
    206         view.set(icon);
    207 
    208         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
    209                 ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
    210         lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
    211         mStatusIcons.addView(view, viewIndex, lp);
    212 
    213         view = new StatusBarIconView(mContext, slot, null, blocked);
    214         view.set(icon);
    215         mStatusIconsKeyguard.addView(view, viewIndex, new LinearLayout.LayoutParams(
    216                 ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
    217         applyIconTint();
    218     }
    219 
    220     public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
    221         int index = getSlotIndex(slot);
    222         StatusBarIcon icon = getIcon(index);
    223         if (icon == null) {
    224             icon = new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
    225                     Icon.createWithResource(mContext, resourceId), 0, 0, contentDescription);
    226             setIcon(slot, icon);
    227         } else {
    228             icon.icon = Icon.createWithResource(mContext, resourceId);
    229             icon.contentDescription = contentDescription;
    230             handleSet(index, icon);
    231         }
    232     }
    233 
    234     public void setExternalIcon(String slot) {
    235         int viewIndex = getViewIndex(getSlotIndex(slot));
    236         int height = mContext.getResources().getDimensionPixelSize(
    237                 R.dimen.status_bar_icon_drawing_size);
    238         ImageView imageView = (ImageView) mStatusIcons.getChildAt(viewIndex);
    239         imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
    240         imageView.setAdjustViewBounds(true);
    241         setHeightAndCenter(imageView, height);
    242         imageView = (ImageView) mStatusIconsKeyguard.getChildAt(viewIndex);
    243         imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
    244         imageView.setAdjustViewBounds(true);
    245         setHeightAndCenter(imageView, height);
    246     }
    247 
    248     private void setHeightAndCenter(ImageView imageView, int height) {
    249         ViewGroup.LayoutParams params = imageView.getLayoutParams();
    250         params.height = height;
    251         if (params instanceof LinearLayout.LayoutParams) {
    252             ((LinearLayout.LayoutParams) params).gravity = Gravity.CENTER_VERTICAL;
    253         }
    254         imageView.setLayoutParams(params);
    255     }
    256 
    257     public void setIcon(String slot, StatusBarIcon icon) {
    258         setIcon(getSlotIndex(slot), icon);
    259     }
    260 
    261     public void removeIcon(String slot) {
    262         int index = getSlotIndex(slot);
    263         removeIcon(index);
    264     }
    265 
    266     public void setIconVisibility(String slot, boolean visibility) {
    267         int index = getSlotIndex(slot);
    268         StatusBarIcon icon = getIcon(index);
    269         if (icon == null || icon.visible == visibility) {
    270             return;
    271         }
    272         icon.visible = visibility;
    273         handleSet(index, icon);
    274     }
    275 
    276     @Override
    277     public void removeIcon(int index) {
    278         if (getIcon(index) == null) {
    279             return;
    280         }
    281         super.removeIcon(index);
    282         int viewIndex = getViewIndex(index);
    283         mStatusIcons.removeViewAt(viewIndex);
    284         mStatusIconsKeyguard.removeViewAt(viewIndex);
    285     }
    286 
    287     @Override
    288     public void setIcon(int index, StatusBarIcon icon) {
    289         if (icon == null) {
    290             removeIcon(index);
    291             return;
    292         }
    293         boolean isNew = getIcon(index) == null;
    294         super.setIcon(index, icon);
    295         if (isNew) {
    296             addSystemIcon(index, icon);
    297         } else {
    298             handleSet(index, icon);
    299         }
    300     }
    301 
    302     private void handleSet(int index, StatusBarIcon icon) {
    303         int viewIndex = getViewIndex(index);
    304         StatusBarIconView view = (StatusBarIconView) mStatusIcons.getChildAt(viewIndex);
    305         view.set(icon);
    306         view = (StatusBarIconView) mStatusIconsKeyguard.getChildAt(viewIndex);
    307         view.set(icon);
    308         applyIconTint();
    309     }
    310 
    311     public void updateNotificationIcons(NotificationData notificationData) {
    312         mNotificationIconAreaController.updateNotificationIcons(notificationData);
    313     }
    314 
    315     public void hideSystemIconArea(boolean animate) {
    316         animateHide(mSystemIconArea, animate);
    317     }
    318 
    319     public void showSystemIconArea(boolean animate) {
    320         animateShow(mSystemIconArea, animate);
    321     }
    322 
    323     public void hideNotificationIconArea(boolean animate) {
    324         animateHide(mNotificationIconAreaInner, animate);
    325     }
    326 
    327     public void showNotificationIconArea(boolean animate) {
    328         animateShow(mNotificationIconAreaInner, animate);
    329     }
    330 
    331     public void setClockVisibility(boolean visible) {
    332         mClock.setVisibility(visible ? View.VISIBLE : View.GONE);
    333     }
    334 
    335     public void dump(PrintWriter pw) {
    336         int N = mStatusIcons.getChildCount();
    337         pw.println("  icon views: " + N);
    338         for (int i=0; i<N; i++) {
    339             StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
    340             pw.println("    [" + i + "] icon=" + ic);
    341         }
    342         super.dump(pw);
    343     }
    344 
    345     public void dispatchDemoCommand(String command, Bundle args) {
    346         if (mDemoStatusIcons == null) {
    347             mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
    348         }
    349         mDemoStatusIcons.dispatchDemoCommand(command, args);
    350     }
    351 
    352     /**
    353      * Hides a view.
    354      */
    355     private void animateHide(final View v, boolean animate) {
    356         v.animate().cancel();
    357         if (!animate) {
    358             v.setAlpha(0f);
    359             v.setVisibility(View.INVISIBLE);
    360             return;
    361         }
    362         v.animate()
    363                 .alpha(0f)
    364                 .setDuration(160)
    365                 .setStartDelay(0)
    366                 .setInterpolator(Interpolators.ALPHA_OUT)
    367                 .withEndAction(new Runnable() {
    368                     @Override
    369                     public void run() {
    370                         v.setVisibility(View.INVISIBLE);
    371                     }
    372                 });
    373     }
    374 
    375     /**
    376      * Shows a view, and synchronizes the animation with Keyguard exit animations, if applicable.
    377      */
    378     private void animateShow(View v, boolean animate) {
    379         v.animate().cancel();
    380         v.setVisibility(View.VISIBLE);
    381         if (!animate) {
    382             v.setAlpha(1f);
    383             return;
    384         }
    385         v.animate()
    386                 .alpha(1f)
    387                 .setDuration(320)
    388                 .setInterpolator(Interpolators.ALPHA_IN)
    389                 .setStartDelay(50)
    390 
    391                 // We need to clean up any pending end action from animateHide if we call
    392                 // both hide and show in the same frame before the animation actually gets started.
    393                 // cancel() doesn't really remove the end action.
    394                 .withEndAction(null);
    395 
    396         // Synchronize the motion with the Keyguard fading if necessary.
    397         if (mPhoneStatusBar.isKeyguardFadingAway()) {
    398             v.animate()
    399                     .setDuration(mPhoneStatusBar.getKeyguardFadingAwayDuration())
    400                     .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
    401                     .setStartDelay(mPhoneStatusBar.getKeyguardFadingAwayDelay())
    402                     .start();
    403         }
    404     }
    405 
    406     /**
    407      * Sets the dark area so {@link #setIconsDark} only affects the icons in the specified area.
    408      *
    409      * @param darkArea the area in which icons should change it's tint, in logical screen
    410      *                 coordinates
    411      */
    412     public void setIconsDarkArea(Rect darkArea) {
    413         if (darkArea == null && mTintArea.isEmpty()) {
    414             return;
    415         }
    416         if (darkArea == null) {
    417             mTintArea.setEmpty();
    418         } else {
    419             mTintArea.set(darkArea);
    420         }
    421         applyIconTint();
    422         mNotificationIconAreaController.setTintArea(darkArea);
    423     }
    424 
    425     public void setIconsDark(boolean dark, boolean animate) {
    426         if (!animate) {
    427             setIconTintInternal(dark ? 1.0f : 0.0f);
    428         } else if (mTransitionPending) {
    429             deferIconTintChange(dark ? 1.0f : 0.0f);
    430         } else if (mTransitionDeferring) {
    431             animateIconTint(dark ? 1.0f : 0.0f,
    432                     Math.max(0, mTransitionDeferringStartTime - SystemClock.uptimeMillis()),
    433                     mTransitionDeferringDuration);
    434         } else {
    435             animateIconTint(dark ? 1.0f : 0.0f, 0 /* delay */, DEFAULT_TINT_ANIMATION_DURATION);
    436         }
    437     }
    438 
    439     private void animateIconTint(float targetDarkIntensity, long delay,
    440             long duration) {
    441         if (mTintAnimator != null) {
    442             mTintAnimator.cancel();
    443         }
    444         if (mDarkIntensity == targetDarkIntensity) {
    445             return;
    446         }
    447         mTintAnimator = ValueAnimator.ofFloat(mDarkIntensity, targetDarkIntensity);
    448         mTintAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    449             @Override
    450             public void onAnimationUpdate(ValueAnimator animation) {
    451                 setIconTintInternal((Float) animation.getAnimatedValue());
    452             }
    453         });
    454         mTintAnimator.setDuration(duration);
    455         mTintAnimator.setStartDelay(delay);
    456         mTintAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
    457         mTintAnimator.start();
    458     }
    459 
    460     private void setIconTintInternal(float darkIntensity) {
    461         mDarkIntensity = darkIntensity;
    462         mIconTint = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity,
    463                 mLightModeIconColorSingleTone, mDarkModeIconColorSingleTone);
    464         mNotificationIconAreaController.setIconTint(mIconTint);
    465         applyIconTint();
    466     }
    467 
    468     private void deferIconTintChange(float darkIntensity) {
    469         if (mTintChangePending && darkIntensity == mPendingDarkIntensity) {
    470             return;
    471         }
    472         mTintChangePending = true;
    473         mPendingDarkIntensity = darkIntensity;
    474     }
    475 
    476     /**
    477      * @return the tint to apply to {@param view} depending on the desired tint {@param color} and
    478      *         the screen {@param tintArea} in which to apply that tint
    479      */
    480     public static int getTint(Rect tintArea, View view, int color) {
    481         if (isInArea(tintArea, view)) {
    482             return color;
    483         } else {
    484             return DEFAULT_ICON_TINT;
    485         }
    486     }
    487 
    488     /**
    489      * @return the dark intensity to apply to {@param view} depending on the desired dark
    490      *         {@param intensity} and the screen {@param tintArea} in which to apply that intensity
    491      */
    492     public static float getDarkIntensity(Rect tintArea, View view, float intensity) {
    493         if (isInArea(tintArea, view)) {
    494             return intensity;
    495         } else {
    496             return 0f;
    497         }
    498     }
    499 
    500     /**
    501      * @return true if more than half of the {@param view} area are in {@param area}, false
    502      *         otherwise
    503      */
    504     private static boolean isInArea(Rect area, View view) {
    505         if (area.isEmpty()) {
    506             return true;
    507         }
    508         sTmpRect.set(area);
    509         view.getLocationOnScreen(sTmpInt2);
    510         int left = sTmpInt2[0];
    511 
    512         int intersectStart = Math.max(left, area.left);
    513         int intersectEnd = Math.min(left + view.getWidth(), area.right);
    514         int intersectAmount = Math.max(0, intersectEnd - intersectStart);
    515 
    516         boolean coversFullStatusBar = area.top <= 0;
    517         boolean majorityOfWidth = 2 * intersectAmount > view.getWidth();
    518         return majorityOfWidth && coversFullStatusBar;
    519     }
    520 
    521     private void applyIconTint() {
    522         for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
    523             StatusBarIconView v = (StatusBarIconView) mStatusIcons.getChildAt(i);
    524             v.setImageTintList(ColorStateList.valueOf(getTint(mTintArea, v, mIconTint)));
    525         }
    526         mSignalCluster.setIconTint(mIconTint, mDarkIntensity, mTintArea);
    527         mBatteryMeterView.setDarkIntensity(
    528                 isInArea(mTintArea, mBatteryMeterView) ? mDarkIntensity : 0);
    529         mClock.setTextColor(getTint(mTintArea, mClock, mIconTint));
    530     }
    531 
    532     public void appTransitionPending() {
    533         mTransitionPending = true;
    534     }
    535 
    536     public void appTransitionCancelled() {
    537         if (mTransitionPending && mTintChangePending) {
    538             mTintChangePending = false;
    539             animateIconTint(mPendingDarkIntensity, 0 /* delay */, DEFAULT_TINT_ANIMATION_DURATION);
    540         }
    541         mTransitionPending = false;
    542     }
    543 
    544     public void appTransitionStarting(long startTime, long duration) {
    545         if (mTransitionPending && mTintChangePending) {
    546             mTintChangePending = false;
    547             animateIconTint(mPendingDarkIntensity,
    548                     Math.max(0, startTime - SystemClock.uptimeMillis()),
    549                     duration);
    550 
    551         } else if (mTransitionPending) {
    552 
    553             // If we don't have a pending tint change yet, the change might come in the future until
    554             // startTime is reached.
    555             mTransitionDeferring = true;
    556             mTransitionDeferringStartTime = startTime;
    557             mTransitionDeferringDuration = duration;
    558             mHandler.removeCallbacks(mTransitionDeferringDoneRunnable);
    559             mHandler.postAtTime(mTransitionDeferringDoneRunnable, startTime);
    560         }
    561         mTransitionPending = false;
    562     }
    563 
    564     public static ArraySet<String> getIconBlacklist(String blackListStr) {
    565         ArraySet<String> ret = new ArraySet<String>();
    566         if (blackListStr == null) {
    567             blackListStr = "rotate,headset";
    568         }
    569         String[] blacklist = blackListStr.split(",");
    570         for (String slot : blacklist) {
    571             if (!TextUtils.isEmpty(slot)) {
    572                 ret.add(slot);
    573             }
    574         }
    575         return ret;
    576     }
    577 
    578     public void onDensityOrFontScaleChanged() {
    579         loadDimens();
    580         mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
    581         updateClock();
    582         for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
    583             View child = mStatusIcons.getChildAt(i);
    584             LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
    585                     ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
    586             lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
    587             child.setLayoutParams(lp);
    588         }
    589         for (int i = 0; i < mStatusIconsKeyguard.getChildCount(); i++) {
    590             View child = mStatusIconsKeyguard.getChildAt(i);
    591             LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
    592                     ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
    593             child.setLayoutParams(lp);
    594         }
    595         scaleBatteryMeterViews(mContext);
    596     }
    597 
    598     private void updateClock() {
    599         FontSizeUtils.updateFontSize(mClock, R.dimen.status_bar_clock_size);
    600         mClock.setPaddingRelative(
    601                 mContext.getResources().getDimensionPixelSize(
    602                         R.dimen.status_bar_clock_starting_padding),
    603                 0,
    604                 mContext.getResources().getDimensionPixelSize(
    605                         R.dimen.status_bar_clock_end_padding),
    606                 0);
    607     }
    608 }
    609