• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.ui.gfx;
6 
7 import android.content.Context;
8 import android.graphics.PixelFormat;
9 import android.graphics.Point;
10 import android.os.Build;
11 import android.util.DisplayMetrics;
12 import android.view.Display;
13 import android.view.Surface;
14 import android.view.WindowManager;
15 
16 import org.chromium.base.CalledByNative;
17 import org.chromium.base.JNINamespace;
18 
19 /**
20  * This class facilitates access to android information typically only
21  * available using the Java SDK, including {@link Display} properties.
22  *
23  * Currently the information consists of very raw display information (height, width, DPI scale)
24  * regarding the main display.
25  */
26 @JNINamespace("gfx")
27 public class DeviceDisplayInfo {
28 
29     private final Context mAppContext;
30     private final WindowManager mWinManager;
31     private Point mTempPoint = new Point();
32     private DisplayMetrics mTempMetrics = new DisplayMetrics();
33 
DeviceDisplayInfo(Context context)34     private DeviceDisplayInfo(Context context) {
35         mAppContext = context.getApplicationContext();
36         mWinManager = (WindowManager) mAppContext.getSystemService(Context.WINDOW_SERVICE);
37     }
38 
39     /**
40      * @return Display height in physical pixels.
41      */
42     @CalledByNative
getDisplayHeight()43     public int getDisplayHeight() {
44         getDisplay().getSize(mTempPoint);
45         return mTempPoint.y;
46     }
47 
48     /**
49      * @return Display width in physical pixels.
50      */
51     @CalledByNative
getDisplayWidth()52     public int getDisplayWidth() {
53         getDisplay().getSize(mTempPoint);
54         return mTempPoint.x;
55     }
56 
57     /**
58      * @return Real physical display height in physical pixels.
59      */
60     @CalledByNative
getPhysicalDisplayHeight()61     public int getPhysicalDisplayHeight() {
62         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
63             return 0;
64         }
65         getDisplay().getRealSize(mTempPoint);
66         return mTempPoint.y;
67     }
68 
69     /**
70      * @return Real physical display width in physical pixels.
71      */
72     @CalledByNative
getPhysicalDisplayWidth()73     public int getPhysicalDisplayWidth() {
74         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
75             return 0;
76         }
77         getDisplay().getRealSize(mTempPoint);
78         return mTempPoint.x;
79     }
80 
81     @SuppressWarnings("deprecation")
getPixelFormat()82     private int getPixelFormat() {
83         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
84             return getDisplay().getPixelFormat();
85         }
86         // JellyBean MR1 and later always uses RGBA_8888.
87         return PixelFormat.RGBA_8888;
88     }
89 
90     /**
91      * @return Bits per pixel.
92      */
93     @CalledByNative
getBitsPerPixel()94     public int getBitsPerPixel() {
95         int format = getPixelFormat();
96         PixelFormat info = new PixelFormat();
97         PixelFormat.getPixelFormatInfo(format, info);
98         return info.bitsPerPixel;
99     }
100 
101     /**
102      * @return Bits per component.
103      */
104     @SuppressWarnings("deprecation")
105     @CalledByNative
getBitsPerComponent()106     public int getBitsPerComponent() {
107         int format = getPixelFormat();
108         switch (format) {
109             case PixelFormat.RGBA_4444:
110                 return 4;
111 
112             case PixelFormat.RGBA_5551:
113                 return 5;
114 
115             case PixelFormat.RGBA_8888:
116             case PixelFormat.RGBX_8888:
117             case PixelFormat.RGB_888:
118                 return 8;
119 
120             case PixelFormat.RGB_332:
121                 return 2;
122 
123             case PixelFormat.RGB_565:
124                 return 5;
125 
126             // Non-RGB formats.
127             case PixelFormat.A_8:
128             case PixelFormat.LA_88:
129             case PixelFormat.L_8:
130                 return 0;
131 
132             // Unknown format. Use 8 as a sensible default.
133             default:
134                 return 8;
135         }
136     }
137 
138     /**
139      * @return A scaling factor for the Density Independent Pixel unit. 1.0 is
140      *         160dpi, 0.75 is 120dpi, 2.0 is 320dpi.
141      */
142     @CalledByNative
getDIPScale()143     public double getDIPScale() {
144         getDisplay().getMetrics(mTempMetrics);
145         return mTempMetrics.density;
146     }
147 
148     /**
149      * @return Smallest screen size in density-independent pixels that the
150      *         application will see, regardless of orientation.
151      */
152     @CalledByNative
getSmallestDIPWidth()153     private int getSmallestDIPWidth() {
154         return mAppContext.getResources().getConfiguration().smallestScreenWidthDp;
155     }
156 
157     /**
158      * @return the screen's rotation angle from its 'natural' orientation.
159      * Expected values are one of { 0, 90, 180, 270 }.
160      * See http://developer.android.com/reference/android/view/Display.html#getRotation()
161      * for more information about Display.getRotation() behavior.
162      */
163     @CalledByNative
getRotationDegrees()164     public int getRotationDegrees() {
165         switch (getDisplay().getRotation()) {
166             case Surface.ROTATION_0:
167                 return 0;
168             case Surface.ROTATION_90:
169                 return 90;
170             case Surface.ROTATION_180:
171                 return 180;
172             case Surface.ROTATION_270:
173                 return 270;
174         }
175 
176         // This should not happen.
177         assert false;
178         return 0;
179     }
180 
181     /**
182      * Inform the native implementation to update its cached representation of
183      * the DeviceDisplayInfo values.
184      */
updateNativeSharedDisplayInfo()185     public void updateNativeSharedDisplayInfo() {
186         nativeUpdateSharedDeviceDisplayInfo(
187                 getDisplayHeight(), getDisplayWidth(),
188                 getPhysicalDisplayHeight(), getPhysicalDisplayWidth(),
189                 getBitsPerPixel(), getBitsPerComponent(),
190                 getDIPScale(), getSmallestDIPWidth(), getRotationDegrees());
191     }
192 
getDisplay()193     private Display getDisplay() {
194         return mWinManager.getDefaultDisplay();
195     }
196 
197     /**
198      * Creates DeviceDisplayInfo for a given Context.
199      *
200      * @param context A context to use.
201      * @return DeviceDisplayInfo associated with a given Context.
202      */
203     @CalledByNative
create(Context context)204     public static DeviceDisplayInfo create(Context context) {
205         return new DeviceDisplayInfo(context);
206     }
207 
nativeUpdateSharedDeviceDisplayInfo( int displayHeight, int displayWidth, int physicalDisplayHeight, int physicalDisplayWidth, int bitsPerPixel, int bitsPerComponent, double dipScale, int smallestDIPWidth, int rotationDegrees)208     private native void nativeUpdateSharedDeviceDisplayInfo(
209             int displayHeight, int displayWidth,
210             int physicalDisplayHeight, int physicalDisplayWidth,
211             int bitsPerPixel, int bitsPerComponent, double dipScale,
212             int smallestDIPWidth, int rotationDegrees);
213 
214 }
215