Merge "Fix unsafe layer hierarchy access" into main
diff --git a/libs/binder/PersistableBundle.cpp b/libs/binder/PersistableBundle.cpp
index 1504715..5b157cc 100644
--- a/libs/binder/PersistableBundle.cpp
+++ b/libs/binder/PersistableBundle.cpp
@@ -82,13 +82,12 @@
          }                                                               \
     }
 
-#define RETURN_IF_ENTRY_ERASED(map, key)                                 \
-    {                                                                    \
-        size_t num_erased = (map).erase(key);                            \
-        if (num_erased) {                                                \
-            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
-            return num_erased;                                           \
-         }                                                               \
+#define RETURN_IF_ENTRY_ERASED(map, key)      \
+    {                                         \
+        size_t num_erased = (map).erase(key); \
+        if (num_erased) {                     \
+            return num_erased;                \
+        }                                     \
     }
 
 status_t PersistableBundle::writeToParcel(Parcel* parcel) const {
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 66b552a..8771af5 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -62,6 +62,7 @@
         "binderStatusUnitTest.cpp",
         "binderMemoryHeapBaseUnitTest.cpp",
         "binderRecordedTransactionTest.cpp",
+        "binderPersistableBundleTest.cpp",
     ],
     shared_libs: [
         "libbinder",
diff --git a/libs/binder/tests/binderPersistableBundleTest.cpp b/libs/binder/tests/binderPersistableBundleTest.cpp
new file mode 100644
index 0000000..392e018
--- /dev/null
+++ b/libs/binder/tests/binderPersistableBundleTest.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2024 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 <binder/Parcel.h>
+#include <binder/PersistableBundle.h>
+#include <gtest/gtest.h>
+#include <numeric>
+
+using android::OK;
+using android::Parcel;
+using android::status_t;
+using android::String16;
+using android::String8;
+using android::os::PersistableBundle;
+
+namespace android {
+
+inline std::string to_string(String16 const& str) {
+    return String8{str}.c_str();
+}
+
+namespace os {
+
+template <typename T>
+inline std::ostream& operator<<(std::ostream& out, std::vector<T> const& vec) {
+    using std::to_string;
+    auto str =
+            std::accumulate(vec.begin(), vec.end(), std::string{},
+                            [](std::string const& a, auto const& b) { return a + to_string(b); });
+    return out << str;
+}
+
+inline std::ostream& operator<<(std::ostream& out, PersistableBundle const& pb) {
+#define PRINT(TYPENAME, TYPE)                                \
+    for (auto const& key : pb.get##TYPENAME##Keys()) {       \
+        TYPE val{};                                          \
+        pb.get##TYPENAME(key, &val);                         \
+        out << #TYPE " " << key << ": " << val << std::endl; \
+    }
+
+    out << "size: " << pb.size() << std::endl;
+    PRINT(Boolean, bool);
+    PRINT(Int, int);
+    PRINT(Long, int64_t);
+    PRINT(Double, double);
+    PRINT(String, String16);
+    PRINT(BooleanVector, std::vector<bool>);
+    PRINT(IntVector, std::vector<int32_t>);
+    PRINT(LongVector, std::vector<int64_t>);
+    PRINT(DoubleVector, std::vector<double>);
+    PRINT(StringVector, std::vector<String16>);
+    PRINT(PersistableBundle, PersistableBundle);
+
+#undef PRINT
+
+    return out;
+}
+
+} // namespace os
+} // namespace android
+
+static const String16 kKey{"key"};
+
+static PersistableBundle createSimplePersistableBundle() {
+    PersistableBundle pb{};
+    pb.putInt(kKey, 64);
+    return pb;
+}
+
+#define TEST_PUT_AND_GET(TYPENAME, TYPE, ...)              \
+    TEST(PersistableBundle, PutAndGet##TYPENAME) {         \
+        TYPE const expected{__VA_ARGS__};                  \
+        PersistableBundle pb{};                            \
+                                                           \
+        pb.put##TYPENAME(kKey, expected);                  \
+                                                           \
+        std::set<String16> expectedKeys{kKey};             \
+        EXPECT_EQ(pb.get##TYPENAME##Keys(), expectedKeys); \
+                                                           \
+        TYPE val{};                                        \
+        EXPECT_TRUE(pb.get##TYPENAME(kKey, &val));         \
+        EXPECT_EQ(val, expected);                          \
+    }
+
+TEST_PUT_AND_GET(Boolean, bool, true);
+TEST_PUT_AND_GET(Int, int, 64);
+TEST_PUT_AND_GET(Long, int64_t, 42);
+TEST_PUT_AND_GET(Double, double, 42.64);
+TEST_PUT_AND_GET(String, String16, String16{"foo"});
+TEST_PUT_AND_GET(BooleanVector, std::vector<bool>, true, true);
+TEST_PUT_AND_GET(IntVector, std::vector<int32_t>, 1, 2);
+TEST_PUT_AND_GET(LongVector, std::vector<int64_t>, 1, 2);
+TEST_PUT_AND_GET(DoubleVector, std::vector<double>, 4.2, 5.9);
+TEST_PUT_AND_GET(StringVector, std::vector<String16>, String16{"foo"}, String16{"bar"});
+TEST_PUT_AND_GET(PersistableBundle, PersistableBundle, createSimplePersistableBundle());
+
+TEST(PersistableBundle, ParcelAndUnparcel) {
+    PersistableBundle expected = createSimplePersistableBundle();
+    PersistableBundle out{};
+
+    Parcel p{};
+    EXPECT_EQ(expected.writeToParcel(&p), 0);
+    p.setDataPosition(0);
+    EXPECT_EQ(out.readFromParcel(&p), 0);
+
+    EXPECT_EQ(expected, out);
+}
+
+TEST(PersistableBundle, OverwriteKey) {
+    PersistableBundle pb{};
+
+    pb.putInt(kKey, 64);
+    pb.putDouble(kKey, 0.5);
+
+    EXPECT_EQ(pb.getIntKeys().size(), 0);
+    EXPECT_EQ(pb.getDoubleKeys().size(), 1);
+
+    double out;
+    EXPECT_TRUE(pb.getDouble(kKey, &out));
+    EXPECT_EQ(out, 0.5);
+}
diff --git a/libs/renderengine/skia/VulkanInterface.cpp b/libs/renderengine/skia/VulkanInterface.cpp
index fc16c56..5e756b0 100644
--- a/libs/renderengine/skia/VulkanInterface.cpp
+++ b/libs/renderengine/skia/VulkanInterface.cpp
@@ -197,7 +197,9 @@
     LOG_ALWAYS_FATAL("%s", crashMsg.str().c_str());
 };
 
-static GrVkGetProc sGetProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
+static skgpu::VulkanGetProc sGetProc = [](const char* proc_name,
+                                          VkInstance instance,
+                                          VkDevice device) {
     if (device != VK_NULL_HANDLE) {
         return vkGetDeviceProcAddr(device, proc_name);
     }
@@ -604,7 +606,7 @@
     mQueue = VK_NULL_HANDLE;          // Implicitly destroyed by destroying mDevice.
     mQueueIndex = 0;
     mApiVersion = 0;
-    mGrExtensions = GrVkExtensions();
+    mGrExtensions = skgpu::VulkanExtensions();
     mGrGetProc = nullptr;
     mIsProtected = false;
     mIsRealtimePriority = false;
diff --git a/libs/renderengine/skia/VulkanInterface.h b/libs/renderengine/skia/VulkanInterface.h
index af0489a..f20b002 100644
--- a/libs/renderengine/skia/VulkanInterface.h
+++ b/libs/renderengine/skia/VulkanInterface.h
@@ -17,7 +17,8 @@
 #pragma once
 
 #include <include/gpu/vk/GrVkBackendContext.h>
-#include <include/gpu/vk/GrVkExtensions.h>
+#include <include/gpu/vk/VulkanExtensions.h>
+#include <include/gpu/vk/VulkanTypes.h>
 
 #include <vulkan/vulkan.h>
 
@@ -85,12 +86,12 @@
     VkQueue mQueue = VK_NULL_HANDLE;
     int mQueueIndex = 0;
     uint32_t mApiVersion = 0;
-    GrVkExtensions mGrExtensions;
+    skgpu::VulkanExtensions mGrExtensions;
     VkPhysicalDeviceFeatures2* mPhysicalDeviceFeatures2 = nullptr;
     VkPhysicalDeviceSamplerYcbcrConversionFeatures* mSamplerYcbcrConversionFeatures = nullptr;
     VkPhysicalDeviceProtectedMemoryFeatures* mProtectedMemoryFeatures = nullptr;
     VkPhysicalDeviceFaultFeaturesEXT* mDeviceFaultFeatures = nullptr;
-    GrVkGetProc mGrGetProc = nullptr;
+    skgpu::VulkanGetProc mGrGetProc = nullptr;
     bool mIsProtected = false;
     bool mIsRealtimePriority = false;
 
diff --git a/services/sensorservice/senserservice_flags.aconfig b/services/sensorservice/senserservice_flags.aconfig
index 5b499a8..4c1d314 100644
--- a/services/sensorservice/senserservice_flags.aconfig
+++ b/services/sensorservice/senserservice_flags.aconfig
@@ -27,4 +27,11 @@
   namespace: "sensors"
   description: "When this flag is enabled, sensor service will only erase dynamic sensor data at the end of the threadLoop to prevent race condition."
   bug: "329020894"
+}
+
+flag {
+  name: "sensor_service_report_sensor_usage_in_tracing"
+  namespace: "sensors"
+  description: "When this flag is enabled, sensor service will report sensor usage when system trace is enabled."
+  bug: "333132224"
 }
\ No newline at end of file