Merge "SF: avoid updating queue if schedule() is called." into rvc-dev
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 9ba4819..d4c1616 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -305,8 +305,9 @@
 
 /*
  * Returns a vector of dump fds under |dir_path| with a given |file_prefix|.
- * The returned vector is sorted by the mtimes of the dumps. If |limit_by_mtime|
- * is set, the vector only contains files that were written in the last 30 minutes.
+ * The returned vector is sorted by the mtimes of the dumps with descending
+ * order. If |limit_by_mtime| is set, the vector only contains files that
+ * were written in the last 30 minutes.
  */
 static std::vector<DumpData> GetDumpFds(const std::string& dir_path,
                                         const std::string& file_prefix,
@@ -353,6 +354,10 @@
 
         dump_data.emplace_back(DumpData{abs_path, std::move(fd), st.st_mtime});
     }
+    if (!dump_data.empty()) {
+        std::sort(dump_data.begin(), dump_data.end(),
+            [](const auto& a, const auto& b) { return a.mtime > b.mtime; });
+    }
 
     return dump_data;
 }
@@ -1362,6 +1367,53 @@
     printf("\n");
 }
 
+static void DumpstateArcOnly() {
+    // Trimmed-down version of dumpstate to only include a whitelisted
+    // set of logs (system log, event log, and system server / system app
+    // crashes, and ARC networking logs). See b/136273873 and b/138459828
+    // for context. New sections must be first approved by Chrome OS Privacy
+    // and then added to server side cros monitoring PII scrubber before adding
+    // them here. See cl/312126645 for an example.
+    DurationReporter duration_reporter("DUMPSTATE");
+    unsigned long timeout_ms;
+    // calculate timeout
+    timeout_ms = logcat_timeout({"main", "system", "crash"});
+    RunCommand("SYSTEM LOG",
+               {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
+               CommandOptions::WithTimeoutInMs(timeout_ms).Build());
+    timeout_ms = logcat_timeout({"events"});
+    RunCommand(
+        "EVENT LOG",
+        {"logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"},
+        CommandOptions::WithTimeoutInMs(timeout_ms).Build());
+
+    printf("========================================================\n");
+    printf("== Networking Service\n");
+    printf("========================================================\n");
+
+    // ARC networking service implements dumpsys by reusing the 'wifi' service name.
+    // The top-level handler is implemented in handleDump() in
+    // vendor/google_arc/libs/arc-services/src/com/android/server/arc/net/ArcNetworkService.java.
+    // It outputs a subset of Android system server state relevant for debugging ARC
+    // connectivity issues, in a PII-free manner. See b/147270970.
+    RunDumpsys("DUMPSYS NETWORK_SERVICE_LIMITED", {"wifi", "-a"},
+               CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
+
+    printf("========================================================\n");
+    printf("== Dropbox crashes\n");
+    printf("========================================================\n");
+
+    RunDumpsys("DROPBOX SYSTEM SERVER CRASHES", {"dropbox", "-p", "system_server_crash"});
+    RunDumpsys("DROPBOX SYSTEM APP CRASHES", {"dropbox", "-p", "system_app_crash"});
+
+    printf("========================================================\n");
+    printf("== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_, ds.progress_->Get(),
+           ds.progress_->GetMax(), ds.progress_->GetInitialMax());
+    printf("========================================================\n");
+    printf("== dumpstate: done (id %d)\n", ds.id_);
+    printf("========================================================\n");
+}
+
 // Dumps various things. Returns early with status USER_CONSENT_DENIED if user denies consent
 // via the consent they are shown. Ignores other errors that occur while running various
 // commands. The consent checking is currently done around long running tasks, which happen to
@@ -2048,7 +2100,7 @@
 static void ShowUsage() {
     fprintf(stderr,
             "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-d] [-p] "
-            "[-z] [-s] [-S] [-q] [-P] [-R] [-V version]\n"
+            "[-z] [-s] [-S] [-q] [-P] [-R] [-A] [-V version]\n"
             "  -h: display this help message\n"
             "  -b: play sound file instead of vibrate, at beginning of job\n"
             "  -e: play sound file instead of vibrate, at end of job\n"
@@ -2061,6 +2113,7 @@
             "  -P: send broadcast when started and do progress updates\n"
             "  -R: take bugreport in remote mode (requires -z and -d, shouldn't be used with -P)\n"
             "  -w: start binder service and make it wait for a call to startBugreport\n"
+            "  -A: output limited information that is safe for submission in ARC++ bugreports\n"
             "  -v: prints the dumpstate header and exit\n");
 }
 
@@ -2306,13 +2359,12 @@
         "do_zip_file: %d do_vibrate: %d use_socket: %d use_control_socket: %d do_screenshot: %d "
         "is_remote_mode: %d show_header_only: %d do_start_service: %d telephony_only: %d "
         "wifi_only: %d do_progress_updates: %d fd: %d bugreport_mode: %s dumpstate_hal_mode: %s "
-        "args: %s\n",
+        "arc_only: %d args: %s\n",
         options.do_zip_file, options.do_vibrate, options.use_socket, options.use_control_socket,
         options.do_screenshot, options.is_remote_mode, options.show_header_only,
-        options.do_start_service,
-        options.telephony_only, options.wifi_only, options.do_progress_updates,
-        options.bugreport_fd.get(), options.bugreport_mode.c_str(),
-        toString(options.dumpstate_hal_mode).c_str(), options.args.c_str());
+        options.do_start_service, options.telephony_only, options.wifi_only,
+        options.do_progress_updates, options.bugreport_fd.get(), options.bugreport_mode.c_str(),
+        toString(options.dumpstate_hal_mode).c_str(), options.arc_only, options.args.c_str());
 }
 
 void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode,
