Merge "Add binder TEST_MAPPING files."
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 032d072..f1426b6 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -47,6 +47,8 @@
     chmod 0666 /sys/kernel/tracing/events/power/clock_set_rate/enable
     chmod 0666 /sys/kernel/debug/tracing/events/power/cpu_frequency_limits/enable
     chmod 0666 /sys/kernel/tracing/events/power/cpu_frequency_limits/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/power/gpu_frequency/enable
+    chmod 0666 /sys/kernel/tracing/events/power/gpu_frequency/enable
     chmod 0666 /sys/kernel/debug/tracing/events/cpufreq_interactive/enable
     chmod 0666 /sys/kernel/tracing/events/cpufreq_interactive/enable
     chmod 0666 /sys/kernel/debug/tracing/events/vmscan/mm_vmscan_direct_reclaim_begin/enable
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index ee32cb4..4020480 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -123,7 +123,6 @@
         "lsmod",
         "lsof",
         "netstat",
-        "parse_radio_log",
         "printenv",
         "procrank",
         "screencap",
@@ -146,6 +145,8 @@
         "tests/dumpstate_test.cpp",
     ],
     static_libs: ["libgmock"],
+    test_config: "dumpstate_test.xml",
+    data: [":dumpstate_test_fixture", "tests/testdata/**/*"]
 }
 
 cc_test {
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 6e99f1d..1fc8107 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1285,8 +1285,6 @@
 
     RunCommand("FILESYSTEMS & FREE SPACE", {"df"});
 
-    RunCommand("LAST RADIO LOG", {"parse_radio_log", "/proc/last_radio_log"});
-
     /* Binder state is expensive to look at as it uses a lot of memory. */
     DumpFile("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
     DumpFile("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
@@ -2257,7 +2255,6 @@
         }
     }
 
-    // TODO: use helper function to convert argv into a string
     for (int i = 0; i < argc; i++) {
         args += argv[i];
         if (i < argc - 1) {
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index d02ec75..ae6a721 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -441,8 +441,7 @@
     // Full path of the bugreport file, be it zip or text, inside bugreport_internal_dir_.
     std::string path_;
 
-    // TODO: If temporary this should be removed at the end.
-    // Full path of the temporary file containing the screenshot (when requested).
+    // Full path of the file containing the screenshot (when requested).
     std::string screenshot_path_;
 
     // Pointer to the zipped file.
diff --git a/cmds/dumpstate/dumpstate_test.xml b/cmds/dumpstate/dumpstate_test.xml
new file mode 100644
index 0000000..e4e4a30
--- /dev/null
+++ b/cmds/dumpstate/dumpstate_test.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for dumpstate_test">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="dumpstate_test->/data/local/tmp/dumpstate_test" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+    <option name="test-suite-tag" value="apct" />
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="file-exclusion-filter-regex" value=".*/dumpstate_test_fixture" />
+        <option name="file-exclusion-filter-regex" value=".*/tests/.*" />
+        <option name="module-name" value="dumpstate_test" />
+    </test>
+</configuration>
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index c5d01fd..0e88e43 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -105,9 +105,8 @@
 
   protected:
     const std::string kTestPath = dirname(android::base::GetExecutablePath().c_str());
-    const std::string kFixturesPath = kTestPath + "/../dumpstate_test_fixture/";
-    const std::string kTestDataPath = kFixturesPath + "tests/testdata/";
-    const std::string kSimpleCommand = kFixturesPath + "dumpstate_test_fixture";
+    const std::string kTestDataPath = kTestPath + "/tests/testdata/";
+    const std::string kSimpleCommand = kTestPath + "/dumpstate_test_fixture";
     const std::string kEchoCommand = "/system/bin/echo";
 
     /*
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 0bb80dc..4cbf577 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -733,6 +733,11 @@
     struct sockaddr addr;
     socklen_t alen = sizeof(addr);
     int fd = accept(s, &addr, &alen);
+
+    // Close socket just after accept(), to make sure that connect() by client will get error
+    // when the socket is used by the other services.
+    close(s);
+
     if (fd < 0) {
         MYLOGE("accept(control socket): %s\n", strerror(errno));
         return -1;
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 3ecfc95..1016832 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -133,6 +133,7 @@
 
 cc_binary {
     name: "otapreopt_chroot",
+    defaults: ["libapexd-deps"],
     cflags: [
         "-Wall",
         "-Werror",
@@ -145,22 +146,11 @@
     ],
     shared_libs: [
         "libbase",
-        "libbinder",
-        "libcrypto",
         "liblog",
-        "libprotobuf-cpp-full",
-        "libselinux",
         "libutils",
-        "libziparchive",
     ],
     static_libs: [
-        "libapex",
         "libapexd",
-        "lib_apex_manifest_proto",
-        "libavb",
-        "libdm",
-        "libverity_tree",
-        "libvold_binder",
     ],
 }
 
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index ae4ea78..47fdcc4 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -2055,10 +2055,15 @@
     CHECK_ARGUMENT_PATH(dexMetadataPath);
     std::lock_guard<std::recursive_mutex> lock(mLock);
 
+    const char* oat_dir = getCStr(outputPath);
+    const char* instruction_set = instructionSet.c_str();
+    if (oat_dir != nullptr && !createOatDir(oat_dir, instruction_set).isOk()) {
+        // Can't create oat dir - let dexopt use cache dir.
+        oat_dir = nullptr;
+    }
+
     const char* apk_path = apkPath.c_str();
     const char* pkgname = getCStr(packageName, "*");
-    const char* instruction_set = instructionSet.c_str();
-    const char* oat_dir = getCStr(outputPath);
     const char* compiler_filter = compilerFilter.c_str();
     const char* volume_uuid = getCStr(uuid);
     const char* class_loader_context = getCStr(classLoaderContext);
diff --git a/cmds/installd/OWNERS b/cmds/installd/OWNERS
index 5673918..9a21104 100644
--- a/cmds/installd/OWNERS
+++ b/cmds/installd/OWNERS
@@ -4,7 +4,9 @@
 calin@google.com
 jsharkey@android.com
 maco@google.com
+mast@google.com
 mathieuc@google.com
 narayan@google.com
 ngeoffray@google.com
+rpl@google.com
 toddke@google.com
diff --git a/cmds/installd/art_helper/Android.bp b/cmds/installd/art_helper/Android.bp
deleted file mode 100644
index c47dd72..0000000
--- a/cmds/installd/art_helper/Android.bp
+++ /dev/null
@@ -1,12 +0,0 @@
-// Inherit image values.
-art_global_defaults {
-    name: "libartimagevalues_defaults",
-}
-
-cc_library_static {
-    name: "libartimagevalues",
-    defaults: ["libartimagevalues_defaults"],
-    srcs: ["art_image_values.cpp"],
-    export_include_dirs: ["."],
-    cflags: ["-Wconversion"],
-}
diff --git a/cmds/installd/art_helper/art_image_values.cpp b/cmds/installd/art_helper/art_image_values.cpp
deleted file mode 100644
index a139049..0000000
--- a/cmds/installd/art_helper/art_image_values.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "art_image_values.h"
-
-namespace android {
-namespace installd {
-namespace art {
-
-uint32_t GetImageBaseAddress() {
-    return ART_BASE_ADDRESS;
-}
-int32_t GetImageMinBaseAddressDelta() {
-    return ART_BASE_ADDRESS_MIN_DELTA;
-}
-int32_t GetImageMaxBaseAddressDelta() {
-    return ART_BASE_ADDRESS_MAX_DELTA;
-}
-
-static_assert(ART_BASE_ADDRESS_MIN_DELTA < ART_BASE_ADDRESS_MAX_DELTA, "Inconsistent setup");
-
-}  // namespace art
-}  // namespace installd
-}  // namespace android
diff --git a/cmds/installd/art_helper/art_image_values.h b/cmds/installd/art_helper/art_image_values.h
deleted file mode 100644
index 20c44c9..0000000
--- a/cmds/installd/art_helper/art_image_values.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef FRAMEWORKS_NATIVE_CMDS_INSTALLD_ART_HELPER_ART_IMAGE_VALUES_H
-#define FRAMEWORKS_NATIVE_CMDS_INSTALLD_ART_HELPER_ART_IMAGE_VALUES_H
-
-#include <cstdint>
-
-namespace android {
-namespace installd {
-namespace art {
-
-uint32_t GetImageBaseAddress();
-int32_t GetImageMinBaseAddressDelta();
-int32_t GetImageMaxBaseAddressDelta();
-
-}  // namespace art
-}  // namespace installd
-}  // namespace android
-
-#endif  // FRAMEWORKS_NATIVE_CMDS_INSTALLD_ART_HELPER_ART_IMAGE_VALUES_H
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index de7b249..db36ce3 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -445,9 +445,11 @@
         }
         cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str()));
 
-        int32_t base_offset = ChooseRelocationOffsetDelta(art::GetImageMinBaseAddressDelta(),
-                                                          art::GetImageMaxBaseAddressDelta());
-        cmd.push_back(StringPrintf("--base=0x%x", art::GetImageBaseAddress() + base_offset));
+        int32_t base_offset = ChooseRelocationOffsetDelta(
+                art::imagevalues::GetImageMinBaseAddressDelta(),
+                art::imagevalues::GetImageMaxBaseAddressDelta());
+        cmd.push_back(StringPrintf("--base=0x%x",
+                art::imagevalues::GetImageBaseAddress() + base_offset));
 
         cmd.push_back(StringPrintf("--instruction-set=%s", isa));
 
@@ -464,7 +466,7 @@
                 "--compiler-filter=",
                 false,
                 cmd);
-        cmd.push_back("--image-classes=/system/etc/preloaded-classes");
+        cmd.push_back("--profile-file=/system/etc/boot-image.prof");
         // TODO: Compiled-classes.
         const std::string* extra_opts =
                 system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags");
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index e8f513a..0c4badf 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -72,9 +72,10 @@
 static void DeactivateApexPackages(const std::vector<apex::ApexFile>& active_packages) {
     for (const apex::ApexFile& apex_file : active_packages) {
         const std::string& package_path = apex_file.GetPath();
-        apex::Status status = apex::deactivatePackage(package_path);
-        if (!status.Ok()) {
-            LOG(ERROR) << "Failed to deactivate " << package_path << ": " << status.ErrorMessage();
+        base::Result<void> status = apex::deactivatePackage(package_path);
+        if (!status) {
+            LOG(ERROR) << "Failed to deactivate " << package_path << ": "
+                       << status.error();
         }
     }
 }
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 13fd067..73780ec 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -241,18 +241,14 @@
     }
 
     ::testing::AssertionResult create_mock_app() {
-        // Create the oat dir.
-        app_oat_dir_ = app_apk_dir_ + "/oat";
         // For debug mode, the directory might already exist. Avoid erroring out.
         if (mkdir(app_apk_dir_, kSystemUid, kSystemGid, 0755) != 0 && !kDebug) {
             return ::testing::AssertionFailure() << "Could not create app dir " << app_apk_dir_
                                                  << " : " << strerror(errno);
         }
-        binder::Status status = service_->createOatDir(app_oat_dir_, kRuntimeIsa);
-        if (!status.isOk()) {
-            return ::testing::AssertionFailure() << "Could not create oat dir: "
-                                                 << status.toString8().c_str();
-        }
+
+        // Initialize the oat dir path.
+        app_oat_dir_ = app_apk_dir_ + "/oat";
 
         // Copy the primary apk.
         apk_path_ = app_apk_dir_ + "/base.jar";
@@ -283,7 +279,7 @@
           }
 
         // Create the app user data.
-        status = service_->createAppData(
+        binder::Status status = service_->createAppData(
                 volume_uuid_,
                 package_name_,
                 kTestUserId,
@@ -647,6 +643,16 @@
                         DEX2OAT_FROM_SCRATCH);
 }
 
+TEST_F(DexoptTest, DexoptPrimaryPublicCreateOatDir) {
+    LOG(INFO) << "DexoptPrimaryPublic";
+    ASSERT_BINDER_SUCCESS(service_->createOatDir(app_oat_dir_, kRuntimeIsa));
+    CompilePrimaryDexOk("verify",
+                        DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
+                        app_oat_dir_.c_str(),
+                        kTestAppGid,
+                        DEX2OAT_FROM_SCRATCH);
+}
+
 TEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
     LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
     binder::Status status;
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index f7dd8c8..495cc80 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -72,14 +72,18 @@
 
 cc_test {
     name: "lshal_test",
+    test_suites: ["device-tests"],
     defaults: ["lshal_defaults"],
     gtest: true,
     static_libs: [
-        "libgmock"
+        "android.hardware.tests.baz@1.0",
+        "libgmock",
     ],
     shared_libs: [
+        "libhwbinder",
+        "libhidlbase",
+        "libhidltransport",
         "libvintf",
-        "android.hardware.tests.baz@1.0"
     ],
     srcs: [
         "test.cpp"
diff --git a/cmds/lshal/TEST_MAPPING b/cmds/lshal/TEST_MAPPING
new file mode 100644
index 0000000..0320624
--- /dev/null
+++ b/cmds/lshal/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "lshal_test"
+    }
+  ]
+}
+
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index fc8d58b..76f7c7f 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -493,19 +493,19 @@
 TEST_F(ListTest, DumpDefault) {
     const std::string expected =
         "[fake description 0]\n"
-        "R Interface            Thread Use Server Clients\n"
-        "N a.h.foo1@1.0::IFoo/1 11/21      1      2 4\n"
-        "Y a.h.foo2@2.0::IFoo/2 12/22      2      3 5\n"
+        "VINTF R Interface            Thread Use Server Clients\n"
+        "X     N a.h.foo1@1.0::IFoo/1 11/21      1      2 4\n"
+        "X     Y a.h.foo2@2.0::IFoo/2 12/22      2      3 5\n"
         "\n"
         "[fake description 1]\n"
-        "R Interface            Thread Use Server Clients\n"
-        "? a.h.foo3@3.0::IFoo/3 N/A        N/A    4 6\n"
-        "? a.h.foo4@4.0::IFoo/4 N/A        N/A    5 7\n"
+        "VINTF R Interface            Thread Use Server Clients\n"
+        "X     ? a.h.foo3@3.0::IFoo/3 N/A        N/A    4 6\n"
+        "X     ? a.h.foo4@4.0::IFoo/4 N/A        N/A    5 7\n"
         "\n"
         "[fake description 2]\n"
-        "R Interface            Thread Use Server Clients\n"
-        "? a.h.foo5@5.0::IFoo/5 N/A        N/A    6 8\n"
-        "? a.h.foo6@6.0::IFoo/6 N/A        N/A    7 9\n"
+        "VINTF R Interface            Thread Use Server Clients\n"
+        "X     ? a.h.foo5@5.0::IFoo/5 N/A        N/A    6 8\n"
+        "X     ? a.h.foo6@6.0::IFoo/6 N/A        N/A    7 9\n"
         "\n";
 
     optind = 1; // mimic Lshal::parseArg()
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index ec170f7..67f968a 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -387,21 +387,6 @@
         }
     }
 
-    mLock.lock();
-    Vector<Obituary>* obits = mObituaries;
-    if(obits != nullptr) {
-        if (ipc) ipc->clearDeathNotification(mHandle, this);
-        mObituaries = nullptr;
-    }
-    mLock.unlock();
-
-    if (obits != nullptr) {
-        // XXX Should we tell any remaining DeathRecipient
-        // objects that the last strong ref has gone away, so they
-        // are no longer linked?
-        delete obits;
-    }
-
     if (ipc) {
         ipc->expungeHandle(mHandle, this);
         ipc->decWeakHandle(mHandle);
@@ -423,6 +408,25 @@
     }
     IPCThreadState* ipc = IPCThreadState::self();
     if (ipc) ipc->decStrongHandle(mHandle);
+
+    mLock.lock();
+    Vector<Obituary>* obits = mObituaries;
+    if(obits != nullptr) {
+        if (!obits->isEmpty()) {
+            ALOGI("onLastStrongRef automatically unlinking death recipients");
+        }
+
+        if (ipc) ipc->clearDeathNotification(mHandle, this);
+        mObituaries = nullptr;
+    }
+    mLock.unlock();
+
+    if (obits != nullptr) {
+        // XXX Should we tell any remaining DeathRecipient
+        // objects that the last strong ref has gone away, so they
+        // are no longer linked?
+        delete obits;
+    }
 }
 
 bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 2d156df..b25cd7b 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -466,7 +466,7 @@
         }
     }
 
-    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
+    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened.  Terminating.", driver);
 }
 
 ProcessState::~ProcessState()
diff --git a/libs/binder/aidl/android/content/pm/OWNERS b/libs/binder/aidl/android/content/pm/OWNERS
new file mode 100644
index 0000000..a967a7f
--- /dev/null
+++ b/libs/binder/aidl/android/content/pm/OWNERS
@@ -0,0 +1,4 @@
+narayan@google.com
+patb@google.com
+svetoslavganov@google.com
+toddke@google.com
diff --git a/libs/binder/tests/binderDriverInterfaceTest.cpp b/libs/binder/tests/binderDriverInterfaceTest.cpp
index 77ebac8..6508bb1 100644
--- a/libs/binder/tests/binderDriverInterfaceTest.cpp
+++ b/libs/binder/tests/binderDriverInterfaceTest.cpp
@@ -286,7 +286,13 @@
         EXPECT_EQ(0u, br.arg2.cookie);
         EXPECT_EQ(0u, br.arg2.code);
         EXPECT_EQ(0u, br.arg2.flags);
-        EXPECT_EQ(0u, br.arg2.data_size);
+
+        // ping returns a 4 byte header in libbinder, but the original
+        // C implementation of servicemanager returns a 0 byte header
+        if (br.arg2.data_size != 0 && br.arg2.data_size != 4) {
+            ADD_FAILURE() << br.arg2.data_size << " is expected to be 0 or 4";
+        }
+
         EXPECT_EQ(0u, br.arg2.offsets_size);
 
         SCOPED_TRACE("3rd WriteRead");
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index c96a2dd..9d7f14c 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -989,14 +989,6 @@
         mCallbackCondition.broadcast();
     }
 
-    // Wait without lock held
-    if (connectedApi == NATIVE_WINDOW_API_EGL) {
-        // Waiting here allows for two full buffers to be queued but not a
-        // third. In the event that frames take varying time, this makes a
-        // small trade-off in favor of latency rather than throughput.
-        lastQueuedFence->waitForever("Throttling EGL Production");
-    }
-
     // Update and get FrameEventHistory.
     nsecs_t postedTime = systemTime(SYSTEM_TIME_MONOTONIC);
     NewFrameEventsEntry newFrameEventsEntry = {
@@ -1008,6 +1000,14 @@
     addAndGetFrameTimestamps(&newFrameEventsEntry,
             getFrameTimestamps ? &output->frameTimestamps : nullptr);
 
+    // Wait without lock held
+    if (connectedApi == NATIVE_WINDOW_API_EGL) {
+        // Waiting here allows for two full buffers to be queued but not a
+        // third. In the event that frames take varying time, this makes a
+        // small trade-off in favor of latency rather than throughput.
+        lastQueuedFence->waitForever("Throttling EGL Production");
+    }
+
     return NO_ERROR;
 }
 
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 76d242d..8aaa436 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -103,9 +103,10 @@
     }
 
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+                                   bool& outCapturedSecureLayers,
                                    Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
                                    int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
-                                   ISurfaceComposer::Rotation rotation) {
+                                   ISurfaceComposer::Rotation rotation, bool captureSecureLayers) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -116,6 +117,7 @@
         data.writeInt32(maxLayerZ);
         data.writeInt32(static_cast<int32_t>(useIdentityTransform));
         data.writeInt32(static_cast<int32_t>(rotation));
+        data.writeInt32(static_cast<int32_t>(captureSecureLayers));
         status_t err = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
 
         if (err != NO_ERROR) {
@@ -129,6 +131,8 @@
 
         *outBuffer = new GraphicBuffer();
         reply.read(**outBuffer);
+        outCapturedSecureLayers = reply.readBool();
+
         return err;
     }
 
@@ -644,13 +648,17 @@
             int32_t maxLayerZ = data.readInt32();
             bool useIdentityTransform = static_cast<bool>(data.readInt32());
             int32_t rotation = data.readInt32();
+            bool captureSecureLayers = static_cast<bool>(data.readInt32());
 
-            status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight,
-                                         minLayerZ, maxLayerZ, useIdentityTransform,
-                                         static_cast<ISurfaceComposer::Rotation>(rotation));
+            bool capturedSecureLayers = false;
+            status_t res = captureScreen(display, &outBuffer, capturedSecureLayers, sourceCrop, reqWidth,
+                                         reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
+                                         static_cast<ISurfaceComposer::Rotation>(rotation), captureSecureLayers);
+
             reply->writeInt32(res);
             if (res == NO_ERROR) {
                 reply->write(*outBuffer);
+                reply->writeBool(capturedSecureLayers);
             }
             return NO_ERROR;
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index f3c6fd2..1002576 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -768,18 +768,29 @@
 status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
                                    uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
                                    bool useIdentityTransform, uint32_t rotation,
-                                   sp<GraphicBuffer>* outBuffer) {
+                                   bool captureSecureLayers, sp<GraphicBuffer>* outBuffer,
+                                   bool& outCapturedSecureLayers) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == NULL) return NO_INIT;
-    status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight, minLayerZ,
-                                    maxLayerZ, useIdentityTransform,
-                                    static_cast<ISurfaceComposer::Rotation>(rotation));
+    status_t ret = s->captureScreen(display, outBuffer, outCapturedSecureLayers, sourceCrop,
+                                    reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
+                                    static_cast<ISurfaceComposer::Rotation>(rotation),
+                                    captureSecureLayers);
     if (ret != NO_ERROR) {
         return ret;
     }
     return ret;
 }
 
+status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
+                                   uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
+                                   bool useIdentityTransform, uint32_t rotation,
+                                   sp<GraphicBuffer>* outBuffer) {
+    bool ignored;
+    return capture(display, sourceCrop, reqWidth, reqHeight,
+                   minLayerZ, maxLayerZ, useIdentityTransform, rotation, false, outBuffer, ignored);
+}
+
 status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
                                          float frameScale, sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
diff --git a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
index b1e44bb..ee88c23 100644
--- a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
@@ -1056,7 +1056,7 @@
 
 status_t H2BGraphicBufferProducer::attachBuffer(
         int* outSlot, const sp<GraphicBuffer>& buffer) {
-    AnwBuffer tBuffer;
+    AnwBuffer tBuffer{};
     wrapAs(&tBuffer, *buffer);
     status_t fnStatus;
     status_t transStatus = toStatusT(mBase->attachBuffer(tBuffer,
@@ -1071,7 +1071,7 @@
         int slot,
         const QueueBufferInput& input,
         QueueBufferOutput* output) {
-    HGraphicBufferProducer::QueueBufferInput tInput;
+    HGraphicBufferProducer::QueueBufferInput tInput{};
     native_handle_t* nh;
     if (!wrapAs(&tInput, &nh, input)) {
         ALOGE("H2BGraphicBufferProducer::queueBuffer - "
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 5f79804..53b9a90 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -195,10 +195,22 @@
      * it) around its center.
      */
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
-                                   Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
-                                   Rotation rotation = eRotateNone) = 0;
+                                   bool& outCapturedSecureLayers, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ,
+                                   int32_t maxLayerZ, bool useIdentityTransform,
+                                   Rotation rotation = eRotateNone,
+                                   bool captureSecureLayers = false) = 0;
 
+    virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+                                   Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ,
+                                   int32_t maxLayerZ, bool useIdentityTransform,
+                                   Rotation rotation = eRotateNone,
+                                   bool captureSecureLayers = false) {
+      bool ignored;
+      return captureScreen(display, outBuffer, ignored, sourceCrop, reqWidth, reqHeight, minLayerZ,
+                           maxLayerZ, useIdentityTransform, rotation, captureSecureLayers);
+    }
     /**
      * Capture a subtree of the layer hierarchy, potentially ignoring the root node.
      */
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index ad8a8b0..49bb687 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -315,6 +315,11 @@
     static status_t capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
                             uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
                             bool useIdentityTransform, uint32_t rotation,
