Surface: Add force disconnection method.
am: 97b9c86338

Change-Id: Ia9f9dbdcbd9527d54dacb2cdc90eda443230e8d9
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/Android.mk b/cmds/dumpstate/Android.mk
index 791a7c4..7a9f9ad 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -14,7 +14,7 @@
 
 LOCAL_MODULE := dumpstate
 
-LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux libbase
+LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux libbase libhardware_legacy
 # ZipArchive support, the order matters here to get all symbols.
 LOCAL_STATIC_LIBRARIES := libziparchive libz libmincrypt
 LOCAL_HAL_STATIC_LIBRARIES := libdumpstate
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 23629b3..97dfd92 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -22,6 +22,7 @@
 #include <memory>
 #include <regex>
 #include <set>
+#include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -35,7 +36,9 @@
 #include <unistd.h>
 
 #include <android-base/stringprintf.h>
+#include <android-base/file.h>
 #include <cutils/properties.h>
+#include <hardware_legacy/power.h>
 
 #include "private/android_filesystem_config.h"
 
@@ -81,6 +84,7 @@
 #define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4)
 #define NUM_TOMBSTONES  10
 #define WLUTIL "/vendor/xbin/wlutil"
+#define WAKE_LOCK_NAME "dumpstate_wakelock"
 
 typedef struct {
   char name[TOMBSTONE_MAX_LEN];
@@ -179,6 +183,136 @@
     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;
+    int retry = 5;
+    long max_ctime = 0, old_mtime;
+    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) {
+        if (stat(trace_path, &st) == 0) {
+            old_mtime = st.st_mtime;
+        } else {
+            MYLOGE("Failed to find: %s\n", trace_path);
+            return false;
+        }
+
+        // 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;
+        }
+
+        while (retry-- > 0 && old_mtime == st.st_mtime) {
+            sleep(1);
+            stat(trace_path, &st);
+        }
+
+        if (retry < 0 && old_mtime == st.st_mtime) {
+            MYLOGE("Failed to stat %s or trace creation timeout\n", trace_path);
+            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");
@@ -1016,11 +1150,31 @@
           VERSION_DEFAULT.c_str());
 }
 
-static void sigpipe_handler(int n) {
-    // don't complain to stderr or stdout
+static void wake_lock_releaser() {
+    if (release_wake_lock(WAKE_LOCK_NAME) < 0) {
+        MYLOGE("Failed to release wake lock: %s \n", strerror(errno));
+    } else {
+        MYLOGD("Wake lock released.\n");
+    }
+}
+
+static void sig_handler(int signo) {
+    wake_lock_releaser();
     _exit(EXIT_FAILURE);
 }
 
+static void register_sig_handler() {
+    struct sigaction sa;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+    sa.sa_handler = sig_handler;
+    sigaction(SIGPIPE, &sa, NULL); // broken pipe
+    sigaction(SIGSEGV, &sa, NULL); // segment fault
+    sigaction(SIGINT, &sa, NULL); // ctrl-c
+    sigaction(SIGTERM, &sa, NULL); // killed
+    sigaction(SIGQUIT, &sa, NULL); // quit
+}
+
 /* adds the temporary report to the existing .zip file, closes the .zip file, and removes the
    temporary file.
  */
@@ -1088,7 +1242,6 @@
 }
 
 int main(int argc, char *argv[]) {
-    struct sigaction sigact;
     int do_add_date = 0;
     int do_zip_file = 0;
     int do_vibrate = 1;
@@ -1105,6 +1258,14 @@
 
     MYLOGI("begin\n");
 
+    if (acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME) < 0) {
+        MYLOGE("Failed to acquire wake lock: %s \n", strerror(errno));
+    } else {
+        MYLOGD("Wake lock acquired.\n");
+        atexit(wake_lock_releaser);
+        register_sig_handler();
+    }
+
     /* gets the sequential id */
     char last_id[PROPERTY_VALUE_MAX];
     property_get("dumpstate.last_id", last_id, "0");
