Merge "Reland "libbinder: ignore CallRestriction for magic 0 cmd""
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 9675a53..d363ee9 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -99,6 +99,7 @@
         "MemoryDealer.cpp",
         "MemoryHeapBase.cpp",
         "Parcel.cpp",
+        "ParcelableHolder.cpp",
         "ParcelFileDescriptor.cpp",
         "PersistableBundle.cpp",
         "ProcessState.cpp",
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 33e7d47..05fcc2b 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -1328,6 +1328,22 @@
         }
 }
 
+status_t IPCThreadState::getProcessFreezeInfo(pid_t pid, bool *sync_received, bool *async_received)
+{
+    int ret = 0;
+    binder_frozen_status_info info;
+    info.pid = pid;
+
+#if defined(__ANDROID__)
+    if (ioctl(self()->mProcess->mDriverFD, BINDER_GET_FROZEN_INFO, &info) < 0)
+        ret = -errno;
+#endif
+    *sync_received = info.sync_recv;
+    *async_received = info.async_recv;
+
+    return ret;
+}
+
 status_t IPCThreadState::freeze(pid_t pid, bool enable, uint32_t timeout_ms) {
     struct binder_freeze_info info;
     int ret = 0;
diff --git a/libs/binder/ParcelableHolder.cpp b/libs/binder/ParcelableHolder.cpp
new file mode 100644
index 0000000..e9df279
--- /dev/null
+++ b/libs/binder/ParcelableHolder.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 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/Parcelable.h>
+#include <binder/ParcelableHolder.h>
+
+#define RETURN_ON_FAILURE(expr)                     \
+    do {                                            \
+        android::status_t _status = (expr);         \
+        if (_status != android::OK) return _status; \
+    } while (false)
+
+namespace android {
+namespace os {
+status_t ParcelableHolder::writeToParcel(Parcel* p) const {
+    std::lock_guard<std::mutex> l(mMutex);
+    RETURN_ON_FAILURE(p->writeInt32(static_cast<int32_t>(this->getStability())));
+    if (this->mParcelPtr) {
+        RETURN_ON_FAILURE(p->writeInt32(this->mParcelPtr->dataSize()));
+        RETURN_ON_FAILURE(p->appendFrom(this->mParcelPtr.get(), 0, this->mParcelPtr->dataSize()));
+        return OK;
+    }
+    if (this->mParcelable) {
+        size_t sizePos = p->dataPosition();
+        RETURN_ON_FAILURE(p->writeInt32(0));
+        size_t dataStartPos = p->dataPosition();
+        RETURN_ON_FAILURE(p->writeUtf8AsUtf16(this->mParcelableName));
+        this->mParcelable->writeToParcel(p);
+        size_t dataSize = p->dataPosition() - dataStartPos;
+
+        p->setDataPosition(sizePos);
+        RETURN_ON_FAILURE(p->writeInt32(dataSize));
+        p->setDataPosition(p->dataPosition() + dataSize);
+        return OK;
+    }
+
+    RETURN_ON_FAILURE(p->writeInt32(0));
+    return OK;
+}
+
+status_t ParcelableHolder::readFromParcel(const Parcel* p) {
+    std::lock_guard<std::mutex> l(mMutex);
+    this->mStability = static_cast<Stability>(p->readInt32());
+    this->mParcelable = nullptr;
+    this->mParcelableName = std::nullopt;
+    int32_t rawDataSize;
+
+    status_t status = p->readInt32(&rawDataSize);
+    if (status != android::OK || rawDataSize < 0) {
+        this->mParcelPtr = nullptr;
+        return status != android::OK ? status : BAD_VALUE;
+    }
+    if (rawDataSize == 0) {
+        if (this->mParcelPtr) {
+            this->mParcelPtr = nullptr;
+        }
+        return OK;
+    }
+
+    size_t dataSize = rawDataSize;
+
+    size_t dataStartPos = p->dataPosition();
+
+    if (dataStartPos > SIZE_MAX - dataSize) {
+        this->mParcelPtr = nullptr;
+        return BAD_VALUE;
+    }
+
+    if (!this->mParcelPtr) {
+        this->mParcelPtr = std::make_unique<Parcel>();
+    }
+    this->mParcelPtr->freeData();
+
+    status = this->mParcelPtr->appendFrom(p, dataStartPos, dataSize);
+    if (status != android::OK) {
+        this->mParcelPtr = nullptr;
+        return status;
+    }
+    p->setDataPosition(dataStartPos + dataSize);
+    return OK;
+}
+} // namespace os
+} // namespace android
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 867d307..49ef253 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -51,6 +51,9 @@
     // returns: 0 in case of success, a value < 0 in case of error
     static  status_t            freeze(pid_t pid, bool enabled, uint32_t timeout_ms);
 
+    // Provide information about the state of a frozen process
+    static  status_t            getProcessFreezeInfo(pid_t pid, bool *sync_received,
+                                                    bool *async_received);
             sp<ProcessState>    process();
             
             status_t            clearLastError();
diff --git a/libs/binder/include/binder/Parcelable.h b/libs/binder/include/binder/Parcelable.h
index 83c2f19..a6e610c 100644
--- a/libs/binder/include/binder/Parcelable.h
+++ b/libs/binder/include/binder/Parcelable.h
@@ -56,7 +56,7 @@
     // WARNING: for use by auto-generated code only (AIDL). Should not be used
     // manually, or there is a risk of breaking CTS, GTS, VTS, or CTS-on-GSI
     // tests.
-    enum class Stability {
+    enum class Stability : int32_t {
         STABILITY_LOCAL,
         STABILITY_VINTF, // corresponds to @VintfStability
     };
diff --git a/libs/binder/include/binder/ParcelableHolder.h b/libs/binder/include/binder/ParcelableHolder.h
new file mode 100644
index 0000000..b6814aa
--- /dev/null
+++ b/libs/binder/include/binder/ParcelableHolder.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <mutex>
+#include <optional>
+#include <tuple>
+
+namespace android {
+namespace os {
+/*
+ * C++ implementation of the Java class android.os.ParcelableHolder
+ */
+class ParcelableHolder : public android::Parcelable {
+public:
+    ParcelableHolder() = delete;
+    explicit ParcelableHolder(Stability stability) : mStability(stability){};
+    virtual ~ParcelableHolder() = default;
+    ParcelableHolder(const ParcelableHolder& other) {
+        mParcelable = other.mParcelable;
+        mParcelableName = other.mParcelableName;
+        if (other.mParcelPtr) {
+            mParcelPtr = std::make_unique<Parcel>();
+            mParcelPtr->appendFrom(other.mParcelPtr.get(), 0, other.mParcelPtr->dataSize());
+        }
+        mStability = other.mStability;
+    };
+
+    status_t writeToParcel(Parcel* parcel) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+    void reset() {
+        this->mParcelable = nullptr;
+        this->mParcelableName = std::nullopt;
+        this->mParcelPtr = nullptr;
+    }
+
+    template <typename T>
+    bool setParcelable(T&& p) {
+        using Tt = typename std::decay<T>::type;
+        return setParcelable<Tt>(std::make_shared<Tt>(std::forward<T>(p)));
+    }
+
+    template <typename T>
+    bool setParcelable(std::shared_ptr<T> p) {
+        std::lock_guard<std::mutex> l(mMutex);
+        static_assert(std::is_base_of<Parcelable, T>::value, "T must be derived from Parcelable");
+        if (p && this->getStability() > p->getStability()) {
+            return false;
+        }
+        this->mParcelable = p;
+        this->mParcelableName = T::getParcelableDescriptor();
+        this->mParcelPtr = nullptr;
+        return true;
+    }
+
+    template <typename T>
+    std::shared_ptr<T> getParcelable() const {
+        static_assert(std::is_base_of<Parcelable, T>::value, "T must be derived from Parcelable");
+        std::lock_guard<std::mutex> l(mMutex);
+        const std::string& parcelableDesc = T::getParcelableDescriptor();
+        if (!this->mParcelPtr) {
+            if (!this->mParcelable || !this->mParcelableName) {
+                ALOGD("empty ParcelableHolder");
+                return nullptr;
+            } else if (parcelableDesc != *mParcelableName) {
+                ALOGD("extension class name mismatch expected:%s actual:%s",
+                      mParcelableName->c_str(), parcelableDesc.c_str());
+                return nullptr;
+            }
+            return std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+        }
+        this->mParcelPtr->setDataPosition(0);
+        status_t status = this->mParcelPtr->readUtf8FromUtf16(&this->mParcelableName);
+        if (status != android::OK || parcelableDesc != this->mParcelableName) {
+            this->mParcelableName = std::nullopt;
+            return nullptr;
+        }
+        this->mParcelable = std::make_shared<T>();
+        status = mParcelable.get()->readFromParcel(this->mParcelPtr.get());
+        if (status != android::OK) {
+            this->mParcelableName = std::nullopt;
+            this->mParcelable = nullptr;
+            return nullptr;
+        }
+        this->mParcelPtr = nullptr;
+        return std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+    }
+
+    Stability getStability() const override { return mStability; };
+
+    inline bool operator!=(const ParcelableHolder& rhs) const {
+        return std::tie(mParcelable, mParcelPtr, mStability) !=
+                std::tie(rhs.mParcelable, rhs.mParcelPtr, rhs.mStability);
+    }
+    inline bool operator<(const ParcelableHolder& rhs) const {
+        return std::tie(mParcelable, mParcelPtr, mStability) <
+                std::tie(rhs.mParcelable, rhs.mParcelPtr, rhs.mStability);
+    }
+    inline bool operator<=(const ParcelableHolder& rhs) const {
+        return std::tie(mParcelable, mParcelPtr, mStability) <=
+                std::tie(rhs.mParcelable, rhs.mParcelPtr, rhs.mStability);
+    }
+    inline bool operator==(const ParcelableHolder& rhs) const {
+        return std::tie(mParcelable, mParcelPtr, mStability) ==
+                std::tie(rhs.mParcelable, rhs.mParcelPtr, rhs.mStability);
+    }
+    inline bool operator>(const ParcelableHolder& rhs) const {
+        return std::tie(mParcelable, mParcelPtr, mStability) >
+                std::tie(rhs.mParcelable, rhs.mParcelPtr, rhs.mStability);
+    }
+    inline bool operator>=(const ParcelableHolder& rhs) const {
+        return std::tie(mParcelable, mParcelPtr, mStability) >=
+                std::tie(rhs.mParcelable, rhs.mParcelPtr, rhs.mStability);
+    }
+
+private:
+    mutable std::shared_ptr<Parcelable> mParcelable;
+    mutable std::optional<std::string> mParcelableName;
+    mutable std::unique_ptr<Parcel> mParcelPtr;
+    Stability mStability;
+    mutable std::mutex mMutex;
+};
+} // namespace os
+} // namespace android
diff --git a/libs/binder/include/private/binder/binder_module.h b/libs/binder/include/private/binder/binder_module.h
index 7898928..7be8f7b 100644
--- a/libs/binder/include/private/binder/binder_module.h
+++ b/libs/binder/include/private/binder/binder_module.h
@@ -66,6 +66,29 @@
 };
 #endif //BINDER_FREEZE
 
+#ifndef BINDER_GET_FROZEN_INFO
+
+#define BINDER_GET_FROZEN_INFO          _IOWR('b', 15, struct binder_frozen_status_info)
+
+struct binder_frozen_status_info {
+    //
+    // Group-leader PID of process to be queried
+    //
+    __u32            pid;
+    //
+    // Indicates whether the process has received any sync calls since last
+    // freeze (cleared at freeze/unfreeze)
+    //
+    __u32            sync_recv;
+    //
+    // Indicates whether the process has received any async calls since last
+    // freeze (cleared at freeze/unfreeze)
+    //
+    __u32            async_recv;
+};
+#endif //BINDER_GET_FROZEN_INFO
+
+
 
 #ifdef __cplusplus
 }   // namespace android
