1 /* 2 * Copyright (C) 2011 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.server.wm; 18 19 import android.content.res.Resources; 20 import android.graphics.PixelFormat; 21 import android.util.Slog; 22 import android.util.TypedValue; 23 import android.view.Surface; 24 import android.view.SurfaceSession; 25 26 import java.io.PrintWriter; 27 28 /** 29 * DimAnimator class that controls the dim animation. This holds the surface and 30 * all state used for dim animation. 31 */ 32 class DimAnimator { 33 Surface mDimSurface; 34 boolean mDimShown = false; 35 float mDimCurrentAlpha; 36 float mDimTargetAlpha; 37 float mDimDeltaPerMs; 38 long mLastDimAnimTime; 39 40 int mLastDimWidth, mLastDimHeight; 41 DimAnimator(SurfaceSession session)42 DimAnimator (SurfaceSession session) { 43 if (mDimSurface == null) { 44 if (WindowManagerService.SHOW_TRANSACTIONS || 45 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, 46 " DIM " + mDimSurface + ": CREATE"); 47 try { 48 mDimSurface = new Surface(session, 0, 49 "DimAnimator", 50 -1, 16, 16, PixelFormat.OPAQUE, 51 Surface.FX_SURFACE_DIM); 52 mDimSurface.setAlpha(0.0f); 53 } catch (Exception e) { 54 Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e); 55 } 56 } 57 } 58 59 /** 60 * Show the dim surface. 61 */ show(int dw, int dh)62 void show(int dw, int dh) { 63 if (!mDimShown) { 64 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" + 65 dw + "x" + dh + ")"); 66 mDimShown = true; 67 try { 68 mLastDimWidth = dw; 69 mLastDimHeight = dh; 70 mDimSurface.setPosition(0, 0); 71 mDimSurface.setSize(dw, dh); 72 mDimSurface.show(); 73 } catch (RuntimeException e) { 74 Slog.w(WindowManagerService.TAG, "Failure showing dim surface", e); 75 } 76 } else if (mLastDimWidth != dw || mLastDimHeight != dh) { 77 mLastDimWidth = dw; 78 mLastDimHeight = dh; 79 mDimSurface.setSize(dw, dh); 80 } 81 } 82 83 /** 84 * Set's the dim surface's layer and update dim parameters that will be used in 85 * {@link updateSurface} after all windows are examined. 86 */ updateParameters(Resources res, WindowState w, long currentTime)87 void updateParameters(Resources res, WindowState w, long currentTime) { 88 mDimSurface.setLayer(w.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM); 89 90 final float target = w.mExiting ? 0 : w.mAttrs.dimAmount; 91 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface 92 + ": layer=" + (w.mAnimLayer-1) + " target=" + target); 93 if (mDimTargetAlpha != target) { 94 // If the desired dim level has changed, then 95 // start an animation to it. 96 mLastDimAnimTime = currentTime; 97 long duration = (w.mAnimating && w.mAnimation != null) 98 ? w.mAnimation.computeDurationHint() 99 : WindowManagerService.DEFAULT_DIM_DURATION; 100 if (target > mDimTargetAlpha) { 101 TypedValue tv = new TypedValue(); 102 res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration, 103 tv, true); 104 if (tv.type == TypedValue.TYPE_FRACTION) { 105 duration = (long)tv.getFraction((float)duration, (float)duration); 106 } else if (tv.type >= TypedValue.TYPE_FIRST_INT 107 && tv.type <= TypedValue.TYPE_LAST_INT) { 108 duration = tv.data; 109 } 110 } 111 if (duration < 1) { 112 // Don't divide by zero 113 duration = 1; 114 } 115 mDimTargetAlpha = target; 116 mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration; 117 } 118 } 119 120 /** 121 * Updating the surface's alpha. Returns true if the animation continues, or returns 122 * false when the animation is finished and the dim surface is hidden. 123 */ updateSurface(boolean dimming, long currentTime, boolean displayFrozen)124 boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) { 125 if (!dimming) { 126 if (mDimTargetAlpha != 0) { 127 mLastDimAnimTime = currentTime; 128 mDimTargetAlpha = 0; 129 mDimDeltaPerMs = (-mDimCurrentAlpha) / WindowManagerService.DEFAULT_DIM_DURATION; 130 } 131 } 132 133 boolean animating = false; 134 if (mLastDimAnimTime != 0) { 135 mDimCurrentAlpha += mDimDeltaPerMs 136 * (currentTime-mLastDimAnimTime); 137 boolean more = true; 138 if (displayFrozen) { 139 // If the display is frozen, there is no reason to animate. 140 more = false; 141 } else if (mDimDeltaPerMs > 0) { 142 if (mDimCurrentAlpha > mDimTargetAlpha) { 143 more = false; 144 } 145 } else if (mDimDeltaPerMs < 0) { 146 if (mDimCurrentAlpha < mDimTargetAlpha) { 147 more = false; 148 } 149 } else { 150 more = false; 151 } 152 153 // Do we need to continue animating? 154 if (more) { 155 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " 156 + mDimSurface + ": alpha=" + mDimCurrentAlpha); 157 mLastDimAnimTime = currentTime; 158 mDimSurface.setAlpha(mDimCurrentAlpha); 159 animating = true; 160 } else { 161 mDimCurrentAlpha = mDimTargetAlpha; 162 mLastDimAnimTime = 0; 163 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " 164 + mDimSurface + ": final alpha=" + mDimCurrentAlpha); 165 mDimSurface.setAlpha(mDimCurrentAlpha); 166 if (!dimming) { 167 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface 168 + ": HIDE"); 169 try { 170 mDimSurface.hide(); 171 } catch (RuntimeException e) { 172 Slog.w(WindowManagerService.TAG, "Illegal argument exception hiding dim surface"); 173 } 174 mDimShown = false; 175 } 176 } 177 } 178 return animating; 179 } 180 printTo(String prefix, PrintWriter pw)181 public void printTo(String prefix, PrintWriter pw) { 182 pw.print(prefix); 183 pw.print("mDimSurface="); pw.println(mDimSurface); 184 pw.print(prefix); 185 pw.print("mDimShown="); pw.print(mDimShown); 186 pw.print(" current="); pw.print(mDimCurrentAlpha); 187 pw.print(" target="); pw.print(mDimTargetAlpha); 188 pw.print(" delta="); pw.print(mDimDeltaPerMs); 189 pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime); 190 } 191 }