Merge "binder: RpcServer / RpcSession add API for certs."
diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp
index 99e0f4c..b2da6d5 100644
--- a/cmds/idlcli/Android.bp
+++ b/cmds/idlcli/Android.bp
@@ -24,7 +24,7 @@
 cc_defaults {
     name: "idlcli-defaults",
     shared_libs: [
-        "android.hardware.vibrator-V1-ndk_platform",
+        "android.hardware.vibrator-V1-ndk",
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index dd3f56d..9875079 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -298,6 +298,9 @@
         "aidl/android/content/pm/IPackageChangeObserver.aidl",
         "aidl/android/content/pm/IPackageManagerNative.aidl",
         "aidl/android/content/pm/PackageChangeEvent.aidl",
+        "aidl/android/content/pm/IStagedApexObserver.aidl",
+        "aidl/android/content/pm/ApexStagedEvent.aidl",
+        "aidl/android/content/pm/StagedApexInfo.aidl",
     ],
     path: "aidl",
 }
@@ -338,6 +341,8 @@
         "//packages/modules/Virtualization/authfs:__subpackages__",
         "//packages/modules/Virtualization/compos:__subpackages__",
         "//packages/modules/Virtualization/microdroid",
+        "//packages/modules/Virtualization/microdroid_manager",
+        "//packages/modules/Virtualization/virtualizationservice",
     ],
 }
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 956524a..b545484 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -104,7 +104,7 @@
     switch (obj.hdr.type) {
         case BINDER_TYPE_BINDER:
             if (obj.binder) {
-                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
+                LOG_REFS("Parcel %p acquiring reference on local %llu", who, obj.cookie);
                 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
             }
             return;
@@ -137,7 +137,7 @@
     switch (obj.hdr.type) {
         case BINDER_TYPE_BINDER:
             if (obj.binder) {
-                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
+                LOG_REFS("Parcel %p releasing reference on local %llu", who, obj.cookie);
                 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
             }
             return;
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 22a7782..c57b749 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -493,37 +493,39 @@
         }
 
         if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
-            if (errno == ECONNRESET) {
+            int connErrno = errno;
+            if (connErrno == EAGAIN || connErrno == EINPROGRESS) {
+                // For non-blocking sockets, connect() may return EAGAIN (for unix domain socket) or
+                // EINPROGRESS (for others). Call poll() and getsockopt() to get the error.
+                status_t pollStatus = mShutdownTrigger->triggerablePoll(serverFd, POLLOUT);
+                if (pollStatus != OK) {
+                    ALOGE("Could not POLLOUT after connect() on non-blocking socket: %s",
+                          statusToString(pollStatus).c_str());
+                    return pollStatus;
+                }
+                // Set connErrno to the errno that connect() would have set if the fd were blocking.
+                socklen_t connErrnoLen = sizeof(connErrno);
+                int ret =
+                        getsockopt(serverFd.get(), SOL_SOCKET, SO_ERROR, &connErrno, &connErrnoLen);
+                if (ret == -1) {
+                    int savedErrno = errno;
+                    ALOGE("Could not getsockopt() after connect() on non-blocking socket: %s. "
+                          "(Original error from connect() is: %s)",
+                          strerror(savedErrno), strerror(connErrno));
+                    return -savedErrno;
+                }
+                // Retrieved the real connErrno as if connect() was called with a blocking socket
+                // fd. Continue checking connErrno.
+            }
+            if (connErrno == ECONNRESET) {
                 ALOGW("Connection reset on %s", addr.toString().c_str());
                 continue;
             }
-            if (errno != EAGAIN && errno != EINPROGRESS) {
-                int savedErrno = errno;
+            // connErrno could be zero if getsockopt determines so. Hence zero-check again.
+            if (connErrno != 0) {
                 ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(),
-                      strerror(savedErrno));
-                return -savedErrno;
-            }
-            // For non-blocking sockets, connect() may return EAGAIN (for unix domain socket) or
-            // EINPROGRESS (for others). Call poll() and getsockopt() to get the error.
-            status_t pollStatus = mShutdownTrigger->triggerablePoll(serverFd, POLLOUT);
-            if (pollStatus != OK) {
-                ALOGE("Could not POLLOUT after connect() on non-blocking socket: %s",
-                      statusToString(pollStatus).c_str());
-                return pollStatus;
-            }
-            int soError;
-            socklen_t soErrorLen = sizeof(soError);
-            int ret = getsockopt(serverFd.get(), SOL_SOCKET, SO_ERROR, &soError, &soErrorLen);
-            if (ret == -1) {
-                int savedErrno = errno;
-                ALOGE("Could not getsockopt() after connect() on non-blocking socket: %s",
-                      strerror(savedErrno));
-                return -savedErrno;
-            }
-            if (soError != 0) {
-                ALOGE("After connect(), getsockopt() returns error for socket at %s: %s",
-                      addr.toString().c_str(), strerror(soError));
-                return -soError;
+                      strerror(connErrno));
+                return -connErrno;
             }
         }
         LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index 9c5ce67..ebb0d27 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -34,6 +34,9 @@
       "name": "binderStabilityTest"
     },
     {
+      "name": "binderRpcWireProtocolTest"
+    },
+    {
       "name": "binderUtilsHostTest"
     },
     {
diff --git a/libs/binder/aidl/android/content/pm/ApexStagedEvent.aidl b/libs/binder/aidl/android/content/pm/ApexStagedEvent.aidl
new file mode 100644
index 0000000..75f8753
--- /dev/null
+++ b/libs/binder/aidl/android/content/pm/ApexStagedEvent.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.content.pm;
+
+/**
+ * This event is designed for notification to native code listener about
+ * any changes to set of apex packages staged for installation on next boot.
+ *
+ * @hide
+ */
+parcelable ApexStagedEvent {
+  @utf8InCpp String[] stagedApexModuleNames;
+}
diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
index dc8d74c..c076be7 100644
--- a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
+++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
@@ -18,6 +18,8 @@
 package android.content.pm;
 
 import android.content.pm.IPackageChangeObserver;
+import android.content.pm.IStagedApexObserver;
+import android.content.pm.StagedApexInfo;
 
 /**
  * Parallel implementation of certain {@link PackageManager} APIs that need to
@@ -101,4 +103,24 @@
      * This does nothing if this observer was not already registered.
      */
     void unregisterPackageChangeObserver(in IPackageChangeObserver observer);
+
+    /** Register a observer for change in set of staged APEX ready for installation */
+    void registerStagedApexObserver(in IStagedApexObserver observer);
+
+    /**
+     * Unregister an existing staged apex observer.
+     * This does nothing if this observer was not already registered.
+     */
+    void unregisterStagedApexObserver(in IStagedApexObserver observer);
+
+    /**
+     * Get APEX module names of all APEX that are staged ready for installation
+     */
+    @utf8InCpp String[] getStagedApexModuleNames();
+
+    /**
+     * Get information of APEX which is staged ready for installation.
+     * Returns null if no such APEX is found.
+     */
+    StagedApexInfo getStagedApexInfo(in @utf8InCpp String moduleName);
 }
