1 /* 2 * Copyright (C) 2007 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 #include <stdio.h> 18 #include <assert.h> 19 20 #include <cutils/properties.h> 21 22 #include <gui/SurfaceComposerClient.h> 23 #include <ui/PixelFormat.h> 24 #include <ui/DisplayInfo.h> 25 26 #include "jni.h" 27 #include "JNIHelp.h" 28 #include <android_runtime/AndroidRuntime.h> 29 #include <utils/misc.h> 30 #include <utils/Log.h> 31 #include <cutils/properties.h> 32 33 // ---------------------------------------------------------------------------- 34 35 namespace android { 36 37 // ---------------------------------------------------------------------------- 38 39 struct offsets_t { 40 jfieldID display; 41 jfieldID pixelFormat; 42 jfieldID fps; 43 jfieldID density; 44 jfieldID xdpi; 45 jfieldID ydpi; 46 }; 47 static offsets_t offsets; 48 static bool headless = false; 49 50 // ---------------------------------------------------------------------------- 51 52 static void android_view_Display_init( 53 JNIEnv* env, jobject clazz, jint dpy) 54 { 55 DisplayInfo info; 56 if (headless) { 57 // initialize dummy display with reasonable values 58 info.pixelFormatInfo.format = 1; // RGB_8888 59 info.fps = 60; 60 info.density = 160; 61 info.xdpi = 160; 62 info.ydpi = 160; 63 } else { 64 status_t err = SurfaceComposerClient::getDisplayInfo(DisplayID(dpy), &info); 65 if (err < 0) { 66 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 67 return; 68 } 69 } 70 env->SetIntField(clazz, offsets.pixelFormat,info.pixelFormatInfo.format); 71 env->SetFloatField(clazz, offsets.fps, info.fps); 72 env->SetFloatField(clazz, offsets.density, info.density); 73 env->SetFloatField(clazz, offsets.xdpi, info.xdpi); 74 env->SetFloatField(clazz, offsets.ydpi, info.ydpi); 75 } 76 77 static jint android_view_Display_getRawWidthNative( 78 JNIEnv* env, jobject clazz) 79 { 80 if (headless) return 640; 81 DisplayID dpy = env->GetIntField(clazz, offsets.display); 82 return SurfaceComposerClient::getDisplayWidth(dpy); 83 } 84 85 static jint android_view_Display_getRawHeightNative( 86 JNIEnv* env, jobject clazz) 87 { 88 if (headless) return 480; 89 DisplayID dpy = env->GetIntField(clazz, offsets.display); 90 return SurfaceComposerClient::getDisplayHeight(dpy); 91 } 92 93 static jint android_view_Display_getOrientation( 94 JNIEnv* env, jobject clazz) 95 { 96 if (headless) return 0; // Surface.ROTATION_0 97 DisplayID dpy = env->GetIntField(clazz, offsets.display); 98 return SurfaceComposerClient::getDisplayOrientation(dpy); 99 } 100 101 static jint android_view_Display_getDisplayCount( 102 JNIEnv* env, jclass clazz) 103 { 104 if (headless) return 1; 105 return SurfaceComposerClient::getNumberOfDisplays(); 106 } 107 108 // ---------------------------------------------------------------------------- 109 110 const char* const kClassPathName = "android/view/Display"; 111 112 static void nativeClassInit(JNIEnv* env, jclass clazz); 113 114 static JNINativeMethod gMethods[] = { 115 { "nativeClassInit", "()V", 116 (void*)nativeClassInit }, 117 { "getDisplayCount", "()I", 118 (void*)android_view_Display_getDisplayCount }, 119 { "init", "(I)V", 120 (void*)android_view_Display_init }, 121 { "getRawWidthNative", "()I", 122 (void*)android_view_Display_getRawWidthNative }, 123 { "getRawHeightNative", "()I", 124 (void*)android_view_Display_getRawHeightNative }, 125 { "getOrientation", "()I", 126 (void*)android_view_Display_getOrientation } 127 }; 128 129 void nativeClassInit(JNIEnv* env, jclass clazz) 130 { 131 char value[PROPERTY_VALUE_MAX]; 132 133 property_get("ro.config.headless", value, "0"); 134 if (strcmp(value, "1") == 0) 135 headless = true; 136 137 offsets.display = env->GetFieldID(clazz, "mDisplay", "I"); 138 offsets.pixelFormat = env->GetFieldID(clazz, "mPixelFormat", "I"); 139 offsets.fps = env->GetFieldID(clazz, "mRefreshRate", "F"); 140 offsets.density = env->GetFieldID(clazz, "mDensity", "F"); 141 offsets.xdpi = env->GetFieldID(clazz, "mDpiX", "F"); 142 offsets.ydpi = env->GetFieldID(clazz, "mDpiY", "F"); 143 } 144 145 int register_android_view_Display(JNIEnv* env) 146 { 147 return AndroidRuntime::registerNativeMethods(env, 148 kClassPathName, gMethods, NELEM(gMethods)); 149 } 150 151 }; 152