+                            bool captureSecureLayers, sp<GraphicBuffer>* outBuffer,
+                            bool& outCapturedSecureLayers);
+    static status_t capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
+                            uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ,
+                            bool useIdentityTransform, uint32_t rotation,
                             sp<GraphicBuffer>* outBuffer);
     static status_t captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, float frameScale,
                                   sp<GraphicBuffer>* outBuffer);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 959aafc..0fd4231 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -126,7 +126,7 @@
 }
 
 // This test probably doesn't belong here.
-TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
+TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersDontSucceed) {
     sp<ANativeWindow> anw(mSurface);
 
     // Verify the screenshot works with no protected buffers.
@@ -134,7 +134,8 @@
     sp<IBinder> display(sf->getBuiltInDisplay(
             ISurfaceComposer::eDisplayIdMain));
     sp<GraphicBuffer> outBuffer;
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
+    bool ignored;
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, ignored, Rect(),
             64, 64, 0, 0x7fffffff, false));
 
     ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(),
@@ -165,7 +166,7 @@
                 &buf));
         ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
     }
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, ignored, Rect(),
             64, 64, 0, 0x7fffffff, false));
 }
 
@@ -601,10 +602,12 @@
         ColorMode /*colorMode*/) override { return NO_ERROR; }
     status_t captureScreen(const sp<IBinder>& /*display*/,
             sp<GraphicBuffer>* /*outBuffer*/,
+            bool& /* outCapturedSecureLayers */,
             Rect /*sourceCrop*/, uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
             int32_t /*minLayerZ*/, int32_t /*maxLayerZ*/,
             bool /*useIdentityTransform*/,
-            Rotation /*rotation*/) override { return NO_ERROR; }
+            Rotation /*rotation*/,
+            bool /*captureSecureLayers*/) override { return NO_ERROR; }
     virtual status_t captureLayers(const sp<IBinder>& /*parentHandle*/,
                                    sp<GraphicBuffer>* /*outBuffer*/, const Rect& /*sourceCrop*/,
                                    float /*frameScale*/, bool /*childrenOnly*/) override {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index d779ca4..725ae35 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -344,17 +344,19 @@
           : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(),
                               rotation) {}
     DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth,