@@ -1113,11 +1274,6 @@
     property_set("dumpstate.last_id", last_id);
     MYLOGI("dumpstate id: %lu\n", id);
 
-    /* clear SIGPIPE handler */
-    memset(&sigact, 0, sizeof(sigact));
-    sigact.sa_handler = sigpipe_handler;
-    sigaction(SIGPIPE, &sigact, NULL);
-
     /* set as high priority, and protect from OOM killer */
     setpriority(PRIO_PROCESS, 0, -20);
 
@@ -1348,7 +1504,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/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index fd6413d..1035cde 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -828,7 +828,7 @@
     }
 
     gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW,
-            AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC };
+            AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC, AID_WAKELOCK };
     if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
         MYLOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
         return false;
@@ -849,8 +849,10 @@
     capheader.version = _LINUX_CAPABILITY_VERSION_3;
     capheader.pid = 0;
 
-    capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
-    capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
+    capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted =
+            (CAP_TO_MASK(CAP_SYSLOG) | CAP_TO_MASK(CAP_BLOCK_SUSPEND));
+    capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective =
+            (CAP_TO_MASK(CAP_SYSLOG) | CAP_TO_MASK(CAP_BLOCK_SUSPEND));
     capdata[0].inheritable = 0;
     capdata[1].inheritable = 0;
 
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 2014e99..4ed8997 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -99,23 +99,64 @@
     return StringPrintf("%s/%s", profile_dir.c_str(), PRIMARY_PROFILE_NAME);
 }
 
-static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid,
-        const char* pkgname, const char* seinfo) {
+/**
+ * Perform restorecon of the given path, but only perform recursive restorecon
+ * if the label of that top-level file actually changed.  This can save us
+ * significant time by avoiding no-op traversals of large filesystem trees.
+ */
+static int restorecon_app_data_lazy(const char* path, const char* seinfo, uid_t uid) {
+    int res = 0;
+    char* before = nullptr;
+    char* after = nullptr;
+
+    // Note that SELINUX_ANDROID_RESTORECON_DATADATA flag is set by
+    // libselinux. Not needed here.
+
+    if (lgetfilecon(path, &before) < 0) {
+        PLOG(ERROR) << "Failed before getfilecon for " << path;
+        goto fail;
+    }
+    if (selinux_android_restorecon_pkgdir(path, seinfo, uid, 0) < 0) {
+        PLOG(ERROR) << "Failed top-level restorecon for " << path;
+        goto fail;
+    }
+    if (lgetfilecon(path, &after) < 0) {
+        PLOG(ERROR) << "Failed after getfilecon for " << path;
+        goto fail;
+    }
+
+    // If the initial top-level restorecon above changed the label, then go
+    // back and restorecon everything recursively
+    if (strcmp(before, after)) {
+        LOG(DEBUG) << "Detected label change from " << before << " to " << after << " at " << path
+                << "; running recursive restorecon";
+        if (selinux_android_restorecon_pkgdir(path, seinfo, uid,
+                SELINUX_ANDROID_RESTORECON_RECURSE) < 0) {
+            PLOG(ERROR) << "Failed recursive restorecon for " << path;
+            goto fail;
+        }
+    }
+
+    goto done;
+fail:
+    res = -1;
+done:
+    free(before);
+    free(after);
+    return res;
+}
+
+static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid) {
     if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, uid) != 0) {
         PLOG(ERROR) << "Failed to prepare " << path;
         return -1;
     }
-    if (selinux_android_setfilecon(path.c_str(), pkgname, seinfo, uid) < 0) {
-        PLOG(ERROR) << "Failed to setfilecon " << path;
-        return -1;
-    }
     return 0;
 }
 
 static int prepare_app_dir(const std::string& parent, const char* name, mode_t target_mode,
-        uid_t uid, const char* pkgname, const char* seinfo) {
-    return prepare_app_dir(StringPrintf("%s/%s", parent.c_str(), name), target_mode, uid, pkgname,
-            seinfo);
+        uid_t uid) {
+    return prepare_app_dir(StringPrintf("%s/%s", parent.c_str(), name), target_mode, uid);
 }
 
 int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags,
