Merge "[sensorservice] Add log to rare CTS failure cause"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 29cf2a4..8faf276 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -105,6 +105,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 868e24f..6d90b97 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -224,7 +224,8 @@
     struct dirent *trace;
     struct stat st;
     DIR *trace_dir;
-    long max_ctime = 0;
+    int retry = 5;
+    long max_ctime = 0, old_mtime;
     long long cur_size = 0;
     const char *trace_path = "/data/misc/anrd/";
 
@@ -237,6 +238,13 @@
     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)) {
@@ -244,6 +252,16 @@
             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);
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 2dddda0..11b0c3e 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -223,7 +223,7 @@
  */
 class DurationReporter {
 public:
-    DurationReporter(const char *title);
+    explicit DurationReporter(const char *title);
     DurationReporter(const char *title, FILE* out);
 
     ~DurationReporter();
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 3d33aca..ea3dc8a 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -688,8 +688,10 @@
   return count;
 }
 
-static void run_patchoat(int input_fd, int oat_fd, const char* input_file_name,
-    const char* output_file_name, const char *pkgname ATTRIBUTE_UNUSED, const char *instruction_set)
+static void run_patchoat(int input_oat_fd, int input_vdex_fd, int out_oat_fd, int out_vdex_fd,
+    const char* input_oat_file_name, const char* input_vdex_file_name,
+    const char* output_oat_file_name, const char* output_vdex_file_name,
+    const char *pkgname ATTRIBUTE_UNUSED, const char *instruction_set)
 {
     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
@@ -703,35 +705,44 @@
 
     /* input_file_name/input_fd should be the .odex/.oat file that is precompiled. I think*/
     char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
-    char output_oat_fd_arg[strlen("--output-oat-fd=") + MAX_INT_LEN];
     char input_oat_fd_arg[strlen("--input-oat-fd=") + MAX_INT_LEN];
+    char input_vdex_fd_arg[strlen("--input-vdex-fd=") + MAX_INT_LEN];
+    char output_oat_fd_arg[strlen("--output-oat-fd=") + MAX_INT_LEN];
+    char output_vdex_fd_arg[strlen("--output-vdex-fd=") + MAX_INT_LEN];
     const char* patched_image_location_arg = "--patched-image-location=/system/framework/boot.art";
     // The caller has already gotten all the locks we need.
     const char* no_lock_arg = "--no-lock-output";
     sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
-    sprintf(output_oat_fd_arg, "--output-oat-fd=%d", oat_fd);
-    sprintf(input_oat_fd_arg, "--input-oat-fd=%d", input_fd);
-    ALOGV("Running %s isa=%s in-fd=%d (%s) out-fd=%d (%s)\n",
-          PATCHOAT_BIN, instruction_set, input_fd, input_file_name, oat_fd, output_file_name);
+    sprintf(output_oat_fd_arg, "--output-oat-fd=%d", out_oat_fd);
+    sprintf(input_oat_fd_arg, "--input-oat-fd=%d", input_oat_fd);
+    ALOGV("Running %s isa=%s in-oat-fd=%d (%s) in-vdex-fd=%d (%s) "
+          "out-oat-fd=%d (%s) out-vdex-fd=%d (%s)\n",
+          PATCHOAT_BIN, instruction_set,
+          input_oat_fd, input_oat_file_name,
+          input_vdex_fd, input_vdex_file_name,
+          out_oat_fd, output_oat_file_name,
+          out_vdex_fd, output_vdex_file_name);
 
     /* patchoat, patched-image-location, no-lock, isa, input-fd, output-fd */
-    char* argv[7];
+    char* argv[9];
     argv[0] = (char*) PATCHOAT_BIN;
     argv[1] = (char*) patched_image_location_arg;
     argv[2] = (char*) no_lock_arg;
     argv[3] = instruction_set_arg;
-    argv[4] = output_oat_fd_arg;
-    argv[5] = input_oat_fd_arg;
-    argv[6] = NULL;
+    argv[4] = input_oat_fd_arg;
+    argv[5] = input_vdex_fd_arg;
+    argv[6] = output_oat_fd_arg;
+    argv[7] = output_vdex_fd_arg;
+    argv[8] = NULL;
 
     execv(PATCHOAT_BIN, (char* const *)argv);
     ALOGE("execv(%s) failed: %s\n", PATCHOAT_BIN, strerror(errno));
 }
 
