summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2011-02-28 19:57:08 -0500
committerSteve Kondik <shade@chemlab.org>2011-02-28 19:57:08 -0500
commit0352af015fa313a1be3deda6956fa4bcd8f50e66 (patch)
tree317badef4730aa39e2a1c9e461e949d8dd8fe533 /libs
parentf1df5d9d3fc04b6d0e8268102eb3bc9c27937fac (diff)
parent322891c689c845b5aa63dbca606967eb9f8f900b (diff)
downloadframeworks_base-0352af015fa313a1be3deda6956fa4bcd8f50e66.zip
frameworks_base-0352af015fa313a1be3deda6956fa4bcd8f50e66.tar.gz
frameworks_base-0352af015fa313a1be3deda6956fa4bcd8f50e66.tar.bz2
Merge branch 'gingerbread' of git://android.git.kernel.org/platform/frameworks/base into 233-merge
Conflicts: api/current.xml core/java/android/content/pm/PackageParser.java core/java/android/net/ConnectivityManager.java core/java/android/widget/TextView.java core/java/com/android/internal/os/BatteryStatsImpl.java core/res/res/drawable-mdpi/btn_check_off.png core/res/res/drawable-mdpi/btn_check_off_disable.png core/res/res/drawable-mdpi/btn_check_off_disable_focused.png core/res/res/drawable-mdpi/btn_check_off_pressed.png core/res/res/drawable-mdpi/btn_check_off_selected.png core/res/res/drawable-mdpi/btn_check_on.png core/res/res/drawable-mdpi/btn_check_on_disable.png core/res/res/drawable-mdpi/btn_check_on_disable_focused.png core/res/res/drawable-mdpi/btn_check_on_pressed.png core/res/res/drawable-mdpi/btn_check_on_selected.png core/res/res/values-ca/strings.xml core/res/res/values-de/strings.xml core/res/res/values/config.xml include/media/AudioSystem.h include/media/mediarecorder.h media/java/android/media/MediaRecorder.java media/libmedia/AudioSystem.cpp media/libstagefright/StagefrightMediaScanner.cpp media/libstagefright/rtsp/ARTSPConnection.cpp media/libstagefright/rtsp/ASessionDescription.cpp media/libstagefright/rtsp/MyHandler.h policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java policy/src/com/android/internal/policy/impl/LockScreen.java policy/src/com/android/internal/policy/impl/PhoneWindowManager.java policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java services/audioflinger/AudioPolicyManagerBase.cpp services/java/com/android/server/PackageManagerService.java services/java/com/android/server/am/ActivityManagerService.java test-runner/src/android/test/mock/MockPackageManager.java voip/java/android/net/sip/SipProfile.java voip/java/com/android/server/sip/SipService.java wifi/java/android/net/wifi/WifiStateTracker.java Change-Id: Ia65d02a66c6206b5f4ed95c3a64e3f28a03e7329
Diffstat (limited to 'libs')
-rw-r--r--libs/camera/Camera.cpp3
-rw-r--r--libs/rs/rsContext.cpp1
-rw-r--r--libs/rs/rsContext.h2
-rw-r--r--libs/rs/rsSampler.cpp6
-rw-r--r--libs/surfaceflinger_client/ISurfaceComposer.cpp4
-rw-r--r--libs/surfaceflinger_client/SharedBufferStack.cpp35
-rw-r--r--libs/surfaceflinger_client/Surface.cpp6
-rw-r--r--libs/ui/EGLUtils.cpp23
-rw-r--r--libs/ui/GraphicBuffer.cpp24
-rw-r--r--libs/ui/GraphicBufferAllocator.cpp13
-rw-r--r--libs/ui/InputDispatcher.cpp16
-rw-r--r--libs/ui/InputReader.cpp52
-rw-r--r--libs/ui/tests/InputReader_test.cpp12
-rw-r--r--libs/utils/Threads.cpp3
14 files changed, 130 insertions, 70 deletions
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index 15894c7..ade02ea 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -370,6 +370,9 @@ void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<
}
if (listener != NULL) {
listener->postDataTimestamp(timestamp, msgType, dataPtr);
+ } else {
+ LOGW("No listener was set. Drop a recording frame.");
+ releaseRecordingFrame(dataPtr);
}
}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 92c6619..90a2c79 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -572,6 +572,7 @@ void Context::setSurface(uint32_t w, uint32_t h, ANativeWindow *sur)
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGL.mMaxFragmentUniformVectors);
mGL.OES_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_OES_texture_npot");
+ mGL.GL_IMG_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_IMG_texture_npot");
}
}
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 709730e..e24fd09 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -166,6 +166,7 @@ public:
mutable const ObjectBase * mObjHead;
bool ext_OES_texture_npot() const {return mGL.OES_texture_npot;}
+ bool ext_GL_IMG_texture_npot() const {return mGL.GL_IMG_texture_npot;}
protected:
Device *mDev;
@@ -202,6 +203,7 @@ protected:
int32_t mMaxVertexTextureUnits;
bool OES_texture_npot;
+ bool GL_IMG_texture_npot;
} mGL;
uint32_t mWidth;
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 71f508f..5693c8a 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -70,7 +70,11 @@ void Sampler::setupGL(const Context *rsc, bool npot)
}
if ((mMinFilter == RS_SAMPLER_LINEAR_MIP_LINEAR) && forceNonMip) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ if (rsc->ext_GL_IMG_texture_npot()) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
}
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index 969ee79..a2a5455 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -247,13 +247,13 @@ status_t BnSurfaceComposer::onTransact(
int32_t mode = data.readInt32();
status_t res = turnElectronBeamOff(mode);
reply->writeInt32(res);
- }
+ } break;
case TURN_ELECTRON_BEAM_ON: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
int32_t mode = data.readInt32();
status_t res = turnElectronBeamOn(mode);
reply->writeInt32(res);
- }
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 4bc5d9e..b45e43f 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -58,7 +58,6 @@ SharedBufferStack::SharedBufferStack()
void SharedBufferStack::init(int32_t i)
{
- inUse = -2;
status = NO_ERROR;
identity = i;
}
@@ -199,9 +198,9 @@ String8 SharedBufferBase::dump(char const* prefix) const
SharedBufferStack& stack( *mSharedStack );
snprintf(buffer, SIZE,
"%s[ head=%2d, available=%2d, queued=%2d ] "
- "reallocMask=%08x, inUse=%2d, identity=%d, status=%d",
+ "reallocMask=%08x, identity=%d, status=%d",
prefix, stack.head, stack.available, stack.queued,
- stack.reallocMask, stack.inUse, stack.identity, stack.status);
+ stack.reallocMask, stack.identity, stack.status);
result.append(buffer);
result.append("\n");
return result;
@@ -261,8 +260,7 @@ bool SharedBufferClient::LockCondition::operator()() const {
// NOTE: if stack.head is messed up, we could crash the client
// or cause some drawing artifacts. This is okay, as long as it is
// limited to the client.
- return (buf != stack.index[stack.head] ||
- (stack.queued > 0 && stack.inUse != buf));
+ return (buf != stack.index[stack.head]);
}
// ----------------------------------------------------------------------------
@@ -295,22 +293,6 @@ ssize_t SharedBufferClient::CancelUpdate::operator()() {
return NO_ERROR;
}
-SharedBufferServer::UnlockUpdate::UnlockUpdate(
- SharedBufferBase* sbb, int lockedBuffer)
- : UpdateBase(sbb), lockedBuffer(lockedBuffer) {
-}
-ssize_t SharedBufferServer::UnlockUpdate::operator()() {
- if (stack.inUse != lockedBuffer) {
- LOGE("unlocking %d, but currently locked buffer is %d "
- "(identity=%d, token=%d)",
- lockedBuffer, stack.inUse,
- stack.identity, stack.token);
- return BAD_VALUE;
- }
- android_atomic_write(-1, &stack.inUse);
- return NO_ERROR;
-}
-
SharedBufferServer::RetireUpdate::RetireUpdate(
SharedBufferBase* sbb, int numBuffers)
: UpdateBase(sbb), numBuffers(numBuffers) {
@@ -320,9 +302,6 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() {
if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
return BAD_VALUE;
- // Preventively lock the current buffer before updating queued.
- android_atomic_write(stack.headBuf, &stack.inUse);
-
// Decrement the number of queued buffers
int32_t queued;
do {
@@ -338,7 +317,6 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() {
head = (head + 1) % numBuffers;
const int8_t headBuf = stack.index[head];
stack.headBuf = headBuf;
- android_atomic_write(headBuf, &stack.inUse);
// head is only modified here, so we don't need to use cmpxchg
android_atomic_write(head, &stack.head);
@@ -542,13 +520,6 @@ ssize_t SharedBufferServer::retireAndLock()
return buf;
}
-status_t SharedBufferServer::unlock(int buf)
-{
- UnlockUpdate update(this, buf);
- status_t err = updateCondition( update );
- return err;
-}
-
void SharedBufferServer::setStatus(status_t status)
{
if (status < NO_ERROR) {
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 854a3c6..017e94c 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -377,7 +377,7 @@ status_t Surface::writeToParcel(
Mutex Surface::sCachedSurfacesLock;
-DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces(wp<Surface>(0));
+DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces;
sp<Surface> Surface::readFromParcel(const Parcel& data) {
Mutex::Autolock _l(sCachedSurfacesLock);
@@ -390,13 +390,13 @@ sp<Surface> Surface::readFromParcel(const Parcel& data) {
if (surface->mSurface == 0) {
surface = 0;
}
- cleanCachedSurfaces();
+ cleanCachedSurfacesLocked();
return surface;
}
// Remove the stale entries from the surface cache. This should only be called
// with sCachedSurfacesLock held.
-void Surface::cleanCachedSurfaces() {
+void Surface::cleanCachedSurfacesLocked() {
for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
wp<Surface> s(sCachedSurfaces.valueAt(i));
if (s == 0 || s.promote() == 0) {
diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp
index 1663313..f24a71d 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/libs/ui/EGLUtils.cpp
@@ -66,12 +66,6 @@ status_t EGLUtils::selectConfigForPixelFormat(
if (outConfig == NULL)
return BAD_VALUE;
- int err;
- PixelFormatInfo fbFormatInfo;
- if ((err = getPixelFormatInfo(PixelFormat(format), &fbFormatInfo)) < 0) {
- return err;
- }
-
// Get all the "potential match" configs...
if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
return BAD_VALUE;
@@ -81,23 +75,14 @@ status_t EGLUtils::selectConfigForPixelFormat(
free(configs);
return BAD_VALUE;
}
-
- const int fbSzA = fbFormatInfo.getSize(PixelFormatInfo::INDEX_ALPHA);
- const int fbSzR = fbFormatInfo.getSize(PixelFormatInfo::INDEX_RED);
- const int fbSzG = fbFormatInfo.getSize(PixelFormatInfo::INDEX_GREEN);
- const int fbSzB = fbFormatInfo.getSize(PixelFormatInfo::INDEX_BLUE);
int i;
EGLConfig config = NULL;
for (i=0 ; i<n ; i++) {
- EGLint r,g,b,a;
- EGLConfig curr = configs[i];
- eglGetConfigAttrib(dpy, curr, EGL_RED_SIZE, &r);
- eglGetConfigAttrib(dpy, curr, EGL_GREEN_SIZE, &g);
- eglGetConfigAttrib(dpy, curr, EGL_BLUE_SIZE, &b);
- eglGetConfigAttrib(dpy, curr, EGL_ALPHA_SIZE, &a);
- if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB == b) {
- config = curr;
+ EGLint nativeVisualId = 0;
+ eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+ if (nativeVisualId>0 && format == nativeVisualId) {
+ config = configs[i];
break;
}
}
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 519c277..3671954 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -45,6 +45,7 @@ GraphicBuffer::GraphicBuffer()
stride =
format =
usage = 0;
+ transform = 0;
handle = NULL;
}
@@ -57,7 +58,8 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
height =
stride =
format =
- usage = 0;
+ usage =
+ transform = 0;
handle = NULL;
mInitCheck = initSize(w, h, reqFormat, reqUsage);
}
@@ -74,6 +76,7 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
stride = inStride;
format = inFormat;
usage = inUsage;
+ transform = 0;
handle = inHandle;
}
@@ -99,6 +102,11 @@ status_t GraphicBuffer::initCheck() const {
return mInitCheck;
}
+void GraphicBuffer::dumpAllocationsToSystemLog()
+{
+ GraphicBufferAllocator::dumpToSystemLog();
+}
+
android_native_buffer_t* GraphicBuffer::getNativeBuffer() const
{
return static_cast<android_native_buffer_t*>(
@@ -177,8 +185,10 @@ status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage)
return res;
}
+const int kFlattenFdsOffset = 9;
+
size_t GraphicBuffer::getFlattenedSize() const {
- return (8 + (handle ? handle->numInts : 0))*sizeof(int);
+ return (kFlattenFdsOffset + (handle ? handle->numInts : 0))*sizeof(int);
}
size_t GraphicBuffer::getFdCount() const {
@@ -203,13 +213,14 @@ status_t GraphicBuffer::flatten(void* buffer, size_t size,
buf[5] = usage;
buf[6] = 0;
buf[7] = 0;
+ buf[8] = transform;
if (handle) {
buf[6] = handle->numFds;
buf[7] = handle->numInts;
native_handle_t const* const h = handle;
memcpy(fds, h->data, h->numFds*sizeof(int));
- memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
+ memcpy(&buf[kFlattenFdsOffset], h->data + h->numFds, h->numInts*sizeof(int));
}
return NO_ERROR;
@@ -218,7 +229,7 @@ status_t GraphicBuffer::flatten(void* buffer, size_t size,
status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
int fds[], size_t count)
{
- if (size < 8*sizeof(int)) return NO_MEMORY;
+ if (size < kFlattenFdsOffset*sizeof(int)) return NO_MEMORY;
int const* buf = static_cast<int const*>(buffer);
if (buf[0] != 'GBFR') return BAD_TYPE;
@@ -226,7 +237,7 @@ status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
const size_t numFds = buf[6];
const size_t numInts = buf[7];
- const size_t sizeNeeded = (8 + numInts) * sizeof(int);
+ const size_t sizeNeeded = (kFlattenFdsOffset + numInts) * sizeof(int);
if (size < sizeNeeded) return NO_MEMORY;
size_t fdCountNeeded = 0;
@@ -243,9 +254,10 @@ status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
stride = buf[3];
format = buf[4];
usage = buf[5];
+ transform = buf[8];
native_handle* h = native_handle_create(numFds, numInts);
memcpy(h->data, fds, numFds*sizeof(int));
- memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));
+ memcpy(h->data + numFds, &buf[kFlattenFdsOffset], numInts*sizeof(int));
handle = h;
} else {
width = height = stride = format = usage = 0;
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index d51664d..9847a5f 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -63,7 +63,7 @@ void GraphicBufferAllocator::dump(String8& result) const
const size_t c = list.size();
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
- snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
+ snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
list.keyAt(i), rec.size/1024.0f,
rec.w, rec.s, rec.h, rec.format, rec.usage);
result.append(buffer);
@@ -73,6 +73,13 @@ void GraphicBufferAllocator::dump(String8& result) const
result.append(buffer);
}
+void GraphicBufferAllocator::dumpToSystemLog()
+{
+ String8 s;
+ GraphicBufferAllocator::getInstance().dump(s);
+ LOGD("%s", s.string());
+}
+
status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
int usage, buffer_handle_t* handle, int32_t* stride)
{
@@ -104,10 +111,6 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma
rec.usage = usage;
rec.size = h * stride[0] * bytesPerPixel(format);
list.add(*handle, rec);
- } else {
- String8 s;
- dump(s);
- LOGD("%s", s.string());
}
return err;
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index cbae662..d0da0f6 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -1405,8 +1405,13 @@ String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication*
void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
- if (eventEntry->type == EventEntry::TYPE_MOTION) {
+ switch (eventEntry->type) {
+ case EventEntry::TYPE_MOTION: {
const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
+ if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
+ return;
+ }
+
if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
switch (motionEntry->action) {
case AMOTION_EVENT_ACTION_DOWN:
@@ -1424,6 +1429,15 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
break;
}
}
+ break;
+ }
+ case EventEntry::TYPE_KEY: {
+ const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
+ if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
+ return;
+ }
+ break;
+ }
}
CommandEntry* commandEntry = postCommandLocked(
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 8000b2d..34e44e4 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -198,7 +198,7 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
const sp<InputDispatcherInterface>& dispatcher) :
mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
- mGlobalMetaState(0) {
+ mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
configureExcludedDevices();
updateGlobalMetaState();
updateInputConfiguration();
@@ -453,6 +453,24 @@ void InputReader::updateInputConfiguration() {
} // release state lock
}
+void InputReader::disableVirtualKeysUntil(nsecs_t time) {
+ mDisableVirtualKeysTimeout = time;
+}
+
+bool InputReader::shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode) {
+ if (now < mDisableVirtualKeysTimeout) {
+ LOGI("Dropping virtual key from device %s because virtual keys are "
+ "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
+ device->getName().string(),
+ (mDisableVirtualKeysTimeout - now) * 0.000001,
+ keyCode, scanCode);
+ return true;
+ } else {
+ return false;
+ }
+}
+
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
{ // acquire state lock
AutoMutex _l(mStateLock);
@@ -937,6 +955,11 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
} else {
// key down
+ if ((policyFlags & POLICY_FLAG_VIRTUAL)
+ && mContext->shouldDropVirtualKey(when, getDevice(), keyCode, scanCode)) {
+ return;
+ }
+
mLocked.keyDowns.push();
KeyDown& keyDown = mLocked.keyDowns.editTop();
keyDown.keyCode = keyCode;
@@ -1340,6 +1363,7 @@ void TouchInputMapper::configureParameters() {
mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+ mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
}
void TouchInputMapper::dumpParameters(String8& dump) {
@@ -2060,6 +2084,7 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
if (touchResult == DISPATCH_TOUCH) {
+ detectGestures(when);
dispatchTouches(when, policyFlags);
}
@@ -2145,6 +2170,11 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
if (mCurrentTouch.pointerCount == 1) {
const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
if (virtualKey) {
+ if (mContext->shouldDropVirtualKey(when, getDevice(),
+ virtualKey->keyCode, virtualKey->scanCode)) {
+ return DROP_STROKE;
+ }
+
mLocked.currentVirtualKey.down = true;
mLocked.currentVirtualKey.downTime = when;
mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
@@ -2182,6 +2212,26 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
return touchResult;
}
+void TouchInputMapper::detectGestures(nsecs_t when) {
+ // Disable all virtual key touches that happen within a short time interval of the
+ // most recent touch. The idea is to filter out stray virtual key presses when
+ // interacting with the touch screen.
+ //
+ // Problems we're trying to solve:
+ //
+ // 1. While scrolling a list or dragging the window shade, the user swipes down into a
+ // virtual key area that is implemented by a separate touch panel and accidentally
+ // triggers a virtual key.
+ //
+ // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
+ // area and accidentally triggers a virtual key. This often happens when virtual keys
+ // are layed out below the screen near to where the on screen keyboard's space bar
+ // is displayed.
+ if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
+ mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime);
+ }
+}
+
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
uint32_t currentPointerCount = mCurrentTouch.pointerCount;
uint32_t lastPointerCount = mLastTouch.pointerCount;
diff --git a/libs/ui/tests/InputReader_test.cpp b/libs/ui/tests/InputReader_test.cpp
index c53d9c0..09d1680 100644
--- a/libs/ui/tests/InputReader_test.cpp
+++ b/libs/ui/tests/InputReader_test.cpp
@@ -131,6 +131,10 @@ private:
return mFilterJumpyTouchEvents;
}
+ virtual nsecs_t getVirtualKeyQuietTime() {
+ return 0;
+ }
+
virtual void getVirtualKeyDefinitions(const String8& deviceName,
Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
ssize_t index = mVirtualKeyDefinitions.indexOfKey(deviceName);
@@ -631,6 +635,14 @@ private:
virtual InputDispatcherInterface* getDispatcher() {
return mDispatcher.get();
}
+
+ virtual void disableVirtualKeysUntil(nsecs_t time) {
+ }
+
+ virtual bool shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode) {
+ return false;
+ }
};
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 0b360f4..b1bd828 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -774,6 +774,9 @@ int Thread::_threadLoop(void* user)
self->mExitPending = true;
self->mLock.lock();
self->mRunning = false;
+ // clear thread ID so that requestExitAndWait() does not exit if
+ // called by a new thread using the same thread ID as this one.
+ self->mThread = thread_id_t(-1);
self->mThreadExitedCondition.broadcast();
self->mThread = thread_id_t(-1); // thread id could be reused
self->mLock.unlock();