Merge "Remove useless code."
diff --git a/include/ui/Input.h b/include/ui/Input.h
index c7ebf56..ba1c6b4 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -157,14 +157,6 @@
};
/*
- * Button state.
- */
-enum {
- // Primary button pressed (left mouse button).
- BUTTON_STATE_PRIMARY = 1 << 0,
-};
-
-/*
* Describes the basic configuration of input devices that are present.
*/
struct InputConfiguration {
@@ -235,6 +227,29 @@
};
/*
+ * Pointer property data.
+ */
+struct PointerProperties {
+ // The id of the pointer.
+ int32_t id;
+
+ // The pointer tool type.
+ int32_t toolType;
+
+ inline void clear() {
+ id = -1;
+ toolType = 0;
+ }
+
+ bool operator==(const PointerProperties& other) const;
+ inline bool operator!=(const PointerProperties& other) const {
+ return !(*this == other);
+ }
+
+ void copyFrom(const PointerProperties& other);
+};
+
+/*
* Input events.
*/
class InputEvent : public AInputEvent {
@@ -346,6 +361,8 @@
inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
+ inline int32_t getButtonState() const { return mButtonState; }
+
inline float getXOffset() const { return mXOffset; }
inline float getYOffset() const { return mYOffset; }
@@ -356,9 +373,21 @@
inline nsecs_t getDownTime() const { return mDownTime; }
- inline size_t getPointerCount() const { return mPointerIds.size(); }
+ inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; }
- inline int32_t getPointerId(size_t pointerIndex) const { return mPointerIds[pointerIndex]; }
+ inline size_t getPointerCount() const { return mPointerProperties.size(); }
+
+ inline const PointerProperties* getPointerProperties(size_t pointerIndex) const {
+ return &mPointerProperties[pointerIndex];
+ }
+
+ inline int32_t getPointerId(size_t pointerIndex) const {
+ return mPointerProperties[pointerIndex].id;
+ }
+
+ inline int32_t getToolType(size_t pointerIndex) const {
+ return mPointerProperties[pointerIndex].toolType;
+ }
inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
@@ -490,6 +519,7 @@
int32_t flags,
int32_t edgeFlags,
int32_t metaState,
+ int32_t buttonState,
float xOffset,
float yOffset,
float xPrecision,
@@ -497,7 +527,7 @@
nsecs_t downTime,
nsecs_t eventTime,
size_t pointerCount,
- const int32_t* pointerIds,
+ const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords);
void copyFrom(const MotionEvent* other, bool keepHistory);
@@ -523,7 +553,9 @@
}
// Low-level accessors.
- inline const int32_t* getPointerIds() const { return mPointerIds.array(); }
+ inline const PointerProperties* getPointerProperties() const {
+ return mPointerProperties.array();
+ }
inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
inline const PointerCoords* getSamplePointerCoords() const {
return mSamplePointerCoords.array();
@@ -534,12 +566,13 @@
int32_t mFlags;
int32_t mEdgeFlags;
int32_t mMetaState;
+ int32_t mButtonState;
float mXOffset;
float mYOffset;
float mXPrecision;
float mYPrecision;
nsecs_t mDownTime;
- Vector<int32_t> mPointerIds;
+ Vector<PointerProperties> mPointerProperties;
Vector<nsecs_t> mSampleEventTimes;
Vector<PointerCoords> mSamplePointerCoords;
};
diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h
index 119db81..95e4447 100644
--- a/include/ui/InputTransport.h
+++ b/include/ui/InputTransport.h
@@ -136,6 +136,7 @@
int32_t action;
int32_t flags;
int32_t metaState;
+ int32_t buttonState;
int32_t edgeFlags;
nsecs_t downTime;
float xOffset;
@@ -143,7 +144,7 @@
float xPrecision;
float yPrecision;
size_t pointerCount;
- int32_t pointerIds[MAX_POINTERS];
+ PointerProperties pointerProperties[MAX_POINTERS];
size_t sampleCount;
SampleData sampleData[0]; // variable length
} motion;
@@ -221,6 +222,7 @@
int32_t flags,
int32_t edgeFlags,
int32_t metaState,
+ int32_t buttonState,
float xOffset,
float yOffset,
float xPrecision,
@@ -228,7 +230,7 @@
nsecs_t downTime,
nsecs_t eventTime,
size_t pointerCount,
- const int32_t* pointerIds,
+ const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords);
/* Appends a motion sample to a motion event unless already consumed.
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index d811dd7..1ba38a7 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -373,6 +373,19 @@
}
+// --- PointerProperties ---
+
+bool PointerProperties::operator==(const PointerProperties& other) const {
+ return id == other.id
+ && toolType == other.toolType;
+}
+
+void PointerProperties::copyFrom(const PointerProperties& other) {
+ id = other.id;
+ toolType = other.toolType;
+}
+
+
// --- MotionEvent ---
void MotionEvent::initialize(
@@ -382,6 +395,7 @@
int32_t flags,
int32_t edgeFlags,
int32_t metaState,
+ int32_t buttonState,
float xOffset,
float yOffset,
float xPrecision,
@@ -389,20 +403,21 @@
nsecs_t downTime,
nsecs_t eventTime,
size_t pointerCount,
- const int32_t* pointerIds,
+ const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords) {
InputEvent::initialize(deviceId, source);
mAction = action;
mFlags = flags;
mEdgeFlags = edgeFlags;
mMetaState = metaState;
+ mButtonState = buttonState;
mXOffset = xOffset;
mYOffset = yOffset;
mXPrecision = xPrecision;
mYPrecision = yPrecision;
mDownTime = downTime;
- mPointerIds.clear();
- mPointerIds.appendArray(pointerIds, pointerCount);
+ mPointerProperties.clear();
+ mPointerProperties.appendArray(pointerProperties, pointerCount);
mSampleEventTimes.clear();
mSamplePointerCoords.clear();
addSample(eventTime, pointerCoords);
@@ -414,12 +429,13 @@
mFlags = other->mFlags;
mEdgeFlags = other->mEdgeFlags;
mMetaState = other->mMetaState;
+ mButtonState = other->mButtonState;
mXOffset = other->mXOffset;
mYOffset = other->mYOffset;
mXPrecision = other->mXPrecision;
mYPrecision = other->mYPrecision;
mDownTime = other->mDownTime;
- mPointerIds = other->mPointerIds;
+ mPointerProperties = other->mPointerProperties;
if (keepHistory) {
mSampleEventTimes = other->mSampleEventTimes;
@@ -484,9 +500,9 @@
}
ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
- size_t pointerCount = mPointerIds.size();
+ size_t pointerCount = mPointerProperties.size();
for (size_t i = 0; i < pointerCount; i++) {
- if (mPointerIds.itemAt(i) == pointerId) {
+ if (mPointerProperties.itemAt(i).id == pointerId) {
return i;
}
}
@@ -583,21 +599,25 @@
mFlags = parcel->readInt32();
mEdgeFlags = parcel->readInt32();
mMetaState = parcel->readInt32();
+ mButtonState = parcel->readInt32();
mXOffset = parcel->readFloat();
mYOffset = parcel->readFloat();
mXPrecision = parcel->readFloat();
mYPrecision = parcel->readFloat();
mDownTime = parcel->readInt64();
- mPointerIds.clear();
- mPointerIds.setCapacity(pointerCount);
+ mPointerProperties.clear();
+ mPointerProperties.setCapacity(pointerCount);
mSampleEventTimes.clear();
mSampleEventTimes.setCapacity(sampleCount);
mSamplePointerCoords.clear();
mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
for (size_t i = 0; i < pointerCount; i++) {
- mPointerIds.push(parcel->readInt32());
+ mPointerProperties.push();
+ PointerProperties& properties = mPointerProperties.editTop();
+ properties.id = parcel->readInt32();
+ properties.toolType = parcel->readInt32();
}
while (sampleCount-- > 0) {
@@ -614,7 +634,7 @@
}
status_t MotionEvent::writeToParcel(Parcel* parcel) const {
- size_t pointerCount = mPointerIds.size();
+ size_t pointerCount = mPointerProperties.size();
size_t sampleCount = mSampleEventTimes.size();
parcel->writeInt32(pointerCount);
@@ -626,6 +646,7 @@
parcel->writeInt32(mFlags);
parcel->writeInt32(mEdgeFlags);
parcel->writeInt32(mMetaState);
+ parcel->writeInt32(mButtonState);
parcel->writeFloat(mXOffset);
parcel->writeFloat(mYOffset);
parcel->writeFloat(mXPrecision);
@@ -633,7 +654,9 @@
parcel->writeInt64(mDownTime);
for (size_t i = 0; i < pointerCount; i++) {
- parcel->writeInt32(mPointerIds.itemAt(i));
+ const PointerProperties& properties = mPointerProperties.itemAt(i);
+ parcel->writeInt32(properties.id);
+ parcel->writeInt32(properties.toolType);
}
const PointerCoords* pc = mSamplePointerCoords.array();
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index 93d0d1f..ffdfe66 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -366,6 +366,7 @@
int32_t flags,
int32_t edgeFlags,
int32_t metaState,
+ int32_t buttonState,
float xOffset,
float yOffset,
float xPrecision,
@@ -373,16 +374,17 @@
nsecs_t downTime,
nsecs_t eventTime,
size_t pointerCount,
- const int32_t* pointerIds,
+ const PointerProperties* pointerProperties,
const PointerCoords* pointerCoords) {
#if DEBUG_TRANSPORT_ACTIONS
LOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, source=0x%x, "
- "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, xOffset=%f, yOffset=%f, "
+ "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
+ "xOffset=%f, yOffset=%f, "
"xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
"pointerCount=%d",
mChannel->getName().string(),
- deviceId, source, action, flags, edgeFlags, metaState, xOffset, yOffset,
- xPrecision, yPrecision, downTime, eventTime, pointerCount);
+ deviceId, source, action, flags, edgeFlags, metaState, buttonState,
+ xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
#endif
if (pointerCount > MAX_POINTERS || pointerCount < 1) {
@@ -400,6 +402,7 @@
mSharedMessage->motion.flags = flags;
mSharedMessage->motion.edgeFlags = edgeFlags;
mSharedMessage->motion.metaState = metaState;
+ mSharedMessage->motion.buttonState = buttonState;
mSharedMessage->motion.xOffset = xOffset;
mSharedMessage->motion.yOffset = yOffset;
mSharedMessage->motion.xPrecision = xPrecision;
@@ -411,7 +414,7 @@
mSharedMessage->motion.sampleData[0].eventTime = eventTime;
for (size_t i = 0; i < pointerCount; i++) {
- mSharedMessage->motion.pointerIds[i] = pointerIds[i];
+ mSharedMessage->motion.pointerProperties[i].copyFrom(pointerProperties[i]);
mSharedMessage->motion.sampleData[0].coords[i].copyFrom(pointerCoords[i]);
}
@@ -694,6 +697,7 @@
mSharedMessage->motion.flags,
mSharedMessage->motion.edgeFlags,
mSharedMessage->motion.metaState,
+ mSharedMessage->motion.buttonState,
mSharedMessage->motion.xOffset,
mSharedMessage->motion.yOffset,
mSharedMessage->motion.xPrecision,
@@ -701,7 +705,7 @@
mSharedMessage->motion.downTime,
mSharedMessage->motion.sampleData[0].eventTime,
mSharedMessage->motion.pointerCount,
- mSharedMessage->motion.pointerIds,
+ mSharedMessage->motion.pointerProperties,
mSharedMessage->motion.sampleData[0].coords);
size_t sampleCount = mSharedMessage->motion.sampleCount;
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp
index b77489e..e48d5b7 100644
--- a/libs/ui/tests/InputEvent_test.cpp
+++ b/libs/ui/tests/InputEvent_test.cpp
@@ -232,7 +232,14 @@
const float MotionEventTest::Y_OFFSET = 1.1f;
void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
- int32_t pointerIds[] = { 1, 2 };
+ PointerProperties pointerProperties[2];
+ pointerProperties[0].clear();
+ pointerProperties[0].id = 1;
+ pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ pointerProperties[1].clear();
+ pointerProperties[1].id = 2;
+ pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+
PointerCoords pointerCoords[2];
pointerCoords[0].clear();
pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
@@ -256,10 +263,10 @@
pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
- AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON,
+ AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
- 2, pointerIds, pointerCoords);
+ 2, pointerProperties, pointerCoords);
pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
@@ -311,6 +318,7 @@
ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState());
ASSERT_EQ(X_OFFSET, event->getXOffset());
ASSERT_EQ(Y_OFFSET, event->getYOffset());
ASSERT_EQ(2.0f, event->getXPrecision());
@@ -319,7 +327,9 @@
ASSERT_EQ(2U, event->getPointerCount());
ASSERT_EQ(1, event->getPointerId(0));
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, event->getToolType(0));
ASSERT_EQ(2, event->getPointerId(1));
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, event->getToolType(1));
ASSERT_EQ(2U, event->getHistorySize());
@@ -534,19 +544,20 @@
const float ROTATION = ARC * 2;
const size_t pointerCount = 11;
- int pointerIds[pointerCount];
+ PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
for (size_t i = 0; i < pointerCount; i++) {
float angle = float(i * ARC * PI_180);
- pointerIds[i] = i;
+ pointerProperties[i].clear();
+ pointerProperties[i].id = i;
pointerCoords[i].clear();
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, sinf(angle) * RADIUS + 3);
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, -cosf(angle) * RADIUS + 2);
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
}
MotionEvent event;
- event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+ event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
float originalRawX = 0 + 3;
float originalRawY = -RADIUS + 2;
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
index 6e18a4f..fcc4cad 100644
--- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
@@ -156,13 +156,19 @@
const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
+ const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
const float xOffset = -10;
const float yOffset = -20;
const float xPrecision = 0.25;
const float yPrecision = 0.5;
const nsecs_t downTime = 3;
const size_t pointerCount = 3;
- const int32_t pointerIds[pointerCount] = { 2, 0, 1 };
+ PointerProperties pointerProperties[pointerCount];
+ for (size_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].clear();
+ pointerProperties[i].id = (i + 2) % pointerCount;
+ pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ }
Vector<nsecs_t> sampleEventTimes;
Vector<PointerCoords> samplePointerCoords;
@@ -186,8 +192,9 @@
}
status = mPublisher->publishMotionEvent(deviceId, source, action, flags, edgeFlags,
- metaState, xOffset, yOffset, xPrecision, yPrecision,
- downTime, sampleEventTimes[0], pointerCount, pointerIds, samplePointerCoords.array());
+ metaState, buttonState, xOffset, yOffset, xPrecision, yPrecision,
+ downTime, sampleEventTimes[0], pointerCount,
+ pointerProperties, samplePointerCoords.array());
ASSERT_EQ(OK, status)
<< "publisher publishMotionEvent should return OK";
@@ -234,6 +241,7 @@
EXPECT_EQ(flags, motionEvent->getFlags());
EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
EXPECT_EQ(metaState, motionEvent->getMetaState());
+ EXPECT_EQ(buttonState, motionEvent->getButtonState());
EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
EXPECT_EQ(downTime, motionEvent->getDownTime());
@@ -243,7 +251,8 @@
for (size_t i = 0; i < pointerCount; i++) {
SCOPED_TRACE(i);
- EXPECT_EQ(pointerIds[i], motionEvent->getPointerId(i));
+ EXPECT_EQ(pointerProperties[i].id, motionEvent->getPointerId(i));
+ EXPECT_EQ(pointerProperties[i].toolType, motionEvent->getToolType(i));
}
for (size_t sampleIndex = 0; sampleIndex < lastSampleIndex; sampleIndex++) {
@@ -352,17 +361,20 @@
ASSERT_NO_FATAL_FAILURE(Initialize());
const size_t pointerCount = 1;
- int32_t pointerIds[pointerCount] = { 0 };
+ PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
- pointerCoords[0].clear();
+ for (size_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].clear();
+ pointerCoords[i].clear();
+ }
- status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- pointerCount, pointerIds, pointerCoords);
+ status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(OK, status)
<< "publisher publishMotionEvent should return OK";
- status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- pointerCount, pointerIds, pointerCoords);
+ status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(INVALID_OPERATION, status)
<< "publisher publishMotionEvent should return INVALID_OPERATION because ";
"the publisher was not reset";
@@ -373,11 +385,11 @@
ASSERT_NO_FATAL_FAILURE(Initialize());
const size_t pointerCount = 0;
- int32_t pointerIds[pointerCount];
+ PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
- status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- pointerCount, pointerIds, pointerCoords);
+ status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(BAD_VALUE, status)
<< "publisher publishMotionEvent should return BAD_VALUE";
}
@@ -387,11 +399,15 @@
ASSERT_NO_FATAL_FAILURE(Initialize());
const size_t pointerCount = MAX_POINTERS + 1;
- int32_t pointerIds[pointerCount];
+ PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
+ for (size_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].clear();
+ pointerCoords[i].clear();
+ }
- status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- pointerCount, pointerIds, pointerCoords);
+ status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(BAD_VALUE, status)
<< "publisher publishMotionEvent should return BAD_VALUE";
}
@@ -432,11 +448,15 @@
ASSERT_NO_FATAL_FAILURE(Initialize());
const size_t pointerCount = MAX_POINTERS;
- int32_t pointerIds[pointerCount];
+ PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
+ for (size_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].clear();
+ pointerCoords[i].clear();
+ }
status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_DOWN,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(OK, status);
status = mPublisher->appendMotionSample(0, pointerCoords);
@@ -449,11 +469,15 @@
ASSERT_NO_FATAL_FAILURE(Initialize());
const size_t pointerCount = MAX_POINTERS;
- int32_t pointerIds[pointerCount];
+ PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
+ for (size_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].clear();
+ pointerCoords[i].clear();
+ }
status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(OK, status);
status = mPublisher->sendDispatchSignal();
@@ -476,11 +500,15 @@
ASSERT_NO_FATAL_FAILURE(Initialize());
const size_t pointerCount = MAX_POINTERS;
- int32_t pointerIds[pointerCount];
+ PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
+ for (size_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].clear();
+ pointerCoords[i].clear();
+ }
status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(OK, status);
for (int count = 1;; count++) {
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index ad4a308..cfb013e 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -454,6 +454,20 @@
return dest;
}
+static void calc_tar_checksum(char* buf) {
+ // [ 148 : 8 ] checksum -- to be calculated with this field as space chars
+ memset(buf + 148, ' ', 8);
+
+ uint16_t sum = 0;
+ for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
+ sum += *p;
+ }
+
+ // Now write the real checksum value:
+ // [ 148 : 8 ] checksum: 6 octal digits [leading zeroes], NUL, SPC
+ sprintf(buf + 148, "%06o", sum); // the trailing space is already in place
+}
+
int write_tarfile(const String8& packageName, const String8& domain,
const String8& rootpath, const String8& filepath, BackupDataWriter* writer)
{
@@ -462,12 +476,18 @@
if (*relstart == '/') relstart++; // won't be true when path == rootpath
String8 relpath(relstart);
+ // If relpath is empty, it means this is the top of one of the standard named
+ // domain directories, so we should just skip it
+ if (relpath.length() == 0) {
+ return 0;
+ }
+
// Too long a name for the ustar format?
// "apps/" + packagename + '/' + domainpath < 155 chars
// relpath < 100 chars
+ bool needExtended = false;
if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {
- LOGE("Filename [%s] too long, skipping", relpath.string());
- return -1;
+ needExtended = true;
}
int err = 0;
@@ -478,6 +498,9 @@
return err;
}
+ String8 fullname; // for pax later on
+ String8 prefix;
+
const int isdir = S_ISDIR(s.st_mode);
// !!! TODO: use mmap when possible to avoid churning the buffer cache
@@ -491,48 +514,29 @@
// read/write up to this much at a time.
const size_t BUFSIZE = 32 * 1024;
-
char* buf = new char[BUFSIZE];
+ char* paxHeader = buf + 512; // use a different chunk of it as separate scratch
+ char* paxData = buf + 1024;
+
if (buf == NULL) {
LOGE("Out of mem allocating transfer buffer");
err = ENOMEM;
- goto done;
+ goto cleanup;
}
// Good to go -- first construct the standard tar header at the start of the buffer
memset(buf, 0, 512); // tar header is 512 bytes
+ memset(paxHeader, 0, 512);
// Magic fields for the ustar file format
strcat(buf + 257, "ustar");
strcat(buf + 263, "00");
- {
- // Prefix and main relative path. Path lengths have been preflighted.
-
- // [ 345 : 155 ] filename path prefix [ustar]
- //
- // packagename and domain can each be empty.
- char* cp = buf + 345;
- if (packageName.length() > 0) {
- // it's an app; so prefix with "apps/packagename/"
- cp = strcpy_ptr(cp, "apps/");
- cp = strcpy_ptr(cp, packageName.string());
- }
-
- if (domain.length() > 0) {
- // only need a / if there was a package name
- if (packageName.length() > 0) *cp++ = '/';
- cp = strcpy_ptr(cp, domain.string());
- }
-
- // [ 0 : 100 ]; file name/path
- strncpy(buf, relpath.string(), 100);
-
- LOGI(" Name: %s/%s", buf + 345, buf);
- }
+ // [ 265 : 32 ] user name, ignored on restore
+ // [ 297 : 32 ] group name, ignored on restore
// [ 100 : 8 ] file mode
- snprintf(buf + 100, 8, "0%o", s.st_mode);
+ snprintf(buf + 100, 8, "%06o ", s.st_mode & ~S_IFMT);
// [ 108 : 8 ] uid -- ignored in Android format; uids are remapped at restore time
// [ 116 : 8 ] gid -- ignored in Android format
@@ -540,14 +544,15 @@
snprintf(buf + 116, 8, "0%lo", s.st_gid);
// [ 124 : 12 ] file size in bytes
- snprintf(buf + 124, 12, "0%llo", s.st_size);
+ if (s.st_size > 077777777777LL) {
+ // very large files need a pax extended size header
+ needExtended = true;
+ }
+ snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);
// [ 136 : 12 ] last mod time as a UTC time_t
snprintf(buf + 136, 12, "%0lo", s.st_mtime);
- // [ 148 : 8 ] checksum -- to be calculated with this field as space chars
- memset(buf + 148, ' ', 8);
-
// [ 156 : 1 ] link/file type
uint8_t type;
if (isdir) {
@@ -562,19 +567,89 @@
// [ 157 : 100 ] name of linked file [not implemented]
- // Now go back and calculate the header checksum
{
- uint16_t sum = 0;
- for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
- sum += *p;
+ // Prefix and main relative path. Path lengths have been preflighted.
+ if (packageName.length() > 0) {
+ prefix = "apps/";
+ prefix += packageName;
+ }
+ if (domain.length() > 0) {
+ prefix.appendPath(domain);
}
- // Now write the real checksum value:
- // [ 148 : 8 ] checksum: 6 octal digits [leading zeroes], NUL, SPC
- sprintf(buf + 148, "%06o", sum); // the trailing space is already in place
+ // pax extended means we don't put in a prefix field, and put a different
+ // string in the basic name field. We can also construct the full path name
+ // out of the substrings we've now built.
+ fullname = prefix;
+ fullname.appendPath(relpath);
+
+ // ustar:
+ // [ 0 : 100 ]; file name/path
+ // [ 345 : 155 ] filename path prefix
+ // We only use the prefix area if fullname won't fit in the path
+ if (fullname.length() > 100) {
+ strncpy(buf, relpath.string(), 100);
+ strncpy(buf + 345, prefix.string(), 155);
+ } else {
+ strncpy(buf, fullname.string(), 100);
+ }
}
- // Write the 512-byte tar file header block to the output
+ // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used
+
+ LOGI(" Name: %s", fullname.string());
+
+ // If we're using a pax extended header, build & write that here; lengths are
+ // already preflighted
+ if (needExtended) {
+ // construct the pax extended header data block
+ memset(paxData, 0, BUFSIZE - (paxData - buf));
+ char* p = paxData;
+ int len;
+
+ // size header -- calc len in digits by actually rendering the number
+ // to a string - brute force but simple
+ len = sprintf(p, "%lld", s.st_size) + 8; // 8 for "1 size=" and final LF
+ if (len >= 10) len++;
+
+ memset(p, 0, 512);
+ p += sprintf(p, "%d size=%lld\n", len, s.st_size);
+
+ // fullname was generated above with the ustar paths
+ len = fullname.length() + 8; // 8 for "1 path=" and final LF
+ if (len >= 10) len++;
+ if (len >= 100) len++;
+ p += sprintf(p, "%d path=%s\n", len, fullname.string());
+
+ // Now we know how big the pax data is
+ int paxLen = p - paxData;
+
+ // Now build the pax *header* templated on the ustar header
+ memcpy(paxHeader, buf, 512);
+
+ String8 leaf = fullname.getPathLeaf();
+ memset(paxHeader, 0, 100); // rewrite the name area
+ snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
+ memset(paxHeader + 345, 0, 155); // rewrite the prefix area
+ strncpy(paxHeader + 345, prefix.string(), 155);
+
+ paxHeader[156] = 'x'; // mark it as a pax extended header
+
+ // [ 124 : 12 ] size of pax extended header data
+ memset(paxHeader + 124, 0, 12);
+ snprintf(paxHeader + 124, 12, "%011o", p - paxData);
+
+ // Checksum and write the pax block header
+ calc_tar_checksum(paxHeader);
+ writer->WriteEntityData(paxHeader, 512);
+
+ // Now write the pax data itself
+ int paxblocks = (paxLen + 511) / 512;
+ writer->WriteEntityData(paxData, 512 * paxblocks);
+ }
+
+ // Checksum and write the 512-byte ustar file header block to the output
+ calc_tar_checksum(buf);
writer->WriteEntityData(buf, 512);
// Now write the file data itself, for real files. We honor tar's convention that