Boost priority of short-running SF FIFO threads slightly.
am: 35520634e2

Change-Id: Ic4a53cc1399dff489414ac1c891a041c2500b8e2
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index facf300..5885738 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -102,6 +102,7 @@
     { "pm",         "Package Manager",  ATRACE_TAG_PACKAGE_MANAGER, { } },
     { "ss",         "System Server",    ATRACE_TAG_SYSTEM_SERVER, { } },
     { "database",   "Database",         ATRACE_TAG_DATABASE, { } },
+    { "network",    "Network",          ATRACE_TAG_NETWORK, { } },
     { k_coreServiceCategory, "Core services", 0, { } },
     { "sched",      "CPU Scheduling",   0, {
         { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" },
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 23629b3..d51fb77 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -35,6 +35,7 @@
 #include <unistd.h>
 
 #include <android-base/stringprintf.h>
+#include <android-base/file.h>
 #include <cutils/properties.h>
 
 #include "private/android_filesystem_config.h"
@@ -179,6 +180,118 @@
     closedir(d);
 }
 
+// return pid of a userspace process. If not found or error, return 0.
+static unsigned int pid_of_process(const char* ps_name) {
+    DIR *proc_dir;
+    struct dirent *ps;
+    unsigned int pid;
+    std::string cmdline;
+
+    if (!(proc_dir = opendir("/proc"))) {
+        MYLOGE("Can't open /proc\n");
+        return 0;
+    }
+
+    while ((ps = readdir(proc_dir))) {
+        if (!(pid = atoi(ps->d_name))) {
+            continue;
+        }
+        android::base::ReadFileToString("/proc/"
+                + std::string(ps->d_name) + "/cmdline", &cmdline);
+        if (cmdline.find(ps_name) == std::string::npos) {
+            continue;
+        } else {
+            closedir(proc_dir);
+            return pid;
+        }
+    }
+    closedir(proc_dir);
+    return 0;
+}
+
+// dump anrd's trace and add to the zip file.
+// 1. check if anrd is running on this device.
+// 2. send a SIGUSR1 to its pid which will dump anrd's trace.
+// 3. wait until the trace generation completes and add to the zip file.
+static bool dump_anrd_trace() {
+    unsigned int pid;
+    char buf[50], path[PATH_MAX];
+    struct dirent *trace;
+    struct stat st;
+    DIR *trace_dir;
+    long max_ctime = 0;
+    long long cur_size = 0;
+    const char *trace_path = "/data/misc/anrd/";
+
+    if (!zip_writer) {
+        MYLOGE("Not dumping anrd trace because zip_writer is not set\n");
+        return false;
+    }
+
+    // find anrd's pid if it is running.
+    pid = pid_of_process("/system/xbin/anrd");
+
+    if (pid > 0) {
+        // send SIGUSR1 to the anrd to generate a trace.
+        sprintf(buf, "%u", pid);
+        if (run_command("ANRD_DUMP", 1, "kill", "-SIGUSR1", buf, NULL)) {
+            MYLOGE("anrd signal timed out. Please manually collect trace\n");
+            return false;
+        }
+
+        // identify the trace file by its creation time.
+        if (!(trace_dir = opendir(trace_path))) {
+            MYLOGE("Can't open trace file under %s\n", trace_path);
+        }
+        while ((trace = readdir(trace_dir))) {
+            if (strcmp(trace->d_name, ".") == 0
+                    || strcmp(trace->d_name, "..") == 0) {
+                continue;
+            }
+            sprintf(path, "%s%s", trace_path, trace->d_name);
+            if (stat(path, &st) == 0) {
+                if (st.st_ctime > max_ctime) {
+                    max_ctime = st.st_ctime;
+                    sprintf(buf, "%s", trace->d_name);
+                }
+            }
+        }
+        closedir(trace_dir);
+
+        // Wait until the dump completes by checking the size of the trace.
+        if (max_ctime > 0) {
+            sprintf(path, "%s%s", trace_path, buf);
+            while(true) {
+                sleep(1);
+                if (stat(path, &st) == 0) {
+                    if (st.st_size == cur_size) {
+                        break;
+                    } else if (st.st_size > cur_size) {
+                        cur_size = st.st_size;
+                    } else {
+                        return false;
+                    }
+                } else {
+                    MYLOGE("Cant stat() %s anymore\n", path);
+                    return false;
+                }
+            }
+            // Add to the zip file.
+            if (!add_zip_entry("anrd_trace.txt", path)) {
+                MYLOGE("Unable to add anrd_trace file %s to zip file\n", path);
+            } else {
+                if (remove(path)) {
+                    MYLOGE("Error removing anrd_trace file %s: %s", path, strerror(errno));
+                }
+                return true;
+            }
+        } else {
+            MYLOGE("Can't stats any trace file under %s\n", trace_path);
+        }
+    }
+    return false;
+}
+
 static void dump_systrace() {
     if (!zip_writer) {
         MYLOGD("Not dumping systrace because zip_writer is not set\n");
@@ -1348,7 +1461,11 @@
     print_header(version);
 
     // Dumps systrace right away, otherwise it will be filled with unnecessary events.
-    dump_systrace();
+    // First try to dump anrd trace if the daemon is running. Otherwise, dump
+    // the raw trace.
+    if (!dump_anrd_trace()) {
+        dump_systrace();
+    }
 
     // TODO: Drop root user and move into dumpstate() once b/28633932 is fixed.
     dump_raft();
diff --git a/data/etc/wearable_core_hardware.xml b/data/etc/wearable_core_hardware.xml
index 4ff00b5..84230da 100644
--- a/data/etc/wearable_core_hardware.xml
+++ b/data/etc/wearable_core_hardware.xml
@@ -24,6 +24,7 @@
     <feature name="android.hardware.location" />
     <!-- devices supporting compass/magnitometer sensor must include
 	 android.hardware.sensor.compass.xml -->
+    <feature name="android.hardware.sensor.gyroscope" />
     <feature name="android.hardware.sensor.accelerometer" />
     <feature name="android.hardware.bluetooth" />
     <feature name="android.hardware.touchscreen" />
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 785df1a..dfece93 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -591,19 +591,25 @@
     const Transform& tr(displayDevice->getTransform());
     Rect transformedFrame = tr.transform(frame);
     auto error = hwcLayer->setDisplayFrame(transformedFrame);
-    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame "
-            "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left,
-            transformedFrame.top, transformedFrame.right,
-            transformedFrame.bottom, to_string(error).c_str(),
-            static_cast<int32_t>(error));
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)",
+                mName.string(), transformedFrame.left, transformedFrame.top,
+                transformedFrame.right, transformedFrame.bottom,
+                to_string(error).c_str(), static_cast<int32_t>(error));
+    } else {
+        hwcInfo.displayFrame = transformedFrame;
+    }
 
     FloatRect sourceCrop = computeCrop(displayDevice);
     error = hwcLayer->setSourceCrop(sourceCrop);
