• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.shell;
18 
19 import android.graphics.Bitmap;
20 import android.graphics.Canvas;
21 import android.graphics.Point;
22 import android.hardware.display.DisplayManagerGlobal;
23 import android.util.Log;
24 import android.view.Display;
25 import android.view.Surface;
26 import android.view.SurfaceControl;
27 
28 /**
29  * Helper class used to take screenshots.
30  *
31  * TODO: logic below was copied and pasted from UiAutomation; it should be refactored into a common
32  * component that could be used by both (Shell and UiAutomation).
33  */
34 final class Screenshooter {
35 
36     private static final String TAG = "Screenshooter";
37 
38     /** Rotation constant: Freeze rotation to 0 degrees (natural orientation) */
39     public static final int ROTATION_FREEZE_0 = Surface.ROTATION_0;
40 
41     /** Rotation constant: Freeze rotation to 90 degrees . */
42     public static final int ROTATION_FREEZE_90 = Surface.ROTATION_90;
43 
44     /** Rotation constant: Freeze rotation to 180 degrees . */
45     public static final int ROTATION_FREEZE_180 = Surface.ROTATION_180;
46 
47     /** Rotation constant: Freeze rotation to 270 degrees . */
48     public static final int ROTATION_FREEZE_270 = Surface.ROTATION_270;
49 
50     /**
51      * Takes a screenshot.
52      *
53      * @return The screenshot bitmap on success, null otherwise.
54      */
takeScreenshot()55     static Bitmap takeScreenshot() {
56         Display display = DisplayManagerGlobal.getInstance()
57                 .getRealDisplay(Display.DEFAULT_DISPLAY);
58         Point displaySize = new Point();
59         display.getRealSize(displaySize);
60         final int displayWidth = displaySize.x;
61         final int displayHeight = displaySize.y;
62 
63         final float screenshotWidth;
64         final float screenshotHeight;
65 
66         final int rotation = display.getRotation();
67         switch (rotation) {
68             case ROTATION_FREEZE_0: {
69                 screenshotWidth = displayWidth;
70                 screenshotHeight = displayHeight;
71             } break;
72             case ROTATION_FREEZE_90: {
73                 screenshotWidth = displayHeight;
74                 screenshotHeight = displayWidth;
75             } break;
76             case ROTATION_FREEZE_180: {
77                 screenshotWidth = displayWidth;
78                 screenshotHeight = displayHeight;
79             } break;
80             case ROTATION_FREEZE_270: {
81                 screenshotWidth = displayHeight;
82                 screenshotHeight = displayWidth;
83             } break;
84             default: {
85                 throw new IllegalArgumentException("Invalid rotation: "
86                         + rotation);
87             }
88         }
89 
90         Log.d(TAG, "Taking screenshot of dimensions " + displayWidth + " x " + displayHeight);
91         // Take the screenshot
92         Bitmap screenShot =
93                 SurfaceControl.screenshot((int) screenshotWidth, (int) screenshotHeight);
94         if (screenShot == null) {
95             Log.e(TAG, "Failed to take screenshot of dimensions " + screenshotWidth + " x "
96                     + screenshotHeight);
97             return null;
98         }
99 
100         // Rotate the screenshot to the current orientation
101         if (rotation != ROTATION_FREEZE_0) {
102             Bitmap unrotatedScreenShot = Bitmap.createBitmap(displayWidth, displayHeight,
103                     Bitmap.Config.ARGB_8888, screenShot.hasAlpha(), screenShot.getColorSpace());
104             Canvas canvas = new Canvas(unrotatedScreenShot);
105             canvas.translate(unrotatedScreenShot.getWidth() / 2,
106                     unrotatedScreenShot.getHeight() / 2);
107             canvas.rotate(getDegreesForRotation(rotation));
108             canvas.translate(- screenshotWidth / 2, - screenshotHeight / 2);
109             canvas.drawBitmap(screenShot, 0, 0, null);
110             canvas.setBitmap(null);
111             screenShot.recycle();
112             screenShot = unrotatedScreenShot;
113         }
114 
115         // Optimization
116         screenShot.setHasAlpha(false);
117 
118         return screenShot;
119     }
120 
getDegreesForRotation(int value)121     private static float getDegreesForRotation(int value) {
122         switch (value) {
123             case Surface.ROTATION_90: {
124                 return 360f - 90f;
125             }
126             case Surface.ROTATION_180: {
127                 return 360f - 180f;
128             }
129             case Surface.ROTATION_270: {
130                 return 360f - 270f;
131             } default: {
132                 return 0;
133             }
134         }
135     }
136 
137 }
138