Merge "libui: Remove FramebufferNativeWindow"
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index 4ab8d3d..8515a01 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -16,7 +16,7 @@
 
 LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux
 # ZipArchive support, the order matters here to get all symbols.
-LOCAL_STATIC_LIBRARIES := libziparchive libz libbase
+LOCAL_STATIC_LIBRARIES := libziparchive libz libbase libmincrypt
 LOCAL_HAL_STATIC_LIBRARIES := libdumpstate
 LOCAL_CFLAGS += -Wall -Wno-unused-parameter -std=gnu99
 LOCAL_INIT_RC := dumpstate.rc
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 8dcca34..258a99f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -47,6 +47,8 @@
 #include "ScopedFd.h"
 #include "ziparchive/zip_writer.h"
 
+#include "mincrypt/sha256.h"
+
 using android::base::StringPrintf;
 
 /* read before root is shed */
@@ -437,6 +439,11 @@
     run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL);
     run_command("LIBRANK", 10, SU_PATH, "root", "librank", NULL);
 
+    run_command("ROUTE", 10, "route", NULL);
+    run_command("PRINTENV", 10, "printenv", NULL);
+    run_command("NETSTAT", 10, "netstat", NULL);
+    run_command("LSMOD", 10, "lsmod", NULL);
+
     do_dmesg();
 
     run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
@@ -725,6 +732,7 @@
             "  -q: disable vibrate\n"
             "  -B: send broadcast when finished (requires -o)\n"
             "  -P: send broadacast when started and update system properties on progress (requires -o and -B)\n"
+            "  -R: take bugreport in remote mode (requires -o, -z, -d and -B, shouldn't be used with -P)\n"
                 );
 }
 
@@ -756,6 +764,41 @@
     return true;
 }
 
+static std::string SHA256_file_hash(std::string filepath) {
+    ScopedFd fd(TEMP_FAILURE_RETRY(open(filepath.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC
+            | O_NOFOLLOW)));
+    if (fd.get() == -1) {
+        ALOGE("open(%s): %s\n", filepath.c_str(), strerror(errno));
+        return NULL;
+    }
+
+    SHA256_CTX ctx;
+    SHA256_init(&ctx);
+
+    std::vector<uint8_t> buffer(65536);
+    while (1) {
+        ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd.get(), buffer.data(), buffer.size()));
+        if (bytes_read == 0) {
+            break;
+        } else if (bytes_read == -1) {
+            ALOGE("read(%s): %s\n", filepath.c_str(), strerror(errno));
+            return NULL;
+        }
+
+        SHA256_update(&ctx, buffer.data(), bytes_read);
+    }
+
+    uint8_t hash[SHA256_DIGEST_SIZE];
+    memcpy(hash, SHA256_final(&ctx), SHA256_DIGEST_SIZE);
+    char hash_buffer[SHA256_DIGEST_SIZE * 2 + 1];
+    for(size_t i = 0; i < SHA256_DIGEST_SIZE; i++) {
+        sprintf(hash_buffer + (i * 2), "%02x", hash[i]);
+    }
+    hash_buffer[sizeof(hash_buffer) - 1] = 0;
+    return std::string(hash_buffer);
+}
+
+
 int main(int argc, char *argv[]) {
     struct sigaction sigact;
     int do_add_date = 0;
@@ -766,6 +809,7 @@
     int do_fb = 0;
     int do_broadcast = 0;
     int do_early_screenshot = 0;
+    int is_remote_mode = 0;
 
     now = time(NULL);
 
@@ -795,7 +839,7 @@
 
     /* parse arguments */
     int c;
-    while ((c = getopt(argc, argv, "dho:svqzpPB")) != -1) {
+    while ((c = getopt(argc, argv, "dho:svqzpPBR")) != -1) {
         switch (c) {
             case 'd': do_add_date = 1;          break;
             case 'z': do_zip_file = 1;          break;
@@ -805,6 +849,7 @@
             case 'q': do_vibrate = 0;           break;
             case 'p': do_fb = 1;                break;
             case 'P': do_update_progress = 1;   break;
+            case 'R': is_remote_mode = 1;       break;
             case 'B': do_broadcast = 1;         break;
             case '?': printf("\n");
             case 'h':
@@ -823,6 +868,11 @@
         exit(1);
     }
 
+    if (is_remote_mode && (do_update_progress || !do_broadcast || !do_zip_file || !do_add_date)) {
+        usage();
+        exit(1);
+    }
+
     do_early_screenshot = do_update_progress;
 
     // If we are going to use a socket, do it as early as possible
@@ -1076,7 +1126,14 @@
                 am_args.push_back("android.intent.extra.SCREENSHOT");
                 am_args.push_back(screenshot_path);
             }
-            send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args);
+            if (is_remote_mode) {
+                am_args.push_back("--es");
+                am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH");
+                am_args.push_back(SHA256_file_hash(path));
+                send_broadcast("android.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
+            } else {
+                send_broadcast("android.intent.action.BUGREPORT_FINISHED", am_args);
+            }
         } else {
             ALOGE("Skipping finished broadcast because bugreport could not be generated\n");
         }
diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc
index 72fdcfa..d1b7f8c 100644
--- a/cmds/dumpstate/dumpstate.rc
+++ b/cmds/dumpstate/dumpstate.rc
@@ -17,3 +17,15 @@
     class main
     disabled
     oneshot
+
+# bugreportremote is an altered version of bugreport that is supposed to be
+# called not by human user of the device, but by DevicePolicyManagerService only when the
+# Device Owner explicitly requests it, and shared with the Device Policy Controller (DPC) app only
+# if the user consents
+# it will disable vibrations, screenshot taking and will not track progress or
+# allow user to enter any details
+service bugreportremote /system/bin/dumpstate -d -q -B -R -z \
+        -o /data/data/com.android.shell/files/bugreports/remote/bugreport
+    class main
+    disabled
+    oneshot
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index 6310502..a8513a9 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -39,13 +39,8 @@
 
     inline Rect() : Rect(INVALID_RECT) {}
 
-    inline Rect(int32_t w, int32_t h) {
-        left = top = 0;
-        right = w;
-        bottom = h;
-    }
-
-    inline Rect(uint32_t w, uint32_t h) {
+    template <typename T>
+    inline Rect(T w, T h) {
         if (w > INT32_MAX) {
             ALOG(LOG_WARN, "Rect",
                     "Width %u too large for Rect class, clamping", w);
@@ -57,8 +52,8 @@
             h = INT32_MAX;
         }
         left = top = 0;
-        right = w;
-        bottom = h;
+        right = static_cast<int32_t>(w);
+        bottom = static_cast<int32_t>(h);
     }
 
     inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) {