Merge "Don't throw an exception from isProviderEnabled and getLastKnownLocation" into gingerbread
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 4fd0681..294c867 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
@@ -147,8 +148,7 @@
static status_t writeToParcel(
const sp<Surface>& control, Parcel* parcel);
- static sp<Surface> readFromParcel(
- const Parcel& data, const sp<Surface>& other);
+ static sp<Surface> readFromParcel(const Parcel& data);
static bool isValid(const sp<Surface>& surface) {
return (surface != 0) && surface->isValid();
@@ -244,6 +244,8 @@
uint32_t *pWidth, uint32_t *pHeight,
uint32_t *pFormat, uint32_t *pUsage) const;
+ static void cleanCachedSurfaces();
+
class BufferInfo {
uint32_t mWidth;
uint32_t mHeight;
@@ -298,6 +300,10 @@
// Inherently thread-safe
mutable Mutex mSurfaceLock;
mutable Mutex mApiLock;
+
+ // A cache of Surface objects that have been deserialized into this process.
+ static Mutex sCachedSurfacesLock;
+ static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces;
};
}; // namespace android
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 85a0084..14bea65 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -286,7 +286,8 @@
int32_t keyEventAction, int32_t keyEventFlags);
void dispatchTouches(nsecs_t when, InputDevice* device, uint32_t policyFlags);
void dispatchTouch(nsecs_t when, InputDevice* device, uint32_t policyFlags,
- InputDevice::TouchData* touch, BitSet32 idBits, int32_t motionEventAction);
+ InputDevice::TouchData* touch, BitSet32 idBits, uint32_t changedId,
+ int32_t motionEventAction);
// display
void resetDisplayProperties();
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index dc6332c..1de3a4f 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -374,15 +374,36 @@
}
-sp<Surface> Surface::readFromParcel(
- const Parcel& data, const sp<Surface>& other)
-{
- sp<Surface> result(other);
+
+Mutex Surface::sCachedSurfacesLock;
+DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces(wp<Surface>(0));
+
+sp<Surface> Surface::readFromParcel(const Parcel& data) {
+ Mutex::Autolock _l(sCachedSurfacesLock);
sp<IBinder> binder(data.readStrongBinder());
- if (other==0 || binder != other->mSurface->asBinder()) {
- result = new Surface(data, binder);
+ sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote();
+ if (surface == 0) {
+ surface = new Surface(data, binder);
+ sCachedSurfaces.add(binder, surface);
+ } else {
+ LOGW("Reusing surface!");
}
- return result;
+ if (surface->mSurface == 0) {
+ surface = 0;
+ }
+ cleanCachedSurfaces();
+ return surface;
+}
+
+// Remove the stale entries from the surface cache. This should only be called
+// with sCachedSurfacesLock held.
+void Surface::cleanCachedSurfaces() {
+ for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
+ wp<Surface> s(sCachedSurfaces.valueAt(i));
+ if (s == 0 || s.promote() == 0) {
+ sCachedSurfaces.removeItemsAt(i);
+ }
+ }
}
void Surface::init()
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index a438c69..a55864b 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -650,10 +650,20 @@
firstMotionSample = & motionEntry->firstSample;
}
+ // Set the X and Y offset depending on the input source.
+ float xOffset, yOffset;
+ if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+ xOffset = dispatchEntry->xOffset;
+ yOffset = dispatchEntry->yOffset;
+ } else {
+ xOffset = 0.0f;
+ yOffset = 0.0f;
+ }
+
// Publish the motion event and the first motion sample.
status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
motionEntry->source, action, motionEntry->edgeFlags, motionEntry->metaState,
- dispatchEntry->xOffset, dispatchEntry->yOffset,
+ xOffset, yOffset,
motionEntry->xPrecision, motionEntry->yPrecision,
motionEntry->downTime, firstMotionSample->eventTime,
motionEntry->pointerCount, motionEntry->pointerIds,
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index cd4654a..30e391f 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -270,6 +270,10 @@
device->trackball.accumulator.fields |=
InputDevice::TrackballState::Accumulator::FIELD_BTN_MOUSE;
device->trackball.accumulator.btnMouse = down;
+
+ // Process the trackball change now since we may not receive a sync immediately.
+ onTrackballStateChanged(rawEvent->when, device);
+ device->trackball.accumulator.clear();
return;
}
}
@@ -766,7 +770,7 @@
// The dispatcher takes care of batching moves so we don't have to deal with that here.
int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
dispatchTouch(when, device, policyFlags, & device->touchScreen.currentTouch,
- currentIdBits, motionEventAction);
+ currentIdBits, -1, motionEventAction);
} else {
// There may be pointers going up and pointers going down at the same time when pointer
// ids are reported by the device driver.
@@ -784,12 +788,11 @@
if (activeIdBits.isEmpty()) {
motionEventAction = AMOTION_EVENT_ACTION_UP;
} else {
- motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP
- | (upId << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+ motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP;
}
dispatchTouch(when, device, policyFlags, & device->touchScreen.lastTouch,
- oldActiveIdBits, motionEventAction);
+ oldActiveIdBits, upId, motionEventAction);
}
while (! downIdBits.isEmpty()) {
@@ -803,18 +806,17 @@
motionEventAction = AMOTION_EVENT_ACTION_DOWN;
device->touchScreen.downTime = when;
} else {
- motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN
- | (downId << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+ motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
}
dispatchTouch(when, device, policyFlags, & device->touchScreen.currentTouch,
- activeIdBits, motionEventAction);
+ activeIdBits, downId, motionEventAction);
}
}
}
void InputReader::dispatchTouch(nsecs_t when, InputDevice* device, uint32_t policyFlags,
- InputDevice::TouchData* touch, BitSet32 idBits,
+ InputDevice::TouchData* touch, BitSet32 idBits, uint32_t changedId,
int32_t motionEventAction) {
int32_t orientedWidth, orientedHeight;
switch (mDisplayOrientation) {
@@ -904,12 +906,15 @@
pointerCoords[pointerCount].toolMinor = toolMinor;
pointerCoords[pointerCount].orientation = orientation;
+ if (id == changedId) {
+ motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ }
+
pointerCount += 1;
}
// Check edge flags by looking only at the first pointer since the flags are
// global to the event.
- // XXX Maybe we should revise the edge flags API to work on a per-pointer basis.
int32_t motionEventEdgeFlags = 0;
if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
if (pointerCoords[0].x <= 0) {