@@ -2334,7 +2386,7 @@
 Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[]) {
     RunStatus status = RunStatus::OK;
     int c;
-    while ((c = getopt(argc, argv, "dho:svqzpPBRSV:w")) != -1) {
+    while ((c = getopt(argc, argv, "dho:svqzpAPBRSV:w")) != -1) {
         switch (c) {
             // clang-format off
             case 'd': do_add_date = true;            break;
@@ -2346,6 +2398,7 @@
             case 'p': do_screenshot = true;          break;
             case 'P': do_progress_updates = true;    break;
             case 'R': is_remote_mode = true;         break;
+            case 'A': arc_only = true;               break;
             case 'V':                                break;  // compatibility no-op
             case 'w':
                 // This was already processed
@@ -2630,6 +2683,7 @@
     // duration is logged into MYLOG instead.
     PrintHeader();
 
+    // TODO(nandana) reduce code repetition in if branches
     if (options_->telephony_only) {
         MaybeTakeEarlyScreenshot();
         onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
@@ -2641,6 +2695,11 @@
         onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
         MaybeCheckUserConsent(calling_uid, calling_package);
         DumpstateWifiOnly();
+    } else if (options_->arc_only) {
+        MaybeTakeEarlyScreenshot();
+        onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
+        MaybeCheckUserConsent(calling_uid, calling_package);
+        DumpstateArcOnly();
     } else {
         // Invoke critical dumpsys first to preserve system state, before doing anything else.
         RunDumpsysCritical();
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 28d8936..c8c9f45 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -377,6 +377,8 @@
         bool do_start_service = false;
         bool telephony_only = false;
         bool wifi_only = false;
+        // Trimmed-down version of dumpstate to only include whitelisted logs.
+        bool arc_only = false;
         // Whether progress updates should be published.
         bool do_progress_updates = false;
         // The mode we'll use when calling IDumpstateDevice::dumpstateBoard.
diff --git a/cmds/dumpstate/main.cpp b/cmds/dumpstate/main.cpp
index 68d3733..f1342a5 100644
--- a/cmds/dumpstate/main.cpp
+++ b/cmds/dumpstate/main.cpp
@@ -30,7 +30,7 @@
     bool do_wait = false;
     int c;
     // Keep flags in sync with Dumpstate::DumpOptions::Initialize.
-    while ((c = getopt(argc, argv, "wdho:svqzpPBRSV:")) != -1 && !do_wait) {
+    while ((c = getopt(argc, argv, "dho:svqzpAPBRSV:w")) != -1 && !do_wait) {
         switch (c) {
             case 'w':
                 do_wait = true;
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 9871a3b..7078521 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -179,6 +179,7 @@
     EXPECT_FALSE(options_.do_screenshot);
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.arc_only);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
 
@@ -206,6 +207,7 @@
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
     EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.arc_only);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
 
@@ -231,6 +233,7 @@
     EXPECT_FALSE(options_.do_screenshot);
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.arc_only);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
 
@@ -249,6 +252,7 @@
     EXPECT_FALSE(options_.is_remote_mode);
     EXPECT_FALSE(options_.use_socket);
     EXPECT_FALSE(options_.do_start_service);
+    EXPECT_FALSE(options_.arc_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
@@ -266,6 +270,7 @@
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.is_remote_mode);
     EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.arc_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
@@ -282,6 +287,7 @@
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.arc_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeWearBugReport) {
@@ -299,6 +305,7 @@
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.is_remote_mode);
     EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.arc_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
@@ -316,6 +323,7 @@
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.is_remote_mode);
     EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.arc_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
@@ -333,6 +341,37 @@
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
     EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.arc_only);
+}
+
+TEST_F(DumpOptionsTest, InitializeArcOnlyBugreport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("dumpstatez"),
+        const_cast<char*>("-S"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-q"),
+        const_cast<char*>("-A")
+    };
+    // clang-format on
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_zip_file);
+    EXPECT_TRUE(options_.use_control_socket);
+    EXPECT_FALSE(options_.do_vibrate);
+    EXPECT_TRUE(options_.arc_only);
+
+    // Other options retain default values
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.do_screenshot);
+    EXPECT_FALSE(options_.do_progress_updates);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.use_socket);
+    EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
 
 TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