-                      uint32_t reqHeight, Transform::orientation_flags rotation)
+                      uint32_t reqHeight, Transform::orientation_flags rotation,
+                      bool allowSecureLayers = true)
           : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE,
                        getDisplayRotation(rotation, device->getInstallOrientation())),
             mDevice(device),
-            mSourceCrop(sourceCrop) {}
+            mSourceCrop(sourceCrop),
+            mAllowSecureLayers(allowSecureLayers) {}
 
     const Transform& getTransform() const override { return mDevice->getTransform(); }
     Rect getBounds() const override { return mDevice->getBounds(); }
     int getHeight() const override { return mDevice->getHeight(); }
     int getWidth() const override { return mDevice->getWidth(); }
-    bool isSecure() const override { return mDevice->isSecure(); }
+    bool isSecure() const override { return mAllowSecureLayers && mDevice->isSecure(); }
 
     bool needsFiltering() const override {
         // check if the projection from the logical display to the physical
@@ -456,6 +458,7 @@
 
     const sp<const DisplayDevice> mDevice;
     const Rect mSourceCrop;
+    const bool mAllowSecureLayers;
 };
 
 }; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 78d751a..5324470 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -494,9 +494,9 @@
 
     // wait patiently for the window manager death
     const String16 name("window");
-    sp<IBinder> window(defaultServiceManager()->getService(name));
-    if (window != 0) {
-        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
+    mWindowManager = defaultServiceManager()->getService(name);
+    if (mWindowManager != 0) {
+        mWindowManager->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
     }
 
     if (mVrFlinger) {
@@ -4849,10 +4849,11 @@
 };
 
 status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
-                                       Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                       int32_t minLayerZ, int32_t maxLayerZ,
-                                       bool useIdentityTransform,
-                                       ISurfaceComposer::Rotation rotation) {
+                                       bool& outCapturedSecureLayers, Rect sourceCrop,
+                                       uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ,
+                                       int32_t maxLayerZ, bool useIdentityTransform,
+                                       ISurfaceComposer::Rotation rotation,
+                                       bool captureSecureLayers) {
     ATRACE_CALL();
 
     if (CC_UNLIKELY(display == 0)) return BAD_VALUE;
@@ -4874,11 +4875,13 @@
         }
     }
 
