Merge "Snap for 6686656 from ea8305102a6cdd1b2cf89b1f020391bd19f71244 to sdk-release" into sdk-release
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 28fdaa4..fc3572c 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -239,6 +239,10 @@
{ OPT, "events/kmem/ion_heap_shrink/enable" },
{ OPT, "events/ion/ion_stat/enable" },
} },
+ { "thermal", "Thermal event", 0, {
+ { REQ, "events/thermal/thermal_temperature/enable" },
+ { OPT, "events/thermal/cdev_update/enable" },
+ } },
};
struct TracingVendorCategory {
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 9b2f4a8..28770f2 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -164,6 +164,12 @@
chmod 0666 /sys/kernel/tracing/events/filemap/mm_filemap_delete_from_page_cache/enable
chmod 0666 /sys/kernel/debug/tracing/events/filemap/mm_filemap_delete_from_page_cache/enable
+ # thermal
+ chmod 0666 /sys/kernel/debug/tracing/events/thermal/thermal_temperature/enable
+ chmod 0666 /sys/kernel/tracing/events/thermal/thermal_temperature/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/thermal/cdev_update/enable
+ chmod 0666 /sys/kernel/tracing/events/thermal/cdev_update/enable
+
# Tracing disabled by default
write /sys/kernel/debug/tracing/tracing_on 0
write /sys/kernel/tracing/tracing_on 0
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 5afae4b..987adaf 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -75,7 +75,7 @@
defaults: ["lshal_defaults"],
gtest: true,
static_libs: [
- "android.hardware.tests.baz@1.0",
+ "android.hardware.tests.inheritance@1.0",
"libgmock",
],
shared_libs: [
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
index af22ac9..72958bd 100644
--- a/cmds/lshal/DebugCommand.cpp
+++ b/cmds/lshal/DebugCommand.cpp
@@ -39,7 +39,7 @@
// Optargs cannnot be used because the flag should not be considered set
// if it should really be contained in mOptions.
if (std::string(arg.argv[optind]) == "-E") {
- mExcludesParentInstances = true;
+ mParentDebugInfoLevel = ParentDebugInfoLevel::NOTHING;
optind++;
}
@@ -67,7 +67,7 @@
return mLshal.emitDebugInfo(
pair.first, pair.second.empty() ? "default" : pair.second, mOptions,
- mExcludesParentInstances,
+ mParentDebugInfoLevel,
mLshal.out().buf(),
mLshal.err());
}
diff --git a/cmds/lshal/DebugCommand.h b/cmds/lshal/DebugCommand.h
index cd57e31..317cc28 100644
--- a/cmds/lshal/DebugCommand.h
+++ b/cmds/lshal/DebugCommand.h
@@ -21,6 +21,7 @@
#include <android-base/macros.h>
#include "Command.h"
+#include "ParentDebugInfoLevel.h"
#include "utils.h"
namespace android {
@@ -42,9 +43,8 @@
std::string mInterfaceName;
std::vector<std::string> mOptions;
- // Outputs the actual descriptor of a hal instead of the debug output
- // if the arguments provided are a superclass of the actual hal impl.
- bool mExcludesParentInstances;
+ // See comment on ParentDebugInfoLevel.
+ ParentDebugInfoLevel mParentDebugInfoLevel = ParentDebugInfoLevel::FULL;
DISALLOW_COPY_AND_ASSIGN(DebugCommand);
};
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index fb11cee..a805a48 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -555,7 +555,7 @@
std::stringstream ss;
auto pair = splitFirst(iName, '/');
mLshal.emitDebugInfo(pair.first, pair.second, {},
- false /* excludesParentInstances */, ss,
+ ParentDebugInfoLevel::FQNAME_ONLY, ss,
NullableOStream<std::ostream>(nullptr));
return ss.str();
};
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 132b31e..2c3efe5 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -101,7 +101,7 @@
const std::string &interfaceName,
const std::string &instanceName,
const std::vector<std::string> &options,
- bool excludesParentInstances,
+ ParentDebugInfoLevel parentDebugInfoLevel,
std::ostream &out,
NullableOStream<std::ostream> err) const {
using android::hidl::base::V1_0::IBase;
@@ -126,7 +126,7 @@
return NO_INTERFACE;
}
- if (excludesParentInstances) {
+ if (parentDebugInfoLevel != ParentDebugInfoLevel::FULL) {
const std::string descriptor = getDescriptor(base.get());
if (descriptor.empty()) {
std::string msg = interfaceName + "/" + instanceName + " getDescriptor failed";
@@ -134,6 +134,9 @@
LOG(ERROR) << msg;
}
if (descriptor != interfaceName) {
+ if (parentDebugInfoLevel == ParentDebugInfoLevel::FQNAME_ONLY) {
+ out << "[See " << descriptor << "/" << instanceName << "]";
+ }
return OK;
}
}
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index 830bd87..50279d4 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -25,6 +25,7 @@
#include "Command.h"
#include "NullableOStream.h"
+#include "ParentDebugInfoLevel.h"
#include "utils.h"
namespace android {
@@ -49,7 +50,7 @@
const std::string &interfaceName,
const std::string &instanceName,
const std::vector<std::string> &options,
- bool excludesParentInstances,
+ ParentDebugInfoLevel parentDebugInfoLevel,
std::ostream &out,
NullableOStream<std::ostream> err) const;
diff --git a/cmds/lshal/ParentDebugInfoLevel.h b/cmds/lshal/ParentDebugInfoLevel.h
new file mode 100644
index 0000000..12ac9c8
--- /dev/null
+++ b/cmds/lshal/ParentDebugInfoLevel.h
@@ -0,0 +1,34 @@
+/*
+ * 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
+
+namespace android {
+namespace lshal {
+
+// Describe verbosity when dumping debug information on a HAL service by
+// referring to a parent HAL interface FQName (for example, when dumping debug information
+// on foo@1.0::IFoo but the HAL implementation is foo@1.1::IFoo).
+enum class ParentDebugInfoLevel {
+ // Write nothing.
+ NOTHING,
+ // Write a short description that includes the FQName of the real implementation.
+ FQNAME_ONLY,
+ // Write full debug info.
+ FULL,
+};
+
+} // namespace lshal
+} // namespace android
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index 3d550ba..afe5d63 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -24,7 +24,7 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
-#include <android/hardware/tests/baz/1.0/IQuux.h>
+#include <android/hardware/tests/inheritance/1.0/IChild.h>
#include <hidl/HidlTransportSupport.h>
#include <vintf/parse_xml.h>
@@ -44,6 +44,7 @@
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
+using ::android::hardware::Void;
using android::vintf::Arch;
using android::vintf::CompatibilityMatrix;
using android::vintf::gCompatibilityMatrixConverter;
@@ -59,10 +60,14 @@
namespace android {
namespace hardware {
namespace tests {
-namespace baz {
+namespace inheritance {
namespace V1_0 {
namespace implementation {
-struct Quux : android::hardware::tests::baz::V1_0::IQuux {
+struct Child : android::hardware::tests::inheritance::V1_0::IChild {
+ ::android::hardware::Return<void> doChild() override { return Void(); }
+ ::android::hardware::Return<void> doParent() override { return Void(); }
+ ::android::hardware::Return<void> doGrandparent() override { return Void(); }
+
::android::hardware::Return<void> debug(const hidl_handle& hh, const hidl_vec<hidl_string>& options) override {
const native_handle_t *handle = hh.getNativeHandle();
if (handle->numFds < 1) {
@@ -76,7 +81,7 @@
}
ssize_t written = write(fd, content.c_str(), content.size());
if (written != (ssize_t)content.size()) {
- LOG(WARNING) << "SERVER(Quux) debug writes " << written << " bytes < "
+ LOG(WARNING) << "SERVER(Child) debug writes " << written << " bytes < "
<< content.size() << " bytes, errno = " << errno;
}
return Void();
@@ -85,7 +90,7 @@
} // namespace implementation
} // namespace V1_0
-} // namespace baz
+} // namespace inheritance
} // namespace tests
} // namespace hardware
@@ -124,18 +129,24 @@
class DebugTest : public ::testing::Test {
public:
void SetUp() override {
- using ::android::hardware::tests::baz::V1_0::IQuux;
- using ::android::hardware::tests::baz::V1_0::implementation::Quux;
+ using ::android::hardware::tests::inheritance::V1_0::IChild;
+ using ::android::hardware::tests::inheritance::V1_0::IParent;
+ using ::android::hardware::tests::inheritance::V1_0::IGrandparent;
+ using ::android::hardware::tests::inheritance::V1_0::implementation::Child;
err.str("");
out.str("");
serviceManager = new testing::NiceMock<MockServiceManager>();
- ON_CALL(*serviceManager, get(_, _)).WillByDefault(Invoke(
- [](const auto &iface, const auto &inst) -> ::android::hardware::Return<sp<IBase>> {
- if (iface == IQuux::descriptor && inst == "default")
- return new Quux();
- return nullptr;
- }));
+ ON_CALL(*serviceManager, get(_, _))
+ .WillByDefault(
+ Invoke([](const auto& iface,
+ const auto& inst) -> ::android::hardware::Return<sp<IBase>> {
+ if (inst != "default") return nullptr;
+ if (iface == IChild::descriptor || iface == IParent::descriptor ||
+ iface == IGrandparent::descriptor)
+ return new Child();
+ return nullptr;
+ }));
lshal = std::make_unique<Lshal>(out, err, serviceManager, serviceManager);
}
@@ -159,17 +170,17 @@
TEST_F(DebugTest, Debug) {
EXPECT_EQ(0u, callMain(lshal, {
- "lshal", "debug", "android.hardware.tests.baz@1.0::IQuux/default", "foo", "bar"
+ "lshal", "debug", "android.hardware.tests.inheritance@1.0::IChild/default", "foo", "bar"
}));
- EXPECT_THAT(out.str(), StrEq("android.hardware.tests.baz@1.0::IQuux\nfoo\nbar"));
+ EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\nfoo\nbar"));
EXPECT_THAT(err.str(), IsEmpty());
}
TEST_F(DebugTest, Debug2) {
EXPECT_EQ(0u, callMain(lshal, {
- "lshal", "debug", "android.hardware.tests.baz@1.0::IQuux", "baz", "quux"
+ "lshal", "debug", "android.hardware.tests.inheritance@1.0::IChild", "baz", "quux"
}));
- EXPECT_THAT(out.str(), StrEq("android.hardware.tests.baz@1.0::IQuux\nbaz\nquux"));
+ EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\nbaz\nquux"));
EXPECT_THAT(err.str(), IsEmpty());
}
@@ -180,6 +191,22 @@
EXPECT_THAT(err.str(), HasSubstr("does not exist"));
}
+TEST_F(DebugTest, DebugParent) {
+ EXPECT_EQ(0u, callMain(lshal, {
+ "lshal", "debug", "android.hardware.tests.inheritance@1.0::IParent", "calling parent"
+ }));
+ EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\ncalling parent"));
+ EXPECT_THAT(err.str(), IsEmpty());
+}
+
+TEST_F(DebugTest, DebugParentExclude) {
+ EXPECT_EQ(0u, callMain(lshal, {
+ "lshal", "debug", "-E", "android.hardware.tests.inheritance@1.0::IParent", "excluding"
+ }));
+ EXPECT_THAT(out.str(), IsEmpty());
+ EXPECT_THAT(err.str(), IsEmpty());
+}
+
class MockLshal : public Lshal {
public:
MockLshal() {}
@@ -766,6 +793,91 @@
EXPECT_EQ("", err.str());
}
+// Fake service returned by mocked IServiceManager::get for DumpDebug.
+// The interfaceChain and getHashChain functions returns
+// foo(id - 1) -> foo(id - 2) -> ... foo1 -> IBase.
+class InheritingService : public IBase {
+public:
+ explicit InheritingService(pid_t id) : mId(id) {}
+ android::hardware::Return<void> interfaceDescriptor(interfaceDescriptor_cb cb) override {
+ cb(getInterfaceName(mId));
+ return hardware::Void();
+ }
+ android::hardware::Return<void> interfaceChain(interfaceChain_cb cb) override {
+ std::vector<hidl_string> ret;
+ for (auto i = mId; i > 0; --i) {
+ ret.push_back(getInterfaceName(i));
+ }
+ ret.push_back(IBase::descriptor);
+ cb(ret);
+ return hardware::Void();
+ }
+ android::hardware::Return<void> getHashChain(getHashChain_cb cb) override {
+ std::vector<hidl_hash> ret;
+ for (auto i = mId; i > 0; --i) {
+ ret.push_back(getHashFromId(i));
+ }
+ ret.push_back(getHashFromId(0xff));
+ cb(ret);
+ return hardware::Void();
+ }
+ android::hardware::Return<void> debug(const hidl_handle& hh,
+ const hidl_vec<hidl_string>&) override {
+ const native_handle_t* handle = hh.getNativeHandle();
+ if (handle->numFds < 1) {
+ return Void();
+ }
+ int fd = handle->data[0];
+ std::string content = "debug info for ";
+ content += getInterfaceName(mId);
+ ssize_t written = write(fd, content.c_str(), content.size());
+ if (written != (ssize_t)content.size()) {
+ LOG(WARNING) << "SERVER(" << descriptor << ") debug writes " << written << " bytes < "
+ << content.size() << " bytes, errno = " << errno;
+ }
+ return Void();
+ }
+
+private:
+ pid_t mId;
+};
+
+TEST_F(ListTest, DumpDebug) {
+ size_t inheritanceLevel = 3;
+ sp<IBase> service = new InheritingService(inheritanceLevel);
+
+ EXPECT_CALL(*serviceManager, list(_)).WillRepeatedly(Invoke([&](IServiceManager::list_cb cb) {
+ std::vector<hidl_string> ret;
+ for (auto i = 1; i <= inheritanceLevel; ++i) {
+ ret.push_back(getInterfaceName(i) + "/default");
+ }
+ cb(ret);
+ return hardware::Void();
+ }));
+ EXPECT_CALL(*serviceManager, get(_, _))
+ .WillRepeatedly(
+ Invoke([&](const hidl_string&, const hidl_string& instance) -> sp<IBase> {
+ int id = getIdFromInstanceName(instance);
+ if (id > inheritanceLevel) return nullptr;
+ return sp<IBase>(service);
+ }));
+
+ const std::string expected = "[fake description 0]\n"
+ "Interface\n"
+ "a.h.foo1@1.0::IFoo/default\n"
+ "[See a.h.foo3@3.0::IFoo/default]\n"
+ "a.h.foo2@2.0::IFoo/default\n"
+ "[See a.h.foo3@3.0::IFoo/default]\n"
+ "a.h.foo3@3.0::IFoo/default\n"
+ "debug info for a.h.foo3@3.0::IFoo\n"
+ "\n";
+
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--types=b", "-id"})));
+ EXPECT_EQ(expected, out.str());
+ EXPECT_EQ("", err.str());
+}
+
class ListVintfTest : public ListTest {
public:
virtual void SetUp() override {
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 05f43e3..25c0b19 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -326,6 +326,11 @@
while(true) {
{
+ // It would be really nice if we could read binder commands on this
+ // thread instead of needing a threadpool to be started, but for
+ // instance, if we call getAndExecuteCommand, it might be the case
+ // that another thread serves the callback, and we never get a
+ // command, so we hang indefinitely.
std::unique_lock<std::mutex> lock(waiter->mMutex);
using std::literals::chrono_literals::operator""s;
waiter->mCv.wait_for(lock, 1s, [&] {
@@ -334,6 +339,8 @@
if (waiter->mBinder != nullptr) return waiter->mBinder;
}
+ ALOGW("Waited one second for %s (is service started? are binder threads started and available?)", name.c_str());
+
// Handle race condition for lazy services. Here is what can happen:
// - the service dies (not processed by init yet).
// - sm processes death notification.
@@ -347,8 +354,6 @@
return nullptr;
}
if (out != nullptr) return out;
-
- ALOGW("Waited one second for %s", name.c_str());
}
}
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
index ebf91f9..b46b3e8 100644
--- a/libs/binder/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -387,7 +387,7 @@
while (cur) {
if (cur->start == start) {
LOG_FATAL_IF(cur->free,
- "block at offset 0x%08lX of size 0x%08lX already freed",
+ "block at offset 0x%08lX of size 0x%08X already freed",
cur->start*kMemoryAlign, cur->size*kMemoryAlign);
// merge freed blocks together
@@ -411,7 +411,7 @@
}
#endif
LOG_FATAL_IF(!freed->free,
- "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+ "freed block at offset 0x%08lX of size 0x%08X is not free!",
freed->start * kMemoryAlign, freed->size * kMemoryAlign);
return freed;
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index b4e4a42..8d51cdc 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -50,7 +50,7 @@
* Returns the SELinux security identifier of the process which has
* made the current binder call. If not in a binder call this will
* return nullptr. If this isn't requested with
- * IBinder::setRequestingSid, it will also return nullptr.
+ * Binder::setRequestingSid, it will also return nullptr.
*
* This can't be restored once it's cleared, and it does not return the
* context of the current process when not in a binder call.
diff --git a/libs/binder/include/binder/TextOutput.h b/libs/binder/include/binder/TextOutput.h
index f66406f..c7e1e14 100644
--- a/libs/binder/include/binder/TextOutput.h
+++ b/libs/binder/include/binder/TextOutput.h
@@ -50,12 +50,18 @@
// ---------------------------------------------------------------------------
+// DO NOT USE: prefer libutils/libbase logs, which don't require static data to
+// be allocated.
// Text output stream for printing to the log (via utils/Log.h).
extern TextOutput& alog;
+// DO NOT USE: prefer libutils/libbase logs, which don't require static data to
+// be allocated.
// Text output stream for printing to stdout.
extern TextOutput& aout;
+// DO NOT USE: prefer libutils/libbase logs, which don't require static data to
+// be allocated.
// Text output stream for printing to stderr.
extern TextOutput& aerr;
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index e66e425..ab00914 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -36,6 +36,7 @@
host_supported: true,
export_include_dirs: [
+ "include_cpp",
"include_ndk",
"include_platform",
],
@@ -95,6 +96,17 @@
license: "NOTICE",
}
+// TODO(b/160624671): package with the aidl compiler
+ndk_headers {
+ name: "libbinder_ndk_helper_headers",
+ from: "include_cpp/android",
+ to: "android",
+ srcs: [
+ "include_cpp/android/*.h",
+ ],
+ license: "NOTICE",
+}
+
ndk_library {
name: "libbinder_ndk",
symbol_file: "libbinder_ndk.map.txt",
@@ -105,6 +117,7 @@
name: "libbinder_ndk",
symbol_file: "libbinder_ndk.map.txt",
export_include_dirs: [
+ "include_cpp",
"include_ndk",
"include_platform",
],
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 649faa1..d287290 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -15,6 +15,7 @@
*/
#include <android/binder_ibinder.h>
+#include <android/binder_ibinder_platform.h>
#include "ibinder_internal.h"
#include <android/binder_stability.h>
@@ -99,8 +100,14 @@
String8 descriptor(getBinder()->getInterfaceDescriptor());
if (descriptor != newDescriptor) {
- LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str()
- << "' but descriptor is actually '" << descriptor.c_str() << "'.";
+ if (getBinder()->isBinderAlive()) {
+ LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str()
+ << "' but descriptor is actually '" << descriptor.c_str() << "'.";
+ } else {
+ // b/155793159
+ LOG(ERROR) << __func__ << ": Cannot associate class '" << newDescriptor.c_str()
+ << "' to dead binder.";
+ }
return false;
}
@@ -676,3 +683,29 @@
rawBinder->setExtension(ext->getBinder());
return STATUS_OK;
}
+
+// platform methods follow
+
+void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) {
+ ABBinder* localBinder = binder->asABBinder();
+ if (localBinder == nullptr) {
+ LOG(FATAL) << "AIBinder_setRequestingSid must be called on a local binder";
+ }
+
+ localBinder->setRequestingSid(requestingSid);
+}
+
+const char* AIBinder_getCallingSid() {
+ return ::android::IPCThreadState::self()->getCallingSid();
+}
+
+android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder) {
+ if (binder == nullptr) return nullptr;
+ return binder->getBinder();
+}
+
+AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder) {
+ sp<AIBinder> ndkBinder = ABpBinder::lookupOrCreateFromBinder(binder);
+ AIBinder_incStrong(ndkBinder.get());
+ return ndkBinder.get();
+}
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
similarity index 100%
rename from libs/binder/ndk/include_ndk/android/binder_auto_utils.h
rename to libs/binder/ndk/include_cpp/android/binder_auto_utils.h
diff --git a/libs/binder/ndk/include_ndk/android/binder_enums.h b/libs/binder/ndk/include_cpp/android/binder_enums.h
similarity index 100%
rename from libs/binder/ndk/include_ndk/android/binder_enums.h
rename to libs/binder/ndk/include_cpp/android/binder_enums.h
diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
similarity index 100%
rename from libs/binder/ndk/include_ndk/android/binder_interface_utils.h
rename to libs/binder/ndk/include_cpp/android/binder_interface_utils.h
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
similarity index 100%
rename from libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
rename to libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 13dbec1..33763d5 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -408,6 +408,8 @@
* This returns true if the class association succeeds. If it fails, no change is made to the
* binder object.
*
+ * Warning: this may fail if the binder is dead.
+ *
* Available since API level 29.
*
* \param binder the object to attach the class to.
diff --git a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
new file mode 100644
index 0000000..d4feaba
--- /dev/null
+++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
@@ -0,0 +1,80 @@
+/*
+ * 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 <android/binder_ibinder.h>
+
+#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
+#include <binder/IBinder.h>
+#endif
+
+__BEGIN_DECLS
+
+/**
+ * Makes calls to AIBinder_getCallingSid work if the kernel supports it. This
+ * must be called on a local binder server before it is sent out to any othe
+ * process. If this is a remote binder, it will abort. If the kernel doesn't
+ * support this feature, you'll always get null from AIBinder_getCallingSid.
+ *
+ * \param binder local server binder to request security contexts on
+ */
+void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) __INTRODUCED_IN(31);
+
+/**
+ * Returns the selinux context of the callee.
+ *
+ * In order for this to work, the following conditions must be met:
+ * - The kernel must be new enough to support this feature.
+ * - The server must have called AIBinder_setRequestingSid.
+ * - The callee must be a remote process.
+ *
+ * \return security context or null if unavailable. The lifetime of this context
+ * is the lifetime of the transaction.
+ */
+__attribute__((warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31);
+
+__END_DECLS
+
+#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
+
+/**
+ * Get libbinder version of binder from AIBinder.
+ *
+ * WARNING: function calls to a local object on the other side of this function
+ * will parcel. When converting between binders, keep in mind it is not as
+ * efficient as a direct function call.
+ *
+ * \param binder binder with ownership retained by the client
+ * \return platform binder object
+ */
+android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder);
+
+/**
+ * Get libbinder_ndk version of binder from platform binder.
+ *
+ * WARNING: function calls to a local object on the other side of this function
+ * will parcel. When converting between binders, keep in mind it is not as
+ * efficient as a direct function call.
+ *
+ * \param binder platform binder which may be from anywhere (doesn't have to be
+ * created with libbinder_ndK)
+ * \return binder with one reference count of ownership given to the client. See
+ * AIBinder_decStrong
+ */
+AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder);
+
+#endif
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index a9eba47..9b5fa26 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -95,8 +95,6 @@
AServiceManager_addService; # apex llndk
AServiceManager_checkService; # apex llndk
AServiceManager_getService; # apex llndk
- local:
- *;
};
LIBBINDER_NDK30 { # introduced=30
@@ -111,11 +109,21 @@
AIBinder_markVendorStability; # llndk
AIBinder_markVintfStability; # apex llndk
AIBinder_Class_setHandleShellCommand; # apex llndk
- local:
- *;
+};
+
+LIBBINDER_NDK31 { # introduced=31
+ global:
+ AIBinder_getCallingSid; # apex
+ AIBinder_setRequestingSid; # apex
};
LIBBINDER_NDK_PLATFORM {
global:
AParcel_getAllowFds;
+ extern "C++" {
+ AIBinder_fromPlatformBinder*;
+ AIBinder_toPlatformBinder*;
+ };
+ local:
+ *;
};
diff --git a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
index 6e8e463..dc77467d 100644
--- a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
+++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
@@ -22,6 +22,10 @@
import IEmpty;
interface IBinderNdkUnitTest {
+ int repeatInt(int a);
+
void takeInterface(IEmpty test);
void forceFlushCommands();
+
+ boolean getsRequestedSid();
}
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index fd30d87..e3fdb4b 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -19,6 +19,7 @@
#include <aidl/BnEmpty.h>
#include <android-base/logging.h>
#include <android/binder_ibinder_jni.h>
+#include <android/binder_ibinder_platform.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <gtest/gtest.h>
@@ -34,6 +35,7 @@
#include <sys/prctl.h>
#include <chrono>
#include <condition_variable>
+#include <iostream>
#include <mutex>
using namespace android;
@@ -42,6 +44,10 @@
constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
+ ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
+ *out = in;
+ return ndk::ScopedAStatus::ok();
+ }
ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
(void)empty;
return ndk::ScopedAStatus::ok();
@@ -52,6 +58,12 @@
android::IPCThreadState::self()->flushCommands();
return ndk::ScopedAStatus::ok();
}
+ ndk::ScopedAStatus getsRequestedSid(bool* out) {
+ const char* sid = AIBinder_getCallingSid();
+ std::cout << "Got security context: " << (sid ?: "null") << std::endl;
+ *out = sid != nullptr;
+ return ndk::ScopedAStatus::ok();
+ }
binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args,
uint32_t numArgs) override {
for (uint32_t i = 0; i < numArgs; i++) {
@@ -66,8 +78,11 @@
ABinderProcess_setThreadPoolMaxThreadCount(0);
auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
- binder_status_t status =
- AServiceManager_addService(service->asBinder().get(), kBinderNdkUnitTestService);
+ auto binder = service->asBinder();
+
+ AIBinder_setRequestingSid(binder.get(), true);
+
+ binder_status_t status = AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
if (status != STATUS_OK) {
LOG(FATAL) << "Could not register: " << status << " " << kBinderNdkUnitTestService;
@@ -274,6 +289,16 @@
EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
}
+TEST(NdkBinder, RequestedSidWorks) {
+ ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
+ std::shared_ptr<aidl::IBinderNdkUnitTest> service =
+ aidl::IBinderNdkUnitTest::fromBinder(binder);
+
+ bool gotSid = false;
+ EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk());
+ EXPECT_TRUE(gotSid);
+}
+
TEST(NdkBinder, SentAidlBinderCanBeDestroyed) {
static volatile bool destroyed = false;
static std::mutex dMutex;
@@ -308,6 +333,30 @@
EXPECT_TRUE(destroyed);
}
+TEST(NdkBinder, ConvertToPlatformBinder) {
+ for (const ndk::SpAIBinder& binder :
+ {// remote
+ ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
+ // local
+ ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
+ // convert to platform binder
+ EXPECT_NE(binder.get(), nullptr);
+ sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
+ EXPECT_NE(platformBinder.get(), nullptr);
+ auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder);
+ EXPECT_NE(proxy, nullptr);
+
+ // use platform binder
+ int out;
+ EXPECT_TRUE(proxy->repeatInt(4, &out).isOk());
+ EXPECT_EQ(out, 4);
+
+ // convert back
+ ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder));
+ EXPECT_EQ(backBinder.get(), binder.get());
+ }
+}
+
class MyResultReceiver : public BnResultReceiver {
public:
Mutex mMutex;
diff --git a/libs/binderthreadstate/test.cpp b/libs/binderthreadstate/test.cpp
index 68cc225..44e2fd1 100644
--- a/libs/binderthreadstate/test.cpp
+++ b/libs/binderthreadstate/test.cpp
@@ -165,7 +165,6 @@
android::ProcessState::self()->startThreadPool();
// HIDL
- setenv("TREBLE_TESTING_OVERRIDE", "true", true);
android::hardware::configureRpcThreadpool(1, true /*callerWillJoin*/);
sp<IHidlStuff> hidlServer = new HidlServer(thisId, otherId);
CHECK(OK == hidlServer->registerAsService(id2name(thisId).c_str()));
@@ -176,7 +175,7 @@
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+ android::hardware::details::setTrebleTestingOverride(true);
if (fork() == 0) {
prctl(PR_SET_PDEATHSIG, SIGHUP);
return server(kP1Id, kP2Id);
diff --git a/libs/vr/libpdx/fuzz/Android.bp b/libs/vr/libpdx/fuzz/Android.bp
index 8ab09f3..b36e0de 100644
--- a/libs/vr/libpdx/fuzz/Android.bp
+++ b/libs/vr/libpdx/fuzz/Android.bp
@@ -1,5 +1,5 @@
cc_fuzz {
- name: "libpdx_fuzz",
+ name: "libpdx_service_dispatcher_fuzzer",
clang: true,
srcs: [
"service_dispatcher_fuzzer.cpp",
@@ -15,6 +15,48 @@
shared_libs: [
"libutils",
"liblog",
- "libcutils",
+ "libcutils"
+ ],
+}
+
+cc_fuzz {
+ name: "libpdx_message_fuzzer",
+ clang: true,
+ srcs: [
+ "message_fuzzer.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+ static_libs: [
+ "libpdx",
+ ],
+ shared_libs: [
+ "libutils",
+ "liblog",
+ "libcutils"
+ ],
+}
+
+cc_fuzz {
+ name: "libpdx_serialization_fuzzer",
+ clang: true,
+ srcs: [
+ "serialization_fuzzer.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+ static_libs: [
+ "libpdx",
+ ],
+ shared_libs: [
+ "libutils",
+ "liblog",
+ "libcutils"
],
}
diff --git a/libs/vr/libpdx/fuzz/message_fuzzer.cpp b/libs/vr/libpdx/fuzz/message_fuzzer.cpp
new file mode 100644
index 0000000..b627045
--- /dev/null
+++ b/libs/vr/libpdx/fuzz/message_fuzzer.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright 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.
+ */
+// Authors: corbin.souffrant@leviathansecurity.com
+// brian.balling@leviathansecurity.com
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <helpers.h>
+#include <pdx/client_channel.h>
+#include <pdx/service.h>
+#include <pdx/service_dispatcher.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/eventfd.h>
+#include <thread>
+
+using namespace android::pdx;
+
+// Fuzzer for Message object functions.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+
+ FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp);
+ std::shared_ptr<Service> service(
+ new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint)));
+ std::shared_ptr<Channel> channel(nullptr);
+
+ // Generate a random Message object to call functions in.
+ MessageInfo info;
+ info.pid = fdp.ConsumeIntegral<int>();
+ info.tid = fdp.ConsumeIntegral<int>();
+ info.cid = fdp.ConsumeIntegral<int>();
+ info.mid = fdp.ConsumeIntegral<int>();
+ info.euid = fdp.ConsumeIntegral<int>();
+ info.egid = fdp.ConsumeIntegral<int>();
+ info.op = fdp.ConsumeIntegral<int32_t>();
+ info.flags = fdp.ConsumeIntegral<uint32_t>();
+ info.service = service.get();
+ info.channel = channel.get();
+ info.send_len = fdp.ConsumeIntegral<size_t>();
+ info.recv_len = fdp.ConsumeIntegral<size_t>();
+ info.fd_count = fdp.ConsumeIntegral<size_t>();
+ if (fdp.remaining_bytes() >= 32) {
+ std::vector<uint8_t> impulse_vec = fdp.ConsumeBytes<uint8_t>(32);
+ memcpy(info.impulse, impulse_vec.data(), 32);
+ }
+
+ Message message = Message(info);
+
+ // A bunch of getters that probably won't do much, but might as well
+ // get coverage, while we are here.
+ message.GetProcessId();
+ message.GetThreadId();
+ message.GetEffectiveUserId();
+ message.GetEffectiveGroupId();
+ message.GetChannelId();
+ message.GetMessageId();
+ message.GetOp();
+ message.GetFlags();
+ message.GetSendLength();
+ message.GetReceiveLength();
+ message.GetFileDescriptorCount();
+ message.ImpulseEnd();
+ message.replied();
+ message.IsChannelExpired();
+ message.IsServiceExpired();
+ message.GetState();
+ message.GetState();
+
+ // Some misc. functions.
+ unsigned int fd = fdp.ConsumeIntegral<unsigned int>();
+ int clear_mask = fdp.ConsumeIntegral<int>();
+ int set_mask = fdp.ConsumeIntegral<int>();
+ Status<void> status = {};
+ message.ModifyChannelEvents(clear_mask, set_mask);
+
+ // Fuzz the handle functions.
+ LocalHandle l_handle = {};
+ BorrowedHandle b_handle = {};
+ RemoteHandle r_handle = {};
+ LocalChannelHandle lc_handle = {};
+ BorrowedChannelHandle bc_handle = {};
+ RemoteChannelHandle rc_handle = {};
+ FileReference f_ref = fdp.ConsumeIntegral<int32_t>();
+ ChannelReference c_ref = fdp.ConsumeIntegral<int32_t>();
+
+ // These don't actually modify any state in the Message or params.
+ // They can be called in any order.
+ message.PushFileHandle(b_handle);
+ message.PushFileHandle(r_handle);
+ message.PushChannelHandle(lc_handle);
+ message.PushChannelHandle(bc_handle);
+ message.PushChannelHandle(rc_handle);
+ message.GetFileHandle(f_ref, &l_handle);
+ message.GetChannelHandle(c_ref, &lc_handle);
+
+ // Can only reply once, pick at random.
+ switch (fdp.ConsumeIntegral<uint8_t>()) {
+ case 0:
+ message.ReplyFileDescriptor(fd);
+ break;
+ case 1:
+ message.Reply(status);
+ break;
+ case 2:
+ message.Reply(l_handle);
+ break;
+ case 3:
+ message.Reply(b_handle);
+ break;
+ case 4:
+ message.Reply(r_handle);
+ break;
+ case 5:
+ message.Reply(lc_handle);
+ break;
+ case 6:
+ message.Reply(bc_handle);
+ break;
+ case 7:
+ message.Reply(rc_handle);
+ }
+
+ // Fuzz the channel functions.
+ int flags = fdp.ConsumeIntegral<int>();
+ int channel_id = 0;
+ message.PushChannel(flags, channel, &channel_id);
+ message.CheckChannel(service.get(), c_ref, &channel);
+ message.CheckChannel(c_ref, &channel);
+ message.PushChannel(service.get(), flags, channel, &channel_id);
+ size_t iovec_size = sizeof(iovec);
+ struct iovec* iovecs = nullptr;
+
+ // Fuzz the read/write functions. Needs at least one iovec, plus one byte.
+ if (fdp.remaining_bytes() >= iovec_size + 1) {
+ std::vector<uint8_t> tmp_vec = fdp.ConsumeBytes<uint8_t>(iovec_size);
+ struct iovec* vector = reinterpret_cast<struct iovec*>(tmp_vec.data());
+ std::vector<uint8_t> tmp_buf =
+ fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
+ void* buf = reinterpret_cast<void*>(tmp_buf.data());
+ size_t buf_size = fdp.ConsumeIntegral<size_t>();
+
+ // Capping num_vecs to 1024 so it doesn't allocate too much memory.
+ size_t num_vecs = fdp.ConsumeIntegralInRange<size_t>(0, 1024);
+
+ if (num_vecs > 0)
+ iovecs = new struct iovec[num_vecs];
+ for (size_t i = 0; i < num_vecs; i++) {
+ iovecs[i] = *vector;
+ }
+
+ message.ReadAll(vector, buf_size);
+ message.WriteAll(buf, buf_size);
+ message.ReadVectorAll(vector, num_vecs);
+ message.WriteVectorAll(vector, num_vecs);
+ message.ReadVector(vector, buf_size);
+ message.WriteVector(vector, buf_size);
+ }
+
+ if (iovecs != nullptr)
+ delete[] iovecs;
+ return 0;
+}
diff --git a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
new file mode 100644
index 0000000..afde5f7
--- /dev/null
+++ b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright 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.
+ */
+// Authors: corbin.souffrant@leviathansecurity.com
+// brian.balling@leviathansecurity.com
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <memory>
+#include <string>
+#include <thread>
+#include <utility>
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <pdx/rpc/argument_encoder.h>
+#include <pdx/rpc/array_wrapper.h>
+#include <pdx/rpc/default_initialization_allocator.h>
+#include <pdx/rpc/payload.h>
+#include <pdx/rpc/serializable.h>
+#include <pdx/rpc/serialization.h>
+#include <pdx/rpc/string_wrapper.h>
+#include <pdx/utility.h>
+
+using namespace android::pdx;
+using namespace android::pdx::rpc;
+
+struct FuzzType {
+ int a;
+ float b;
+ std::string c;
+
+ FuzzType() {}
+ FuzzType(int a, float b, const std::string& c) : a(a), b(b), c(c) {}
+
+ private:
+ PDX_SERIALIZABLE_MEMBERS(FuzzType, a, b, c);
+};
+
+// Fuzzer for Serialization operations, this is mostly just lifted from the
+// existing test cases to use fuzzed values as inputs.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+ Payload result;
+
+ // Currently, only fuzzing subset of types. In the future, may want
+ // to add more difficult to generate types like array, map, enum, etc...
+ bool b_val = fdp.ConsumeBool();
+ uint8_t u8_val = fdp.ConsumeIntegral<uint8_t>();
+ uint16_t u16_val = fdp.ConsumeIntegral<uint16_t>();
+ uint32_t u32_val = fdp.ConsumeIntegral<uint32_t>();
+ uint64_t u64_val = fdp.ConsumeIntegral<uint64_t>();
+ int8_t i8_val = fdp.ConsumeIntegral<int8_t>();
+ int16_t i16_val = fdp.ConsumeIntegral<uint16_t>();
+ int32_t i32_val = fdp.ConsumeIntegral<uint32_t>();
+ int64_t i64_val = fdp.ConsumeIntegral<uint64_t>();
+ float f_val = fdp.ConsumeFloatingPoint<float>();
+ double d_val = fdp.ConsumeFloatingPoint<double>();
+ std::string s_val = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
+ std::vector<uint8_t> vec_val =
+ fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
+ FuzzType t1_val{reinterpret_cast<int>(i32_val), f_val, s_val};
+
+ // Types need to be individually fuzzed because code path changes depending
+ // on which type is being serialized/deserialized.
+ Serialize(b_val, &result);
+ Deserialize(&b_val, &result);
+ Serialize(u8_val, &result);
+ Deserialize(&u8_val, &result);
+ Serialize(u16_val, &result);
+ Deserialize(&u16_val, &result);
+ Serialize(u32_val, &result);
+ Deserialize(&u32_val, &result);
+ Serialize(u64_val, &result);
+ Deserialize(&u64_val, &result);
+ Serialize(i8_val, &result);
+ Deserialize(&i8_val, &result);
+ Serialize(i16_val, &result);
+ Deserialize(&i16_val, &result);
+ Serialize(i32_val, &result);
+ Deserialize(&i32_val, &result);
+ Serialize(i64_val, &result);
+ Deserialize(&i64_val, &result);
+ Serialize(f_val, &result);
+ Deserialize(&f_val, &result);
+ Serialize(d_val, &result);
+ Deserialize(&d_val, &result);
+ Serialize(s_val, &result);
+ Deserialize(&s_val, &result);
+ Serialize(WrapString(s_val), &result);
+ Deserialize(&s_val, &result);
+ Serialize(vec_val, &result);
+ Deserialize(&vec_val, &result);
+ Serialize(t1_val, &result);
+ Deserialize(&t1_val, &result);
+
+ return 0;
+}
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 86d91a9..ef567c7 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -332,7 +332,8 @@
virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) = 0;
/* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */
- virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0;
+ virtual std::shared_ptr<PointerControllerInterface> obtainPointerController(
+ int32_t deviceId) = 0;
/* Notifies the input reader policy that some input devices have changed
* and provides information about all current input devices.
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index 194c665..85d7247 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -33,7 +33,7 @@
* The pointer controller is responsible for providing synchronization and for tracking
* display orientation changes if needed.
*/
-class PointerControllerInterface : public virtual RefBase {
+class PointerControllerInterface {
protected:
PointerControllerInterface() { }
virtual ~PointerControllerInterface() { }
@@ -59,11 +59,11 @@
/* Gets the absolute location of the pointer. */
virtual void getPosition(float* outX, float* outY) const = 0;
- enum Transition {
+ enum class Transition {
// Fade/unfade immediately.
- TRANSITION_IMMEDIATE,
+ IMMEDIATE,
// Fade/unfade gradually.
- TRANSITION_GRADUAL,
+ GRADUAL,
};
/* Fades the pointer out now. */
@@ -75,11 +75,11 @@
* wants to ensure that the pointer becomes visible again. */
virtual void unfade(Transition transition) = 0;
- enum Presentation {
+ enum class Presentation {
// Show the mouse pointer.
- PRESENTATION_POINTER,
+ POINTER,
// Show spots and a spot anchor in place of the mouse pointer.
- PRESENTATION_SPOT,
+ SPOT,
};
/* Sets the mode of the pointer controller. */
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index 2395177..da837a5 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -20,6 +20,7 @@
#include "CursorButtonAccumulator.h"
#include "CursorScrollAccumulator.h"
+#include "PointerControllerInterface.h"
#include "TouchCursorInputMapperCommon.h"
namespace android {
@@ -153,7 +154,7 @@
mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
mSource = AINPUT_SOURCE_MOUSE_RELATIVE;
// Keep PointerController around in order to preserve the pointer position.
- mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
} else {
ALOGE("Cannot request pointer capture, device is not in MODE_POINTER");
}
@@ -335,7 +336,7 @@
int32_t displayId;
if (mSource == AINPUT_SOURCE_MOUSE) {
if (moved || scrolled || buttonsChanged) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+ mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
if (moved) {
mPointerController->move(deltaX, deltaY);
@@ -345,7 +346,7 @@
mPointerController->setButtonState(currentButtonState);
}
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
}
float x, y;
@@ -480,7 +481,7 @@
void CursorInputMapper::fadePointer() {
if (mPointerController != nullptr) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
}
}
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index 05b6967..a1e9f10 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -107,7 +107,7 @@
int32_t mOrientation;
- sp<PointerControllerInterface> mPointerController;
+ std::shared_ptr<PointerControllerInterface> mPointerController;
int32_t mButtonState;
nsecs_t mDownTime;
diff --git a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
index efa3d6d..ca18edc 100644
--- a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
+++ b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h
@@ -17,12 +17,12 @@
#ifndef _UI_INPUTREADER_TOUCH_CURSOR_INPUT_MAPPER_COMMON_H
#define _UI_INPUTREADER_TOUCH_CURSOR_INPUT_MAPPER_COMMON_H
+#include <stdint.h>
+
#include "EventHub.h"
#include "InputListener.h"
#include "InputReaderContext.h"
-#include <stdint.h>
-
namespace android {
// --- Static Definitions ---
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index fb35bee..97cbad2 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -778,7 +778,7 @@
mPointerController->setDisplayViewport(defaultViewport.value_or(mViewport));
}
} else {
- mPointerController.clear();
+ mPointerController.reset();
}
if (viewportChanged || deviceModeChanged) {
@@ -1394,7 +1394,7 @@
resetExternalStylus();
if (mPointerController != nullptr) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
mPointerController->clearSpots();
}
@@ -1614,8 +1614,8 @@
} else {
if (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches &&
mPointerController != nullptr) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->setPresentation(PointerControllerInterface::Presentation::SPOT);
+ mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
mPointerController->setButtonState(mCurrentRawState.buttonState);
mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords,
@@ -2366,7 +2366,7 @@
// Update the pointer presentation and spots.
if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+ mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
if (finishPreviousGesture || cancelPreviousGesture) {
mPointerController->clearSpots();
}
@@ -2378,7 +2378,7 @@
mPointerController->getDisplayId());
}
} else {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+ mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
}
// Show or hide the pointer if needed.
@@ -2388,7 +2388,7 @@
if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH &&
mPointerGesture.lastGestureMode == PointerGesture::FREEFORM) {
// Remind the user of where the pointer is after finishing a gesture with spots.
- mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->unfade(PointerControllerInterface::Transition::GRADUAL);
}
break;
case PointerGesture::TAP:
@@ -2399,15 +2399,15 @@
case PointerGesture::SWIPE:
// Unfade the pointer when the current gesture manipulates the
// area directly under the pointer.
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
break;
case PointerGesture::FREEFORM:
// Fade the pointer when the current gesture manipulates a different
// area and there are spots to guide the user experience.
if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
} else {
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
}
break;
}
@@ -2578,7 +2578,7 @@
// Remove any current spots.
if (mPointerController != nullptr) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
mPointerController->clearSpots();
}
}
@@ -3438,12 +3438,12 @@
if (mPointerController != nullptr) {
if (down || hovering) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+ mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
mPointerController->clearSpots();
mPointerController->setButtonState(mCurrentRawState.buttonState);
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
} else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
}
displayId = mPointerController->getDisplayId();
}
@@ -3652,7 +3652,7 @@
void TouchInputMapper::fadePointer() {
if (mPointerController != nullptr) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
}
}
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index d14812a..b445981 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -444,7 +444,7 @@
nsecs_t mDownTime;
// The pointer controller, or null if the device is not a pointer.
- sp<PointerControllerInterface> mPointerController;
+ std::shared_ptr<PointerControllerInterface> mPointerController;
std::vector<VirtualKey> mVirtualKeys;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 7442e68..8e80b63 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -24,11 +24,12 @@
#include <SwitchInputMapper.h>
#include <TestInputListener.h>
#include <TouchInputMapper.h>
-
#include <gtest/gtest.h>
#include <inttypes.h>
#include <math.h>
+#include <memory>
+#include <unordered_map>
namespace android {
@@ -68,15 +69,14 @@
int32_t mButtonState;
int32_t mDisplayId;
-protected:
- virtual ~FakePointerController() { }
-
public:
FakePointerController() :
mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
mButtonState(0), mDisplayId(ADISPLAY_ID_DEFAULT) {
}
+ virtual ~FakePointerController() {}
+
void setBounds(float minX, float minY, float maxX, float maxY) {
mHaveBounds = true;
mMinX = minX;
@@ -165,7 +165,7 @@
class FakeInputReaderPolicy : public InputReaderPolicyInterface {
InputReaderConfiguration mConfig;
- KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
+ std::unordered_map<int32_t, std::shared_ptr<FakePointerController>> mPointerControllers;
std::vector<InputDeviceInfo> mInputDevices;
std::vector<DisplayViewport> mViewports;
TouchAffineTransformation transform;
@@ -226,8 +226,8 @@
}
}
- void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) {
- mPointerControllers.add(deviceId, controller);
+ void setPointerController(int32_t deviceId, std::shared_ptr<FakePointerController> controller) {
+ mPointerControllers.insert_or_assign(deviceId, std::move(controller));
}
const InputReaderConfiguration* getReaderConfiguration() const {
@@ -288,8 +288,8 @@
*outConfig = mConfig;
}
- virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
- return mPointerControllers.valueFor(deviceId);
+ virtual std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
+ return mPointerControllers[deviceId];
}
virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) {
@@ -1887,9 +1887,9 @@
ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
}
- static void assertPosition(const sp<FakePointerController>& controller, float x, float y) {
+ static void assertPosition(const FakePointerController& controller, float x, float y) {
float actualX, actualY;
- controller->getPosition(&actualX, &actualY);
+ controller.getPosition(&actualX, &actualY);
ASSERT_NEAR(x, actualX, 1);
ASSERT_NEAR(y, actualY, 1);
}
@@ -2395,12 +2395,12 @@
protected:
static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
- sp<FakePointerController> mFakePointerController;
+ std::shared_ptr<FakePointerController> mFakePointerController;
virtual void SetUp() {
InputMapperTest::SetUp();
- mFakePointerController = new FakePointerController();
+ mFakePointerController = std::make_shared<FakePointerController>();
mFakePolicy->setPointerController(mDevice->getId(), mFakePointerController);
}
@@ -3067,7 +3067,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+ ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
}
TEST_F(CursorInputMapperTest, Process_PointerCapture) {
@@ -3096,7 +3096,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f));
+ ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
// Button press.
process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 1);
@@ -3135,7 +3135,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f));
+ ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
// Disable pointer capture and check that the device generation got bumped
// and events are generated the usual way.
@@ -3156,7 +3156,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+ ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
}
TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
@@ -3185,7 +3185,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+ ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
ASSERT_EQ(SECOND_DISPLAY_ID, args.displayId);
}
@@ -6340,7 +6340,8 @@
TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
// Setup for second display.
- sp<FakePointerController> fakePointerController = new FakePointerController();
+ std::shared_ptr<FakePointerController> fakePointerController =
+ std::make_shared<FakePointerController>();
fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
fakePointerController->setPosition(100, 200);
fakePointerController->setButtonState(0);
@@ -6401,7 +6402,8 @@
device2->reset(ARBITRARY_TIME);
// Setup PointerController.
- sp<FakePointerController> fakePointerController = new FakePointerController();
+ std::shared_ptr<FakePointerController> fakePointerController =
+ std::make_shared<FakePointerController>();
mFakePolicy->setPointerController(mDevice->getId(), fakePointerController);
mFakePolicy->setPointerController(SECOND_DEVICE_ID, fakePointerController);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 60b3cf0..c033290 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -55,6 +55,7 @@
#include <gui/IProducerListener.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
+#include <hidl/ServiceManagement.h>
#include <input/IInputFlinger.h>
#include <renderengine/RenderEngine.h>
#include <ui/ColorSpace.h>
@@ -401,7 +402,7 @@
// deriving the setting from the set service name, but it
// would be brittle if the name that's not 'default' is used
// for production purposes later on.
- setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+ android::hardware::details::setTrebleTestingOverride(true);
}
}