Home | History | Annotate | Download | only in phone
      1 /*
      2  * Copyright (C) 2014 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.Animator;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.animation.PropertyValuesHolder;
     22 import android.animation.ValueAnimator;
     23 import android.content.Context;
     24 import android.graphics.Color;
     25 import android.graphics.Rect;
     26 import android.view.View;
     27 import android.view.ViewGroup;
     28 import android.view.ViewTreeObserver;
     29 import android.view.animation.DecelerateInterpolator;
     30 import android.view.animation.Interpolator;
     31 import android.view.animation.PathInterpolator;
     32 
     33 import com.android.keyguard.KeyguardUpdateMonitor;
     34 import com.android.systemui.R;
     35 import com.android.systemui.statusbar.ExpandableNotificationRow;
     36 import com.android.systemui.statusbar.NotificationData;
     37 import com.android.systemui.statusbar.ScrimView;
     38 import com.android.systemui.statusbar.policy.HeadsUpManager;
     39 import com.android.systemui.statusbar.stack.StackStateAnimator;
     40 
     41 /**
     42  * Controls both the scrim behind the notifications and in front of the notifications (when a
     43  * security method gets shown).
     44  */
     45 public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
     46         HeadsUpManager.OnHeadsUpChangedListener {
     47     public static final long ANIMATION_DURATION = 220;
     48     public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR
     49             = new PathInterpolator(0f, 0, 0.7f, 1f);
     50     public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED
     51             = new PathInterpolator(0.3f, 0f, 0.8f, 1f);
     52     private static final float SCRIM_BEHIND_ALPHA = 0.62f;
     53     protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
     54     protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
     55     private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
     56     private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = 0.85f;
     57     private static final int TAG_KEY_ANIM = R.id.scrim;
     58     private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
     59     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
     60     private static final int TAG_END_ALPHA = R.id.scrim_alpha_end;
     61 
     62     protected final ScrimView mScrimBehind;
     63     private final ScrimView mScrimInFront;
     64     private final UnlockMethodCache mUnlockMethodCache;
     65     private final View mHeadsUpScrim;
     66     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     67 
     68     private float mScrimBehindAlpha = SCRIM_BEHIND_ALPHA;
     69     private float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
     70     private float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
     71 
     72     protected boolean mKeyguardShowing;
     73     private float mFraction;
     74 
     75     private boolean mDarkenWhileDragging;
     76     protected boolean mBouncerShowing;
     77     private boolean mWakeAndUnlocking;
     78     private boolean mAnimateChange;
     79     private boolean mUpdatePending;
     80     private boolean mExpanding;
     81     private boolean mAnimateKeyguardFadingOut;
     82     private long mDurationOverride = -1;
     83     private long mAnimationDelay;
     84     private Runnable mOnAnimationFinished;
     85     private final Interpolator mInterpolator = new DecelerateInterpolator();
     86     private boolean mDozing;
     87     private float mDozeInFrontAlpha;
     88     private float mDozeBehindAlpha;
     89     private float mCurrentInFrontAlpha;
     90     private float mCurrentBehindAlpha;
     91     private float mCurrentHeadsUpAlpha = 1;
     92     private int mPinnedHeadsUpCount;
     93     private float mTopHeadsUpDragAmount;
     94     private View mDraggedHeadsUpView;
     95     private boolean mForceHideScrims;
     96     private boolean mSkipFirstFrame;
     97     private boolean mDontAnimateBouncerChanges;
     98     private boolean mKeyguardFadingOutInProgress;
     99     private ValueAnimator mKeyguardFadeoutAnimation;
    100 
    101     public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim) {
    102         mScrimBehind = scrimBehind;
    103         mScrimInFront = scrimInFront;
    104         mHeadsUpScrim = headsUpScrim;
    105         final Context context = scrimBehind.getContext();
    106         mUnlockMethodCache = UnlockMethodCache.getInstance(context);
    107         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
    108         updateHeadsUpScrim(false);
    109     }
    110 
    111     public void setKeyguardShowing(boolean showing) {
    112         mKeyguardShowing = showing;
    113         scheduleUpdate();
    114     }
    115 
    116     public void setShowScrimBehind(boolean show) {
    117         if (show) {
    118             mScrimBehindAlpha = SCRIM_BEHIND_ALPHA;
    119             mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
    120             mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
    121         } else {
    122             mScrimBehindAlpha = 0;
    123             mScrimBehindAlphaKeyguard = 0;
    124             mScrimBehindAlphaUnlocking = 0;
    125         }
    126         scheduleUpdate();
    127     }
    128 
    129     protected void setScrimBehindValues(float scrimBehindAlphaKeyguard,
    130             float scrimBehindAlphaUnlocking) {
    131         mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
    132         mScrimBehindAlphaUnlocking = scrimBehindAlphaUnlocking;
    133         scheduleUpdate();
    134     }
    135 
    136     public void onTrackingStarted() {
    137         mExpanding = true;
    138         mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
    139     }
    140 
    141     public void onExpandingFinished() {
    142         mExpanding = false;
    143     }
    144 
    145     public void setPanelExpansion(float fraction) {
    146         if (mFraction != fraction) {
    147             mFraction = fraction;
    148             scheduleUpdate();
    149             if (mPinnedHeadsUpCount != 0) {
    150                 updateHeadsUpScrim(false);
    151             }
    152             if (mKeyguardFadeoutAnimation != null) {
    153                 mKeyguardFadeoutAnimation.cancel();
    154             }
    155         }
    156     }
    157 
    158     public void setBouncerShowing(boolean showing) {
    159         mBouncerShowing = showing;
    160         mAnimateChange = !mExpanding && !mDontAnimateBouncerChanges;
    161         scheduleUpdate();
    162     }
    163 
    164     public void setWakeAndUnlocking() {
    165         mWakeAndUnlocking = true;
    166         scheduleUpdate();
    167     }
    168 
    169     public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished,
    170             boolean skipFirstFrame) {
    171         mWakeAndUnlocking = false;
    172         mAnimateKeyguardFadingOut = true;
    173         mDurationOverride = duration;
    174         mAnimationDelay = delay;
    175         mAnimateChange = true;
    176         mSkipFirstFrame = skipFirstFrame;
    177         mOnAnimationFinished = onAnimationFinished;
    178 
    179         if (!mKeyguardUpdateMonitor.needsSlowUnlockTransition()) {
    180             scheduleUpdate();
    181 
    182             // No need to wait for the next frame to be drawn for this case - onPreDraw will execute
    183             // the changes we just scheduled.
    184             onPreDraw();
    185         } else {
    186 
    187             // In case the user isn't unlocked, make sure to delay a bit because the system is hosed
    188             // with too many things in this case, in order to not skip the initial frames.
    189             mScrimInFront.postOnAnimationDelayed(this::scheduleUpdate, 16);
    190         }
    191     }
    192 
    193     public void abortKeyguardFadingOut() {
    194         if (mAnimateKeyguardFadingOut) {
    195             endAnimateKeyguardFadingOut(true /* force */);
    196         }
    197     }
    198 
    199     public void animateKeyguardUnoccluding(long duration) {
    200         mAnimateChange = false;
    201         setScrimBehindColor(0f);
    202         mAnimateChange = true;
    203         scheduleUpdate();
    204         mDurationOverride = duration;
    205     }
    206 
    207     public void animateGoingToFullShade(long delay, long duration) {
    208         mDurationOverride = duration;
    209         mAnimationDelay = delay;
    210         mAnimateChange = true;
    211         scheduleUpdate();
    212     }
    213 
    214     public void animateNextChange() {
    215         mAnimateChange = true;
    216     }
    217 
    218     public void setDozing(boolean dozing) {
    219         if (mDozing != dozing) {
    220             mDozing = dozing;
    221             scheduleUpdate();
    222         }
    223     }
    224 
    225     public void setDozeInFrontAlpha(float alpha) {
    226         mDozeInFrontAlpha = alpha;
    227         updateScrimColor(mScrimInFront);
    228     }
    229 
    230     public void setDozeBehindAlpha(float alpha) {
    231         mDozeBehindAlpha = alpha;
    232         updateScrimColor(mScrimBehind);
    233     }
    234 
    235     public float getDozeBehindAlpha() {
    236         return mDozeBehindAlpha;
    237     }
    238 
    239     public float getDozeInFrontAlpha() {
    240         return mDozeInFrontAlpha;
    241     }
    242 
    243     private float getScrimInFrontAlpha() {
    244         return mKeyguardUpdateMonitor.needsSlowUnlockTransition()
    245                 ? SCRIM_IN_FRONT_ALPHA_LOCKED
    246                 : SCRIM_IN_FRONT_ALPHA;
    247     }
    248     private void scheduleUpdate() {
    249         if (mUpdatePending) return;
    250 
    251         // Make sure that a frame gets scheduled.
    252         mScrimBehind.invalidate();
    253         mScrimBehind.getViewTreeObserver().addOnPreDrawListener(this);
    254         mUpdatePending = true;
    255     }
    256 
    257     protected void updateScrims() {
    258         if (mAnimateKeyguardFadingOut || mForceHideScrims) {
    259             setScrimInFrontColor(0f);
    260             setScrimBehindColor(0f);
    261         } else if (mWakeAndUnlocking) {
    262 
    263             // During wake and unlock, we first hide everything behind a black scrim, which then
    264             // gets faded out from animateKeyguardFadingOut.
    265             if (mDozing) {
    266                 setScrimInFrontColor(0f);
    267                 setScrimBehindColor(1f);
    268             } else {
    269                 setScrimInFrontColor(1f);
    270                 setScrimBehindColor(0f);
    271             }
    272         } else if (!mKeyguardShowing && !mBouncerShowing) {
    273             updateScrimNormal();
    274             setScrimInFrontColor(0);
    275         } else {
    276             updateScrimKeyguard();
    277         }
    278         mAnimateChange = false;
    279     }
    280 
    281     private void updateScrimKeyguard() {
    282         if (mExpanding && mDarkenWhileDragging) {
    283             float behindFraction = Math.max(0, Math.min(mFraction, 1));
    284             float fraction = 1 - behindFraction;
    285             fraction = (float) Math.pow(fraction, 0.8f);
    286             behindFraction = (float) Math.pow(behindFraction, 0.8f);
    287             setScrimInFrontColor(fraction * getScrimInFrontAlpha());
    288             setScrimBehindColor(behindFraction * mScrimBehindAlphaKeyguard);
    289         } else if (mBouncerShowing) {
    290             setScrimInFrontColor(getScrimInFrontAlpha());
    291             setScrimBehindColor(0f);
    292         } else {
    293             float fraction = Math.max(0, Math.min(mFraction, 1));
    294             setScrimInFrontColor(0f);
    295             setScrimBehindColor(fraction
    296                     * (mScrimBehindAlphaKeyguard - mScrimBehindAlphaUnlocking)
    297                     + mScrimBehindAlphaUnlocking);
    298         }
    299     }
    300 
    301     private void updateScrimNormal() {
    302         float frac = mFraction;
    303         // let's start this 20% of the way down the screen
    304         frac = frac * 1.2f - 0.2f;
    305         if (frac <= 0) {
    306             setScrimBehindColor(0);
    307         } else {
    308             // woo, special effects
    309             final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
    310             setScrimBehindColor(k * mScrimBehindAlpha);
    311         }
    312     }
    313 
    314     private void setScrimBehindColor(float alpha) {
    315         setScrimColor(mScrimBehind, alpha);
    316     }
    317 
    318     private void setScrimInFrontColor(float alpha) {
    319         setScrimColor(mScrimInFront, alpha);
    320         if (alpha == 0f) {
    321             mScrimInFront.setClickable(false);
    322         } else {
    323 
    324             // Eat touch events (unless dozing).
    325             mScrimInFront.setClickable(!mDozing);
    326         }
    327     }
    328 
    329     private void setScrimColor(View scrim, float alpha) {
    330         updateScrim(mAnimateChange, scrim, alpha, getCurrentScrimAlpha(scrim));
    331     }
    332 
    333     private float getDozeAlpha(View scrim) {
    334         return scrim == mScrimBehind ? mDozeBehindAlpha : mDozeInFrontAlpha;
    335     }
    336 
    337     private float getCurrentScrimAlpha(View scrim) {
    338         return scrim == mScrimBehind ? mCurrentBehindAlpha
    339                 : scrim == mScrimInFront ? mCurrentInFrontAlpha
    340                 : mCurrentHeadsUpAlpha;
    341     }
    342 
    343     private void setCurrentScrimAlpha(View scrim, float alpha) {
    344         if (scrim == mScrimBehind) {
    345             mCurrentBehindAlpha = alpha;
    346         } else if (scrim == mScrimInFront) {
    347             mCurrentInFrontAlpha = alpha;
    348         } else {
    349             alpha = Math.max(0.0f, Math.min(1.0f, alpha));
    350             mCurrentHeadsUpAlpha = alpha;
    351         }
    352     }
    353 
    354     private void updateScrimColor(View scrim) {
    355         float alpha1 = getCurrentScrimAlpha(scrim);
    356         if (scrim instanceof ScrimView) {
    357             float alpha2 = getDozeAlpha(scrim);
    358             float alpha = 1 - (1 - alpha1) * (1 - alpha2);
    359             alpha = Math.max(0, Math.min(1.0f, alpha));
    360             ((ScrimView) scrim).setScrimColor(Color.argb((int) (alpha * 255), 0, 0, 0));
    361         } else {
    362             scrim.setAlpha(alpha1);
    363         }
    364     }
    365 
    366     private void startScrimAnimation(final View scrim, float target) {
    367         float current = getCurrentScrimAlpha(scrim);
    368         ValueAnimator anim = ValueAnimator.ofFloat(current, target);
    369         anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    370             @Override
    371             public void onAnimationUpdate(ValueAnimator animation) {
    372                 float alpha = (float) animation.getAnimatedValue();
    373                 setCurrentScrimAlpha(scrim, alpha);
    374                 updateScrimColor(scrim);
    375             }
    376         });
    377         anim.setInterpolator(getInterpolator());
    378         anim.setStartDelay(mAnimationDelay);
    379         anim.setDuration(mDurationOverride != -1 ? mDurationOverride : ANIMATION_DURATION);
    380         anim.addListener(new AnimatorListenerAdapter() {
    381             @Override
    382             public void onAnimationEnd(Animator animation) {
    383                 if (mOnAnimationFinished != null) {
    384                     mOnAnimationFinished.run();
    385                     mOnAnimationFinished = null;
    386                 }
    387                 if (mKeyguardFadingOutInProgress) {
    388                     mKeyguardFadeoutAnimation = null;
    389                     mKeyguardFadingOutInProgress = false;
    390                 }
    391                 scrim.setTag(TAG_KEY_ANIM, null);
    392                 scrim.setTag(TAG_KEY_ANIM_TARGET, null);
    393             }
    394         });
    395         anim.start();
    396         if (mAnimateKeyguardFadingOut) {
    397             mKeyguardFadingOutInProgress = true;
    398             mKeyguardFadeoutAnimation = anim;
    399         }
    400         if (mSkipFirstFrame) {
    401             anim.setCurrentPlayTime(16);
    402         }
    403         scrim.setTag(TAG_KEY_ANIM, anim);
    404         scrim.setTag(TAG_KEY_ANIM_TARGET, target);
    405     }
    406 
    407     private Interpolator getInterpolator() {
    408         if (mAnimateKeyguardFadingOut && mKeyguardUpdateMonitor.needsSlowUnlockTransition()) {
    409             return KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED;
    410         } else if (mAnimateKeyguardFadingOut) {
    411             return KEYGUARD_FADE_OUT_INTERPOLATOR;
    412         } else {
    413             return mInterpolator;
    414         }
    415     }
    416 
    417     @Override
    418     public boolean onPreDraw() {
    419         mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this);
    420         mUpdatePending = false;
    421         if (mDontAnimateBouncerChanges) {
    422             mDontAnimateBouncerChanges = false;
    423         }
    424         updateScrims();
    425         mDurationOverride = -1;
    426         mAnimationDelay = 0;
    427         mSkipFirstFrame = false;
    428 
    429         // Make sure that we always call the listener even if we didn't start an animation.
    430         endAnimateKeyguardFadingOut(false /* force */);
    431         return true;
    432     }
    433 
    434     private void endAnimateKeyguardFadingOut(boolean force) {
    435         mAnimateKeyguardFadingOut = false;
    436         if (force || (!isAnimating(mScrimInFront) && !isAnimating(mScrimBehind))) {
    437             if (mOnAnimationFinished != null) {
    438                 mOnAnimationFinished.run();
    439                 mOnAnimationFinished = null;
    440             }
    441             mKeyguardFadingOutInProgress = false;
    442         }
    443     }
    444 
    445     private boolean isAnimating(View scrim) {
    446         return scrim.getTag(TAG_KEY_ANIM) != null;
    447     }
    448 
    449     public void setDrawBehindAsSrc(boolean asSrc) {
    450         mScrimBehind.setDrawAsSrc(asSrc);
    451     }
    452 
    453     @Override
    454     public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
    455     }
    456 
    457     @Override
    458     public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
    459         mPinnedHeadsUpCount++;
    460         updateHeadsUpScrim(true);
    461     }
    462 
    463     @Override
    464     public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
    465         mPinnedHeadsUpCount--;
    466         if (headsUp == mDraggedHeadsUpView) {
    467             mDraggedHeadsUpView = null;
    468             mTopHeadsUpDragAmount = 0.0f;
    469         }
    470         updateHeadsUpScrim(true);
    471     }
    472 
    473     @Override
    474     public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
    475     }
    476 
    477     private void updateHeadsUpScrim(boolean animate) {
    478         updateScrim(animate, mHeadsUpScrim, calculateHeadsUpAlpha(), mCurrentHeadsUpAlpha);
    479     }
    480 
    481     private void updateScrim(boolean animate, View scrim, float alpha, float currentAlpha) {
    482         if (mKeyguardFadingOutInProgress) {
    483             return;
    484         }
    485 
    486         ValueAnimator previousAnimator = StackStateAnimator.getChildTag(scrim,
    487                 TAG_KEY_ANIM);
    488         float animEndValue = -1;
    489         if (previousAnimator != null) {
    490             if (animate || alpha == currentAlpha) {
    491                 previousAnimator.cancel();
    492             } else {
    493                 animEndValue = StackStateAnimator.getChildTag(scrim, TAG_END_ALPHA);
    494             }
    495         }
    496         if (alpha != currentAlpha && alpha != animEndValue) {
    497             if (animate) {
    498                 startScrimAnimation(scrim, alpha);
    499                 scrim.setTag(TAG_START_ALPHA, currentAlpha);
    500                 scrim.setTag(TAG_END_ALPHA, alpha);
    501             } else {
    502                 if (previousAnimator != null) {
    503                     float previousStartValue = StackStateAnimator.getChildTag(scrim,
    504                             TAG_START_ALPHA);
    505                     float previousEndValue = StackStateAnimator.getChildTag(scrim,
    506                             TAG_END_ALPHA);
    507                     // we need to increase all animation keyframes of the previous animator by the
    508                     // relative change to the end value
    509                     PropertyValuesHolder[] values = previousAnimator.getValues();
    510                     float relativeDiff = alpha - previousEndValue;
    511                     float newStartValue = previousStartValue + relativeDiff;
    512                     newStartValue = Math.max(0, Math.min(1.0f, newStartValue));
    513                     values[0].setFloatValues(newStartValue, alpha);
    514                     scrim.setTag(TAG_START_ALPHA, newStartValue);
    515                     scrim.setTag(TAG_END_ALPHA, alpha);
    516                     previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
    517                 } else {
    518                     // update the alpha directly
    519                     setCurrentScrimAlpha(scrim, alpha);
    520                     updateScrimColor(scrim);
    521                 }
    522             }
    523         }
    524     }
    525 
    526     /**
    527      * Set the amount the current top heads up view is dragged. The range is from 0 to 1 and 0 means
    528      * the heads up is in its resting space and 1 means it's fully dragged out.
    529      *
    530      * @param draggedHeadsUpView the dragged view
    531      * @param topHeadsUpDragAmount how far is it dragged
    532      */
    533     public void setTopHeadsUpDragAmount(View draggedHeadsUpView, float topHeadsUpDragAmount) {
    534         mTopHeadsUpDragAmount = topHeadsUpDragAmount;
    535         mDraggedHeadsUpView = draggedHeadsUpView;
    536         updateHeadsUpScrim(false);
    537     }
    538 
    539     private float calculateHeadsUpAlpha() {
    540         float alpha;
    541         if (mPinnedHeadsUpCount >= 2) {
    542             alpha = 1.0f;
    543         } else if (mPinnedHeadsUpCount == 0) {
    544             alpha = 0.0f;
    545         } else {
    546             alpha = 1.0f - mTopHeadsUpDragAmount;
    547         }
    548         float expandFactor = (1.0f - mFraction);
    549         expandFactor = Math.max(expandFactor, 0.0f);
    550         return alpha * expandFactor;
    551     }
    552 
    553     public void forceHideScrims(boolean hide) {
    554         mForceHideScrims = hide;
    555         mAnimateChange = false;
    556         scheduleUpdate();
    557     }
    558 
    559     public void dontAnimateBouncerChangesUntilNextFrame() {
    560         mDontAnimateBouncerChanges = true;
    561     }
    562 
    563     public void setExcludedBackgroundArea(Rect area) {
    564         mScrimBehind.setExcludedArea(area);
    565     }
    566 
    567     public void setLeftInset(int inset) {
    568         mScrimBehind.setLeftInset(inset);
    569     }
    570 
    571     public int getScrimBehindColor() {
    572         return mScrimBehind.getScrimColorWithAlpha();
    573     }
    574 
    575     public void setScrimBehindChangeRunnable(Runnable changeRunnable) {
    576         mScrimBehind.setChangeRunnable(changeRunnable);
    577     }
    578 
    579     public void onDensityOrFontScaleChanged() {
    580         ViewGroup.LayoutParams layoutParams = mHeadsUpScrim.getLayoutParams();
    581         layoutParams.height = mHeadsUpScrim.getResources().getDimensionPixelSize(
    582                 R.dimen.heads_up_scrim_height);
    583         mHeadsUpScrim.setLayoutParams(layoutParams);
    584     }
    585 
    586     public void setCurrentUser(int currentUser) {
    587         // Don't care in the base class.
    588     }
    589 }
    590