-    DisplayRenderArea renderArea(device, sourceCrop, reqWidth, reqHeight, renderAreaRotation);
+    DisplayRenderArea renderArea(device, sourceCrop, reqWidth, reqHeight, renderAreaRotation,
+                                 captureSecureLayers);
 
     auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
                                     device, minLayerZ, maxLayerZ, std::placeholders::_1);
-    return captureScreenCommon(renderArea, traverseLayers, outBuffer, useIdentityTransform);
+    return captureScreenCommon(renderArea, traverseLayers, outBuffer, useIdentityTransform,
+                               outCapturedSecureLayers);
 }
 
 status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
@@ -5007,13 +5010,16 @@
             visitor(layer);
         });
     };
-    return captureScreenCommon(renderArea, traverseLayers, outBuffer, false);
+    bool outCapturedSecureLayers = false;
+    return captureScreenCommon(renderArea, traverseLayers, outBuffer, false,
+                               outCapturedSecureLayers);
 }
 
 status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
                                              TraverseLayersFunction traverseLayers,
                                              sp<GraphicBuffer>* outBuffer,
-                                             bool useIdentityTransform) {
+                                             bool useIdentityTransform,
+                                             bool& outCapturedSecureLayers) {
     ATRACE_CALL();
 
     const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
@@ -5049,7 +5055,8 @@
             Mutex::Autolock _l(mStateLock);
             renderArea.render([&]() {
                 result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(),
-                                                 useIdentityTransform, forSystem, &fd);
+                                                 useIdentityTransform, forSystem, &fd,
+                                                 outCapturedSecureLayers);
             });
         }
 
