diff options
author | Steve Kondik <shade@chemlab.org> | 2011-02-28 19:57:08 -0500 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2011-02-28 19:57:08 -0500 |
commit | 0352af015fa313a1be3deda6956fa4bcd8f50e66 (patch) | |
tree | 317badef4730aa39e2a1c9e461e949d8dd8fe533 /libs | |
parent | f1df5d9d3fc04b6d0e8268102eb3bc9c27937fac (diff) | |
parent | 322891c689c845b5aa63dbca606967eb9f8f900b (diff) | |
download | frameworks_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.cpp | 3 | ||||
-rw-r--r-- | libs/rs/rsContext.cpp | 1 | ||||
-rw-r--r-- | libs/rs/rsContext.h | 2 | ||||
-rw-r--r-- | libs/rs/rsSampler.cpp | 6 | ||||
-rw-r--r-- | libs/surfaceflinger_client/ISurfaceComposer.cpp | 4 | ||||
-rw-r--r-- | libs/surfaceflinger_client/SharedBufferStack.cpp | 35 | ||||
-rw-r--r-- | libs/surfaceflinger_client/Surface.cpp | 6 | ||||
-rw-r--r-- | libs/ui/EGLUtils.cpp | 23 | ||||
-rw-r--r-- | libs/ui/GraphicBuffer.cpp | 24 | ||||
-rw-r--r-- | libs/ui/GraphicBufferAllocator.cpp | 13 | ||||
-rw-r--r-- | libs/ui/InputDispatcher.cpp | 16 | ||||
-rw-r--r-- | libs/ui/InputReader.cpp | 52 | ||||
-rw-r--r-- | libs/ui/tests/InputReader_test.cpp | 12 | ||||
-rw-r--r-- | libs/utils/Threads.cpp | 3 |
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(); |