diff --git a/libs/binder/aidl/android/content/pm/IStagedApexObserver.aidl b/libs/binder/aidl/android/content/pm/IStagedApexObserver.aidl
new file mode 100644
index 0000000..9906436
--- /dev/null
+++ b/libs/binder/aidl/android/content/pm/IStagedApexObserver.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.content.pm;
+
+import android.content.pm.ApexStagedEvent;
+
+/**
+ * This is a non-blocking notification when set of staged apex has changed
+ *
+ * @hide
+ */
+oneway interface IStagedApexObserver {
+  void onApexStaged(in ApexStagedEvent event);
+}
diff --git a/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl b/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl
new file mode 100644
index 0000000..ece7989
--- /dev/null
+++ b/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.content.pm;
+
+/**
+ * This object is designed for returning information regarding
+ * staged APEX that are ready to be installed on next reboot.
+ *
+ * @hide
+ */
+parcelable StagedApexInfo {
+  @utf8InCpp String moduleName;
+  @utf8InCpp String diskImagePath;
+  long versionCode;
+  @utf8InCpp String versionName;
+}
diff --git a/libs/binder/ndk/tests/Android.bp b/libs/binder/ndk/tests/Android.bp
index 488009f..8ee396e 100644
--- a/libs/binder/ndk/tests/Android.bp
+++ b/libs/binder/ndk/tests/Android.bp
@@ -71,7 +71,7 @@
     srcs: ["libbinder_ndk_unit_test.cpp"],
     static_libs: [
         "IBinderNdkUnitTest-cpp",
-        "IBinderNdkUnitTest-ndk_platform",
+        "IBinderNdkUnitTest-ndk",
     ],
     test_suites: [
         "general-tests",
@@ -88,8 +88,8 @@
     ],
     static_libs: [
         "IBinderVendorDoubleLoadTest-cpp",
-        "IBinderVendorDoubleLoadTest-ndk_platform",
-        "libbinder_aidl_test_stub-ndk_platform",
+        "IBinderVendorDoubleLoadTest-ndk",
+        "libbinder_aidl_test_stub-ndk",
     ],
     // critical that libbinder/libbinder_ndk are shared for VTS
     shared_libs: [
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index cdd7c08..b03ed49 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -38,7 +38,7 @@
 ///
 /// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper
 /// is untyped; typed interface access is implemented by the AIDL compiler.
-pub struct SpIBinder(*mut sys::AIBinder);
+pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
 
 impl fmt::Debug for SpIBinder {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -74,7 +74,7 @@
     /// to an `AIBinder`, which will remain valid for the entire lifetime of the
     /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
     pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
-        ptr.as_mut().map(|p| Self(p))
+        ptr::NonNull::new(ptr).map(Self)
     }
 
     /// Extract a raw `AIBinder` pointer from this wrapper.
@@ -88,7 +88,7 @@
     /// The SpIBinder object retains ownership of the AIBinder and the caller
     /// should not attempt to free the returned pointer.
     pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
-        self.0
+        self.0.as_ptr()
     }
 
     /// Return true if this binder object is hosted in a different process than
