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 35namespace android { 36 37// ---------------------------------------------------------------------------- 38 39struct offsets_t { 40 jfieldID display; 41 jfieldID pixelFormat; 42 jfieldID fps; 43 jfieldID density; 44 jfieldID xdpi; 45 jfieldID ydpi; 46}; 47static offsets_t offsets; 48static bool headless = false; 49 50// ---------------------------------------------------------------------------- 51 52static 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 77static 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 85static 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 93static 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 101static jint android_view_Display_getDisplayCount( 102 JNIEnv* env, jclass clazz) 103{ 104 if (headless) return 1; 105 return SurfaceComposerClient::getNumberOfDisplays(); 106} 107 108// ---------------------------------------------------------------------------- 109 110const char* const kClassPathName = "android/view/Display"; 111 112static void nativeClassInit(JNIEnv* env, jclass clazz); 113 114static 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 129void 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 145int register_android_view_Display(JNIEnv* env) 146{ 147 return AndroidRuntime::registerNativeMethods(env, 148 kClassPathName, gMethods, NELEM(gMethods)); 149} 150 151}; 152