diff --git a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
index f44ce0c..a4f4441 100644
--- a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
@@ -93,7 +93,7 @@
     //
     // Use 'SharedRefBase::make<T>(...)' to make. SharedRefBase has implicit
     // ownership. Making this operator private to avoid double-ownership.
-#if !defined(__ANDROID_API__) || __ANDROID_API__ >= 30
+#if !defined(__ANDROID_API__) || __ANDROID_API__ >= 30 || defined(__ANDROID_APEX__)
    private:
 #else
     [[deprecated("Prefer SharedRefBase::make<T>(...) if possible.")]]
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index ceb6ade..81a5f02 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -590,6 +590,15 @@
                 f.pad(stringify!($interface))
             }
         }
+
+        // Convert a &dyn $interface to Box<dyn $interface>
+        impl std::borrow::ToOwned for dyn $interface {
+            type Owned = Box<dyn $interface>;
+            fn to_owned(&self) -> Self::Owned {
+                self.as_binder().into_interface()
+                    .expect(concat!("Error cloning interface ", stringify!($interface)))
+            }
+        }
     };
 }
 
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 145c099..98f0868 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -432,6 +432,15 @@
     EXPECT_EQ(-EAGAIN, IPCThreadState::self()->freeze(pid, 1, 0));
     EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, 1, 1000));
     EXPECT_EQ(FAILED_TRANSACTION, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply));