@@ -176,13 +176,13 @@
             // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
             // this pointer is always safe to pass to `AIBinder_lt` (null is
             // also safe to pass to this function, but we should never do that).
-            sys::AIBinder_lt(self.0, other.0)
+            sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr())
         };
         let greater_than = unsafe {
             // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
             // this pointer is always safe to pass to `AIBinder_lt` (null is
             // also safe to pass to this function, but we should never do that).
-            sys::AIBinder_lt(other.0, self.0)
+            sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr())
         };
         if !less_than && !greater_than {
             Ordering::Equal
@@ -202,7 +202,7 @@
 
 impl PartialEq for SpIBinder {
     fn eq(&self, other: &Self) -> bool {
-        ptr::eq(self.0, other.0)
+        ptr::eq(self.0.as_ptr(), other.0.as_ptr())
     }
 }
 
@@ -214,7 +214,7 @@
             // Safety: Cloning a strong reference must increment the reference
             // count. We are guaranteed by the `SpIBinder` constructor
             // invariants that `self.0` is always a valid `AIBinder` pointer.
-            sys::AIBinder_incStrong(self.0);
+            sys::AIBinder_incStrong(self.0.as_ptr());
         }
         Self(self.0)
     }
@@ -443,7 +443,7 @@
 ///
 /// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
 /// is untyped; typed interface access is implemented by the AIDL compiler.
-pub struct WpIBinder(*mut sys::AIBinder_Weak);
+pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
 
 impl fmt::Debug for WpIBinder {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -470,8 +470,7 @@
             // valid pointer to an `AIBinder`.
             sys::AIBinder_Weak_new(binder.as_native_mut())
         };
-        assert!(!ptr.is_null());
-        Self(ptr)
+        Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new"))
     }
 
     /// Promote this weak reference to a strong reference to the binder object.