@@ -124,9 +165,14 @@
     mode_t target_mode = target_sdk_version >= MIN_RESTRICTED_HOME_SDK_VERSION ? 0700 : 0751;
     if (flags & FLAG_STORAGE_CE) {
         auto path = create_data_user_ce_package_path(uuid, userid, pkgname);
-        if (prepare_app_dir(path, target_mode, uid, pkgname, seinfo) ||
-                prepare_app_dir(path, "cache", 0771, uid, pkgname, seinfo) ||
-                prepare_app_dir(path, "code_cache", 0771, uid, pkgname, seinfo)) {
+        if (prepare_app_dir(path, target_mode, uid) ||
+                prepare_app_dir(path, "cache", 0771, uid) ||
+                prepare_app_dir(path, "code_cache", 0771, uid)) {
+            return -1;
+        }
+
+        // Consider restorecon over contents if label changed
+        if (restorecon_app_data_lazy(path.c_str(), seinfo, uid)) {
             return -1;
         }
 
@@ -139,11 +185,16 @@
     }
     if (flags & FLAG_STORAGE_DE) {
         auto path = create_data_user_de_package_path(uuid, userid, pkgname);
-        if (prepare_app_dir(path, target_mode, uid, pkgname, seinfo)) {
+        if (prepare_app_dir(path, target_mode, uid)) {
             // TODO: include result once 25796509 is fixed
             return 0;
         }
 
+        // Consider restorecon over contents if label changed
+        if (restorecon_app_data_lazy(path.c_str(), seinfo, uid)) {
+            return -1;
+        }
+
         if (property_get_bool("dalvik.vm.usejitprofiles")) {
             const std::string profile_path = create_data_user_profile_package_path(userid, pkgname);
             // read-write-execute only for the app user.
@@ -2186,6 +2237,9 @@
         bool art_success = true;
         if (!a_image_path.empty()) {
             art_success = move_ab_path(b_image_path, a_image_path);
+            if (!art_success) {
+                unlink(a_image_path.c_str());
+            }
         }
 
         success = art_success || kIgnoreAppImageFailure;
@@ -2199,5 +2253,35 @@
     return success ? 0 : -1;
 }
 
+bool delete_odex(const char *apk_path, const char *instruction_set, const char *oat_dir) {
+    // Delete the oat/odex file.
+    char out_path[PKG_PATH_MAX];
+    if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_path)) {
+        return false;
+    }
+
+    // In case of a permission failure report the issue. Otherwise just print a warning.
+    auto unlink_and_check = [](const char* path) -> bool {
+        int result = unlink(path);
+        if (result != 0) {
+            if (errno == EACCES || errno == EPERM) {
+                PLOG(ERROR) << "Could not unlink " << path;
+                return false;
+            }
+            PLOG(WARNING) << "Could not unlink " << path;
+        }
+        return true;
+    };
+
+    // Delete the oat/odex file.
+    bool return_value_oat = unlink_and_check(out_path);
+
+    // Derive and delete the app image.
+    bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
+
+    // Report success.
+    return return_value_oat && return_value_art;
+}
+
 }  // namespace installd
 }  // namespace android
diff --git a/cmds/installd/commands.h b/cmds/installd/commands.h
index e990f1b..ba27517 100644
--- a/cmds/installd/commands.h
+++ b/cmds/installd/commands.h
@@ -85,6 +85,9 @@
 // Move a B version over to the A location. Only works for oat_dir != nullptr.
 int move_ab(const char *apk_path, const char *instruction_set, const char* oat_dir);
 
