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