blob: 299567a9163a2e6df73da59280f1977ff29861fb [file] [log] [blame]
Dianne Hackborna1111872010-11-23 20:55:11 -08001/*
2 * Copyright (C) 2010 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
17package com.android.server; // TODO: use com.android.server.wm, once things move there
18
19import android.graphics.Bitmap;
20import android.graphics.Canvas;
21import android.graphics.Color;
22import android.graphics.Matrix;
23import android.graphics.Paint;
24import android.graphics.PixelFormat;
25import android.graphics.Rect;
26import android.util.DisplayMetrics;
27import android.util.Slog;
28import android.view.Display;
29import android.view.Surface;
30import android.view.SurfaceSession;
31
32class ScreenRotationAnimation {
33 private static final String TAG = "ScreenRotationAnimation";
34
35 Surface mSurface;
36 int mWidth, mHeight;
37
38 int mBaseRotation;
39 int mCurRotation;
40 int mDeltaRotation;
41
42 final Matrix mMatrix = new Matrix();
43 final float[] mTmpFloats = new float[9];
44
45 public ScreenRotationAnimation(Display display, SurfaceSession session) {
46 final DisplayMetrics dm = new DisplayMetrics();
47 display.getMetrics(dm);
48
49 Bitmap screenshot = Surface.screenshot(0, 0);
50
51 if (screenshot != null) {
52 // Screenshot does NOT include rotation!
53 mBaseRotation = 0;
54 mWidth = screenshot.getWidth();
55 mHeight = screenshot.getHeight();
56 } else {
57 // Just in case.
58 mBaseRotation = display.getRotation();
59 mWidth = dm.widthPixels;
60 mHeight = dm.heightPixels;
61 }
62
63 Surface.openTransaction();
64 if (mSurface != null) {
65 mSurface.destroy();
66 mSurface = null;
67 }
68 try {
69 mSurface = new Surface(session, 0, "FreezeSurface",
70 -1, mWidth, mHeight, PixelFormat.OPAQUE, 0);
71 } catch (Surface.OutOfResourcesException e) {
72 Slog.w(TAG, "Unable to allocate freeze surface", e);
73 }
74 mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 200);
75 setRotation(display.getRotation());
76
77 Rect dirty = new Rect(0, 0, mWidth, mHeight);
78 Canvas c = null;
79 try {
80 c = mSurface.lockCanvas(dirty);
81 } catch (IllegalArgumentException e) {
82 Slog.w(TAG, "Unable to lock surface", e);
83 return;
84 } catch (Surface.OutOfResourcesException e) {
85 Slog.w(TAG, "Unable to lock surface", e);
86 return;
87 }
88 if (c == null) {
89 Slog.w(TAG, "Null surface");
90 return;
91 }
92
93 if (screenshot != null) {
94 c.drawBitmap(screenshot, 0, 0, new Paint(0));
95 } else {
96 c.drawColor(Color.GREEN);
97 }
98
99 mSurface.unlockCanvasAndPost(c);
100 Surface.closeTransaction();
101
102 screenshot.recycle();
103 }
104
105 // Must be called while in a transaction.
106 public void setRotation(int rotation) {
107 mCurRotation = rotation;
108 int delta = mCurRotation - mBaseRotation;
109 if (delta < 0) delta += 4;
110 mDeltaRotation = delta;
111
112 switch (delta) {
113 case Surface.ROTATION_0:
114 mMatrix.reset();
115 break;
116 case Surface.ROTATION_90:
117 mMatrix.setRotate(90, 0, 0);
118 mMatrix.postTranslate(0, mWidth);
119 break;
120 case Surface.ROTATION_180:
121 mMatrix.setRotate(180, 0, 0);
122 mMatrix.postTranslate(mWidth, mHeight);
123 break;
124 case Surface.ROTATION_270:
125 mMatrix.setRotate(270, 0, 0);
126 mMatrix.postTranslate(mHeight, 0);
127 break;
128 }
129
130 mMatrix.getValues(mTmpFloats);
131 mSurface.setPosition((int)mTmpFloats[Matrix.MTRANS_X],
132 (int)mTmpFloats[Matrix.MTRANS_Y]);
133 mSurface.setMatrix(
134 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_X],
135 mTmpFloats[Matrix.MSKEW_Y], mTmpFloats[Matrix.MSCALE_Y]);
136
137 if (false) {
138 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
139 float[] dstPnts = new float[8];
140 mMatrix.mapPoints(dstPnts, srcPnts);
141 Slog.i(TAG, "**** ROTATION: " + delta);
142 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
143 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
144 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
145 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
146 }
147 }
148
149 public void dismiss() {
150 mSurface.destroy();
151 }
152}