+
+    bool sync_received, async_received;
+
+    EXPECT_EQ(NO_ERROR, IPCThreadState::self()->getProcessFreezeInfo(pid, &sync_received,
+                &async_received));
+
+    EXPECT_EQ(sync_received, 1);
+    EXPECT_EQ(async_received, 0);
+
     EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, 0, 0));
     EXPECT_EQ(NO_ERROR, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply));
 }
diff --git a/libs/gralloc/types/Gralloc4.cpp b/libs/gralloc/types/Gralloc4.cpp
index 53c68b7..e2f072a 100644
--- a/libs/gralloc/types/Gralloc4.cpp
+++ b/libs/gralloc/types/Gralloc4.cpp
@@ -706,35 +706,35 @@
         return err;
     }
 
-    err = encodeInteger<int64_t>(static_cast<int32_t>(input.offsetInBytes), output);
+    err = encodeInteger<int64_t>(static_cast<int64_t>(input.offsetInBytes), output);
     if (err) {
         return err;
     }
-    err = encodeInteger<int64_t>(static_cast<int32_t>(input.sampleIncrementInBits), output);
+    err = encodeInteger<int64_t>(static_cast<int64_t>(input.sampleIncrementInBits), output);
     if (err) {
         return err;
     }
-    err = encodeInteger<int64_t>(static_cast<int32_t>(input.strideInBytes), output);
+    err = encodeInteger<int64_t>(static_cast<int64_t>(input.strideInBytes), output);
     if (err) {
         return err;
     }
