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