Merge "Remove unused MediaDrm.unprovisionDevice"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index b4485c0..4bafc37 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -52,8 +52,6 @@
 static char cmdline_buf[16384] = "(unknown)";
 static const char *dump_traces_path = NULL;
 
-static std::string screenshot_path;
-
 #define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
 
 #define RAFT_DIR "/data/misc/raft/"
@@ -272,7 +270,7 @@
 /* End copy from system/core/logd/LogBuffer.cpp */
 
 /* dumps the current system state to stdout */
-static void dumpstate() {
+static void dumpstate(std::string screenshot_path) {
     unsigned long timeout;
     time_t now = time(NULL);
     char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
@@ -333,9 +331,8 @@
     for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
 
     if (!screenshot_path.empty()) {
-        ALOGI("taking screenshot\n");
-        const char *args[] = { "/system/bin/screencap", "-p", screenshot_path.c_str(), NULL };
-        run_command_always(NULL, 10, args);
+        ALOGI("taking late screenshot\n");
+        take_screenshot(screenshot_path);
         ALOGI("wrote screenshot: %s\n", screenshot_path.c_str());
     }
 
@@ -688,6 +685,7 @@
     int use_socket = 0;
     int do_fb = 0;
     int do_broadcast = 0;
+    int do_early_screenshot = 0;
 
     if (getuid() != 0) {
         // Old versions of the adb client would call the
@@ -743,6 +741,8 @@
         exit(1);
     }
 
+    do_early_screenshot = do_update_progress;
+
     // If we are going to use a socket, do it as early as possible
     // to avoid timeouts from bugreport.
     if (use_socket) {
@@ -755,6 +755,9 @@
     /* full path of the temporary file containing the bug report */
     std::string tmp_path;
 
+    /* full path of the temporary file containing the screenshot (when requested) */
+    std::string screenshot_path;
+
     /* base name (without suffix or extensions) of the bug report files */
     std::string base_name;
 
@@ -812,6 +815,16 @@
         }
     }
 
+    if (!screenshot_path.empty() && do_early_screenshot) {
+        ALOGI("taking early screenshot\n");
+        take_screenshot(screenshot_path);
+        ALOGI("wrote screenshot: %s\n", screenshot_path.c_str());
+        if (chown(screenshot_path.c_str(), AID_SHELL, AID_SHELL)) {
+            ALOGE("Unable to change ownership of screenshot file %s: %s\n",
+                    screenshot_path.c_str(), strerror(errno));
+        }
+    }
+
     /* read /proc/cmdline before dropping root */
     FILE *cmdline = fopen("/proc/cmdline", "re");
     if (cmdline) {
@@ -871,7 +884,7 @@
         redirect_to_file(stdout, const_cast<char*>(tmp_path.c_str()));
     }
 
-    dumpstate();
+    dumpstate(do_early_screenshot ? NULL : screenshot_path);
 
     /* done */
     if (vibrator) {
@@ -960,6 +973,7 @@
         }
     }
 
+    ALOGD("Final progress: %d/%d (originally %d)\n", progress, weight_total, WEIGHT_TOTAL);
     ALOGI("done\n");
 
     return 0;
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index c7e7f52..26e16d0 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -69,7 +69,7 @@
  * It would be better to take advantage of the C++ migration and encapsulate the state in an object,
  * but that will be better handled in a major C++ refactoring, which would also get rid of other C
  * idioms (like using std::string instead of char*, removing varargs, etc...) */
-extern int do_update_progress;
+extern int do_update_progress, progress, weight_total;
 
 /* prints the contents of a file */
 int dump_file(const char *title, const char *path);
@@ -139,6 +139,9 @@
 /* Implemented by libdumpstate_board to dump board-specific info */
 void dumpstate_board();
 
+/* Takes a screenshot and save it to the given file */
+void take_screenshot(std::string path);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index a7637d8..5115e66 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -879,3 +879,8 @@
                 key, value, status);
     }
 }
+
+void take_screenshot(std::string path) {
+    const char *args[] = { "/system/bin/screencap", "-p", path.c_str(), NULL };
+    run_command_always(NULL, 10, args);
+}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 093ca12..1e33847 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2241,7 +2241,7 @@
         if (what & layer_state_t::eLayerChanged) {
             // NOTE: index needs to be calculated before we update the state
             ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
-            if (layer->setLayer(s.z)) {
+            if (layer->setLayer(s.z) && idx >= 0) {
                 mCurrentState.layersSortedByZ.removeAt(idx);
                 mCurrentState.layersSortedByZ.add(layer);
                 // we need traversal (state changed)
@@ -2277,7 +2277,7 @@
         if (what & layer_state_t::eLayerStackChanged) {
             // NOTE: index needs to be calculated before we update the state
             ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
-            if (layer->setLayerStack(s.layerStack)) {
+            if (layer->setLayerStack(s.layerStack) && idx >= 0) {
                 mCurrentState.layersSortedByZ.removeAt(idx);
                 mCurrentState.layersSortedByZ.add(layer);
                 // we need traversal (state changed)