• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }