Merge "binder: print the bad cmd error to android log" am: 2e9ff8c5be am: 564e686168
am: 521f992ae8

Change-Id: I19ad71ec63036a6e4db2477cd6c2a2f75d975fc2
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index e478651..0433f31 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -10,7 +10,7 @@
 
 LOCAL_MODULE := dumpstate
 
-LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux libbase libhardware_legacy
+LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux libbase
 # ZipArchive support, the order matters here to get all symbols.
 LOCAL_STATIC_LIBRARIES := libziparchive libz libcrypto_static
 LOCAL_HAL_STATIC_LIBRARIES := libdumpstate
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 41b200c..c7b904d 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -23,7 +23,6 @@
 #include <memory>
 #include <regex>
 #include <set>
-#include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -36,11 +35,11 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-#include <android-base/stringprintf.h>
-#include <android-base/unique_fd.h>
 #include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
 #include <cutils/properties.h>
-#include <hardware_legacy/power.h>
 
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
@@ -83,7 +82,6 @@
 #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];
@@ -387,6 +385,80 @@
     }
 }
 
+/**
+ * Finds the last modified file in the directory dir whose name starts with file_prefix
+ * Function returns empty string when it does not find a file
+ */
+static std::string get_last_modified_file_matching_prefix(const std::string& dir,
+                                                          const std::string& file_prefix) {
+    std::unique_ptr<DIR, decltype(&closedir)> d(opendir(dir.c_str()), closedir);
+    if (d == nullptr) {
+        MYLOGD("Error %d opening %s\n", errno, dir.c_str());
+        return "";
+    }
+
+    // Find the newest file matching the file_prefix in dir
+    struct dirent *de;
+    time_t last_modified = 0;
+    std::string last_modified_file = "";
+    struct stat s;
+
+    while ((de = readdir(d.get()))) {
+        std::string file = std::string(de->d_name);
+        if (!file_prefix.empty()) {
+            if (!android::base::StartsWith(file, file_prefix.c_str())) continue;
+        }
+        file = dir + "/" + file;
+        int ret = stat(file.c_str(), &s);
+
+        if ((ret == 0) && (s.st_mtime > last_modified)) {
+            last_modified_file = file;
+            last_modified = s.st_mtime;
+        }
+    }
+
+    return last_modified_file;
+}
+
+void dump_modem_logs() {
+    DurationReporter duration_reporter("dump_modem_logs");
+    if (is_user_build()) {
+        return;
+    }
+
+    if (!is_zipping()) {
+        MYLOGD("Not dumping modem logs. dumpstate is not generating a zipping bugreport\n");
+        return;
+    }
+
+    char property[PROPERTY_VALUE_MAX];
+    property_get("ro.radio.log_prefix", property, "");
+    std::string file_prefix = std::string(property);
+    if(file_prefix.empty()) {
+        MYLOGD("No modem log : file_prefix is empty\n");
+        return;
+    }
+
+    MYLOGD("dump_modem_logs: directory is %s and file_prefix is %s\n",
+           bugreport_dir.c_str(), file_prefix.c_str());
+
+    std::string modem_log_file =
+        get_last_modified_file_matching_prefix(bugreport_dir, file_prefix);
+
+    struct stat s;
+    if (modem_log_file.empty() || stat(modem_log_file.c_str(), &s) != 0) {
+        MYLOGD("Modem log %s does not exist\n", modem_log_file.c_str());
+        return;
+    }
+
+    std::string filename = basename(modem_log_file.c_str());
+    if (!add_zip_entry(filename, modem_log_file)) {
+        MYLOGE("Unable to add modem log %s to zip file\n", modem_log_file.c_str());
+    } else {
+        MYLOGD("Modem Log %s is added to zip\n", modem_log_file.c_str());
+    }
+}
+
 static bool skip_not_stat(const char *path) {
     static const char stat[] = "/stat";
     size_t len = strlen(path);
@@ -1039,6 +1111,10 @@
 
     run_command("APP PROVIDERS", 30, "dumpsys", "-t", "30", "activity", "provider", "all", NULL);
 
+    // dump_modem_logs adds the modem logs if available to the bugreport.
+    // Do this at the end to allow for sufficient time for the modem logs to be
+    // collected.
+    dump_modem_logs();
 
     printf("========================================================\n");
     printf("== Final progress (pid %d): %d/%d (originally %d)\n",
@@ -1071,31 +1147,11 @@
           VERSION_DEFAULT.c_str());
 }
 
-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();
+static void sigpipe_handler(int n) {
+    // don't complain to stderr or stdout
     _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.
  */
@@ -1164,6 +1220,7 @@
 }
 
 int main(int argc, char *argv[]) {
+    struct sigaction sigact;
     int do_add_date = 0;
     int do_zip_file = 0;
     int do_vibrate = 1;
@@ -1180,14 +1237,6 @@
 
     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");
@@ -1196,6 +1245,11 @@
     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);
 
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 0d9cce2..285c01e 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -828,8 +828,7 @@
     }
 
     gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW,
-            AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC, AID_WAKELOCK,
-            AID_BLUETOOTH };
+            AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC, AID_BLUETOOTH };
     if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
         MYLOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
         return false;
@@ -850,10 +849,8 @@
     capheader.version = _LINUX_CAPABILITY_VERSION_3;
     capheader.pid = 0;
 