@@ -481,7 +480,7 @@
             // can pass this pointer to `AIBinder_Weak_promote`. Returns either
             // null or an AIBinder owned by the caller, both of which are valid
             // to pass to `SpIBinder::from_raw`.
-            let ptr = sys::AIBinder_Weak_promote(self.0);
+            let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr());
             SpIBinder::from_raw(ptr)
         }
     }
@@ -496,13 +495,9 @@
             //
             // We get ownership of the returned pointer, so can construct a new
             // WpIBinder object from it.
-            sys::AIBinder_Weak_clone(self.0)
+            sys::AIBinder_Weak_clone(self.0.as_ptr())
         };
-        assert!(
-            !ptr.is_null(),
-            "Unexpected null pointer from AIBinder_Weak_clone"
-        );
-        Self(ptr)
+        Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
     }
 }
 
@@ -513,14 +508,14 @@
             // so this pointer is always safe to pass to `AIBinder_Weak_lt`
             // (null is also safe to pass to this function, but we should never
             // do that).
-            sys::AIBinder_Weak_lt(self.0, other.0)
+            sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr())
         };
         let greater_than = unsafe {
             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
             // so this pointer is always safe to pass to `AIBinder_Weak_lt`
             // (null is also safe to pass to this function, but we should never
             // do that).
-            sys::AIBinder_Weak_lt(other.0, self.0)
+            sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr())
         };
         if !less_than && !greater_than {
             Ordering::Equal
@@ -551,7 +546,7 @@
         unsafe {
             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
             // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
-            sys::AIBinder_Weak_delete(self.0);
+            sys::AIBinder_Weak_delete(self.0.as_ptr());
         }
     }
 }
@@ -716,10 +711,10 @@
 /// `AIBinder`, so we can trivially extract this pointer here.
 unsafe impl AsNative<sys::AIBinder> for SpIBinder {
     fn as_native(&self) -> *const sys::AIBinder {
-        self.0
+        self.0.as_ptr()
     }
 
     fn as_native_mut(&mut self) -> *mut sys::AIBinder {
-        self.0
+        self.0.as_ptr()
     }
 }
diff --git a/libs/binder/rust/tests/Android.bp b/libs/binder/rust/tests/Android.bp
index 607860f..ecc61f4 100644
--- a/libs/binder/rust/tests/Android.bp
+++ b/libs/binder/rust/tests/Android.bp
@@ -50,7 +50,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "IBinderRustNdkInteropTest-ndk_platform",
+        "IBinderRustNdkInteropTest-ndk",
         "libbinder_ndk_rust_interop",
     ],
     test_suites: ["general-tests"],
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 54f1f07..13ea827 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -162,7 +162,7 @@
     static_libs: [
         "libbinder_tls_static",
         "binderRpcTestIface-cpp",
-        "binderRpcTestIface-ndk_platform",
+        "binderRpcTestIface-ndk",
     ],
     test_suites: ["general-tests"],
     require_root: true,
@@ -190,6 +190,33 @@
 }
 
 cc_test {
+    name: "binderRpcWireProtocolTest",
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+        android: {
+            test_suites: ["vts"],
+        },
+    },
+    defaults: [
+        "binder_test_defaults",
+    ],
+    srcs: [
+        "binderRpcWireProtocolTest.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbase",
+        "libutils",
+        "libcutils",
+        "liblog",
+    ],
+    test_suites: ["general-tests"],
+}
+
+cc_test {
     name: "binderThroughputTest",
     defaults: ["binder_test_defaults"],
     srcs: ["binderThroughputTest.cpp"],
@@ -298,7 +325,7 @@
     ],
     static_libs: [
         "binderStabilityTestIface-cpp",
-        "binderStabilityTestIface-ndk_platform",
+        "binderStabilityTestIface-ndk",
     ],
 
     test_suites: ["device-tests", "vts"],
diff --git a/libs/binder/tests/binderRpcWireProtocolTest.cpp b/libs/binder/tests/binderRpcWireProtocolTest.cpp
new file mode 100644
index 0000000..46e9630
--- /dev/null
+++ b/libs/binder/tests/binderRpcWireProtocolTest.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2021 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 <android-base/hex.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <binder/Parcel.h>
+#include <binder/RpcSession.h>
+#include <gtest/gtest.h>
+
+#include "../Debug.h"
+
+namespace android {
+
+static const int32_t kInt32Array[] = {-1, 0, 17};
+static const uint8_t kByteArray[] = {0, 17, 255};
+enum EnumInt8 : int8_t { Int8A, Int8B };
+enum EnumInt32 : int32_t { Int32A, Int32B };
+enum EnumInt64 : int64_t { Int64A, Int64B };
+struct AParcelable : Parcelable {
+    status_t writeToParcel(Parcel* parcel) const { return parcel->writeInt32(37); }
+    status_t readFromParcel(const Parcel*) { return OK; }
+};
+
+// clang-format off
+constexpr size_t kFillFunIndexLineBase = __LINE__ + 2;
+static const std::vector<std::function<void(Parcel* p)>> kFillFuns {
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInterfaceToken(String16(u"tok"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32(-1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32(17)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint32(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint32(1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint32(10003)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64(-1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64(17)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64(1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64(10003)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloat(0.0f)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloat(0.1f)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloat(9.1f)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDouble(0.0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDouble(0.1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDouble(9.1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCString("")); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCString("a")); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCString("baba")); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString8(String8(""))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString8(String8("a"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString8(String8("baba"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16(String16(u""))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16(String16(u"a"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16(String16(u"baba"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinder(nullptr)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Array(arraysize(kInt32Array), kInt32Array)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteArray(arraysize(kByteArray), kByteArray)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBool(true)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBool(false)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeChar('a')); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeChar('?')); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeChar('\0')); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByte(-128)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByte(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByte(127)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::string(""))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::string("a"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::string("abab"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::nullopt)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::optional<std::string>(""))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::optional<std::string>("a"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::optional<std::string>("abab"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::optional<std::vector<int8_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::optional<std::vector<int8_t>>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::vector<int8_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::vector<int8_t>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::optional<std::vector<uint8_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::optional<std::vector<uint8_t>>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::vector<uint8_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::vector<uint8_t>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Vector(std::optional<std::vector<int32_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Vector(std::optional<std::vector<int32_t>>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Vector(std::vector<int32_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Vector(std::vector<int32_t>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64Vector(std::optional<std::vector<int64_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64Vector(std::optional<std::vector<int64_t>>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64Vector(std::vector<int64_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64Vector(std::vector<int64_t>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64Vector(std::optional<std::vector<uint64_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64Vector(std::optional<std::vector<uint64_t>>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64Vector(std::vector<uint64_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64Vector(std::vector<uint64_t>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloatVector(std::optional<std::vector<float>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloatVector(std::optional<std::vector<float>>({0.0f, 0.1f, 9.1f}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloatVector(std::vector<float>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloatVector(std::vector<float>({0.0f, 0.1f, 9.1f}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDoubleVector(std::optional<std::vector<double>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDoubleVector(std::optional<std::vector<double>>({0.0, 0.1, 9.1}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDoubleVector(std::vector<double>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDoubleVector(std::vector<double>({0.0, 0.1, 9.1}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBoolVector(std::optional<std::vector<bool>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBoolVector(std::optional<std::vector<bool>>({true, false}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBoolVector(std::vector<bool>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBoolVector(std::vector<bool>({true, false}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCharVector(std::optional<std::vector<char16_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCharVector(std::optional<std::vector<char16_t>>({'a', '\0', '?'}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCharVector(std::vector<char16_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCharVector(std::vector<char16_t>({'a', '\0', '?'}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16Vector(std::optional<std::vector<std::optional<String16>>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16Vector(std::optional<std::vector<std::optional<String16>>>({std::nullopt, String16(), String16(u"a")}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16Vector(std::vector<std::optional<String16>>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16Vector(std::vector<std::optional<String16>>({std::nullopt, String16(), String16(u"a")}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8VectorAsUtf16Vector(std::optional<std::vector<std::optional<std::string>>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8VectorAsUtf16Vector(std::optional<std::vector<std::optional<std::string>>>({std::nullopt, std::string(), std::string("a")}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8VectorAsUtf16Vector(std::vector<std::optional<std::string>>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8VectorAsUtf16Vector(std::vector<std::optional<std::string>>({std::nullopt, std::string(), std::string("a")}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinderVector(std::optional<std::vector<sp<IBinder>>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinderVector(std::optional<std::vector<sp<IBinder>>>({nullptr}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinderVector(std::vector<sp<IBinder>>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinderVector(std::vector<sp<IBinder>>({nullptr}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt8>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt8>>({Int8A, Int8B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::vector<EnumInt8>({Int8A, Int8B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt32>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt32>>({Int32A, Int32B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::vector<EnumInt32>({Int32A, Int32B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt64>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt64>>({Int64A, Int64B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::vector<EnumInt64>({Int64A, Int64B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeParcelableVector(std::optional<std::vector<std::optional<AParcelable>>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeParcelableVector(std::optional<std::vector<std::optional<AParcelable>>>({AParcelable()}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeParcelableVector(std::vector<AParcelable>({AParcelable()}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeNullableParcelable(std::optional<AParcelable>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeNullableParcelable(std::optional<AParcelable>(AParcelable()))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeParcelable(AParcelable())); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeVectorSize(std::vector<int32_t>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeVectorSize(std::vector<AParcelable>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeVectorSize(std::optional<std::vector<int32_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeVectorSize(std::optional<std::vector<int32_t>>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeNoException()); },
+};
+// clang-format on
+
+static void setParcelForRpc(Parcel* p, uint32_t version) {
+    auto session = RpcSession::make();
+    CHECK(session->setProtocolVersion(version));
+    CHECK_EQ(OK, session->addNullDebuggingClient());
+    p->markForRpc(session);
+}
+
+static std::string buildRepr(uint32_t version) {
+    std::string result;
+    for (size_t i = 0; i < kFillFuns.size(); i++) {
+        if (i != 0) result += "|";
+        Parcel p;
+        setParcelForRpc(&p, version);
+        kFillFuns[i](&p);
+
+        result += base::HexString(p.data(), p.dataSize());
+    }
+    return result;
+}
+
+static void checkRepr(const std::string& repr, uint32_t version) {
+    const std::string actualRepr = buildRepr(version);
+
+    auto expected = base::Split(repr, "|");
+    ASSERT_EQ(expected.size(), kFillFuns.size());
+
+    auto actual = base::Split(actualRepr, "|");
+    ASSERT_EQ(actual.size(), kFillFuns.size());
+
+    for (size_t i = 0; i < kFillFuns.size(); i++) {
+        EXPECT_EQ(expected[i], actual[i])
+                << "Format mismatch, see " __FILE__ " line " << (kFillFunIndexLineBase + i);
+    }
+
+    // same check as in the loop, but the above error is more clear to debug,
+    // and this error is more clear to be able to update the source file here.
+    EXPECT_EQ(repr, actualRepr);
+}
+
+const std::string kCurrentRepr =
+        "0300000074006f006b000000|ffffffff|00000000|11000000|00000000|01000000|13270000|"
+        "ffffffffffffffff|0000000000000000|1100000000000000|0000000000000000|0100000000000000|"
+        "1327000000000000|00000000|cdcccc3d|9a991141|0000000000000000|9a9999999999b93f|"
+        "3333333333332240|00000000|61000000|6261626100000000|0000000000000000|0100000061000000|"
+        "040000006261626100000000|0000000000000000|0100000061000000|"
+        "04000000620061006200610000000000|0000000000000000|03000000ffffffff0000000011000000|"
+        "030000000011ff00|01000000|00000000|61000000|3f000000|00000000|80ffffff|00000000|7f000000|"
+        "0000000000000000|0100000061000000|04000000610062006100620000000000|ffffffff|"
+        "0000000000000000|0100000061000000|04000000610062006100620000000000|ffffffff|"
+        "03000000ff001100|00000000|03000000ff001100|ffffffff|0300000000011100|00000000|"
+        "0300000000011100|ffffffff|03000000ffffffff0000000011000000|00000000|"
+        "03000000ffffffff0000000011000000|ffffffff|"
+        "03000000ffffffffffffffff00000000000000001100000000000000|00000000|"
+        "03000000ffffffffffffffff00000000000000001100000000000000|ffffffff|"
+        "03000000000000000000000001000000000000001100000000000000|00000000|"
+        "03000000000000000000000001000000000000001100000000000000|ffffffff|"
+        "0300000000000000cdcccc3d9a991141|00000000|0300000000000000cdcccc3d9a991141|ffffffff|"
+        "0300000000000000000000009a9999999999b93f3333333333332240|00000000|"
+        "0300000000000000000000009a9999999999b93f3333333333332240|ffffffff|"
+        "020000000100000000000000|00000000|020000000100000000000000|ffffffff|"
+        "0300000061000000000000003f000000|00000000|0300000061000000000000003f000000|ffffffff|"
+        "03000000ffffffff00000000000000000100000061000000|00000000|"
+        "03000000ffffffff00000000000000000100000061000000|ffffffff|"
+        "03000000ffffffff00000000000000000100000061000000|00000000|"
+        "03000000ffffffff00000000000000000100000061000000|ffffffff|010000000000000000000000|"
+        "00000000|010000000000000000000000|ffffffff|0200000000010000|0200000000010000|ffffffff|"
+        "020000000000000001000000|020000000000000001000000|ffffffff|"
+        "0200000000000000000000000100000000000000|0200000000000000000000000100000000000000|"
+        "ffffffff|010000000100000025000000|010000000100000025000000|00000000|0100000025000000|"
+        "0100000025000000|03000000|00000000|ffffffff|03000000|00000000";
+
+TEST(RpcWire, CurrentVersion) {
+    checkRepr(kCurrentRepr, RPC_WIRE_PROTOCOL_VERSION);
+}
+
+static_assert(RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL,
+              "you better update this test!");
+
+TEST(RpcWire, ReleaseBranchHasFrozenRpcWireProtocol) {
+    if (RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) {
+        EXPECT_FALSE(base::GetProperty("ro.build.version.codename", "") == "REL")
+                << "Binder RPC wire protocol must be frozen on a release branch!";
+    }
+}
+
+TEST(RpcWire, IfNotExperimentalCodeHasNoExperimentalFeatures) {
+    if (RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) {
+        GTEST_SKIP() << "Version is experimental, so experimental features are okay.";
+    }
+
+    // if we set the wire protocol version to experimental, none of the code
+    // should introduce a difference (if this fails, it means we have features
+    // which are enabled under experimental mode, but we aren't actually using
+    // or testing them!)
+    checkRepr(kCurrentRepr, RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
+}
+
+} // namespace android
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index a0032ae..cda9e19 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -52,14 +52,14 @@
     ],
 
     shared_libs: [
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libhidlbase",
         "liblog",
     ],
 
     export_shared_lib_headers: [
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libhidlbase",
     ],
diff --git a/libs/input/VelocityControl.cpp b/libs/input/VelocityControl.cpp
index bcf55b0..03c49cc 100644
--- a/libs/input/VelocityControl.cpp
+++ b/libs/input/VelocityControl.cpp
@@ -18,7 +18,7 @@
 //#define LOG_NDEBUG 0
 
 // Log debug messages about acceleration.
-#define DEBUG_ACCELERATION 0
+static constexpr bool DEBUG_ACCELERATION = false;
 
 #include <math.h>
 #include <limits.h>
@@ -52,10 +52,10 @@
 void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
     if ((deltaX && *deltaX) || (deltaY && *deltaY)) {
         if (eventTime >= mLastMovementTime + STOP_TIME) {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
-                    (eventTime - mLastMovementTime) * 0.000001f);
-#endif
+            if (DEBUG_ACCELERATION && mLastMovementTime != LLONG_MIN) {
+                ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
+                           (eventTime - mLastMovementTime) * 0.000001f);
+            }
             reset();
         }
 
@@ -83,19 +83,20 @@
                         * (mParameters.acceleration - 1);
             }
 
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
-                    "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration,
-                    vx, vy, speed, scale / mParameters.scale);
-#endif
+            if (DEBUG_ACCELERATION) {
+                ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
+                        "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
+                        mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
+                        mParameters.acceleration,
+                        vx, vy, speed, scale / mParameters.scale);
+            }
+
         } else {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration);
-#endif
+            if (DEBUG_ACCELERATION) {
+                ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
+                        mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
+                        mParameters.acceleration);
+            }
         }
 
         if (deltaX) {
diff --git a/libs/renderengine/OWNERS b/libs/renderengine/OWNERS
index c478506..5d23a5e 100644
--- a/libs/renderengine/OWNERS
+++ b/libs/renderengine/OWNERS
@@ -1,3 +1,4 @@
+adyabr@google.com
 alecmouri@google.com
 djsollen@google.com
 jreck@google.com
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 07760ab..26c874e 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -89,7 +89,7 @@
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.allocator@4.0",
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@2.1",
@@ -106,7 +106,7 @@
 
     export_shared_lib_headers: [
         "android.hardware.graphics.common@1.2",
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libgralloctypes",
     ],
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index cbdb1d0..bfdc02c 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -905,6 +905,13 @@
             mTiltXScale = M_PI / 180;
             mTiltYScale = M_PI / 180;
 
+            if (mRawPointerAxes.tiltX.resolution) {
+                mTiltXScale = 1.0 / mRawPointerAxes.tiltX.resolution;
+            }
+            if (mRawPointerAxes.tiltY.resolution) {
+                mTiltYScale = 1.0 / mRawPointerAxes.tiltY.resolution;
+            }
+
             mOrientedRanges.haveTilt = true;
 
             mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
diff --git a/services/memtrackproxy/Android.bp b/services/memtrackproxy/Android.bp
index 7d78f3b..3233cc9 100644
--- a/services/memtrackproxy/Android.bp
+++ b/services/memtrackproxy/Android.bp
@@ -32,7 +32,7 @@
         "libcutils",
         "libutils",
         "android.hardware.memtrack@1.0",
-        "android.hardware.memtrack-V1-ndk_platform",
+        "android.hardware.memtrack-V1-ndk",
     ],
     srcs: [
         "MemtrackProxy.cpp",
@@ -45,6 +45,6 @@
     ],
     export_shared_lib_headers: [
         "android.hardware.memtrack@1.0",
-        "android.hardware.memtrack-V1-ndk_platform",
+        "android.hardware.memtrack-V1-ndk",
     ],
 }
diff --git a/services/memtrackproxy/test/Android.bp b/services/memtrackproxy/test/Android.bp
index f943761..1dc21bf 100644
--- a/services/memtrackproxy/test/Android.bp
+++ b/services/memtrackproxy/test/Android.bp
@@ -29,7 +29,7 @@
     shared_libs: [
         "libbinder_ndk",
         "libmemtrackproxy",
-        "android.hardware.memtrack-V1-ndk_platform",
+        "android.hardware.memtrack-V1-ndk",
     ],
     test_suites: ["general-tests"],
     require_root: true,
diff --git a/services/surfaceflinger/TimeStats/OWNERS b/services/surfaceflinger/TimeStats/OWNERS
index ded3ebb..d78f5e2 100644
--- a/services/surfaceflinger/TimeStats/OWNERS
+++ b/services/surfaceflinger/TimeStats/OWNERS
@@ -1 +1,2 @@
+adyabr@google.com
 alecmouri@google.com
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 15744a1..81e39c7 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -53,7 +53,7 @@
         "libtrace_proto",
     ],
     shared_libs: [
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.composer@2.1",
         "libandroid",