@@ -361,6 +400,7 @@
     EXPECT_FALSE(options_.is_remote_mode);
     EXPECT_FALSE(options_.use_socket);
     EXPECT_FALSE(options_.wifi_only);
+    EXPECT_FALSE(options_.arc_only);
 }
 
 TEST_F(DumpOptionsTest, InitializePartial1) {
@@ -390,6 +430,7 @@
     EXPECT_FALSE(options_.do_screenshot);
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.arc_only);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
 
@@ -419,6 +460,7 @@
     EXPECT_FALSE(options_.do_zip_file);
     EXPECT_FALSE(options_.use_socket);
     EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.arc_only);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
 
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 7d1c1ad..b9c1add 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -1074,6 +1074,7 @@
             res = error(rc, "Failed copying " + from_ce + " to " + to_ce);
             return res;
         }
+        delete_dir_contents_and_dir(from_ce, true /* ignore_if_missing */);
     }
 
     if (needs_de_rollback) {
@@ -1090,6 +1091,7 @@
             res = error(rc, "Failed copying " + from_de + " to " + to_de);
             return res;
         }
+        delete_dir_contents_and_dir(from_de, true /* ignore_if_missing */);
     }
 
     // Finally, restore the SELinux label on the app data.
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 9655277..dcc213f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2122,7 +2122,9 @@
             // but a transform matrix can define horizontal and vertical scales.
             // Let's take the average between both of them and pass into the shader, practically we
             // never do this type of transformation on windows anyway.
-            parentState.radius *= (t[0][0] + t[1][1]) / 2.0f;
+            auto scaleX = sqrtf(t[0][0] * t[0][0] + t[0][1] * t[0][1]);
+            auto scaleY = sqrtf(t[1][0] * t[1][0] + t[1][1] * t[1][1]);
+            parentState.radius *= (scaleX + scaleY) / 2.0f;
             return parentState;
         }
     }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2e22735..68dec66 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2675,7 +2675,8 @@
         }
         processDisplayAdded(displayToken, currentState);
         if (currentState.physical) {
-            initializeDisplays();
+            const auto display = getDisplayDeviceLocked(displayToken);
+            setPowerModeInternal(display, hal::PowerMode::ON);
         }
         return;
     }
diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
index d666d7e..7d4314f 100644
--- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
@@ -220,6 +220,51 @@
         shot->expectColor(Rect(size - testArea, 0, right, testArea), Color::BLACK);
         shot->expectColor(Rect(0, bottom - testArea, testArea, bottom), Color::BLACK);
         shot->expectColor(Rect(size - testArea, bottom - testArea, right, bottom), Color::BLACK);
+        // Solid center
+        shot->expectColor(Rect(size / 2 - testArea / 2, size / 2 - testArea / 2,
+                               size / 2 + testArea / 2, size / 2 + testArea / 2),
+                          Color::RED);
+    }
+}
+
+TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusRotated) {
+    sp<SurfaceControl> parent;
+    sp<SurfaceControl> child;
+    const uint8_t size = 64;
+    const uint8_t testArea = 4;
+    const float cornerRadius = 20.0f;
+    ASSERT_NO_FATAL_FAILURE(parent = createLayer("parent", size, size));
+    ASSERT_NO_FATAL_FAILURE(fillLayerColor(parent, Color::RED, size, size));
+    ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size));
+    ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size));
+
+    auto transaction = Transaction()
+                               .setCornerRadius(parent, cornerRadius)
+                               .setCrop_legacy(parent, Rect(0, 0, size, size))
+                               .reparent(child, parent->getHandle())
+                               .setPosition(child, 0, size)
+                               // Rotate by half PI
+                               .setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f);
+    if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) {
+        transaction.setCrop_legacy(parent, Rect(0, 0, size, size));
+    } else {
+        transaction.setFrame(parent, Rect(0, 0, size, size));
+    }
+    transaction.apply();
+
+    {
+        const uint8_t bottom = size - 1;
+        const uint8_t right = size - 1;
+        auto shot = getScreenCapture();
+        // Edges are transparent
+        shot->expectColor(Rect(0, 0, testArea, testArea), Color::BLACK);
+        shot->expectColor(Rect(size - testArea, 0, right, testArea), Color::BLACK);
+        shot->expectColor(Rect(0, bottom - testArea, testArea, bottom - testArea), Color::BLACK);
+        shot->expectColor(Rect(right - testArea, bottom - testArea, right, bottom), Color::BLACK);
+        // Solid center
+        shot->expectColor(Rect(size / 2 - testArea / 2, size / 2 - testArea / 2,
+                               size / 2 + testArea / 2, size / 2 + testArea / 2),
+                          Color::GREEN);
     }
 }