+// Delete odex files generated by dexopt.
+bool delete_odex(const char *apk_path, const char *instruction_set, const char *oat_dir);
+
 }  // namespace installd
 }  // namespace android
 
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index facbc72..8f883db 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -418,6 +418,11 @@
     return move_ab(arg[0], arg[1], arg[2]);
 }
 
+static int do_delete_odex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) {
+    // apk_path, instruction_set, oat_dir
+    return delete_odex(arg[0], arg[1], arg[2]) ? 0 : -1;
+}
+
 struct cmdinfo {
     const char *name;
     unsigned numargs;
@@ -453,6 +458,7 @@
     { "move_ab",              3, do_move_ab },
     { "merge_profiles",       2, do_merge_profiles },
     { "dump_profiles",        3, do_dump_profiles },
+    { "delete_odex",          3, do_delete_odex },
 };
 
 static int readx(int s, void *_buf, int count)
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/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index dddcf92..5311c59 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -115,13 +115,13 @@
     EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
     EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
 
-    EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255));
-    EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255));
-    EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255));
-    EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
-    EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255));
-    EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255));
-    EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
+    EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255, 3));
+    EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255, 3));
+    EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255, 3));
+    EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255, 3));
+    EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255, 3));
+    EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255, 3));
+    EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255, 3));
 }
 
 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
diff --git a/services/sensorservice/RecentEventLogger.cpp b/services/sensorservice/RecentEventLogger.cpp
index 754b603..62e9ce0 100644
--- a/services/sensorservice/RecentEventLogger.cpp
+++ b/services/sensorservice/RecentEventLogger.cpp
@@ -31,7 +31,7 @@
 
 RecentEventLogger::RecentEventLogger(int sensorType) :
         mSensorType(sensorType), mEventSize(eventSizeBySensorType(mSensorType)),
-        mRecentEvents(logSizeBySensorType(sensorType)) {
+        mRecentEvents(logSizeBySensorType(sensorType)), mMaskData(false) {
     // blank
 }
 
@@ -60,18 +60,30 @@
                 (int) ns2ms(ev.mWallTime.tv_nsec));
 
         // data
-        if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
-            buffer.appendFormat("%" PRIu64 ", ", ev.mEvent.u64.step_counter);
-        } else {
-            for (size_t k = 0; k < mEventSize; ++k) {
-                buffer.appendFormat("%.2f, ", ev.mEvent.data[k]);
+        if (!mMaskData) {
+            if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
+                buffer.appendFormat("%" PRIu64 ", ", ev.mEvent.u64.step_counter);
+            } else {
+                for (size_t k = 0; k < mEventSize; ++k) {
+                    buffer.appendFormat("%.2f, ", ev.mEvent.data[k]);
+                }
             }
+        } else {
+            buffer.append("[value masked]");
         }
         buffer.append("\n");
     }
     return std::string(buffer.string());
 }
 