@@ -5122,21 +5129,19 @@
 status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,
                                                  TraverseLayersFunction traverseLayers,
                                                  ANativeWindowBuffer* buffer,
-                                                 bool useIdentityTransform,
-                                                 bool forSystem,
-                                                 int* outSyncFd) {
+                                                 bool useIdentityTransform, bool forSystem,
+                                                 int* outSyncFd, bool& outCapturedSecureLayers) {
     ATRACE_CALL();
 
-    bool secureLayerIsVisible = false;
-
     traverseLayers([&](Layer* layer) {
-        secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() && layer->isSecure());
+        outCapturedSecureLayers =
+                outCapturedSecureLayers || (layer->isVisible() && layer->isSecure());
     });
 
     // We allow the system server to take screenshots of secure layers for
     // use in situations like the Screen-rotation animation and place
     // the impetus on WindowManager to not persist them.
-    if (secureLayerIsVisible && !forSystem) {
+    if (outCapturedSecureLayers && !forSystem) {
         ALOGW("FB is protected: PERMISSION_DENIED");
         return PERMISSION_DENIED;
     }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 0914a09..fce877c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -422,9 +422,10 @@
     virtual sp<IDisplayEventConnection> createDisplayEventConnection(
             ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp);
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+                                   bool& outCapturedSecureLayers,
                                    Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
                                    int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform,
-                                   ISurfaceComposer::Rotation rotation);
+                                   ISurfaceComposer::Rotation rotation, bool captureSecureLayers);
     virtual status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer,
                                    const Rect& sourceCrop, float frameScale, bool childrenOnly);
     virtual status_t getDisplayStats(const sp<IBinder>& display,
@@ -577,11 +578,11 @@
                                 bool yswap, bool useIdentityTransform);
     status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
                                  sp<GraphicBuffer>* outBuffer,