-    err = encodeInteger<int64_t>(static_cast<int32_t>(input.widthInSamples), output);
+    err = encodeInteger<int64_t>(static_cast<int64_t>(input.widthInSamples), output);
     if (err) {
         return err;
     }
-    err = encodeInteger<int64_t>(static_cast<int32_t>(input.heightInSamples), output);
+    err = encodeInteger<int64_t>(static_cast<int64_t>(input.heightInSamples), output);
     if (err) {
         return err;
     }
-    err = encodeInteger<int64_t>(static_cast<int32_t>(input.totalSizeInBytes), output);
+    err = encodeInteger<int64_t>(static_cast<int64_t>(input.totalSizeInBytes), output);
     if (err) {
         return err;
     }
-    err = encodeInteger<int64_t>(static_cast<int32_t>(input.horizontalSubsampling), output);
+    err = encodeInteger<int64_t>(static_cast<int64_t>(input.horizontalSubsampling), output);
     if (err) {
         return err;
     }
-    return encodeInteger<int64_t>(static_cast<int32_t>(input.verticalSubsampling), output);
+    return encodeInteger<int64_t>(static_cast<int64_t>(input.verticalSubsampling), output);
 }
 
 status_t decodePlaneLayout(InputHidlVec* input, PlaneLayout* output) {
diff --git a/services/gpuservice/Android.bp b/services/gpuservice/Android.bp
index 6eed24a..4da6db3 100644
--- a/services/gpuservice/Android.bp
+++ b/services/gpuservice/Android.bp
@@ -42,11 +42,11 @@
     defaults: ["libgpuservice_defaults"],
     cflags: [
         "-fvisibility=hidden",
-        "-fwhole-program-vtables", // requires ThinLTO
     ],
     lto: {
         thin: true,
     },
+    whole_program_vtables: true, // Requires ThinLTO
 }
 
 filegroup {
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index a790d0b..bdd04db 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -108,11 +108,11 @@
     defaults: ["libsurfaceflinger_defaults"],
     cflags: [
         "-fvisibility=hidden",
-        "-fwhole-program-vtables", // requires ThinLTO
     ],
     lto: {
         thin: true,
     },
+    whole_program_vtables: true, // Requires ThinLTO
     // TODO(b/131771163): Fix broken fuzzer support with LTO.
     sanitize: {
         fuzzer: false,