+void RecentEventLogger::setFormat(std::string format) {
+    if (format == "mask_data" ) {
+        mMaskData = true;
+    } else {
+        mMaskData = false;
+    }
+}
+
 bool RecentEventLogger::populateLastEvent(sensors_event_t *event) const {
     std::lock_guard<std::mutex> lk(mLock);
 
diff --git a/services/sensorservice/RecentEventLogger.h b/services/sensorservice/RecentEventLogger.h
index 4f9bc4a..8b15e5a 100644
--- a/services/sensorservice/RecentEventLogger.h
+++ b/services/sensorservice/RecentEventLogger.h
@@ -43,6 +43,7 @@
 
     // Dumpable interface
     virtual std::string dump() const override;
+    virtual void setFormat(std::string format) override;
 
 protected:
     struct SensorEventLog {
@@ -57,6 +58,8 @@
     mutable std::mutex mLock;
     RingBuffer<SensorEventLog> mRecentEvents;
 
+    bool mMaskData;
+
 private:
     static size_t logSizeBySensorType(int sensorType);
 };
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index c1e1bad..f2f1444 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -206,7 +206,7 @@
 status_t SensorService::SensorEventConnection::sendEvents(
         sensors_event_t const* buffer, size_t numEvents,
         sensors_event_t* scratch,
-        SensorEventConnection const * const * mapFlushEventsToConnections) {
+        wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
     // filter out events not for this connection
     int count = 0;
     Mutex::Autolock _l(mConnectionLock);
@@ -234,7 +234,7 @@
             FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
             // Check if there is a pending flush_complete event for this sensor on this connection.
             if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
-                    this == mapFlushEventsToConnections[i]) {
+                    mapFlushEventsToConnections[i] == this) {
                 flushInfo.mFirstFlushPending = false;
                 ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
                         buffer[i].meta_data.sensor);
@@ -255,7 +255,7 @@
                 // from the same sensor_handle AND the current connection is mapped to the
                 // corresponding flush_complete_event.
                 if (buffer[i].type == SENSOR_TYPE_META_DATA) {
-                    if (this == mapFlushEventsToConnections[i]) {
+                    if (mapFlushEventsToConnections[i] == this) {
                         scratch[count++] = buffer[i];
                     }
                     ++i;
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index b796cc0..883c16e 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -52,7 +52,7 @@
                           bool isDataInjectionMode, const String16& opPackageName);
 
     status_t sendEvents(sensors_event_t const* buffer, size_t count, sensors_event_t* scratch,
-                        SensorEventConnection const * const * mapFlushEventsToConnections = NULL);
+                        wp<const SensorEventConnection> const * mapFlushEventsToConnections = NULL);
     bool hasSensor(int32_t handle) const;
     bool hasAnySensor() const;
     bool hasOneShotSensors() const;
diff --git a/services/sensorservice/SensorRecord.cpp b/services/sensorservice/SensorRecord.cpp
index 644cfb0..53fb9de 100644
--- a/services/sensorservice/SensorRecord.cpp
+++ b/services/sensorservice/SensorRecord.cpp
@@ -21,13 +21,13 @@
 namespace android {
 
 SensorService::SensorRecord::SensorRecord(
-        const sp<SensorEventConnection>& connection)
+        const sp<const SensorEventConnection>& connection)
 {
     mConnections.add(connection);
 }
 
 bool SensorService::SensorRecord::addConnection(
-        const sp<SensorEventConnection>& connection)
+        const sp<const SensorEventConnection>& connection)
 {
     if (mConnections.indexOf(connection) < 0) {
         mConnections.add(connection);
@@ -37,16 +37,16 @@
 }
 
 bool SensorService::SensorRecord::removeConnection(
-        const wp<SensorEventConnection>& connection)
+        const wp<const SensorEventConnection>& connection)
 {
     ssize_t index = mConnections.indexOf(connection);
     if (index >= 0) {
         mConnections.removeItemsAt(index, 1);
     }
     // Remove this connections from the queue of flush() calls made on this sensor.
-    for (Vector< wp<SensorEventConnection> >::iterator it = mPendingFlushConnections.begin();
+    for (Vector< wp<const SensorEventConnection> >::iterator it = mPendingFlushConnections.begin();
             it != mPendingFlushConnections.end(); ) {
-        if (it->unsafe_get() == connection.unsafe_get()) {
+        if (*it == connection) {
             it = mPendingFlushConnections.erase(it);
         } else {
             ++it;
@@ -56,7 +56,7 @@
 }
 
 void SensorService::SensorRecord::addPendingFlushConnection(
-        const sp<SensorEventConnection>& connection) {
+        const sp<const SensorEventConnection>& connection) {
     mPendingFlushConnections.add(connection);
 }
 
@@ -66,10 +66,10 @@
     }
 }
 
-SensorService::SensorEventConnection *
+wp<const SensorService::SensorEventConnection>
         SensorService::SensorRecord::getFirstPendingFlushConnection() {
     if (mPendingFlushConnections.size() > 0) {
-        return mPendingFlushConnections[0].unsafe_get();
+        return mPendingFlushConnections[0];
     }
     return NULL;
 }
diff --git a/services/sensorservice/SensorRecord.h b/services/sensorservice/SensorRecord.h
index 29b970d..5a35410 100644
--- a/services/sensorservice/SensorRecord.h
+++ b/services/sensorservice/SensorRecord.h
@@ -25,20 +25,20 @@
 
 class SensorService::SensorRecord {
 public:
-    SensorRecord(const sp<SensorEventConnection>& connection);
-    bool addConnection(const sp<SensorEventConnection>& connection);
-    bool removeConnection(const wp<SensorEventConnection>& connection);
+    SensorRecord(const sp<const SensorEventConnection>& connection);
+    bool addConnection(const sp<const SensorEventConnection>& connection);
+    bool removeConnection(const wp<const SensorEventConnection>& connection);
     size_t getNumConnections() const { return mConnections.size(); }
 
-    void addPendingFlushConnection(const sp<SensorEventConnection>& connection);
+    void addPendingFlushConnection(const sp<const SensorEventConnection>& connection);
     void removeFirstPendingFlushConnection();
-    SensorEventConnection * getFirstPendingFlushConnection();
+    wp<const SensorEventConnection> getFirstPendingFlushConnection();
     void clearAllPendingFlushConnections();
 private:
-    SortedVector< wp<SensorEventConnection> > mConnections;
+    SortedVector< wp<const SensorEventConnection> > mConnections;
     // A queue of all flush() calls made on this sensor. Flush complete events
     // will be sent in this order.
-    Vector< wp<SensorEventConnection> > mPendingFlushConnections;
+    Vector< wp<const SensorEventConnection> > mPendingFlushConnections;
 };
 
 }
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index a24740b..2930637 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -260,7 +260,7 @@
             const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
             mSensorEventBuffer = new sensors_event_t[minBufferSize];
             mSensorEventScratch = new sensors_event_t[minBufferSize];
-            mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
+            mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
             mCurrentOperatingMode = NORMAL;
 
             mNextSensorRegIndex = 0;
@@ -322,6 +322,7 @@
                 IPCThreadState::self()->getCallingPid(),
                 IPCThreadState::self()->getCallingUid());
     } else {
+        bool privileged = IPCThreadState::self()->getCallingUid() == 0;
         if (args.size() > 2) {
            return INVALID_OPERATION;
         }
@@ -393,8 +394,12 @@
             result.append("Recent Sensor events:\n");
             for (auto&& i : mRecentEvent) {
                 sp<SensorInterface> s = mSensors.getInterface(i.first);
-                if (!i.second->isEmpty() &&
-                    s->getSensor().getRequiredPermission().isEmpty()) {
+                if (!i.second->isEmpty()) {
+                    if (privileged || s->getSensor().getRequiredPermission().isEmpty()) {
+                        i.second->setFormat("normal");
+                    } else {
+                        i.second->setFormat("mask_data");
+                    }
                     // if there is events and sensor does not need special permission.
                     result.appendFormat("%s: ", s->getSensor().getName().string());
                     result.append(i.second->dump().c_str());
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 1e1ea5a..4a63ef0 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -237,7 +237,7 @@
     SortedVector< wp<SensorEventConnection> > mActiveConnections;
     bool mWakeLockAcquired;
     sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
-    SensorEventConnection const **mMapFlushEventsToConnections;
+    wp<const SensorEventConnection> * mMapFlushEventsToConnections;
     std::unordered_map<int, RecentEventLogger*> mRecentEvent;
     Mode mCurrentOperatingMode;
 
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index dc5e97b..ffda035 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -79,18 +79,36 @@
     LOCAL_CFLAGS += -DRUNNING_WITHOUT_SYNC_FRAMEWORK
 endif
 
-# See build/target/board/generic/BoardConfig.mk for a description of this setting.
+# The following two BoardConfig variables define (respectively):
+#
+#   - The phase offset between hardware vsync and when apps are woken up by the
+#     Choreographer callback
+#   - The phase offset between hardware vsync and when SurfaceFlinger wakes up
+#     to consume input
+#
+# Their values can be tuned to trade off between display pipeline latency (both
+# overall latency and the lengths of the app --> SF and SF --> display phases)
+# and frame delivery jitter (which typically manifests as "jank" or "jerkiness"
+# while interacting with the device). The default values should produce a
+# relatively low amount of jitter at the expense of roughly two frames of
+# app --> display latency, and unless significant testing is performed to avoid
+# increased display jitter (both manual investigation using systrace [1] and
+# automated testing using dumpsys gfxinfo [2] are recommended), they should not
+# be modified.
+#
+# [1] https://developer.android.com/studio/profile/systrace.html
+# [2] https://developer.android.com/training/testing/performance.html
+
 ifneq ($(VSYNC_EVENT_PHASE_OFFSET_NS),)
     LOCAL_CFLAGS += -DVSYNC_EVENT_PHASE_OFFSET_NS=$(VSYNC_EVENT_PHASE_OFFSET_NS)
 else
-    LOCAL_CFLAGS += -DVSYNC_EVENT_PHASE_OFFSET_NS=0
+    LOCAL_CFLAGS += -DVSYNC_EVENT_PHASE_OFFSET_NS=1000000
 endif
 
-# See build/target/board/generic/BoardConfig.mk for a description of this setting.
 ifneq ($(SF_VSYNC_EVENT_PHASE_OFFSET_NS),)
     LOCAL_CFLAGS += -DSF_VSYNC_EVENT_PHASE_OFFSET_NS=$(SF_VSYNC_EVENT_PHASE_OFFSET_NS)
 else
-    LOCAL_CFLAGS += -DSF_VSYNC_EVENT_PHASE_OFFSET_NS=0
+    LOCAL_CFLAGS += -DSF_VSYNC_EVENT_PHASE_OFFSET_NS=1000000
 endif
 
 ifneq ($(PRESENT_TIME_OFFSET_FROM_VSYNC_NS),)
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index c67feb3..1a9820d 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -385,7 +385,7 @@
     mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
     // set DispSync to SCHED_FIFO to minimize jitter
     struct sched_param param = {0};
-    param.sched_priority = 1;
+    param.sched_priority = 2;
     if (sched_setscheduler(mThread->getTid(), SCHED_FIFO, &param) != 0) {
         ALOGE("Couldn't set SCHED_FIFO for DispSyncThread");
     }
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
index 8bcee39..cc0dfb0 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
@@ -2305,7 +2305,14 @@
                 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
                 break;
             case Composition::SolidColor:
-                hwc1Layer.compositionType = HWC_BACKGROUND;
+                // In theory the following line should work, but since the HWC1
+                // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
+                // devices may not work correctly. To be on the safe side, we
+                // fall back to client composition.
+                //
+                // hwc1Layer.compositionType = HWC_BACKGROUND;
+                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
+                hwc1Layer.flags |= HWC_SKIP_LAYER;
                 break;
             case Composition::Cursor:
                 hwc1Layer.compositionType = HWC_FRAMEBUFFER;
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 2a67f4c..8db071e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -471,7 +471,7 @@
 
         // set SFEventThread to SCHED_FIFO to minimize jitter
         struct sched_param param = {0};
-        param.sched_priority = 1;
+        param.sched_priority = 2;
         if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
             ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
         }
@@ -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
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 650d6b4..b0f418c 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -467,7 +467,7 @@
 
     // set SFEventThread to SCHED_FIFO to minimize jitter
     struct sched_param param = {0};
-    param.sched_priority = 1;
+    param.sched_priority = 2;
     if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
         ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
     }