-                                 bool useIdentityTransform);
+                                 bool useIdentityTransform, bool& outCapturedSecureLayers);
     status_t captureScreenImplLocked(const RenderArea& renderArea,
                                      TraverseLayersFunction traverseLayers,
                                      ANativeWindowBuffer* buffer, bool useIdentityTransform,
-                                     bool forSystem, int* outSyncFd);
+                                     bool forSystem, int* outSyncFd, bool& outCapturedSecureLayers);
     void traverseLayersInDisplay(const sp<const DisplayDevice>& display, int32_t minLayerZ,
                                  int32_t maxLayerZ, const LayerVector::Visitor& visitor);
 
@@ -892,6 +893,9 @@
     // either AID_GRAPHICS or AID_SYSTEM.
     status_t CheckTransactCodeCredentials(uint32_t code);
 
+    // to linkToDeath
+    sp<IBinder> mWindowManager;
+
     std::unique_ptr<dvr::VrFlinger> mVrFlinger;
     std::atomic<bool> mVrFlingerRequestsDisplay;
     static bool useVrFlinger;
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index d4f1e29..9c34aa7 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -277,6 +277,9 @@
     std::lock_guard<std::mutex> lock(mMutex);
     if (!timeStatsTracker.count(layerName)) return;
     LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (layerRecord.waitData < 0 ||
+        layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+        return;
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameNumber == frameNumber) {
         timeRecord.latchTime = latchTime;
@@ -294,6 +297,9 @@
     std::lock_guard<std::mutex> lock(mMutex);
     if (!timeStatsTracker.count(layerName)) return;
     LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (layerRecord.waitData < 0 ||
+        layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+        return;
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameNumber == frameNumber) {
         timeRecord.desiredTime = desiredTime;
@@ -311,6 +317,9 @@
     std::lock_guard<std::mutex> lock(mMutex);
     if (!timeStatsTracker.count(layerName)) return;
     LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (layerRecord.waitData < 0 ||
+        layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+        return;
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameNumber == frameNumber) {
         timeRecord.acquireTime = acquireTime;
@@ -328,6 +337,9 @@
     std::lock_guard<std::mutex> lock(mMutex);
     if (!timeStatsTracker.count(layerName)) return;
     LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (layerRecord.waitData < 0 ||
+        layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+        return;
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameNumber == frameNumber) {
         timeRecord.acquireFence = acquireFence;
@@ -345,6 +357,9 @@
     std::lock_guard<std::mutex> lock(mMutex);
     if (!timeStatsTracker.count(layerName)) return;
     LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (layerRecord.waitData < 0 ||
+        layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+        return;
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameNumber == frameNumber) {
         timeRecord.presentTime = presentTime;
@@ -366,6 +381,9 @@
     std::lock_guard<std::mutex> lock(mMutex);
     if (!timeStatsTracker.count(layerName)) return;
     LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (layerRecord.waitData < 0 ||
+        layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+        return;
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameNumber == frameNumber) {
         timeRecord.presentFence = presentFence;
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 79f27df..e04e1e9 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -29,6 +29,7 @@
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
 #include <private/gui/ComposerService.h>
+#include <private/android_filesystem_config.h>
 
 #include <ui/DisplayInfo.h>
 #include <ui/Rect.h>
@@ -36,6 +37,8 @@
 
 #include <math.h>
 #include <math/vec3.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 namespace android {
 
@@ -68,6 +71,30 @@
 }
 
 // Fill a region with the specified color.
+void fillANativeWindowBufferColor(const ANativeWindow_Buffer& buffer, const Rect& rect,
+                                  const Color& color) {
+    Rect r(0, 0, buffer.width, buffer.height);
+    if (!r.intersect(rect, &r)) {
+        return;
+    }
+
+    int32_t width = r.right - r.left;
+    int32_t height = r.bottom - r.top;
+
+    for (int32_t row = 0; row < height; row++) {
+        uint8_t* dst =
+                static_cast<uint8_t*>(buffer.bits) + (buffer.stride * (r.top + row) + r.left) * 4;
+        for (int32_t column = 0; column < width; column++) {
+            dst[0] = color.r;
+            dst[1] = color.g;
+            dst[2] = color.b;
+            dst[3] = color.a;
+            dst += 4;
+        }
+    }
+}
+
+// Fill a region with the specified color.
 void fillBufferColor(const ANativeWindow_Buffer& buffer, const Rect& rect, const Color& color) {
     int32_t x = rect.left;
     int32_t y = rect.top;
@@ -319,6 +346,16 @@
         return layer;
     }
 
+    ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
+        // wait for previous transactions (such as setSize) to complete
+        Transaction().apply(true);
+
+        ANativeWindow_Buffer buffer = {};
+        EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
+
+        return buffer;
+    }
+
     ANativeWindow_Buffer getLayerBuffer(const sp<SurfaceControl>& layer) {
         // wait for previous transactions (such as setSize) to complete
         Transaction().apply(true);
@@ -336,6 +373,21 @@
         waitForLayerBuffers();
     }
 
+    void postBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
+        ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
+
+        // wait for the newly posted buffer to be latched
+        waitForLayerBuffers();
+    }
+
+    virtual void fillBufferQueueLayerColor(const sp<SurfaceControl>& layer, const Color& color,
+                                           int32_t bufferWidth, int32_t bufferHeight) {
+        ANativeWindow_Buffer buffer;
+        ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer));
+        fillANativeWindowBufferColor(buffer, Rect(0, 0, bufferWidth, bufferHeight), color);
+        postBufferQueueLayerBuffer(layer);
+    }
+
     void fillLayerColor(const sp<SurfaceControl>& layer, const Color& color) {
         ANativeWindow_Buffer buffer;
         ASSERT_NO_FATAL_FAILURE(buffer = getLayerBuffer(layer));
@@ -847,6 +899,57 @@
                                       false));
 }
 