-    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[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
+    capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
     capdata[0].inheritable = 0;
     capdata[1].inheritable = 0;
 
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 1d291ca..f4c2448 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -104,7 +104,7 @@
  * 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) {
+static int restorecon_app_data_lazy(const std::string& path, const char* seinfo, uid_t uid) {
     int res = 0;
     char* before = nullptr;
     char* after = nullptr;
@@ -112,15 +112,15 @@
     // Note that SELINUX_ANDROID_RESTORECON_DATADATA flag is set by
     // libselinux. Not needed here.
 
-    if (lgetfilecon(path, &before) < 0) {
+    if (lgetfilecon(path.c_str(), &before) < 0) {
         PLOG(ERROR) << "Failed before getfilecon for " << path;
         goto fail;
     }
-    if (selinux_android_restorecon_pkgdir(path, seinfo, uid, 0) < 0) {
+    if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, 0) < 0) {
         PLOG(ERROR) << "Failed top-level restorecon for " << path;
         goto fail;
     }
-    if (lgetfilecon(path, &after) < 0) {
+    if (lgetfilecon(path.c_str(), &after) < 0) {
         PLOG(ERROR) << "Failed after getfilecon for " << path;
         goto fail;
     }
@@ -130,7 +130,7 @@
     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,
+        if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid,
                 SELINUX_ANDROID_RESTORECON_RECURSE) < 0) {
             PLOG(ERROR) << "Failed recursive restorecon for " << path;
             goto fail;
@@ -146,6 +146,11 @@
     return res;
 }
 
+static int restorecon_app_data_lazy(const std::string& parent, const char* name, const char* seinfo,
+        uid_t uid) {
+    return restorecon_app_data_lazy(StringPrintf("%s/%s", parent.c_str(), name), seinfo, uid);
+}
+
 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;
@@ -172,7 +177,9 @@
         }
 
         // Consider restorecon over contents if label changed
-        if (restorecon_app_data_lazy(path.c_str(), seinfo, uid)) {
+        if (restorecon_app_data_lazy(path, seinfo, uid) ||
+                restorecon_app_data_lazy(path, "cache", seinfo, uid) ||
+                restorecon_app_data_lazy(path, "code_cache", seinfo, uid)) {
             return -1;
         }
 
@@ -191,7 +198,7 @@
         }
 
         // Consider restorecon over contents if label changed
-        if (restorecon_app_data_lazy(path.c_str(), seinfo, uid)) {
+        if (restorecon_app_data_lazy(path, seinfo, uid)) {
             return -1;
         }
 
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index 9cb4d6d..f9464e8 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -50,8 +50,8 @@
     <!-- Feature to specify if the device support managed users. -->
     <feature name="android.software.managed_users" />
 
-    <!-- Feature to specify if the device supports a VR mode. -->
-    <feature name="android.software.vr.mode" />
+    <!-- Feature to specify if the device supports a VR mode.
+         feature name="android.software.vr.mode" -->
     <!-- Devices with all optimizations required to be a "VR Ready" device that
          pass all CTS tests for this feature must include feature
          android.hardware.vr.high_performance -->
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index aa0db45..10e999c 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -1228,14 +1228,19 @@
         EGL_NONE,
     };
     if (!crop.isValid()) {
-        // No crop rect to set, so terminate the attrib array before the crop.
-        attrs[2] = EGL_NONE;
+        // No crop rect to set, so leave the crop out of the attrib array. Make
+        // sure to propagate the protected content attrs if they are set.
+        attrs[2] = attrs[10];
+        attrs[3] = attrs[11];
+        attrs[4] = EGL_NONE;
     } else if (!isEglImageCroppable(crop)) {
         // The crop rect is not at the origin, so we can't set the crop on the
         // EGLImage because that's not allowed by the EGL_ANDROID_image_crop
         // extension.  In the future we can add a layered extension that
         // removes this restriction if there is hardware that can support it.
-        attrs[2] = EGL_NONE;
+        attrs[2] = attrs[10];
+        attrs[3] = attrs[11];
+        attrs[4] = EGL_NONE;
     }
     eglInitialize(dpy, 0, 0);
     EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d13b6db..1b90678 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1362,6 +1362,7 @@
 
         // Wake us up to check if the frame has been received
         setTransactionFlags(eTransactionNeeded);
+        mFlinger->setTransactionFlags(eTraversalNeeded);
     }
     mPendingStates.push_back(mCurrentState);
 }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c84739a..30ebfd5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1781,12 +1781,9 @@
 
 void SurfaceFlinger::commitTransaction()
 {
-    sp<const DisplayDevice> hw = getDefaultDisplayDevice();
-
-    if (!mLayersPendingRemoval.isEmpty() && hw->isDisplayOn()) {
+    if (!mLayersPendingRemoval.isEmpty()) {
         // Notify removed layers now that they can't be drawn from
         for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
-            mCurrentState.layersSortedByZ.remove(mLayersPendingRemoval[i]);
             recordBufferingStats(mLayersPendingRemoval[i]->getName().string(),
                     mLayersPendingRemoval[i]->getOccupancyHistory(true));
             mLayersPendingRemoval[i]->onRemoved();
@@ -2233,10 +2230,14 @@
         return NO_ERROR;
     }
 
-    mLayersPendingRemoval.push(layer);
-    mLayersRemoved = true;
-    setTransactionFlags(eTransactionNeeded);
-    return NO_ERROR;
+    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
+    if (index >= 0) {
+        mLayersPendingRemoval.push(layer);
+        mLayersRemoved = true;
+        setTransactionFlags(eTransactionNeeded);
+        return NO_ERROR;
+    }
+    return status_t(index);
 }
 
 uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {