Merge "libbinder: no 'okay' EX_TRANSACTION_FAILED"
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 73098f8..28c7658 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -361,12 +361,11 @@
}
std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa);
- if (access(preopted_boot_art_path.c_str(), F_OK) == 0) {
- return PatchoatBootImage(isa_path, isa);
- } else {
+ if (access(preopted_boot_art_path.c_str(), F_OK) != 0) {
// No preopted boot image. Try to compile.
return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa);
}
+ return true;
}
static bool CreatePath(const std::string& path) {
@@ -431,29 +430,6 @@
CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
}
- bool PatchoatBootImage(const std::string& output_dir, const char* isa) const {
- // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
-
- std::vector<std::string> cmd;
- cmd.push_back("/system/bin/patchoat");
-
- cmd.push_back("--input-image-location=/system/framework/boot.art");
- cmd.push_back(StringPrintf("--output-image-directory=%s", output_dir.c_str()));
-
- cmd.push_back(StringPrintf("--instruction-set=%s", isa));
-
- int32_t base_offset = ChooseRelocationOffsetDelta(art::GetImageMinBaseAddressDelta(),
- art::GetImageMaxBaseAddressDelta());
- cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset));
-
- std::string error_msg;
- bool result = Exec(cmd, &error_msg);
- if (!result) {
- LOG(ERROR) << "Could not generate boot image: " << error_msg;
- }
- return result;
- }
-
bool Dex2oatBootImage(const std::string& boot_cp,
const std::string& art_path,
const std::string& oat_path,
diff --git a/headers/media_plugin/media/arcvideobridge/IArcVideoBridge.h b/headers/media_plugin/media/arcvideobridge/IArcVideoBridge.h
deleted file mode 100644
index b32c92e..0000000
--- a/headers/media_plugin/media/arcvideobridge/IArcVideoBridge.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2016 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 ANDROID_IARC_VIDEO_BRIDGE_H
-#define ANDROID_IARC_VIDEO_BRIDGE_H
-
-#include <arc/IArcBridgeService.h>
-#include <binder/IInterface.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-class IArcVideoBridge : public IInterface {
-public:
- DECLARE_META_INTERFACE(ArcVideoBridge);
-
- // Returns MojoBootstrapResult for creating mojo ipc channel of
- // VideoAcceleratorFactory.
- virtual ::arc::MojoBootstrapResult bootstrapVideoAcceleratorFactory() = 0;
-
- // Get the version of the remote VideoHost on Chromium side.
- virtual int32_t hostVersion() = 0;
-};
-
-class BnArcVideoBridge : public BnInterface<IArcVideoBridge> {
-public:
- virtual status_t onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IARC_VIDEO_BRIDGE_H
diff --git a/libs/binder/include/binder/ParcelFileDescriptor.h b/libs/binder/include/binder/ParcelFileDescriptor.h
index 455462b..ad950af 100644
--- a/libs/binder/include/binder/ParcelFileDescriptor.h
+++ b/libs/binder/include/binder/ParcelFileDescriptor.h
@@ -31,6 +31,7 @@
public:
ParcelFileDescriptor();
explicit ParcelFileDescriptor(android::base::unique_fd fd);
+ explicit ParcelFileDescriptor(ParcelFileDescriptor&& other) : mFd(std::move(other.mFd)) { }
~ParcelFileDescriptor() override;
int get() const { return mFd.get(); }
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
new file mode 100644
index 0000000..d947e7b
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_auto_utils.h
+ * @brief These objects provide a more C++-like thin interface to the .
+ */
+
+#pragma once
+
+#include <android/binder_ibinder.h>
+#include <android/binder_parcel.h>
+#include <android/binder_status.h>
+
+#ifdef __cplusplus
+
+#include <cstddef>
+
+namespace ndk {
+
+/**
+ * Represents one strong pointer to an AIBinder object.
+ */
+class SpAIBinder {
+public:
+ /**
+ * Takes ownership of one strong refcount of binder.
+ */
+ explicit SpAIBinder(AIBinder* binder = nullptr) : mBinder(binder) {}
+
+ /**
+ * Convenience operator for implicitly constructing an SpAIBinder from nullptr. This is not
+ * explicit because it is not taking ownership of anything.
+ */
+ SpAIBinder(std::nullptr_t) : SpAIBinder() {}
+
+ /**
+ * This will delete the underlying object if it exists. See operator=.
+ */
+ SpAIBinder(const SpAIBinder& other) { *this = other; }
+
+ /**
+ * This deletes the underlying object if it exists. See set.
+ */
+ ~SpAIBinder() { set(nullptr); }
+
+ /**
+ * This takes ownership of a binder from another AIBinder object but it does not affect the
+ * ownership of that other object.
+ */
+ SpAIBinder& operator=(const SpAIBinder& other) {
+ AIBinder_incStrong(other.mBinder);
+ set(other.mBinder);
+ return *this;
+ }
+
+ /**
+ * Takes ownership of one strong refcount of binder
+ */
+ void set(AIBinder* binder) {
+ if (mBinder != nullptr) AIBinder_decStrong(mBinder);
+ mBinder = binder;
+ }
+
+ /**
+ * This returns the underlying binder object for transactions. If it is used to create another
+ * SpAIBinder object, it should first be incremented.
+ */
+ AIBinder* get() const { return mBinder; }
+
+ /**
+ * This allows the value in this class to be set from beneath it. If you call this method and
+ * then change the value of T*, you must take ownership of the value you are replacing and add
+ * ownership to the object that is put in here.
+ *
+ * Recommended use is like this:
+ * SpAIBinder a; // will be nullptr
+ * SomeInitFunction(a.getR()); // value is initialized with refcount
+ *
+ * Other usecases are discouraged.
+ *
+ */
+ AIBinder** getR() { return &mBinder; }
+
+private:
+ AIBinder* mBinder = nullptr;
+};
+
+/**
+ * This baseclass owns a single object, used to make various classes RAII.
+ */
+template <typename T, void (*Destroy)(T*)>
+class ScopedAResource {
+public:
+ /**
+ * Takes ownership of t.
+ */
+ explicit ScopedAResource(T* t = nullptr) : mT(t) {}
+
+ /**
+ * This deletes the underlying object if it exists. See set.
+ */
+ ~ScopedAResource() { set(nullptr); }
+
+ /**
+ * Takes ownership of t.
+ */
+ void set(T* t) {
+ Destroy(mT);
+ mT = t;
+ }
+
+ /**
+ * This returns the underlying object to be modified but does not affect ownership.
+ */
+ T* get() { return mT; }
+
+ /**
+ * This returns the const underlying object but does not affect ownership.
+ */
+ const T* get() const { return mT; }
+
+ /**
+ * This allows the value in this class to be set from beneath it. If you call this method and
+ * then change the value of T*, you must take ownership of the value you are replacing and add
+ * ownership to the object that is put in here.
+ *
+ * Recommended use is like this:
+ * ScopedAResource<T> a; // will be nullptr
+ * SomeInitFunction(a.getR()); // value is initialized with refcount
+ *
+ * Other usecases are discouraged.
+ *
+ */
+ T** getR() { return &mT; }
+
+ // copy-constructing, or move/copy assignment is disallowed
+ ScopedAResource(const ScopedAResource&) = delete;
+ ScopedAResource& operator=(const ScopedAResource&) = delete;
+ ScopedAResource& operator=(ScopedAResource&&) = delete;
+
+ // move-constructing is okay
+ ScopedAResource(ScopedAResource&&) = default;
+
+private:
+ T* mT;
+};
+
+/**
+ * Convenience wrapper. See AParcel.
+ */
+class ScopedAParcel : public ScopedAResource<AParcel, AParcel_delete> {
+public:
+ /**
+ * Takes ownership of a.
+ */
+ explicit ScopedAParcel(AParcel* a = nullptr) : ScopedAResource(a) {}
+ ~ScopedAParcel() {}
+ ScopedAParcel(ScopedAParcel&&) = default;
+};
+
+/**
+ * Convenience wrapper. See AStatus.
+ */
+class ScopedAStatus : public ScopedAResource<AStatus, AStatus_delete> {
+public:
+ /**
+ * Takes ownership of a.
+ */
+ explicit ScopedAStatus(AStatus* a = nullptr) : ScopedAResource(a) {}
+ ~ScopedAStatus() {}
+ ScopedAStatus(ScopedAStatus&&) = default;
+
+ /**
+ * See AStatus_isOk.
+ */
+ bool isOk() { return get() != nullptr && AStatus_isOk(get()); }
+};
+
+/**
+ * Convenience wrapper. See AIBinder_DeathRecipient.
+ */
+class ScopedAIBinder_DeathRecipient
+ : public ScopedAResource<AIBinder_DeathRecipient, AIBinder_DeathRecipient_delete> {
+public:
+ /**
+ * Takes ownership of a.
+ */
+ explicit ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient* a = nullptr)
+ : ScopedAResource(a) {}
+ ~ScopedAIBinder_DeathRecipient() {}
+ ScopedAIBinder_DeathRecipient(ScopedAIBinder_DeathRecipient&&) = default;
+};
+
+/**
+ * Convenience wrapper. See AIBinder_Weak.
+ */
+class ScopedAIBinder_Weak : public ScopedAResource<AIBinder_Weak, AIBinder_Weak_delete> {
+public:
+ /**
+ * Takes ownership of a.
+ */
+ explicit ScopedAIBinder_Weak(AIBinder_Weak* a = nullptr) : ScopedAResource(a) {}
+ ~ScopedAIBinder_Weak() {}
+ ScopedAIBinder_Weak(ScopedAIBinder_Weak&&) = default;
+
+ /**
+ * See AIBinder_Weak_promote.
+ */
+ SpAIBinder promote() { return SpAIBinder(AIBinder_Weak_promote(get())); }
+};
+
+} // namespace ndk
+
+#endif // __cplusplus
+
+/** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
new file mode 100644
index 0000000..5a4196a
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_interface_utils.h
+ * @brief This provides common C++ classes for common operations and as base classes for C++
+ * interfaces.
+ */
+
+#pragma once
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder.h>
+
+#ifdef __cplusplus
+
+#include <memory>
+#include <mutex>
+
+namespace ndk {
+
+/**
+ * analog using std::shared_ptr for internally held refcount
+ */
+class SharedRefBase {
+public:
+ SharedRefBase() {}
+ virtual ~SharedRefBase() {}
+
+ /**
+ * A shared_ptr must be held to this object when this is called. This must be called once during
+ * the lifetime of this object.
+ */
+ std::shared_ptr<SharedRefBase> ref() {
+ std::shared_ptr<SharedRefBase> thiz = mThis.lock();
+
+ std::call_once(mFlagThis, [&]() { mThis = thiz = std::shared_ptr<SharedRefBase>(this); });
+
+ return thiz;
+ }
+
+ /**
+ * Convenience method for a ref (see above) which automatically casts to the desired child type.
+ */
+ template <typename CHILD>
+ std::shared_ptr<CHILD> ref() {
+ return std::static_pointer_cast<CHILD>(ref());
+ }
+
+ /**
+ * Convenience method for making an object directly with a reference.
+ */
+ template<class T, class... Args>
+ static std::shared_ptr<T> make(Args&&... args) {
+ T* t = new T(std::forward<Args>(args)...);
+ return t->template ref<T>();
+ }
+
+private:
+ std::once_flag mFlagThis;
+ std::weak_ptr<SharedRefBase> mThis;
+};
+
+/**
+ * wrapper analog to IInterface
+ */
+class ICInterface : public SharedRefBase {
+public:
+ ICInterface() {}
+ virtual ~ICInterface() {}
+
+ /**
+ * This either returns the single existing implementation or creates a new implementation.
+ */
+ virtual SpAIBinder asBinder() = 0;
+
+ /**
+ * Returns whether this interface is in a remote process. If it cannot be determined locally,
+ * this will be checked using AIBinder_isRemote.
+ */
+ virtual bool isRemote() = 0;
+};
+
+/**
+ * implementation of IInterface for server (n = native)
+ */
+template <typename INTERFACE>
+class BnCInterface : public INTERFACE {
+public:
+ BnCInterface() {}
+ virtual ~BnCInterface() {}
+
+ SpAIBinder asBinder() override;
+
+ bool isRemote() override { return true; }
+
+protected:
+ /**
+ * This function should only be called by asBinder. Otherwise, there is a possibility of
+ * multiple AIBinder* objects being created for the same instance of an object.
+ */
+ virtual SpAIBinder createBinder() = 0;
+
+private:
+ std::mutex mMutex; // for asBinder
+ ScopedAIBinder_Weak mWeakBinder;
+};
+
+/**
+ * implementation of IInterface for client (p = proxy)
+ */
+template <typename INTERFACE>
+class BpCInterface : public INTERFACE {
+public:
+ BpCInterface(const SpAIBinder& binder) : mBinder(binder) {}
+ virtual ~BpCInterface() {}
+
+ SpAIBinder asBinder() override;
+
+ bool isRemote() override { return AIBinder_isRemote(mBinder.get()); }
+
+private:
+ SpAIBinder mBinder;
+};
+
+template <typename INTERFACE>
+SpAIBinder BnCInterface<INTERFACE>::asBinder() {
+ std::lock_guard<std::mutex> l(mMutex);
+
+ SpAIBinder binder;
+ if (mWeakBinder.get() != nullptr) {
+ binder.set(AIBinder_Weak_promote(mWeakBinder.get()));
+ }
+ if (binder.get() == nullptr) {
+ binder = createBinder();
+ mWeakBinder.set(AIBinder_Weak_new(binder.get()));
+ }
+
+ return binder;
+}
+
+template <typename INTERFACE>
+SpAIBinder BpCInterface<INTERFACE>::asBinder() {
+ return mBinder;
+}
+
+} // namespace ndk
+
+#endif // __cplusplus
+
+/** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index a3800da..0e97b50 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -88,6 +88,43 @@
binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status)
__INTRODUCED_IN(29);
+/**
+ * Writes string value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length)
+ __INTRODUCED_IN(29);
+
+/**
+ * This is called to allocate a buffer
+ *
+ * The length here includes the space required to insert a '\0' for a properly formed c-str. If the
+ * buffer returned from this function is retStr, it will be filled by AParcel_readString with the
+ * data from the remote process, and it will be filled such that retStr[length] == '\0'.
+ *
+ * If allocation fails, null should be returned.
+ */
+typedef void* (*AParcel_string_reallocator)(void* stringData, size_t length);
+
+/**
+ * This is called to get the buffer from a stringData object.
+ */
+typedef char* (*AParcel_string_getter)(void* stringData);
+
+/**
+ * Reads and allocates string value from the next location in a non-null parcel.
+ *
+ * Data is passed to the string allocator once the string size is known. This data should be used to
+ * point to some kind of string data. For instance, it could be a char*, and the string allocator
+ * could be realloc. Then the getter would simply be a cast to char*. In more complicated cases,
+ * stringData could be a structure containing additional string data.
+ *
+ * If this function returns a success, the buffer returned by allocator when passed stringData will
+ * contain a null-terminated c-str read from the binder.
+ */
+binder_status_t AParcel_readString(const AParcel* parcel, AParcel_string_reallocator reallocator,
+ AParcel_string_getter getter, void** stringData)
+ __INTRODUCED_IN(29);
+
// @START
/**
* Writes int32_t value to the next location in a non-null parcel.
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
new file mode 100644
index 0000000..d3e6cae
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_parcel_utils.h
+ * @brief A collection of helper wrappers for AParcel.
+ */
+
+#pragma once
+
+#include <android/binder_parcel.h>
+
+#ifdef __cplusplus
+
+#include <string>
+
+namespace ndk {
+
+/**
+ * Takes a std::string and reallocates it to the specified length. For use with AParcel_readString.
+ * See use below in AParcel_readString.
+ */
+static inline void* AParcel_std_string_reallocator(void* stringData, size_t length) {
+ std::string* str = static_cast<std::string*>(stringData);
+ str->resize(length - 1);
+ return stringData;
+}
+
+/**
+ * Takes a std::string and returns the inner char*.
+ */
+static inline char* AParcel_std_string_getter(void* stringData) {
+ std::string* str = static_cast<std::string*>(stringData);
+ return &(*str)[0];
+}
+
+/**
+ * Convenience API for writing a std::string.
+ */
+static inline binder_status_t AParcel_writeString(AParcel* parcel, const std::string& str) {
+ return AParcel_writeString(parcel, str.c_str(), str.size());
+}
+
+/**
+ * Convenience API for reading a std::string.
+ */
+static inline binder_status_t AParcel_readString(const AParcel* parcel, std::string* str) {
+ void* stringData = static_cast<void*>(str);
+ return AParcel_readString(parcel, AParcel_std_string_reallocator, AParcel_std_string_getter,
+ &stringData);
+}
+
+} // namespace ndk
+
+#endif // __cplusplus
+
+/** @} */
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 4f486c9..2a1bff1 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -32,6 +32,7 @@
AParcel_readInt64;
AParcel_readNullableStrongBinder;
AParcel_readStatusHeader;
+ AParcel_readString;
AParcel_readStrongBinder;
AParcel_readUint32;
AParcel_readUint64;
@@ -43,6 +44,7 @@
AParcel_writeInt32;
AParcel_writeInt64;
AParcel_writeStatusHeader;
+ AParcel_writeString;
AParcel_writeStrongBinder;
AParcel_writeUint32;
AParcel_writeUint64;
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 385e898..3e03e90 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -20,7 +20,11 @@
#include "ibinder_internal.h"
#include "status_internal.h"
+#include <limits>
+
+#include <android-base/logging.h>
#include <binder/Parcel.h>
+#include <utils/Unicode.h>
using ::android::IBinder;
using ::android::Parcel;
@@ -69,6 +73,67 @@
return ret;
}
+binder_status_t AParcel_writeString(AParcel* parcel, const char* string, size_t length) {
+ const uint8_t* str8 = (uint8_t*)string;
+
+ const ssize_t len16 = utf8_to_utf16_length(str8, length);
+
+ if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) {
+ LOG(WARNING) << __func__ << ": Invalid string length: " << len16;
+ return STATUS_BAD_VALUE;
+ }
+
+ status_t err = parcel->get()->writeInt32(len16);
+ if (err) {
+ return PruneStatusT(err);
+ }
+
+ void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t));
+ if (str16 == nullptr) {
+ return STATUS_NO_MEMORY;
+ }
+
+ utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1);
+
+ return STATUS_OK;
+}
+
+binder_status_t AParcel_readString(const AParcel* parcel, AParcel_string_reallocator reallocator,
+ AParcel_string_getter getter, void** stringData) {
+ size_t len16;
+ const char16_t* str16 = parcel->get()->readString16Inplace(&len16);
+
+ if (str16 == nullptr) {
+ LOG(WARNING) << __func__ << ": Failed to read string in place.";
+ return STATUS_UNEXPECTED_NULL;
+ }
+
+ ssize_t len8;
+
+ if (len16 == 0) {
+ len8 = 1;
+ } else {
+ len8 = utf16_to_utf8_length(str16, len16) + 1;
+ }
+
+ if (len8 <= 0 || len8 >= std::numeric_limits<int32_t>::max()) {
+ LOG(WARNING) << __func__ << ": Invalid string length: " << len8;
+ return STATUS_BAD_VALUE;
+ }
+
+ *stringData = reallocator(*stringData, len8);
+ char* str8 = getter(*stringData);
+
+ if (str8 == nullptr) {
+ LOG(WARNING) << __func__ << ": AParcel_string_allocator failed to allocate.";
+ return STATUS_NO_MEMORY;
+ }
+
+ utf16_to_utf8(str16, len16, str8, len8);
+
+ return STATUS_OK;
+}
+
// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
// libbinder and this library.
// @START
diff --git a/libs/binder/ndk/status.cpp b/libs/binder/ndk/status.cpp
index e0ae469..1f75b0b 100644
--- a/libs/binder/ndk/status.cpp
+++ b/libs/binder/ndk/status.cpp
@@ -27,11 +27,11 @@
}
AStatus* AStatus_fromExceptionCode(binder_exception_t exception) {
- return new AStatus(Status::fromExceptionCode(exception));
+ return new AStatus(Status::fromExceptionCode(PruneException(exception)));
}
AStatus* AStatus_fromExceptionCodeWithMessage(binder_exception_t exception, const char* message) {
- return new AStatus(Status::fromExceptionCode(exception, message));
+ return new AStatus(Status::fromExceptionCode(PruneException(exception), message));
}
AStatus* AStatus_fromServiceSpecificError(int32_t serviceSpecific) {
@@ -43,7 +43,7 @@
}
AStatus* AStatus_fromStatus(binder_status_t status) {
- return new AStatus(Status::fromStatusT(status));
+ return new AStatus(Status::fromStatusT(PruneStatusT(status)));
}
bool AStatus_isOk(const AStatus* status) {
diff --git a/libs/binder/ndk/test/main_client.cpp b/libs/binder/ndk/test/main_client.cpp
index 3fc096a..22bf1e5 100644
--- a/libs/binder/ndk/test/main_client.cpp
+++ b/libs/binder/ndk/test/main_client.cpp
@@ -131,3 +131,6 @@
EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName2));
EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
}
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_interface_utils.h>
diff --git a/services/media/arcvideobridge/Android.bp b/services/media/arcvideobridge/Android.bp
deleted file mode 100644
index ca5b896..0000000
--- a/services/media/arcvideobridge/Android.bp
+++ /dev/null
@@ -1,28 +0,0 @@
-cc_library_shared {
- name: "libarcvideobridge",
- product_variables: {
- arc: {
- srcs: [
- "IArcVideoBridge.cpp",
- ],
- shared_libs: [
- "libarcbridge",
- "libarcbridgeservice",
- "libbinder",
- "libchrome",
- "liblog",
- "libmojo",
- "libutils",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wunused",
- "-Wunreachable-code",
- ],
- include_dirs: [
- "frameworks/native/include/media/arcvideobridge",
- ]
- }
- }
-}
diff --git a/services/media/arcvideobridge/IArcVideoBridge.cpp b/services/media/arcvideobridge/IArcVideoBridge.cpp
deleted file mode 100644
index 468b76b..0000000
--- a/services/media/arcvideobridge/IArcVideoBridge.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2016 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.
- */
-
-#define LOG_TAG "IArcVideoBridge"
-//#define LOG_NDEBUG 0
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "IArcVideoBridge.h"
-#include <binder/Parcel.h>
-#include <utils/Log.h>
-
-namespace android {
-
-enum {
- BOOTSTRAP_VIDEO_ACCELERATOR_FACTORY = IBinder::FIRST_CALL_TRANSACTION,
- HOST_VERSION,
-};
-
-class BpArcVideoBridge : public BpInterface<IArcVideoBridge> {
-public:
- BpArcVideoBridge(const sp<IBinder>& impl) : BpInterface<IArcVideoBridge>(impl) { }
-
- virtual ::arc::MojoBootstrapResult bootstrapVideoAcceleratorFactory() {
- Parcel data, reply;
- ALOGV("bootstrapVideoAcceleratorFactory");
- data.writeInterfaceToken(IArcVideoBridge::getInterfaceDescriptor());
- status_t status = remote()->transact(
- BOOTSTRAP_VIDEO_ACCELERATOR_FACTORY, data, &reply, 0);
- if (status != 0) {
- ALOGE("transact failed: %d", status);
- return arc::MojoBootstrapResult();
- }
- return arc::MojoBootstrapResult::createFromParcel(reply);
- }
-
- virtual int32_t hostVersion() {
- Parcel data, reply;
- ALOGV("hostVersion");
- data.writeInterfaceToken(IArcVideoBridge::getInterfaceDescriptor());
- status_t status = remote()->transact(HOST_VERSION, data, &reply, 0);
- if (status != 0) {
- ALOGE("transact failed: %d", status);
- return false;
- }
- return reply.readInt32();
- }
-};
-
-IMPLEMENT_META_INTERFACE(ArcVideoBridge, "android.os.IArcVideoBridge");
-
-status_t BnArcVideoBridge::onTransact(
- uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
- switch(code) {
- case BOOTSTRAP_VIDEO_ACCELERATOR_FACTORY: {
- ALOGV("BOOTSTRAP_VIDEO_ACCELERATOR_FACTORY");
- CHECK_INTERFACE(IArcVideoBridge, data, reply);
- arc::MojoBootstrapResult result = bootstrapVideoAcceleratorFactory();
- return result.writeToParcel(reply);
- }
- case HOST_VERSION: {
- ALOGV("HOST_VERSION");
- CHECK_INTERFACE(IArcVideoBridge, data, reply);
- reply->writeInt32(hostVersion());
- return OK;
- }
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp
index 04ab121..2a67955 100644
--- a/services/surfaceflinger/LayerStats.cpp
+++ b/services/surfaceflinger/LayerStats.cpp
@@ -68,7 +68,7 @@
base::StringAppendF(&key, ",%s", layerCompositionType(layer->hwcCompositionType));
base::StringAppendF(&key, ",%d", layer->isProtected);
base::StringAppendF(&key, ",%s", layerTransform(layer->hwcTransform));
- base::StringAppendF(&key, ",%s", layerPixelFormat(layer->activeBuffer.format));
+ base::StringAppendF(&key, ",%s", layerPixelFormat(layer->activeBuffer.format).c_str());
base::StringAppendF(&key, ",%s", layer->dataspace.c_str());
base::StringAppendF(&key, ",%s",
destinationLocation(layer->hwcFrame.left, layerGlobal.resolution[0],
@@ -162,8 +162,8 @@
return getCompositionName(static_cast<hwc2_composition_t>(compositionType));
}
-const char* LayerStats::layerPixelFormat(int32_t pixelFormat) {
- return decodePixelFormat(pixelFormat).c_str();
+std::string LayerStats::layerPixelFormat(int32_t pixelFormat) {
+ return decodePixelFormat(pixelFormat);
}
std::string LayerStats::scaleRatioWH(const LayerProtoParser::Layer* layer) {
diff --git a/services/surfaceflinger/LayerStats.h b/services/surfaceflinger/LayerStats.h
index 7a190fd..bd17d82 100644
--- a/services/surfaceflinger/LayerStats.h
+++ b/services/surfaceflinger/LayerStats.h
@@ -50,7 +50,7 @@
// Return the name of the composition type
static const char* layerCompositionType(int32_t compositionType);
// Return the name of the pixel format
- static const char* layerPixelFormat(int32_t pixelFormat);
+ static std::string layerPixelFormat(int32_t pixelFormat);
// Calculate scale ratios of layer's width/height with rotation information
static std::string scaleRatioWH(const LayerProtoParser::Layer* layer);
// Calculate scale ratio from source to destination and convert to string
diff --git a/services/surfaceflinger/tests/SurfaceFlinger_test.filter b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
index 36424b9..cca84e5 100644
--- a/services/surfaceflinger/tests/SurfaceFlinger_test.filter
+++ b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
@@ -1,5 +1,5 @@
{
"presubmit": {
- "filter": "LayerTransactionTest.*:LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*:ScreenCaptureTest.*:DereferenceSurfaceControlTest.*"
+ "filter": "LayerTransactionTest.*:LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*:ScreenCaptureTest.*:DereferenceSurfaceControlTest.*:-CropLatchingTest.FinalCropLatchingBufferOldSize"
}
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index f1556d8..eec505e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -211,13 +211,20 @@
return *this;
}
- auto& addCapability(HWC2::Capability cap) {
- mCapabilities.emplace(cap);
+ auto& setCapabilities(const std::unordered_set<HWC2::Capability>* capabilities) {
+ mCapabilities = capabilities;
return *this;
}
void inject(TestableSurfaceFlinger* flinger, Hwc2::Composer* composer) {
- auto display = std::make_unique<HWC2Display>(*composer, mCapabilities, mHwcDisplayId,
+ static const std::unordered_set<HWC2::Capability> defaultCapabilities;
+ if (mCapabilities == nullptr) mCapabilities = &defaultCapabilities;
+
+ // Caution - Make sure that any values passed by reference here do
+ // not refer to an instance owned by FakeHwcDisplayInjector. This
+ // class has temporary lifetime, while the constructed HWC2::Display
+ // is much longer lived.
+ auto display = std::make_unique<HWC2Display>(*composer, *mCapabilities, mHwcDisplayId,
mHwcDisplayType);
auto config = HWC2::Display::Config::Builder(*display, mActiveConfig);
@@ -247,7 +254,7 @@
int32_t mDpiX = DEFAULT_DPI;
int32_t mDpiY = DEFAULT_DPI;
int32_t mActiveConfig = DEFAULT_ACTIVE_CONFIG;
- std::unordered_set<HWC2::Capability> mCapabilities;
+ const std::unordered_set<HWC2::Capability>* mCapabilities = nullptr;
};
class FakeDisplayDeviceInjector {