+/** RAII Wrapper around get/seteuid */
+class UIDFaker {
+    uid_t oldId;
+public:
+    UIDFaker(uid_t uid) {
+        oldId = geteuid();
+        seteuid(uid);
+    }
+    ~UIDFaker() {
+        seteuid(oldId);
+    }
+};
+
+TEST_F(LayerTransactionTest, SetFlagsSecureEUidSystem) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
+
+    sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+    sp<GraphicBuffer> outBuffer;
+    Transaction()
+            .setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
+            .apply(true);
+
+    ASSERT_EQ(PERMISSION_DENIED,
+              composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, 0, INT_MAX, false));
+
+    UIDFaker f(AID_SYSTEM);
+
+    // By default the system can capture screenshots with secure layers but they
+    // will be blacked out
+    ASSERT_EQ(NO_ERROR,
+              composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, 0, INT_MAX, false));
+
+    {
+        SCOPED_TRACE("as system");
+        auto shot = screenshot();
+        shot->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
+    }
+
+    // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
+    // to receive them...we are expected to take care with the results.
+    bool outCapturedSecureLayers = false;
+    ASSERT_EQ(NO_ERROR,
+              composer->captureScreen(mDisplay, &outBuffer, outCapturedSecureLayers,
+                      Rect(), 0, 0, 0, INT_MAX, false, ISurfaceComposer::eRotateNone, true));
+    ASSERT_EQ(true, outCapturedSecureLayers);
+    ScreenCapture sc(outBuffer);
+    sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
+}
+
 TEST_F(LayerTransactionTest, SetTransparentRegionHintBasic) {
     const Rect top(0, 0, 32, 16);
     const Rect bottom(0, 16, 32, 32);
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index fdbd969..b494bca 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -945,7 +945,9 @@
 
             memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
                    sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
-            prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
+            // b/130182551 VK_KHR_SWAPCHAIN_SPEC_VERSION > 68 has structs the
+            // loader doesn't handle properly. So drop the spec version to 68.
+            prop.specVersion = 68;
         }
     }