-    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop "
-            "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(),
-            sourceCrop.left, sourceCrop.top, sourceCrop.right,
-            sourceCrop.bottom, to_string(error).c_str(),
-            static_cast<int32_t>(error));
+    if (error != HWC2::Error::None) {
+        ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
+                "%s (%d)", mName.string(), sourceCrop.left, sourceCrop.top,
+                sourceCrop.right, sourceCrop.bottom, to_string(error).c_str(),
+                static_cast<int32_t>(error));
+    } else {
+        hwcInfo.sourceCrop = sourceCrop;
+    }
 
     error = hwcLayer->setPlaneAlpha(s.alpha);
     ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: "
@@ -2235,6 +2241,54 @@
     }
 }
 
+#ifdef USE_HWC2
+void Layer::miniDumpHeader(String8& result) {
+    result.append("----------------------------------------");
+    result.append("---------------------------------------\n");
+    result.append(" Layer name\n");
+    result.append("           Z | ");
+    result.append(" Comp Type | ");
+    result.append("  Disp Frame (LTRB) | ");
+    result.append("         Source Crop (LTRB)\n");
+    result.append("----------------------------------------");
+    result.append("---------------------------------------\n");
+}
+
+void Layer::miniDump(String8& result, int32_t hwcId) const {
+    if (mHwcLayers.count(hwcId) == 0) {
+        return;
+    }
+
+    String8 name;
+    if (mName.length() > 77) {
+        std::string shortened;
+        shortened.append(mName.string(), 36);
+        shortened.append("[...]");
+        shortened.append(mName.string() + (mName.length() - 36), 36);
+        name = shortened.c_str();
+    } else {
+        name = mName;
+    }
+
+    result.appendFormat(" %s\n", name.string());
+
+    const Layer::State& layerState(getDrawingState());
+    const HWCInfo& hwcInfo = mHwcLayers.at(hwcId);
+    result.appendFormat("  %10u | ", layerState.z);
+    result.appendFormat("%10s | ",
+            to_string(getCompositionType(hwcId)).c_str());
+    const Rect& frame = hwcInfo.displayFrame;
+    result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top,
+            frame.right, frame.bottom);
+    const FloatRect& crop = hwcInfo.sourceCrop;
+    result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top,
+            crop.right, crop.bottom);
+
+    result.append("- - - - - - - - - - - - - - - - - - - - ");
+    result.append("- - - - - - - - - - - - - - - - - - - -\n");
+}
+#endif
+
 void Layer::dumpFrameStats(String8& result) const {
     mFrameTracker.dumpStats(result);
 }
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 6533953..2ce1340 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -402,6 +402,10 @@
 
     /* always call base class first */
     void dump(String8& result, Colorizer& colorizer) const;
+#ifdef USE_HWC2
+    static void miniDumpHeader(String8& result);
+    void miniDump(String8& result, int32_t hwcId) const;
+#endif
     void dumpFrameStats(String8& result) const;
     void clearFrameStats();
     void logFrameStats();
@@ -588,6 +592,8 @@
         bool forceClientComposition;
         HWC2::Composition compositionType;
         bool clearClientTarget;
+        Rect displayFrame;
+        FloatRect sourceCrop;
     };
     std::unordered_map<int32_t, HWCInfo> mHwcLayers;
 #else
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 92c6571..8db071e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3057,6 +3057,26 @@
      * VSYNC state
      */
     mEventThread->dump(result);
+    result.append("\n");
+
+    /*
+     * HWC layer minidump
+     */
+    for (size_t d = 0; d < mDisplays.size(); d++) {
+        const sp<const DisplayDevice>& displayDevice(mDisplays[d]);
+        int32_t hwcId = displayDevice->getHwcDisplayId();
+        if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
+            continue;
+        }
+
+        result.appendFormat("Display %d HWC layers:\n", hwcId);
+        Layer::miniDumpHeader(result);
+        for (size_t l = 0; l < count; l++) {
+            const sp<Layer>& layer(currentLayers[l]);
+            layer->miniDump(result, hwcId);
+        }
+        result.append("\n");
+    }
 
     /*
      * Dump HWComposer state