-static void run_dex2oat(int zip_fd, int oat_fd, int image_fd, const char* input_file_name,
-        const char* output_file_name, int swap_fd, const char *instruction_set,
-        const char* compiler_filter, bool vm_safe_mode, bool debuggable, bool post_bootcomplete,
-        int profile_fd, const char* shared_libraries) {
+static void run_dex2oat(int zip_fd, int oat_fd, int vdex_fd, int image_fd,
+        const char* input_file_name, const char* output_file_name, int swap_fd,
+        const char *instruction_set, const char* compiler_filter, bool vm_safe_mode,
+        bool debuggable, bool post_bootcomplete, int profile_fd, const char* shared_libraries) {
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
 
     if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
@@ -812,6 +823,7 @@
 
     char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
     char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
+    char vdex_fd_arg[strlen("--vdex-fd=") + MAX_INT_LEN];
     char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
     char oat_location_arg[strlen("--oat-location=") + PKG_PATH_MAX];
     char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
@@ -827,6 +839,7 @@
 
     sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
     sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
+    sprintf(vdex_fd_arg, "--vdex-fd=%d", vdex_fd);
     sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
     sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
     sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
@@ -889,7 +902,7 @@
 
     ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
 
-    const char* argv[7  // program name, mandatory arguments and the final NULL
+    const char* argv[8  // program name, mandatory arguments and the final NULL
                      + (have_dex2oat_isa_variant ? 1 : 0)
                      + (have_dex2oat_isa_features ? 1 : 0)
                      + (have_dex2oat_Xms_flag ? 2 : 0)
@@ -910,6 +923,7 @@
     argv[i++] = DEX2OAT_BIN;
     argv[i++] = zip_fd_arg;
     argv[i++] = zip_location_arg;
+    argv[i++] = vdex_fd_arg;
     argv[i++] = oat_fd_arg;
     argv[i++] = oat_location_arg;
     argv[i++] = instruction_set_arg;
@@ -1367,31 +1381,40 @@
     return true;
 }
 
-// Translate the given oat path to an art (app image) path. An empty string
-// denotes an error.
-static std::string create_image_filename(const std::string& oat_path) {
-  // A standard dalvik-cache entry. Replace ".dex" with ".art."
+static std::string replace_file_extension(const std::string& oat_path, const std::string& new_ext) {
+  // A standard dalvik-cache entry. Replace ".dex" with `new_ext`.
   if (EndsWith(oat_path, ".dex")) {
-    std::string art_path = oat_path;
-    art_path.replace(art_path.length() - strlen("dex"), strlen("dex"), "art");
-    CHECK(EndsWith(art_path, ".art"));
-    return art_path;
+    std::string new_path = oat_path;
+    new_path.replace(new_path.length() - strlen(".dex"), strlen(".dex"), new_ext);
+    CHECK(EndsWith(new_path, new_ext.c_str()));
+    return new_path;
   }
 
   // An odex entry. Not that this may not be an extension, e.g., in the OTA
   // case (where the base name will have an extension for the B artifact).
   size_t odex_pos = oat_path.rfind(".odex");
   if (odex_pos != std::string::npos) {
-    std::string art_path = oat_path;
-    art_path.replace(odex_pos, strlen(".odex"), ".art");
-    CHECK_NE(art_path.find(".art"), std::string::npos);
-    return art_path;
+    std::string new_path = oat_path;
+    new_path.replace(odex_pos, strlen(".odex"), new_ext);
+    CHECK_NE(new_path.find(new_ext), std::string::npos);
+    return new_path;
   }
 
   // Don't know how to handle this.
   return "";
 }
 
+// Translate the given oat path to an art (app image) path. An empty string
+// denotes an error.
+static std::string create_image_filename(const std::string& oat_path) {
+    return replace_file_extension(oat_path, ".art");
+}
+
+// Translate the given oat path to a vdex path. An empty string denotes an error.
+static std::string create_vdex_filename(const std::string& oat_path) {
+    return replace_file_extension(oat_path, ".vdex");
+}
+
 static bool add_extension_to_file_name(char* file_name, const char* extension) {
     if (strlen(file_name) + strlen(extension) + 1 > PKG_PATH_MAX) {
         return false;
@@ -1427,7 +1450,7 @@
 }
 
 static bool create_oat_out_path(const char* apk_path, const char* instruction_set,
-            const char* oat_dir, /*out*/ char* out_path) {
+            const char* oat_dir, /*out*/ char* out_oat_path) {
     // Early best-effort check whether we can fit the the path into our buffers.
     // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
     // without a swap file, if necessary. Reference profiles file also add an extra ".prof"
@@ -1442,11 +1465,11 @@
             ALOGE("invalid oat_dir '%s'\n", oat_dir);
             return false;
         }
-        if (!calculate_oat_file_path(out_path, oat_dir, apk_path, instruction_set)) {
+        if (!calculate_oat_file_path(out_oat_path, oat_dir, apk_path, instruction_set)) {
             return false;
         }
     } else {
-        if (!create_cache_path(out_path, apk_path, instruction_set)) {
+        if (!create_cache_path(out_oat_path, apk_path, instruction_set)) {
             return false;
         }
     }
@@ -1568,9 +1591,6 @@
     bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
     bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
 
-    // Don't use profile for vm_safe_mode. b/30688277
-    profile_guided = profile_guided && !vm_safe_mode;
-
     CHECK(pkgname != nullptr);
     CHECK(pkgname[0] != 0);
 
@@ -1591,8 +1611,8 @@
         LOG_FATAL("dexopt flags contains unknown fields\n");
     }
 
-    char out_path[PKG_PATH_MAX];
-    if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_path)) {
+    char out_oat_path[PKG_PATH_MAX];
+    if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_oat_path)) {
         return false;
     }
 
@@ -1611,7 +1631,7 @@
             break;
 
         case DEXOPT_SELF_PATCHOAT_NEEDED:
-            input_file = out_path;
+            input_file = out_oat_path;
             break;
 
         default:
@@ -1623,21 +1643,57 @@
     memset(&input_stat, 0, sizeof(input_stat));
     stat(input_file, &input_stat);
 
+    // Open the input file. If running dex2oat, `input_file` is the APK. If running
+    // patchoat, it is the OAT file to be relocated.
     base::unique_fd input_fd(open(input_file, O_RDONLY, 0));
     if (input_fd.get() < 0) {
         ALOGE("installd cannot open '%s' for input during dexopt\n", input_file);
         return -1;
     }
 
-    const std::string out_path_str(out_path);
-    Dex2oatFileWrapper<std::function<void ()>> out_fd(
-            open_output_file(out_path, /*recreate*/true, /*permissions*/0644),
-            [out_path_str]() { unlink(out_path_str.c_str()); });
-    if (out_fd.get() < 0) {
-        ALOGE("installd cannot open '%s' for output during dexopt\n", out_path);
+    // If invoking patchoat, open the VDEX associated with the OAT too.
+    std::string in_vdex_path_str;
+    base::unique_fd input_vdex_fd;
+    if (dexopt_needed == DEXOPT_PATCHOAT_NEEDED
+        || dexopt_needed == DEXOPT_SELF_PATCHOAT_NEEDED) {
+        in_vdex_path_str = create_vdex_filename(input_file);
+        if (in_vdex_path_str.empty()) {
+            return -1;
+        }
+        input_vdex_fd.reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
+        if (input_vdex_fd.get() < 0) {
+            ALOGE("installd cannot open '%s' for input during dexopt\n", in_vdex_path_str.c_str());
+            return -1;
+        }
+    }
+
+    // Create the output OAT file.
+    const std::string out_oat_path_str(out_oat_path);
+    Dex2oatFileWrapper<std::function<void ()>> out_oat_fd(
+            open_output_file(out_oat_path, /*recreate*/true, /*permissions*/0644),
+            [out_oat_path_str]() { unlink(out_oat_path_str.c_str()); });
+    if (out_oat_fd.get() < 0) {
+        ALOGE("installd cannot open '%s' for output during dexopt\n", out_oat_path);
         return -1;
     }
-    if (!set_permissions_and_ownership(out_fd.get(), is_public, uid, out_path)) {
+    if (!set_permissions_and_ownership(out_oat_fd.get(), is_public, uid, out_oat_path)) {
+        return -1;
+    }
+
+    // Infer the name of the output VDEX and create it.
+    const std::string out_vdex_path_str = create_vdex_filename(out_oat_path_str);
+    if (out_vdex_path_str.empty()) {
+        return -1;
+    }
+    Dex2oatFileWrapper<std::function<void ()>> out_vdex_fd(
+            open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644),
+            [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
+    if (out_vdex_fd.get() < 0) {
+        ALOGE("installd cannot open '%s' for output during dexopt\n", out_vdex_path_str.c_str());
+        return -1;
+    }
+    if (!set_permissions_and_ownership(out_vdex_fd.get(), is_public,
+                uid, out_vdex_path_str.c_str())) {
         return -1;
     }
 
@@ -1646,7 +1702,7 @@
     if (ShouldUseSwapFileForDexopt()) {
         // Make sure there really is enough space.
         char swap_file_name[PKG_PATH_MAX];
-        strcpy(swap_file_name, out_path);
+        strcpy(swap_file_name, out_oat_path);
         if (add_extension_to_file_name(swap_file_name, ".swap")) {
             swap_fd.reset(open_output_file(swap_file_name, /*recreate*/true, /*permissions*/0600));
         }
@@ -1664,8 +1720,8 @@
 
     // Avoid generating an app image for extract only since it will not contain any classes.
     Dex2oatFileWrapper<std::function<void ()>> image_fd;
-    const std::string image_path = create_image_filename(out_path);
-    if (!image_path.empty()) {
+    const std::string image_path = create_image_filename(out_oat_path);
+    if (dexopt_needed == DEXOPT_DEX2OAT_NEEDED && !image_path.empty()) {
         char app_image_format[kPropertyValueMax];
         bool have_app_image_format =
                 get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
@@ -1710,27 +1766,32 @@
         drop_capabilities(uid);
 
         SetDex2OatAndPatchOatScheduling(boot_complete);
-        if (flock(out_fd.get(), LOCK_EX | LOCK_NB) != 0) {
-            ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno));
+        if (flock(out_oat_fd.get(), LOCK_EX | LOCK_NB) != 0) {
+            ALOGE("flock(%s) failed: %s\n", out_oat_path, strerror(errno));
             _exit(67);
         }
 
         if (dexopt_needed == DEXOPT_PATCHOAT_NEEDED
             || dexopt_needed == DEXOPT_SELF_PATCHOAT_NEEDED) {
             run_patchoat(input_fd.get(),
-                         out_fd.get(),
+                         input_vdex_fd.get(),
+                         out_oat_fd.get(),
+                         out_vdex_fd.get(),
                          input_file,
-                         out_path,
+                         in_vdex_path_str.c_str(),
+                         out_oat_path,
+                         out_vdex_path_str.c_str(),
                          pkgname,
                          instruction_set);
         } else if (dexopt_needed == DEXOPT_DEX2OAT_NEEDED) {
             // Pass dex2oat the relative path to the input file.
             const char *input_file_name = get_location_from_path(input_file);
             run_dex2oat(input_fd.get(),
-                        out_fd.get(),
+                        out_oat_fd.get(),
+                        out_vdex_fd.get(),
                         image_fd.get(),
                         input_file_name,
-                        out_path,
+                        out_oat_path,
                         swap_fd.get(),
                         instruction_set,
                         compiler_filter,
@@ -1757,10 +1818,11 @@
     struct utimbuf ut;
     ut.actime = input_stat.st_atime;
     ut.modtime = input_stat.st_mtime;
-    utime(out_path, &ut);
+    utime(out_oat_path, &ut);
 
     // We've been successful, don't delete output.
-    out_fd.SetCleanup(false);
+    out_oat_fd.SetCleanup(false);
+    out_vdex_fd.SetCleanup(false);
     image_fd.SetCleanup(false);
     reference_profile_fd.SetCleanup(false);
 
@@ -2165,33 +2227,41 @@
     if (!calculate_oat_file_path(a_path, oat_dir, apk_path, instruction_set)) {
         return -1;
     }
+    const std::string a_vdex_path = create_vdex_filename(a_path);
     const std::string a_image_path = create_image_filename(a_path);
 
     // B path = A path + slot suffix.
     const std::string b_path = StringPrintf("%s.%s", a_path, slot_suffix.c_str());
+    const std::string b_vdex_path = StringPrintf("%s.%s", a_vdex_path.c_str(), slot_suffix.c_str());
     const std::string b_image_path = StringPrintf("%s.%s",
                                                   a_image_path.c_str(),
                                                   slot_suffix.c_str());
 
-    bool oat_success = move_ab_path(b_path, a_path);
-    bool success;
+    bool success = true;
+    if (move_ab_path(b_path, a_path)) {
+        if (move_ab_path(b_vdex_path, a_vdex_path)) {
+            // Note: we can live without an app image. As such, ignore failure to move the image file.
+            //       If we decide to require the app image, or the app image being moved correctly,
+            //       then change accordingly.
+            constexpr bool kIgnoreAppImageFailure = true;
 
-    if (oat_success) {
-        // Note: we can live without an app image. As such, ignore failure to move the image file.
-        //       If we decide to require the app image, or the app image being moved correctly,
-        //       then change accordingly.
-        constexpr bool kIgnoreAppImageFailure = true;
-
-        bool art_success = true;
-        if (!a_image_path.empty()) {
-            art_success = move_ab_path(b_image_path, a_image_path);
+            if (!a_image_path.empty()) {
+                if (!move_ab_path(b_image_path, a_image_path)) {
+                    unlink(a_image_path.c_str());
+                    if (!kIgnoreAppImageFailure) {
+                        success = false;
+                    }
+                }
+            }
+        } else {
+            // Cleanup: delete B image, ignore errors.
+            unlink(b_image_path.c_str());
+            success = false;
         }
-
-        success = art_success || kIgnoreAppImageFailure;
     } else {
         // Cleanup: delete B image, ignore errors.
+        unlink(b_vdex_path.c_str());
         unlink(b_image_path.c_str());
-
         success = false;
     }
 
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index 2bc3dfa..531c6df 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -151,12 +151,11 @@
         return false;
     }
 
-    sprintf(path,"%s%s/%s/%s%s",
+    sprintf(path,"%s%s/%s/%s",
             android_data_dir.path,
             DALVIK_CACHE,
             instruction_set,
-            src + 1, /* skip the leading / */
-            DALVIK_CACHE_POSTFIX);
+            src + 1 /* skip the leading / */);
 
     char* tmp =
             path +
@@ -171,6 +170,7 @@
         }
     }
 
+    strcat(path, DALVIK_CACHE_POSTFIX);
     return true;
 }
 
diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h
index 41732cc..b0bcce9 100644
--- a/cmds/installd/installd_constants.h
+++ b/cmds/installd/installd_constants.h
@@ -28,8 +28,7 @@
 
 // This is used as a string literal, can't be constants. TODO: std::string...
 #define DALVIK_CACHE "dalvik-cache"
-constexpr const char* DALVIK_CACHE_POSTFIX = "/classes.dex";
-constexpr const char* DALVIK_CACHE_POSTFIX2 = "@classes.dex";
+constexpr const char* DALVIK_CACHE_POSTFIX = "@classes.dex";
 
 constexpr size_t PKG_NAME_MAX = 128u;   /* largest allowed package name */
 constexpr size_t PKG_PATH_MAX = 256u;   /* max size of any path we use */
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 5fa972a..7e02b6b 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -823,7 +823,7 @@
                                               DALVIK_CACHE,
                                               instruction_set,
                                               from_src.c_str(),
-                                              DALVIK_CACHE_POSTFIX2);
+                                              DALVIK_CACHE_POSTFIX);
 
     if (assembled_path.length() + 1 > PKG_PATH_MAX) {
         return false;
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 1c054f5..90c69ce 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -455,7 +455,7 @@
     };
 
     struct ConfigurationChangedEntry : EventEntry {
-        ConfigurationChangedEntry(nsecs_t eventTime);
+        explicit ConfigurationChangedEntry(nsecs_t eventTime);
         virtual void appendDescription(String8& msg) const;
 
     protected:
@@ -591,7 +591,7 @@
 
     class Connection;
     struct CommandEntry : Link<CommandEntry> {
-        CommandEntry(Command command);
+        explicit CommandEntry(Command command);
         ~CommandEntry();
 
         Command command;
diff --git a/services/inputflinger/InputListener.h b/services/inputflinger/InputListener.h
index 1ec09ce..ea3dd1c 100644
--- a/services/inputflinger/InputListener.h
+++ b/services/inputflinger/InputListener.h
@@ -40,7 +40,7 @@
 
     inline NotifyConfigurationChangedArgs() { }
 
-    NotifyConfigurationChangedArgs(nsecs_t eventTime);
+    explicit NotifyConfigurationChangedArgs(nsecs_t eventTime);
 
     NotifyConfigurationChangedArgs(const NotifyConfigurationChangedArgs& other);
 
@@ -178,7 +178,7 @@
     virtual ~QueuedInputListener();
 
 public:
-    QueuedInputListener(const sp<InputListenerInterface>& innerListener);
+    explicit QueuedInputListener(const sp<InputListenerInterface>& innerListener);
 
     virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
     virtual void notifyKey(const NotifyKeyArgs* args);
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index b9be675..4dec34b 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -6652,6 +6652,7 @@
     size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
     size_t outCount = 0;
     BitSet32 newPointerIdBits;
+    mHavePointerIds = true;
 
     for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
         const MultiTouchMotionAccumulator::Slot* inSlot =
@@ -6696,33 +6697,33 @@
         outPointer.isHovering = isHovering;
 
         // Assign pointer id using tracking id if available.
-        mHavePointerIds = true;
-        int32_t trackingId = inSlot->getTrackingId();
-        int32_t id = -1;
-        if (trackingId >= 0) {
-            for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
-                uint32_t n = idBits.clearFirstMarkedBit();
-                if (mPointerTrackingIdMap[n] == trackingId) {
-                    id = n;
+        if (mHavePointerIds) {
+            int32_t trackingId = inSlot->getTrackingId();
+            int32_t id = -1;
+            if (trackingId >= 0) {
+                for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
+                    uint32_t n = idBits.clearFirstMarkedBit();
+                    if (mPointerTrackingIdMap[n] == trackingId) {
+                        id = n;
+                    }
+                }
+
+                if (id < 0 && !mPointerIdBits.isFull()) {
+                    id = mPointerIdBits.markFirstUnmarkedBit();
+                    mPointerTrackingIdMap[id] = trackingId;
                 }
             }
-
-            if (id < 0 && !mPointerIdBits.isFull()) {
-                id = mPointerIdBits.markFirstUnmarkedBit();
-                mPointerTrackingIdMap[id] = trackingId;
+            if (id < 0) {
+                mHavePointerIds = false;
+                outState->rawPointerData.clearIdBits();
+                newPointerIdBits.clear();
+            } else {
+                outPointer.id = id;
+                outState->rawPointerData.idToIndex[id] = outCount;
+                outState->rawPointerData.markIdBit(id, isHovering);
+                newPointerIdBits.markBit(id);
             }
         }
-        if (id < 0) {
-            mHavePointerIds = false;
-            outState->rawPointerData.clearIdBits();
-            newPointerIdBits.clear();
-        } else {
-            outPointer.id = id;
-            outState->rawPointerData.idToIndex[id] = outCount;
-            outState->rawPointerData.markIdBit(id, isHovering);
-            newPointerIdBits.markBit(id);
-        }
-
         outCount += 1;
     }
 
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 076f3d6..8e2fe95 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -484,7 +484,7 @@
         InputReader* mReader;
 
     public:
-        ContextImpl(InputReader* reader);
+        explicit ContextImpl(InputReader* reader);
 
         virtual void updateGlobalMetaState();
         virtual int32_t getGlobalMetaState();
@@ -568,7 +568,7 @@
 /* Reads raw events from the event hub and processes them, endlessly. */
 class InputReaderThread : public Thread {
 public:
-    InputReaderThread(const sp<InputReaderInterface>& reader);
+    explicit InputReaderThread(const sp<InputReaderInterface>& reader);
     virtual ~InputReaderThread();
 
 private:
@@ -1007,7 +1007,7 @@
  */
 class InputMapper {
 public:
-    InputMapper(InputDevice* device);
+    explicit InputMapper(InputDevice* device);
     virtual ~InputMapper();
 
     inline InputDevice* getDevice() { return mDevice; }
@@ -1058,7 +1058,7 @@
 
 class SwitchInputMapper : public InputMapper {
 public:
-    SwitchInputMapper(InputDevice* device);
+    explicit SwitchInputMapper(InputDevice* device);
     virtual ~SwitchInputMapper();
 
     virtual uint32_t getSources();
@@ -1078,7 +1078,7 @@
 
 class VibratorInputMapper : public InputMapper {
 public:
-    VibratorInputMapper(InputDevice* device);
+    explicit VibratorInputMapper(InputDevice* device);
     virtual ~VibratorInputMapper();
 
     virtual uint32_t getSources();
@@ -1178,7 +1178,7 @@
 
 class CursorInputMapper : public InputMapper {
 public:
-    CursorInputMapper(InputDevice* device);
+    explicit CursorInputMapper(InputDevice* device);
     virtual ~CursorInputMapper();
 
     virtual uint32_t getSources();
@@ -1243,7 +1243,7 @@
 
 class RotaryEncoderInputMapper : public InputMapper {
 public:
-    RotaryEncoderInputMapper(InputDevice* device);
+    explicit RotaryEncoderInputMapper(InputDevice* device);
     virtual ~RotaryEncoderInputMapper();
 
     virtual uint32_t getSources();
@@ -1264,7 +1264,7 @@
 
 class TouchInputMapper : public InputMapper {
 public:
-    TouchInputMapper(InputDevice* device);
+    explicit TouchInputMapper(InputDevice* device);
     virtual ~TouchInputMapper();
 
     virtual uint32_t getSources();
@@ -1887,7 +1887,7 @@
 
 class SingleTouchInputMapper : public TouchInputMapper {
 public:
-    SingleTouchInputMapper(InputDevice* device);
+    explicit SingleTouchInputMapper(InputDevice* device);
     virtual ~SingleTouchInputMapper();
 
     virtual void reset(nsecs_t when);
@@ -1905,7 +1905,7 @@
 
 class MultiTouchInputMapper : public TouchInputMapper {
 public:
-    MultiTouchInputMapper(InputDevice* device);
+    explicit MultiTouchInputMapper(InputDevice* device);
     virtual ~MultiTouchInputMapper();
 
     virtual void reset(nsecs_t when);
@@ -1926,7 +1926,7 @@
 
 class ExternalStylusInputMapper : public InputMapper {
 public:
-    ExternalStylusInputMapper(InputDevice* device);
+    explicit ExternalStylusInputMapper(InputDevice* device);
     virtual ~ExternalStylusInputMapper() = default;
 
     virtual uint32_t getSources();
@@ -1948,7 +1948,7 @@
 
 class JoystickInputMapper : public InputMapper {
 public:
-    JoystickInputMapper(InputDevice* device);
+    explicit JoystickInputMapper(InputDevice* device);
     virtual ~JoystickInputMapper();
 
     virtual uint32_t getSources();
diff --git a/services/inputflinger/InputWindow.h b/services/inputflinger/InputWindow.h
index e243637..feca6cf 100644
--- a/services/inputflinger/InputWindow.h
+++ b/services/inputflinger/InputWindow.h
@@ -196,7 +196,7 @@
     void releaseInfo();
 
 protected:
-    InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle);
+    explicit InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle);
     virtual ~InputWindowHandle();
 
     InputWindowInfo* mInfo;
diff --git a/services/inputflinger/host/InputDriver.h b/services/inputflinger/host/InputDriver.h
index 8d5a31e..e56673b 100644
--- a/services/inputflinger/host/InputDriver.h
+++ b/services/inputflinger/host/InputDriver.h
@@ -82,7 +82,7 @@
 
 class InputDriver : public InputDriverInterface {
 public:
-    InputDriver(const char* name);
+    explicit InputDriver(const char* name);
     virtual ~InputDriver() = default;
 
     virtual void init() override;
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..bf1f655 100644
--- a/services/sensorservice/RecentEventLogger.h
+++ b/services/sensorservice/RecentEventLogger.h
@@ -35,7 +35,7 @@
 // behavior.
 class RecentEventLogger : public Dumpable {
 public:
-    RecentEventLogger(int sensorType);
+    explicit RecentEventLogger(int sensorType);
     void addEvent(const sensors_event_t& event);
     bool populateLastEvent(sensors_event_t *event) const;
     bool isEmpty() const;
@@ -43,10 +43,11 @@
 
     // Dumpable interface
     virtual std::string dump() const override;
+    virtual void setFormat(std::string format) override;
 
 protected:
     struct SensorEventLog {
-        SensorEventLog(const sensors_event_t& e);
+        explicit SensorEventLog(const sensors_event_t& e);
         timespec mWallTime;
         sensors_event_t mEvent;
     };
@@ -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/RingBuffer.h b/services/sensorservice/RingBuffer.h
index ec98a01..a60eb90 100644
--- a/services/sensorservice/RingBuffer.h
+++ b/services/sensorservice/RingBuffer.h
@@ -39,7 +39,7 @@
     /**
      * Construct a RingBuffer that can grow up to the given length.
      */
-    RingBuffer(size_t length);
+    explicit RingBuffer(size_t length);
 
     /**
      * Forward iterator to this class.  Implements an std:forward_iterator.
diff --git a/services/sensorservice/RotationVectorSensor.h b/services/sensorservice/RotationVectorSensor.h
index 3cc2248..265b4c4 100644
--- a/services/sensorservice/RotationVectorSensor.h
+++ b/services/sensorservice/RotationVectorSensor.h
@@ -34,7 +34,7 @@
 
 class RotationVectorSensor : public VirtualSensor {
 public:
-    RotationVectorSensor(int mode = FUSION_9AXIS);
+    explicit RotationVectorSensor(int mode = FUSION_9AXIS);
     virtual bool process(sensors_event_t* outEvent, const sensors_event_t& event) override;
     virtual status_t activate(void* ident, bool enabled) override;
     virtual status_t setDelay(void* ident, int handle, int64_t ns) override;
diff --git a/services/sensorservice/SensorEventAckReceiver.h b/services/sensorservice/SensorEventAckReceiver.h
index 998597a..20fa4c7 100644
--- a/services/sensorservice/SensorEventAckReceiver.h
+++ b/services/sensorservice/SensorEventAckReceiver.h
@@ -27,7 +27,7 @@
     sp<SensorService> const mService;
 public:
     virtual bool threadLoop();
-    SensorEventAckReceiver(const sp<SensorService>& service)
+    explicit SensorEventAckReceiver(const sp<SensorService>& service)
             : mService(service) {
     }
 };
diff --git a/services/sensorservice/SensorInterface.h b/services/sensorservice/SensorInterface.h
index dafcf2d..0867dc2 100644
--- a/services/sensorservice/SensorInterface.h
+++ b/services/sensorservice/SensorInterface.h
@@ -47,7 +47,7 @@
 
 class BaseSensor : public SensorInterface {
 public:
-    BaseSensor(const sensor_t& sensor);
+    explicit BaseSensor(const sensor_t& sensor);
     BaseSensor(const sensor_t& sensor, const uint8_t (&uuid)[16]);
 
     // Not all sensors need to support batching.
@@ -74,7 +74,7 @@
 
 class HardwareSensor : public BaseSensor {
 public:
-    HardwareSensor(const sensor_t& sensor);
+    explicit HardwareSensor(const sensor_t& sensor);
     HardwareSensor(const sensor_t& sensor, const uint8_t (&uuid)[16]);
 
     virtual ~HardwareSensor();
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index dbd0624..2930637 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -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/mat.h b/services/sensorservice/mat.h
index a76fc91..495c14e 100644
--- a/services/sensorservice/mat.h
+++ b/services/sensorservice/mat.h
@@ -139,13 +139,13 @@
 
     mat() { }
     mat(const mat& rhs)  : base(rhs) { }
-    mat(const base& rhs) : base(rhs) { }
+    mat(const base& rhs) : base(rhs) { }  // NOLINT(implicit)
 
     // -----------------------------------------------------------------------
     // conversion constructors
 
     // sets the diagonal to the value, off-diagonal to zero
-    mat(pTYPE rhs) {
+    mat(pTYPE rhs) {  // NOLINT(implicit)
         helpers::doAssign(*this, rhs);
     }
 
@@ -220,7 +220,7 @@
     template<size_t PREV_COLUMN>
     struct column_builder {
         mat& matrix;
-        column_builder(mat& matrix) : matrix(matrix) { }
+        explicit column_builder(mat& matrix) : matrix(matrix) { }
     };
 
     // operator << is not a method of column_builder<> so we can
@@ -265,9 +265,9 @@
     enum { ROWS = R, COLS = 1 };
 
     mat() { }
-    mat(const base& rhs) : base(rhs) { }
+    explicit mat(const base& rhs) : base(rhs) { }
     mat(const mat& rhs) : base(rhs) { }
-    mat(const TYPE& rhs) { helpers::doAssign(*this, rhs); }
+    explicit mat(const TYPE& rhs) { helpers::doAssign(*this, rhs); }
     mat& operator=(const mat& rhs) { base::operator=(rhs); return *this; }
     mat& operator=(const base& rhs) { base::operator=(rhs); return *this; }
     mat& operator=(const TYPE& rhs) { return helpers::doAssign(*this, rhs); }
diff --git a/services/sensorservice/vec.h b/services/sensorservice/vec.h
index a142bad..9e5d280 100644
--- a/services/sensorservice/vec.h
+++ b/services/sensorservice/vec.h
@@ -322,12 +322,12 @@
 
     vec() { }
     vec(const vec& rhs)  : base(rhs) { }
-    vec(const base& rhs) : base(rhs) { }
+    vec(const base& rhs) : base(rhs) { }  // NOLINT(implicit)
 
     // -----------------------------------------------------------------------
     // conversion constructors
 
-    vec(pTYPE rhs) {
+    vec(pTYPE rhs) {  // NOLINT(implicit)
         for (size_t i=0 ; i<SIZE ; i++)
             base::operator[](i) = rhs;
     }
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 6c48b28..39b4528 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -81,18 +81,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/Client.h b/services/surfaceflinger/Client.h
index 12db505..9c7d050 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -38,7 +38,7 @@
 class Client : public BnSurfaceComposerClient
 {
 public:
-        Client(const sp<SurfaceFlinger>& flinger);
+        explicit Client(const sp<SurfaceFlinger>& flinger);
         ~Client();
 
     status_t initCheck() const;
diff --git a/services/surfaceflinger/Colorizer.h b/services/surfaceflinger/Colorizer.h
index 6524481..f2e6491 100644
--- a/services/surfaceflinger/Colorizer.h
+++ b/services/surfaceflinger/Colorizer.h
@@ -34,7 +34,7 @@
         WHITE   = 37
     };
 
-    Colorizer(bool enabled)
+    explicit Colorizer(bool enabled)
         : mEnabled(enabled) {
     }
 
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 245c27b..836fb89 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/DispSync.h b/services/surfaceflinger/DispSync.h
index 537c81b..2763e59 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -61,7 +61,7 @@
         virtual void onDispSyncEvent(nsecs_t when) = 0;
     };
 
-    DispSync(const char* name);
+    explicit DispSync(const char* name);
     ~DispSync();
 
     // reset clears the resync samples and error value.
diff --git a/services/surfaceflinger/DisplayHardware/FloatRect.h b/services/surfaceflinger/DisplayHardware/FloatRect.h
index 9ad1040..151eaaa 100644
--- a/services/surfaceflinger/DisplayHardware/FloatRect.h
+++ b/services/surfaceflinger/DisplayHardware/FloatRect.h
@@ -32,7 +32,7 @@
 
     inline FloatRect()
         : left(0), top(0), right(0), bottom(0) { }
-    inline FloatRect(const Rect& other)
+    inline FloatRect(const Rect& other)  // NOLINT(implicit)
         : left(other.left), top(other.top), right(other.right), bottom(other.bottom) { }
 
     inline float getWidth() const { return right - left; }
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index fb04af8..32a9de0 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -57,7 +57,7 @@
 class Device
 {
 public:
-    Device(hwc2_device_t* device);
+    explicit Device(hwc2_device_t* device);
     ~Device();
 
     friend class HWC2::Display;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
index e447c3c..047e3aa 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h
@@ -43,7 +43,7 @@
 class HWC2On1Adapter : public hwc2_device_t
 {
 public:
-    HWC2On1Adapter(struct hwc_composer_device_1* hwc1Device);
+    explicit HWC2On1Adapter(struct hwc_composer_device_1* hwc1Device);
     ~HWC2On1Adapter();
 
     struct hwc_composer_device_1* getHwc1Device() const { return mHwc1Device; }
@@ -496,7 +496,7 @@
 
     class Layer {
         public:
-            Layer(Display& display);
+            explicit Layer(Display& display);
 
             bool operator==(const Layer& other) { return mId == other.mId; }
             bool operator!=(const Layer& other) { return !(*this == other); }
diff --git a/services/surfaceflinger/EventControlThread.h b/services/surfaceflinger/EventControlThread.h
index be6c53a..9368db6 100644
--- a/services/surfaceflinger/EventControlThread.h
+++ b/services/surfaceflinger/EventControlThread.h
@@ -29,7 +29,7 @@
 class EventControlThread: public Thread {
 public:
 
-    EventControlThread(const sp<SurfaceFlinger>& flinger);
+    explicit EventControlThread(const sp<SurfaceFlinger>& flinger);
     virtual ~EventControlThread() {}
 
     void setVsyncEnabled(bool enabled);
diff --git a/services/surfaceflinger/EventLog/EventLog.h b/services/surfaceflinger/EventLog/EventLog.h
index 5207514..efc5d70 100644
--- a/services/surfaceflinger/EventLog/EventLog.h
+++ b/services/surfaceflinger/EventLog/EventLog.h
@@ -52,7 +52,7 @@
         bool mOverflow;
         char mStorage[STORAGE_MAX_SIZE];
     public:
-        TagBuffer(int32_t tag);
+        explicit TagBuffer(int32_t tag);
 
         // starts list of items
         void startList(int8_t count);
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index f1f89f8..3f1d0bb 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -57,7 +57,7 @@
 class EventThread : public Thread, private VSyncSource::Callback {
     class Connection : public BnDisplayEventConnection {
     public:
-        Connection(const sp<EventThread>& eventThread);
+        explicit Connection(const sp<EventThread>& eventThread);
         status_t postEvent(const DisplayEventReceiver::Event& event);
 
         // count >= 1 : continuous event. count is the vsync rate
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c8911f3..8ad3878 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -573,19 +573,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: "
@@ -2217,6 +2223,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 56f6607..efb0fb8 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -397,6 +397,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();
@@ -476,7 +480,7 @@
     class SyncPoint
     {
     public:
-        SyncPoint(uint64_t frameNumber) : mFrameNumber(frameNumber),
+        explicit SyncPoint(uint64_t frameNumber) : mFrameNumber(frameNumber),
                 mFrameIsAvailable(false), mTransactionIsApplied(false) {}
 
         uint64_t getFrameNumber() const {
@@ -610,6 +614,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/MessageQueue.h b/services/surfaceflinger/MessageQueue.h
index 1004f4c..aed0aa9 100644
--- a/services/surfaceflinger/MessageQueue.h
+++ b/services/surfaceflinger/MessageQueue.h
@@ -69,7 +69,7 @@
         MessageQueue& mQueue;
         int32_t mEventMask;
     public:
-        Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }
+        explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }
         virtual void handleMessage(const Message& message);
         void dispatchRefresh();
         void dispatchInvalidate();
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c15b4bc..13c98e7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -511,7 +511,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");
         }
@@ -3146,6 +3146,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 97ad9b2..3ae2c04 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -507,7 +507,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");
     }
diff --git a/vulkan/libvulkan/debug_report.h b/vulkan/libvulkan/debug_report.h
index be9b645..3d8bd50 100644
--- a/vulkan/libvulkan/debug_report.h
+++ b/vulkan/libvulkan/debug_report.h
@@ -85,9 +85,9 @@
 
 class DebugReportLogger {
    public:
-    DebugReportLogger(const VkInstanceCreateInfo& info)
+    explicit DebugReportLogger(const VkInstanceCreateInfo& info)
         : instance_pnext_(info.pNext), callbacks_(nullptr) {}
-    DebugReportLogger(const DebugReportCallbackList& callbacks)
+    explicit DebugReportLogger(const DebugReportCallbackList& callbacks)
         : instance_pnext_(nullptr), callbacks_(&callbacks) {}
 
     void Message(VkDebugReportFlagsEXT flags,
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index a02ebd7..a1612c7 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -61,7 +61,7 @@
 VK_DEFINE_HANDLE(DeviceDispatchable)
 
 struct InstanceData {
-    InstanceData(const VkAllocationCallbacks& alloc)
+    explicit InstanceData(const VkAllocationCallbacks& alloc)
         : opaque_api_data(),
           allocator(alloc),
           driver(),
diff --git a/vulkan/libvulkan/layers_extensions.h b/vulkan/libvulkan/layers_extensions.h
index 79fe59d..07ac1a3 100644
--- a/vulkan/libvulkan/layers_extensions.h
+++ b/vulkan/libvulkan/layers_extensions.h
@@ -26,7 +26,7 @@
 
 class LayerRef {
    public:
-    LayerRef(const Layer* layer);
+    explicit LayerRef(const Layer* layer);
     LayerRef(LayerRef&& other);
     ~LayerRef();
     LayerRef(const LayerRef&) = delete;