summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/android/native_window.h14
-rw-r--r--libs/binder/BpBinder.cpp12
-rw-r--r--libs/binder/IServiceManager.cpp29
-rw-r--r--libs/gui/IGraphicBufferProducer.cpp14
-rw-r--r--libs/gui/Sensor.cpp8
-rw-r--r--libs/gui/Surface.cpp10
-rw-r--r--opengl/libagl/egl.cpp3
-rw-r--r--opengl/libs/EGL/Loader.cpp7
-rw-r--r--opengl/libs/EGL/eglApi.cpp44
-rw-r--r--opengl/libs/EGL/egl_object.cpp5
-rw-r--r--services/inputflinger/Android.mk3
-rw-r--r--services/inputflinger/EventHub.cpp35
-rw-r--r--services/inputflinger/EventHub.h1
-rw-r--r--services/inputflinger/InputReader.cpp92
-rw-r--r--services/inputflinger/InputReader.h8
-rw-r--r--services/surfaceflinger/Android.mk6
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp260
-rw-r--r--services/surfaceflinger/DisplayDevice.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp1
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp4
-rw-r--r--services/surfaceflinger/EventThread.cpp8
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp47
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h3
23 files changed, 534 insertions, 84 deletions
diff --git a/include/android/native_window.h b/include/android/native_window.h
index cf07f1a..d44ac05 100644
--- a/include/android/native_window.h
+++ b/include/android/native_window.h
@@ -27,6 +27,7 @@
#define ANDROID_NATIVE_WINDOW_H
#include <android/rect.h>
+#include <system/window.h>
#ifdef __cplusplus
extern "C" {
@@ -44,19 +45,6 @@ enum {
WINDOW_FORMAT_RGB_565 = 4,
};
-struct ANativeWindow;
-/**
- * {@link ANativeWindow} is opaque type that provides access to a native window.
- *
- * A pointer can be obtained using ANativeWindow_fromSurface().
- */
-typedef struct ANativeWindow ANativeWindow;
-
-/**
- * {@link ANativeWindow} is a struct that represents a windows buffer.
- *
- * A pointer can be obtained using ANativeWindow_lock().
- */
typedef struct ANativeWindow_Buffer {
// The number of pixels that are show horizontally.
int32_t width;
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 345ba20..a338276 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -159,14 +159,20 @@ status_t BpBinder::dump(int fd, const Vector<String16>& args)
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
- // Once a binder has died, it will never come back to life.
+ // Once a binder has died, it will never come back to life. But
+ // note that the special case of the global service manager cannot
+ // die; there is no guarantee in the framework that it will be
+ // alive before a binder service object is instantiated, so we
+ // ignore errors for that special object so that
+ // IServiceManager::addService() calls can be retried.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
- if (status == DEAD_OBJECT) mAlive = 0;
+ if (status == DEAD_OBJECT)
+ if (this != ProcessState::self()->getContextObject(NULL).get())
+ mAlive = 0;
return status;
}
-
return DEAD_OBJECT;
}
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 3c716df..e4df78a 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -28,6 +28,8 @@
#include <unistd.h>
+#define ADD_SERVICE_RETRY_SECS 10
+
namespace android {
sp<IServiceManager> defaultServiceManager()
@@ -155,13 +157,26 @@ public:
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeStrongBinder(service);
- data.writeInt32(allowIsolated ? 1 : 0);
- status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
- return err == NO_ERROR ? reply.readExceptionCode() : err;
+ status_t err;
+ for (int i=0; i<ADD_SERVICE_RETRY_SECS; i++) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+ data.writeString16(name);
+ data.writeStrongBinder(service);
+ data.writeInt32(allowIsolated ? 1 : 0);
+ err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
+ if (err == NO_ERROR)
+ return reply.readExceptionCode();
+ if (i != ADD_SERVICE_RETRY_SECS) {
+ ALOGI("addService() %s failed (err %d - no service manager yet?). Retrying...\n",
+ String8(name).string(), err);
+ sleep(1);
+ } else {
+ ALOGE("addService() %s failed (err %d). Giving up.\n",
+ String8(name).string(), err);
+ }
+ }
+ return err;
}
virtual Vector<String16> listServices()
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index c3c6235..da02c68 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -185,7 +185,12 @@ public:
if (result != NO_ERROR) {
return result;
}
- memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
+ const void *out_data =reply.readInplace(sizeof(*output));
+ if(out_data != NULL) {
+ memcpy(output, out_data, sizeof(*output));
+ } else {
+ return BAD_VALUE;
+ }
result = reply.readInt32();
return result;
}
@@ -227,7 +232,12 @@ public:
if (result != NO_ERROR) {
return result;
}
- memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
+ const void *out_data =reply.readInplace(sizeof(*output));
+ if(out_data != NULL) {
+ memcpy(output, out_data, sizeof(*output));
+ } else {
+ return BAD_VALUE;
+ }
result = reply.readInt32();
return result;
}
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 235cbbd..f0c52a0 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -376,10 +376,10 @@ size_t Sensor::getFlattenedSize() const
sizeof(bool);
size_t variableSize =
- sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) +
- sizeof(uint32_t) + FlattenableUtils::align<4>(mVendor.length()) +
- sizeof(uint32_t) + FlattenableUtils::align<4>(mStringType.length()) +
- sizeof(uint32_t) + FlattenableUtils::align<4>(mRequiredPermission.length());
+ sizeof(size_t) + FlattenableUtils::align<sizeof(size_t)>(mName.length()) +
+ sizeof(size_t) + FlattenableUtils::align<sizeof(size_t)>(mVendor.length()) +
+ sizeof(size_t) + FlattenableUtils::align<sizeof(size_t)>(mStringType.length()) +
+ sizeof(size_t) + FlattenableUtils::align<sizeof(size_t)>(mRequiredPermission.length());
return fixedSize + variableSize;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 4b76f98..4f8a9a1 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -141,9 +141,12 @@ int Surface::hook_queueBuffer(ANativeWindow* window,
int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
ANativeWindowBuffer** buffer) {
Surface* c = getSelf(window);
- ANativeWindowBuffer* buf;
+ ANativeWindowBuffer* buf = NULL;
int fenceFd = -1;
int result = c->dequeueBuffer(&buf, &fenceFd);
+
+ if (result != NO_ERROR) return result;
+
sp<Fence> fence(new Fence(fenceFd));
int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
if (waitResult != OK) {
@@ -254,10 +257,13 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
mGraphicBufferProducer->cancelBuffer(buf, fence);
return result;
+ } else if (gbuf == 0) {
+ ALOGE("dequeueBuffer: Buffer is null return");
+ return INVALID_OPERATION;
}
}
- if (fence->isValid()) {
+ if ((fence != NULL) && fence->isValid()) {
*fenceFd = fence->dup();
if (*fenceFd == -1) {
ALOGE("dequeueBuffer: error duping fence: %d", errno);
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 593d0c2..58aeabb 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -1468,6 +1468,9 @@ EGLBoolean eglGetConfigs( EGLDisplay dpy,
if (egl_display_t::is_valid(dpy) == EGL_FALSE)
return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ if (ggl_unlikely(num_config==0))
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+
GLint numConfigs = NELEM(gConfigs);
if (!configs) {
*num_config = numConfigs;
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 1fcc048..6bd2f6d 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -86,6 +86,13 @@ checkGlesEmulationStatus(void)
char prop[PROPERTY_VALUE_MAX];
int result = -1;
+ /* Check if hardware acceleration disabled explicitly */
+ property_get("debug.egl.hw", prop, "1");
+ if (!atoi(prop)) {
+ ALOGD("3D hardware acceleration is disabled");
+ return 0;
+ }
+
/* First, check for qemu=1 */
property_get("ro.kernel.qemu",prop,"0");
if (atoi(prop) != 1)
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index cdec565..a86c54c 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -23,6 +23,7 @@
#include <hardware/gralloc.h>
#include <system/window.h>
+#include <sys/mman.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -414,6 +415,35 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
}
// ----------------------------------------------------------------------------
+// Utility procedure to test a NativeWindowType for validity before referencing
+// through the pointer. It's not feasible to test for deliberate forgeries,
+// but this heuristic is good enough to test for basic accidental cases, using
+// the special "magic" value placed in a native-window structure.
+// ----------------------------------------------------------------------------
+EGLBoolean isValidNativeWindow(NativeWindowType window)
+{
+ ANativeWindow *nwindow = static_cast<ANativeWindow*>(window);
+ // the msync system call returns with ENOMEM error for unmapped memory
+ // pages. This is used here as a way to test whether we can read through a
+ // pointer without getting a segfault.
+ uintptr_t pagesize = (uintptr_t) sysconf(_SC_PAGESIZE);
+ uintptr_t addr = ((uintptr_t)(&nwindow->common.magic)) & (~(pagesize - 1));
+ int rc = msync((void *)addr, pagesize, MS_ASYNC);
+ if (0 == rc) {
+ if (nwindow->common.magic == ANDROID_NATIVE_WINDOW_MAGIC)
+ return EGL_TRUE;
+ else
+ return EGL_FALSE;
+ }
+ if (ENOMEM == errno)
+ return EGL_FALSE;
+ ALOGE("error unexpected msync error: %s (%d)",
+ strerror(-errno), errno);
+ return EGL_FALSE;
+}
+
+
+// ----------------------------------------------------------------------------
// surfaces
// ----------------------------------------------------------------------------
@@ -448,6 +478,10 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
if (dp) {
EGLDisplay iDpy = dp->disp.dpy;
+ if (!isValidNativeWindow(window)) {
+ ALOGE("EGLNativeWindow %p invalid", window);
+ return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
if (result != OK) {
ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
@@ -462,15 +496,19 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
// modify the EGLconfig's format before setting the native window's
// format.
- // by default, just pick RGBA_8888
- EGLint format = HAL_PIXEL_FORMAT_RGBA_8888;
+ EGLint format;
android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
EGLint a = 0;
cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a);
if (a > 0) {
// alpha-channel requested, there's really only one suitable format
- format = HAL_PIXEL_FORMAT_RGBA_8888;
+ if (!cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_NATIVE_VISUAL_ID,
+ &format)) {
+ ALOGE("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed: %#x",
+ eglGetError());
+ format = HAL_PIXEL_FORMAT_RGBA_8888;
+ }
} else {
EGLint r, g, b;
r = g = b = 0;
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 918faa8..dee64db 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -111,11 +111,6 @@ void egl_context_t::onMakeCurrent(EGLSurface draw, EGLSurface read) {
// call the implementation's glGetString(GL_EXTENSIONS)
const char* exts = (const char *)gEGLImpl.hooks[version]->gl.glGetString(GL_EXTENSIONS);
gl_extensions.setTo(exts);
- if (gl_extensions.find("GL_EXT_debug_marker") < 0) {
- String8 temp("GL_EXT_debug_marker ");
- temp.append(gl_extensions);
- gl_extensions.setTo(temp);
- }
// tokenize the supported extensions for the glGetStringi() wrapper
std::stringstream ss;
diff --git a/services/inputflinger/Android.mk b/services/inputflinger/Android.mk
index ed867d8..773064f 100644
--- a/services/inputflinger/Android.mk
+++ b/services/inputflinger/Android.mk
@@ -39,6 +39,9 @@ LOCAL_SHARED_LIBRARIES := \
#LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_CFLAGS += -Wno-unused-parameter
+ifneq ($(TARGET_BUILD_VARIANT),user)
+ LOCAL_CFLAGS += -DCONSOLE_MANAGER -DANDROID_VT=7
+endif
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 5859606..61817f3 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -50,6 +50,8 @@
#include <input/KeyCharacterMap.h>
#include <input/VirtualKeyMap.h>
+#include <linux/vt.h>
+
/* this macro is used to tell if "bit" is set in "array"
* it selects a byte from the array, and does a boolean AND
* operation with a byte that only has the relevant bit set.
@@ -790,6 +792,14 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
}
}
+#ifdef CONSOLE_MANAGER
+ struct vt_stat vs;
+ int fd_vt = open("/dev/tty0", O_RDWR | O_SYNC);
+ if (fd_vt >= 0) {
+ ioctl(fd_vt, VT_GETSTATE, &vs);
+ close(fd_vt);
+ }
+#endif
// Grab the next input event.
bool deviceChanged = false;
while (mPendingEventIndex < mPendingEventCount) {
@@ -844,6 +854,12 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
} else if ((readSize % sizeof(struct input_event)) != 0) {
ALOGE("could not get event (wrong size: %d)", readSize);
} else {
+#ifdef CONSOLE_MANAGER
+ if (vs.v_active != ANDROID_VT) {
+ ALOGV("Skip a non Android VT event");
+ continue;
+ }
+#endif
int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
size_t count = size_t(readSize) / sizeof(struct input_event);
@@ -1066,8 +1082,17 @@ static const int32_t GAMEPAD_KEYCODES[] = {
};
status_t EventHub::openDeviceLocked(const char *devicePath) {
+ return openDeviceLocked(devicePath, false);
+}
+
+status_t EventHub::openDeviceLocked(const char *devicePath, bool ignoreAlreadyOpened) {
char buffer[80];
+ if (ignoreAlreadyOpened && (getDeviceByPathLocked(devicePath) != 0)) {
+ ALOGV("Ignoring device '%s' that has already been opened.", devicePath);
+ return 0;
+ }
+
ALOGV("Opening device: %s", devicePath);
int fd = open(devicePath, O_RDWR | O_CLOEXEC);
@@ -1202,7 +1227,7 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
}
// Is this an old style single-touch driver?
- } else if (test_bit(BTN_TOUCH, device->keyBitmask)
+ } else if ((test_bit(BTN_TOUCH, device->keyBitmask) || test_bit(BTN_LEFT, device->keyBitmask))
&& test_bit(ABS_X, device->absBitmask)
&& test_bit(ABS_Y, device->absBitmask)) {
device->classes |= INPUT_DEVICE_CLASS_TOUCH;
@@ -1275,7 +1300,11 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
// 'Q' key support = cheap test of whether this is an alpha-capable kbd
if (hasKeycodeLocked(device, AKEYCODE_Q)) {
- device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.ignore_atkbd", value, "0");
+ if ((device->identifier.name != "AT Translated Set 2 keyboard") || (!atoi(value))) {
+ device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
+ }
}
// See if this device has a DPAD.
@@ -1617,7 +1646,7 @@ status_t EventHub::readNotifyLocked() {
if(event->len) {
strcpy(filename, event->name);
if(event->mask & IN_CREATE) {
- openDeviceLocked(devname);
+ openDeviceLocked(devname, true);
} else {
ALOGI("Removing device '%s' due to inotify event\n", devname);
closeDeviceByPathLocked(devname);
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h
index 0f94c77..ed61319 100644
--- a/services/inputflinger/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -379,6 +379,7 @@ private:
};
status_t openDeviceLocked(const char *devicePath);
+ status_t openDeviceLocked(const char *devicePath, bool ignoreAlreadyOpened);
void createVirtualKeyboardLocked();
void addDeviceLocked(Device* device);
void assignDescriptorLocked(InputDeviceIdentifier& identifier);
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index b2cbfe8..fb270ed 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -1345,7 +1345,7 @@ TouchButtonAccumulator::TouchButtonAccumulator() :
}
void TouchButtonAccumulator::configure(InputDevice* device) {
- mHaveBtnTouch = device->hasKey(BTN_TOUCH);
+ mHaveBtnTouch = device->hasKey(BTN_TOUCH) || device->hasKey(BTN_LEFT);
mHaveStylus = device->hasKey(BTN_TOOL_PEN)
|| device->hasKey(BTN_TOOL_RUBBER)
|| device->hasKey(BTN_TOOL_BRUSH)
@@ -1354,7 +1354,7 @@ void TouchButtonAccumulator::configure(InputDevice* device) {
}
void TouchButtonAccumulator::reset(InputDevice* device) {
- mBtnTouch = device->isKeyPressed(BTN_TOUCH);
+ mBtnTouch = device->isKeyPressed(BTN_TOUCH) || device->isKeyPressed(BTN_LEFT);
mBtnStylus = device->isKeyPressed(BTN_STYLUS);
// BTN_0 is what gets mapped for the HID usage Digitizers.SecondaryBarrelSwitch
mBtnStylus2 =
@@ -1393,6 +1393,7 @@ void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_KEY) {
switch (rawEvent->code) {
case BTN_TOUCH:
+ case BTN_LEFT:
mBtnTouch = rawEvent->value;
break;
case BTN_STYLUS:
@@ -2940,6 +2941,19 @@ void TouchInputMapper::configure(nsecs_t when,
configureSurface(when, &resetNeeded);
}
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
+ // Get 5-point calibration parameters
+ int *p = mCalibration.fiveCal;
+ p[6] = 0;
+ if (FILE *file = fopen("/data/misc/tscal/pointercal", "r")) {
+ if (fscanf(file, "%d %d %d %d %d %d %d", &p[0], &p[1], &p[2], &p[3], &p[4], &p[5], &p[6]) == 7) {
+ p[0] *= mXScale, p[1] *= mYScale, p[3] *= mXScale, p[4] *= mYScale;
+ ALOGD("pointercal loaded ok");
+ }
+ fclose(file);
+ }
+ }
+
if (changes && resetNeeded) {
// Send reset, unless this is the first time the device has been configured,
// in which case the reader will call reset itself after all mappers are ready.
@@ -2962,15 +2976,15 @@ void TouchInputMapper::configureParameters() {
// multitouch. The spot-based presentation relies on being able to accurately
// locate two or more fingers on the touch pad.
mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
- ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
+ ? Parameters::GESTURE_MODE_SINGLE_TOUCH : Parameters::GESTURE_MODE_MULTI_TOUCH;
String8 gestureModeString;
if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
gestureModeString)) {
- if (gestureModeString == "pointer") {
- mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
- } else if (gestureModeString == "spots") {
- mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
+ if (gestureModeString == "single-touch") {
+ mParameters.gestureMode = Parameters::GESTURE_MODE_SINGLE_TOUCH;
+ } else if (gestureModeString == "multi-touch") {
+ mParameters.gestureMode = Parameters::GESTURE_MODE_MULTI_TOUCH;
} else if (gestureModeString != "default") {
ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
}
@@ -3038,11 +3052,11 @@ void TouchInputMapper::dumpParameters(String8& dump) {
dump.append(INDENT3 "Parameters:\n");
switch (mParameters.gestureMode) {
- case Parameters::GESTURE_MODE_POINTER:
- dump.append(INDENT4 "GestureMode: pointer\n");
+ case Parameters::GESTURE_MODE_SINGLE_TOUCH:
+ dump.append(INDENT4 "GestureMode: single-touch\n");
break;
- case Parameters::GESTURE_MODE_SPOTS:
- dump.append(INDENT4 "GestureMode: spots\n");
+ case Parameters::GESTURE_MODE_MULTI_TOUCH:
+ dump.append(INDENT4 "GestureMode: multi-touch\n");
break;
default:
assert(false);
@@ -3637,6 +3651,8 @@ void TouchInputMapper::parseCalibration() {
out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
} else if (pressureCalibrationString == "amplitude") {
out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+ } else if (pressureCalibrationString == "disable") {
+ out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DISABLE;
} else if (pressureCalibrationString != "default") {
ALOGW("Invalid value for touch.pressure.calibration: '%s'",
pressureCalibrationString.string());
@@ -3707,6 +3723,9 @@ void TouchInputMapper::resolveCalibration() {
if (mRawPointerAxes.pressure.valid) {
if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
+ } else if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DISABLE) {
+ mRawPointerAxes.pressure.valid = false;
+ mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
}
} else {
mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
@@ -4701,11 +4720,24 @@ void TouchInputMapper::cookPointerData() {
// Adjust X, Y, and coverage coords for surface orientation.
float x, y;
float left, top, right, bottom;
+ float x_temp = float(xTransformed - mRawPointerAxes.x.minValue);
+ float y_temp = float(yTransformed - mRawPointerAxes.y.minValue);
+ float x_cal, y_cal;
+ int *p = mCalibration.fiveCal;
+ if (p[6]) {
+ // Apply 5-point calibration algorithm
+ x_cal = (x_temp * p[0] + y_temp * p[1] + p[2] ) / p[6];
+ y_cal = (x_temp * p[3] + y_temp * p[4] + p[5] ) / p[6];
+ ALOGV("5cal: x_temp=%f y_temp=%f x_cal=%f y_cal=%f", x_temp, y_temp, x_cal, y_cal);
+ } else {
+ x_cal = x_temp * mXScale;
+ y_cal = y_temp * mYScale;
+ }
switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
- x = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- y = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
+ x = y_cal + mYTranslate;
+ y = mSurfaceWidth - x_cal + mXTranslate;
left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
@@ -4716,8 +4748,8 @@ void TouchInputMapper::cookPointerData() {
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
- y = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
+ x = mSurfaceWidth - x_cal + mXTranslate;
+ y = mSurfaceHeight - y_cal + mYTranslate;
left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
@@ -4728,8 +4760,8 @@ void TouchInputMapper::cookPointerData() {
}
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
- y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+ x = mSurfaceHeight - y_cal + mYTranslate;
+ y = x_cal + mXTranslate;
left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
@@ -4740,8 +4772,8 @@ void TouchInputMapper::cookPointerData() {
}
break;
default:
- x = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- y = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+ x = x_cal + mXTranslate;
+ y = y_cal + mYTranslate;
left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
@@ -4838,14 +4870,17 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
}
// Update the pointer presentation and spots.
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
+ if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) {
+ mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
if (finishPreviousGesture || cancelPreviousGesture) {
mPointerController->clearSpots();
}
- mPointerController->setSpots(mPointerGesture.currentGestureCoords,
- mPointerGesture.currentGestureIdToIndex,
- mPointerGesture.currentGestureIdBits);
+
+ if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
+ mPointerController->setSpots(mPointerGesture.currentGestureCoords,
+ mPointerGesture.currentGestureIdToIndex,
+ mPointerGesture.currentGestureIdBits);
+ }
} else {
mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
}
@@ -4854,9 +4889,8 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
switch (mPointerGesture.currentGestureMode) {
case PointerGesture::NEUTRAL:
case PointerGesture::QUIET:
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
- && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
- || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
+ if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH
+ && mPointerGesture.lastGestureMode == PointerGesture::FREEFORM) {
// Remind the user of where the pointer is after finishing a gesture with spots.
mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
}
@@ -4866,15 +4900,15 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
case PointerGesture::BUTTON_CLICK_OR_DRAG:
case PointerGesture::HOVER:
case PointerGesture::PRESS:
+ case PointerGesture::SWIPE:
// Unfade the pointer when the current gesture manipulates the
// area directly under the pointer.
mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
break;
- case PointerGesture::SWIPE:
case PointerGesture::FREEFORM:
// Fade the pointer when the current gesture manipulates a different
// area and there are spots to guide the user experience.
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
+ if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) {
mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
} else {
mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 30c84b1..32bf188 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -1305,8 +1305,8 @@ protected:
bool hasButtonUnderPad;
enum GestureMode {
- GESTURE_MODE_POINTER,
- GESTURE_MODE_SPOTS,
+ GESTURE_MODE_SINGLE_TOUCH,
+ GESTURE_MODE_MULTI_TOUCH,
};
GestureMode gestureMode;
@@ -1340,6 +1340,7 @@ protected:
PRESSURE_CALIBRATION_NONE,
PRESSURE_CALIBRATION_PHYSICAL,
PRESSURE_CALIBRATION_AMPLITUDE,
+ PRESSURE_CALIBRATION_DISABLE,
};
PressureCalibration pressureCalibration;
@@ -1386,6 +1387,9 @@ protected:
*outSize = 0;
}
}
+
+ // 5-point calibration parameters
+ int fiveCal[7];
} mCalibration;
// Affine location transformation/calibration
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 1eb2361..d77540d 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -40,6 +40,9 @@ LOCAL_SRC_FILES := \
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+ifneq ($(TARGET_BUILD_VARIANT),user)
+ LOCAL_CFLAGS += -DCONSOLE_MANAGER -DANDROID_VT=7
+endif
ifeq ($(TARGET_BOARD_PLATFORM),omap4)
LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
endif
@@ -88,6 +91,9 @@ ifneq ($(MAX_VIRTUAL_DISPLAY_DIMENSION),)
else
LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=0
endif
+ifneq ($(BOARD_GPU_DRIVERS),)
+ LOCAL_C_INCLUDES := external/drm_gralloc
+endif
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
LOCAL_CFLAGS += -std=c++11
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 13d44f3..1e42c17 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -19,6 +19,11 @@
#include <string.h>
#include <math.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+
#include <cutils/properties.h>
#include <utils/RefBase.h>
@@ -39,11 +44,249 @@
#include "DisplayDevice.h"
#include "SurfaceFlinger.h"
#include "Layer.h"
+#include "gralloc_drm.h"
// ----------------------------------------------------------------------------
using namespace android;
// ----------------------------------------------------------------------------
+#ifdef CONSOLE_MANAGER
+class ConsoleManagerThread : public Thread {
+public:
+ ConsoleManagerThread(const sp<SurfaceFlinger>&, const wp<IBinder>&);
+ virtual ~ConsoleManagerThread();
+
+ status_t releaseScreen() const;
+
+private:
+ sp<SurfaceFlinger> mFlinger;
+ wp<IBinder> mDisplayToken;
+ int consoleFd;
+ long prev_vt_num;
+ vt_mode vm;
+ virtual void onFirstRef();
+ virtual status_t readyToRun();
+ virtual void requestExit();
+ virtual bool threadLoop();
+ static void sigHandler(int sig);
+ static pid_t sSignalCatcherPid;
+};
+
+ConsoleManagerThread::ConsoleManagerThread(const sp<SurfaceFlinger>& flinger, const wp<IBinder>& token)
+ : Thread(false), mFlinger(flinger), mDisplayToken(token), consoleFd(-1)
+{
+ sSignalCatcherPid = 0;
+
+ // create a new console
+ char const * const ttydev = "/dev/tty0";
+ int fd = open(ttydev, O_RDWR | O_SYNC);
+ if (fd < 0) {
+ ALOGE("Can't open %s, errno=%d (%s)", ttydev, errno, strerror(errno));
+ consoleFd = -errno;
+ return;
+ }
+ ALOGD("Open /dev/tty0 OK");
+
+ // to make sure that we are in text mode
+ int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
+ if (res < 0) {
+ ALOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
+ fd, res, strerror(errno));
+ }
+
+ // get the current console
+ struct vt_stat vs;
+ res = ioctl(fd, VT_GETSTATE, &vs);
+ if (res < 0) {
+ ALOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
+ fd, res, strerror(errno));
+ consoleFd = -errno;
+ return;
+ }
+
+ // switch to console 7 (which is what X normaly uses)
+ do {
+ res = ioctl(fd, VT_ACTIVATE, ANDROID_VT);
+ } while(res < 0 && errno == EINTR);
+ if (res < 0) {
+ ALOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for vt %d",
+ fd, errno, strerror(errno), ANDROID_VT);
+ consoleFd = -errno;
+ return;
+ }
+
+ do {
+ res = ioctl(fd, VT_WAITACTIVE, ANDROID_VT);
+ } while (res < 0 && errno == EINTR);
+ if (res < 0) {
+ ALOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for vt %d",
+ fd, res, errno, strerror(errno), ANDROID_VT);
+ consoleFd = -errno;
+ return;
+ }
+
+ // open the new console
+ close(fd);
+ fd = open(ttydev, O_RDWR | O_SYNC);
+ if (fd < 0) {
+ ALOGE("Can't open new console %s", ttydev);
+ consoleFd = -errno;
+ return;
+ }
+
+ /* disable console line buffer, echo, ... */
+ struct termios ttyarg;
+ ioctl(fd, TCGETS , &ttyarg);
+ ttyarg.c_iflag = 0;
+ ttyarg.c_lflag = 0;
+ ioctl(fd, TCSETS , &ttyarg);
+
+ // set up signals so we're notified when the console changes
+ // we can't use SIGUSR1 because it's used by the java-vm
+ vm.mode = VT_PROCESS;
+ vm.waitv = 0;
+ vm.relsig = SIGUSR2;
+ vm.acqsig = SIGUNUSED;
+ vm.frsig = 0;
+
+ struct sigaction act;
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = sigHandler;
+ act.sa_flags = 0;
+ sigaction(vm.relsig, &act, NULL);
+
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = sigHandler;
+ act.sa_flags = 0;
+ sigaction(vm.acqsig, &act, NULL);
+
+ sigset_t mask;
+ sigemptyset(&mask);
+ sigaddset(&mask, vm.relsig);
+ sigaddset(&mask, vm.acqsig);
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+
+ // switch to graphic mode
+ res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
+ ALOGW_IF(res < 0,
+ "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
+
+ prev_vt_num = vs.v_active;
+ consoleFd = fd;
+}
+
+ConsoleManagerThread::~ConsoleManagerThread()
+{
+ if (consoleFd >= 0) {
+ int fd = consoleFd;
+ int res;
+ ioctl(fd, KDSETMODE, (void*)KD_TEXT);
+ do {
+ res = ioctl(fd, VT_ACTIVATE, prev_vt_num);
+ } while(res < 0 && errno == EINTR);
+ do {
+ res = ioctl(fd, VT_WAITACTIVE, prev_vt_num);
+ } while(res < 0 && errno == EINTR);
+ close(fd);
+ char const * const ttydev = "/dev/tty0";
+ fd = open(ttydev, O_RDWR | O_SYNC);
+ ioctl(fd, VT_DISALLOCATE, 0);
+ close(fd);
+ }
+}
+
+status_t ConsoleManagerThread::releaseScreen() const
+{
+ int err = ioctl(consoleFd, VT_RELDISP, (void*)1);
+ ALOGE_IF(err < 0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
+ consoleFd, errno, strerror(errno));
+ return (err < 0) ? (-errno) : status_t(NO_ERROR);
+}
+
+void ConsoleManagerThread::onFirstRef()
+{
+ run("ConsoleManagerThread", PRIORITY_URGENT_DISPLAY);
+}
+
+status_t ConsoleManagerThread::readyToRun()
+{
+ if (consoleFd >= 0) {
+ sSignalCatcherPid = gettid();
+
+ sigset_t mask;
+ sigemptyset(&mask);
+ sigaddset(&mask, vm.relsig);
+ sigaddset(&mask, vm.acqsig);
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+
+ int res = ioctl(consoleFd, VT_SETMODE, &vm);
+ if (res < 0) {
+ ALOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
+ consoleFd, errno, strerror(errno));
+ }
+ return NO_ERROR;
+ }
+ return consoleFd;
+}
+
+void ConsoleManagerThread::requestExit()
+{
+ Thread::requestExit();
+ if (sSignalCatcherPid != 0) {
+ // wake the thread up
+ kill(sSignalCatcherPid, SIGINT);
+ // wait for it...
+ }
+}
+
+bool ConsoleManagerThread::threadLoop()
+{
+ sigset_t mask;
+ sigemptyset(&mask);
+ sigaddset(&mask, vm.relsig);
+ sigaddset(&mask, vm.acqsig);
+
+ int sig = 0;
+ sigwait(&mask, &sig);
+
+ hw_module_t const* mod;
+ gralloc_module_t const* gr = NULL;
+ status_t err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
+ if (!err) {
+ gr = reinterpret_cast<gralloc_module_t const*>(mod);
+ if (!gr->perform)
+ gr = NULL;
+ }
+
+ if (sig == vm.relsig) {
+ if (gr)
+ gr->perform(gr, GRALLOC_MODULE_PERFORM_LEAVE_VT);
+ mFlinger->screenReleased(mDisplayToken.promote());
+ } else if (sig == vm.acqsig) {
+ mFlinger->screenAcquired(mDisplayToken.promote());
+ if (gr)
+ gr->perform(gr, GRALLOC_MODULE_PERFORM_ENTER_VT);
+ }
+
+ return true;
+}
+
+void ConsoleManagerThread::sigHandler(int sig)
+{
+ // resend the signal to our signal catcher thread
+ ALOGW("received signal %d in thread %d, resending to %d",
+ sig, gettid(), sSignalCatcherPid);
+
+ // we absolutely need the delays below because without them
+ // our main thread never gets a chance to handle the signal.
+ usleep(10000);
+ kill(sSignalCatcherPid, sig);
+ usleep(10000);
+}
+
+pid_t ConsoleManagerThread::sSignalCatcherPid;
+#endif
+
#ifdef EGL_ANDROID_swap_rectangle
static constexpr bool kEGLAndroidSwapRectangle = true;
#else
@@ -83,6 +326,9 @@ DisplayDevice::DisplayDevice(
mPageFlipCount(),
mIsSecure(isSecure),
mSecureLayerVisible(false),
+#ifdef CONSOLE_MANAGER
+ mConsoleManagerThread(0),
+#endif
mLayerStack(NO_LAYER_STACK),
mOrientation(),
mPowerMode(HWC_POWER_MODE_OFF),
@@ -131,6 +377,9 @@ DisplayDevice::DisplayDevice(
switch (mType) {
case DISPLAY_PRIMARY:
mDisplayName = "Built-in Screen";
+#ifdef CONSOLE_MANAGER
+ mConsoleManagerThread = new ConsoleManagerThread(mFlinger, mDisplayToken);
+#endif
break;
case DISPLAY_EXTERNAL:
mDisplayName = "HDMI Screen";
@@ -149,6 +398,12 @@ DisplayDevice::~DisplayDevice() {
eglDestroySurface(mDisplay, mSurface);
mSurface = EGL_NO_SURFACE;
}
+#ifdef CONSOLE_MANAGER
+ if (mConsoleManagerThread != 0) {
+ mConsoleManagerThread->requestExitAndWait();
+ ALOGD("ConsoleManagerThread: destroy primary DisplayDevice");
+ }
+#endif
}
void DisplayDevice::disconnect(HWComposer& hwc) {
@@ -335,6 +590,11 @@ Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
// ----------------------------------------------------------------------------
void DisplayDevice::setPowerMode(int mode) {
mPowerMode = mode;
+#ifdef CONSOLE_MANAGER
+ if (mode != HWC_POWER_MODE_NORMAL && mConsoleManagerThread != 0) {
+ mConsoleManagerThread->releaseScreen();
+ }
+#endif
}
int DisplayDevice::getPowerMode() const {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 8695a44..852141c 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -34,6 +34,7 @@
#include "Transform.h"
struct ANativeWindow;
+class ConsoleManagerThread;
namespace android {
@@ -205,6 +206,9 @@ private:
// Whether we have a visible secure layer on this display
bool mSecureLayerVisible;
+#ifdef CONSOLE_MANAGER
+ sp<ConsoleManagerThread> mConsoleManagerThread;
+#endif
/*
* Transaction state
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 6ef3295..70af656 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -67,6 +67,7 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp,
mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp));
mConsumer->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp));
mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
+ mConsumer->setMaxAcquiredBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS - 1);
}
status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0859149..ff30bb3 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -422,7 +422,7 @@ status_t HWComposer::queryDisplayProperties(int disp) {
}
// FIXME: what should we set the format to?
- mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;
+ mDisplayData[disp].format = HAL_PIXEL_FORMAT_BGRA_8888;
mDisplayData[disp].connected = true;
return NO_ERROR;
}
@@ -846,7 +846,7 @@ int HWComposer::getVisualID() const {
// FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
// is supported by the implementation. we can only be in this case
// if we have HWC 1.1
- return HAL_PIXEL_FORMAT_RGBA_8888;
+ return HAL_PIXEL_FORMAT_BGRA_8888;
//return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
} else {
return mFbDev->format;
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index f760200..fa1423e 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -281,11 +281,11 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
}
// Here we figure out if we need to enable or disable vsyncs
- if (timestamp && !waitForVSync) {
- // we received a VSYNC but we have no clients
- // don't report it, and disable VSYNC events
+ if (!waitForVSync) {
+ // we have no clients waiting on next VSYNC
+ // just disable VSYNC events.
disableVSyncLocked();
- } else if (!timestamp && waitForVSync) {
+ } else if (!timestamp) {
// we have at least one client, so we want vsync enabled
// (TODO: this function is called right after we finish
// notifying clients of a vsync, so this call will be made
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fdc3650..31889f7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -585,8 +585,31 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
public:
static int getEmuDensity() {
return getDensityFromProperty("qemu.sf.lcd_density"); }
- static int getBuildDensity() {
- return getDensityFromProperty("ro.sf.lcd_density"); }
+ static int getBuildDensity(const DisplayInfo& info) {
+ static int density = getDensityFromProperty("ro.sf.lcd_density");
+#if defined(__i386__) || defined(__x86_64__)
+ if (density == 0) {
+ uint32_t area = info.w * info.h;
+ if (area <= 800 * 480) {
+ density = 120;
+ } else if (area <= 1024 * 600) {
+ density = 130;
+ } else if (area < 1024 * 768) {
+ density = 140;
+ } else if (area < 1920 * 1080) {
+ density = 160;
+ } else if (area < 2160 * 1440) {
+ density = 240;
+ } else if (area < 2736 * 1824) {
+ density = 280;
+ } else {
+ density = 320;
+ }
+ ALOGI("auto set density to %d", density);
+ }
+#endif
+ return density;
+ }
};
configs->clear();
@@ -599,10 +622,12 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
float xdpi = hwConfig.xdpi;
float ydpi = hwConfig.ydpi;
+ info.w = hwConfig.width;
+ info.h = hwConfig.height;
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// The density of the device is provided by a build property
- float density = Density::getBuildDensity() / 160.0f;
+ float density = Density::getBuildDensity(info) / 160.0f;
if (density == 0) {
// the build doesn't provide a density -- this is wrong!
// use xdpi instead
@@ -626,8 +651,6 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
info.orientation = 0;
}
- info.w = hwConfig.width;
- info.h = hwConfig.height;
info.xdpi = xdpi;
info.ydpi = ydpi;
info.fps = float(1e9 / hwConfig.refresh);
@@ -757,6 +780,20 @@ void SurfaceFlinger::waitForEvent() {
mEventQueue.waitMessage();
}
+#ifdef CONSOLE_MANAGER
+void SurfaceFlinger::screenReleased(const sp<IBinder>& display) {
+ // this may be called by a signal handler, we can't do too much in here
+ setPowerMode(display, HWC_POWER_MODE_OFF);
+ signalLayerUpdate();
+}
+
+void SurfaceFlinger::screenAcquired(const sp<IBinder>& display) {
+ // this may be called by a signal handler, we can't do too much in here
+ setPowerMode(display, HWC_POWER_MODE_NORMAL);
+ signalLayerUpdate();
+}
+#endif
+
void SurfaceFlinger::signalTransaction() {
mEventQueue.invalidate();
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b3baadd..10a74da 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -134,6 +134,9 @@ public:
return *mRenderEngine;
}
+ void screenReleased(const sp<IBinder>& display);
+ void screenAcquired(const sp<IBinder>& display);
+
private:
friend class Client;
friend class DisplayEventConnection;