Merge "installd_service_test: fix ServiceTest.CreateAppDataSnapshot_ClearsCache" am: 4febfd6da7
am: 3f3a196a5b

Change-Id: I52182a9a79f3306c57bec5ae1b8843df2951b403
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 1ea2c2c..ecdc075 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -41,6 +41,13 @@
  *
  * Note that this structure is used for IPCs so its layout must be identical
  * on 64 and 32 bit processes. This is tested in StructLayout_test.cpp.
+ *
+ * Since the struct must be aligned to an 8-byte boundary, there could be uninitialized bytes
+ * in-between the defined fields. This padding data should be explicitly accounted for by adding
+ * "empty" fields into the struct. This data is memset to zero before sending the struct across
+ * the socket. Adding the explicit fields ensures that the memset is not optimized away by the
+ * compiler. When a new field is added to the struct, the corresponding change
+ * in StructLayout_test should be made.
  */
 struct InputMessage {
     enum {
@@ -61,6 +68,7 @@
     union Body {
         struct Key {
             uint32_t seq;
+            uint32_t empty1;
             nsecs_t eventTime __attribute__((aligned(8)));
             int32_t deviceId;
             int32_t source;
@@ -71,6 +79,7 @@
             int32_t scanCode;
             int32_t metaState;
             int32_t repeatCount;
+            uint32_t empty2;
             nsecs_t downTime __attribute__((aligned(8)));
 
             inline size_t size() const {
@@ -80,6 +89,7 @@
 
         struct Motion {
             uint32_t seq;
+            uint32_t empty1;
             nsecs_t eventTime __attribute__((aligned(8)));
             int32_t deviceId;
             int32_t source;
@@ -90,12 +100,14 @@
             int32_t metaState;
             int32_t buttonState;
             int32_t edgeFlags;
+            uint32_t empty2;
             nsecs_t downTime __attribute__((aligned(8)));
             float xOffset;
             float yOffset;
             float xPrecision;
             float yPrecision;
             uint32_t pointerCount;
+            uint32_t empty3;
             // Note that PointerCoords requires 8 byte alignment.
             struct Pointer {
                 PointerProperties properties;
@@ -126,6 +138,7 @@
 
     bool isValid(size_t actualSize) const;
     size_t size() const;
+    void getSanitizedCopy(InputMessage* msg) const;
 };
 
 /*
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index aa0bf17..03f593f 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -96,6 +96,106 @@
     return sizeof(Header);
 }
 
+/**
+ * There could be non-zero bytes in-between InputMessage fields. Force-initialize the entire
+ * memory to zero, then only copy the valid bytes on a per-field basis.
+ */
+void InputMessage::getSanitizedCopy(InputMessage* msg) const {
+    memset(msg, 0, sizeof(*msg));
+
+    // Write the header
+    msg->header.type = header.type;
+
+    // Write the body
+    switch(header.type) {
+        case InputMessage::TYPE_KEY: {
+            // uint32_t seq
+            msg->body.key.seq = body.key.seq;
+            // nsecs_t eventTime
+            msg->body.key.eventTime = body.key.eventTime;
+            // int32_t deviceId
+            msg->body.key.deviceId = body.key.deviceId;
+            // int32_t source
+            msg->body.key.source = body.key.source;
+            // int32_t displayId
+            msg->body.key.displayId = body.key.displayId;
+            // int32_t action
+            msg->body.key.action = body.key.action;
+            // int32_t flags
+            msg->body.key.flags = body.key.flags;
+            // int32_t keyCode
+            msg->body.key.keyCode = body.key.keyCode;
+            // int32_t scanCode
+            msg->body.key.scanCode = body.key.scanCode;
+            // int32_t metaState
+            msg->body.key.metaState = body.key.metaState;
+            // int32_t repeatCount
+            msg->body.key.repeatCount = body.key.repeatCount;
+            // nsecs_t downTime
+            msg->body.key.downTime = body.key.downTime;
+            break;
+        }
+        case InputMessage::TYPE_MOTION: {
+            // uint32_t seq
+            msg->body.motion.seq = body.motion.seq;
+            // nsecs_t eventTime
+            msg->body.motion.eventTime = body.motion.eventTime;
+            // int32_t deviceId
+            msg->body.motion.deviceId = body.motion.deviceId;
+            // int32_t source
+            msg->body.motion.source = body.motion.source;
+            // int32_t displayId
+            msg->body.motion.displayId = body.motion.displayId;
+            // int32_t action
+            msg->body.motion.action = body.motion.action;
+            // int32_t actionButton
+            msg->body.motion.actionButton = body.motion.actionButton;
+            // int32_t flags
+            msg->body.motion.flags = body.motion.flags;
+            // int32_t metaState
+            msg->body.motion.metaState = body.motion.metaState;
+            // int32_t buttonState
+            msg->body.motion.buttonState = body.motion.buttonState;
+            // int32_t edgeFlags
+            msg->body.motion.edgeFlags = body.motion.edgeFlags;
+            // nsecs_t downTime
+            msg->body.motion.downTime = body.motion.downTime;
+            // float xOffset
+            msg->body.motion.xOffset = body.motion.xOffset;
+            // float yOffset
+            msg->body.motion.yOffset = body.motion.yOffset;
+            // float xPrecision
+            msg->body.motion.xPrecision = body.motion.xPrecision;
+            // float yPrecision
+            msg->body.motion.yPrecision = body.motion.yPrecision;
+            // uint32_t pointerCount
+            msg->body.motion.pointerCount = body.motion.pointerCount;
+            //struct Pointer pointers[MAX_POINTERS]
+            for (size_t i = 0; i < body.motion.pointerCount; i++) {
+                // PointerProperties properties
+                msg->body.motion.pointers[i].properties.id = body.motion.pointers[i].properties.id;
+                msg->body.motion.pointers[i].properties.toolType =
+                        body.motion.pointers[i].properties.toolType,
+                // PointerCoords coords
+                msg->body.motion.pointers[i].coords.bits = body.motion.pointers[i].coords.bits;
+                const uint32_t count = BitSet64::count(body.motion.pointers[i].coords.bits);
+                memcpy(&msg->body.motion.pointers[i].coords.values[0],
+                        &body.motion.pointers[i].coords.values[0],
+                        count * (sizeof(body.motion.pointers[i].coords.values[0])));
+            }
+            break;
+        }
+        case InputMessage::TYPE_FINISHED: {
+            msg->body.finished.seq = body.finished.seq;
+            msg->body.finished.handled = body.finished.handled;
+            break;
+        }
+        default: {
+            LOG_FATAL("Unexpected message type %i", header.type);
+            break;
+        }
+    }
+}
 
 // --- InputChannel ---
 
@@ -149,10 +249,12 @@
 }
 
 status_t InputChannel::sendMessage(const InputMessage* msg) {
-    size_t msgLength = msg->size();
+    const size_t msgLength = msg->size();
+    InputMessage cleanMsg;
+    msg->getSanitizedCopy(&cleanMsg);
     ssize_t nWrite;
     do {
-        nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
+        nWrite = ::send(mFd, &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
     } while (nWrite == -1 && errno == EINTR);
 
     if (nWrite < 0) {
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index d19f3b8..12a6782 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -65,6 +65,9 @@
   CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 76);
   CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 80);
   CHECK_OFFSET(InputMessage::Body::Motion, pointers, 88);
+
+  CHECK_OFFSET(InputMessage::Body::Finished, seq, 0);
+  CHECK_OFFSET(InputMessage::Body::Finished, handled, 4);
 }
 
 } // namespace android
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index fe992f1..2073b05 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -220,7 +220,7 @@
                     const highp float c2 = (2413.0 / 4096.0) * 32.0;
                     const highp float c3 = (2392.0 / 4096.0) * 32.0;
 
-                    highp vec3 tmp = pow(color, 1.0 / vec3(m2));
+                    highp vec3 tmp = pow(clamp(color, 0.0, 1.0), 1.0 / vec3(m2));
                     tmp = max(tmp - c1, 0.0) / (c2 - c3 * tmp);
                     return pow(tmp, 1.0 / vec3(m1));
                 }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e693dd2..82bf19f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4433,6 +4433,12 @@
     result.append("\n");
 
     /*
+     * Tracing state
+     */
+    mTracing.dump(result);
+    result.append("\n");
+
+    /*
      * HWC layer minidump
      */
     for (size_t d = 0; d < mDisplays.size(); d++) {
@@ -4779,12 +4785,12 @@
             case 1025: { // Set layer tracing
                 n = data.readInt32();
                 if (n) {
-                    ALOGV("LayerTracing enabled");
+                    ALOGD("LayerTracing enabled");
                     mTracing.enable();
                     doTracing("tracing.enable");
                     reply->writeInt32(NO_ERROR);
                 } else {
-                    ALOGV("LayerTracing disabled");
+                    ALOGD("LayerTracing disabled");
                     status_t err = mTracing.disable();
                     reply->writeInt32(err);
                 }
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index f8c466e..67dcd06 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -27,52 +27,67 @@
 namespace android {
 
 void SurfaceTracing::enable() {
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
     if (mEnabled) {
         return;
     }
-    ATRACE_CALL();
     mEnabled = true;
-    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
 
-    mTrace.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
-                            LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+    mTrace = std::make_unique<LayersTraceFileProto>();
+    mTrace->set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+                             LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
 }
 
 status_t SurfaceTracing::disable() {
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
     if (!mEnabled) {
         return NO_ERROR;
     }
-    ATRACE_CALL();
-    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
     mEnabled = false;
     status_t err(writeProtoFileLocked());
     ALOGE_IF(err == PERMISSION_DENIED, "Could not save the proto file! Permission denied");
     ALOGE_IF(err == NOT_ENOUGH_DATA, "Could not save the proto file! There are missing fields");
-    mTrace.Clear();
+    mTrace.reset();
     return err;
 }
 
-bool SurfaceTracing::isEnabled() {
+bool SurfaceTracing::isEnabled() const {
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
     return mEnabled;
 }
 
 void SurfaceTracing::traceLayers(const char* where, LayersProto layers) {
     std::lock_guard<std::mutex> protoGuard(mTraceMutex);
-
-    LayersTraceProto* entry = mTrace.add_entry();
+    if (!mEnabled) {
+        return;
+    }
+    LayersTraceProto* entry = mTrace->add_entry();
     entry->set_elapsed_realtime_nanos(elapsedRealtimeNano());
     entry->set_where(where);
     entry->mutable_layers()->Swap(&layers);
+
+    constexpr int maxBufferedEntryCount = 3600;
+    if (mTrace->entry_size() >= maxBufferedEntryCount) {
+        // TODO: flush buffered entries without disabling tracing
+        ALOGE("too many buffered frames; force disable tracing");
+        mEnabled = false;
+        writeProtoFileLocked();
+        mTrace.reset();
+    }
 }
 
 status_t SurfaceTracing::writeProtoFileLocked() {
     ATRACE_CALL();
 
-    if (!mTrace.IsInitialized()) {
+    if (!mTrace->IsInitialized()) {
         return NOT_ENOUGH_DATA;
     }
     std::string output;
-    if (!mTrace.SerializeToString(&output)) {
+    if (!mTrace->SerializeToString(&output)) {
         return PERMISSION_DENIED;
     }
     if (!android::base::WriteStringToFile(output, mOutputFileName, true)) {
@@ -82,4 +97,11 @@
     return NO_ERROR;
 }
 
+void SurfaceTracing::dump(String8& result) const {
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
+    result.appendFormat("Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
+    result.appendFormat("  number of entries: %d\n", mTrace ? mTrace->entry_size() : 0);
+}
+
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 590ab96..fd8cb82 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -18,7 +18,9 @@
 
 #include <layerproto/LayerProtoHeader.h>
 #include <utils/Errors.h>
+#include <utils/String8.h>
 
+#include <memory>
 #include <mutex>
 
 using namespace android::surfaceflinger;
@@ -32,9 +34,10 @@
 public:
     void enable();
     status_t disable();
-    bool isEnabled();
+    bool isEnabled() const;
 
     void traceLayers(const char* where, LayersProto);
+    void dump(String8& result) const;
 
 private:
     static constexpr auto DEFAULT_FILENAME = "/data/misc/wmtrace/layers_trace.pb";
@@ -43,8 +46,8 @@
 
     bool mEnabled = false;
     std::string mOutputFileName = DEFAULT_FILENAME;
-    std::mutex mTraceMutex;
-    LayersTraceFileProto mTrace;
+    mutable std::mutex mTraceMutex;
+    std::unique_ptr<LayersTraceFileProto> mTrace;
 };
 
 } // namespace android