Merge "Reland "Let InputReader handle its own thread""
diff --git a/Android.bp b/Android.bp
index bf4cf5d..9829c7f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -7,6 +7,7 @@
 }
 
 subdirs = [
+    "adbd_auth",
     "cmds/*",
     "headers",
     "libs/*",
diff --git a/cmds/installd/migrate_legacy_obb_data.sh b/cmds/installd/migrate_legacy_obb_data.sh
index 1075688..0e6d7b9 100644
--- a/cmds/installd/migrate_legacy_obb_data.sh
+++ b/cmds/installd/migrate_legacy_obb_data.sh
@@ -15,17 +15,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-rm -rf /sdcard/Android/obb/test_probe
-mkdir -p /sdcard/Android/obb/
-touch /sdcard/Android/obb/test_probe
+rm -rf /data/media/Android/obb/test_probe
+mkdir -p /data/media/Android/obb/
+touch /data/media/Android/obb/test_probe
 if ! test -f /data/media/0/Android/obb/test_probe ; then
   log -p i -t migrate_legacy_obb_data "No support for 'unshared_obb'. Not migrating"
-  rm -rf /sdcard/Android/obb/test_probe
+  rm -rf /data/media/Android/obb/test_probe
   exit 0
 fi
 
 # Delete the test file, and remove the obb folder if it is empty
-rm -rf /sdcard/Android/obb/test_probe
+rm -rf /data/media/Android/obb/test_probe
 rmdir /data/media/obb
 
 if ! test -d /data/media/obb ; then
diff --git a/headers/media_plugin/media/openmax/OMX_Video.h b/headers/media_plugin/media/openmax/OMX_Video.h
index b6edaa9..81ee5fb 100644
--- a/headers/media_plugin/media/openmax/OMX_Video.h
+++ b/headers/media_plugin/media/openmax/OMX_Video.h
@@ -90,6 +90,7 @@
     OMX_VIDEO_CodingHEVC,       /**< ITU H.265/HEVC */
     OMX_VIDEO_CodingDolbyVision,/**< Dolby Vision */
     OMX_VIDEO_CodingImageHEIC,  /**< HEIF image encoded with HEVC */
+    OMX_VIDEO_CodingAV1,        /**< AV1 */
     OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
     OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_CodingMax = 0x7FFFFFFF
diff --git a/libs/adbd_auth/Android.bp b/libs/adbd_auth/Android.bp
new file mode 100644
index 0000000..9cf0143
--- /dev/null
+++ b/libs/adbd_auth/Android.bp
@@ -0,0 +1,44 @@
+// Copyright (C) 2019 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.
+
+cc_library {
+    name: "libadbd_auth",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wthread-safety",
+        "-Werror",
+    ],
+    srcs: ["adbd_auth.cpp"],
+    export_include_dirs: ["include"],
+
+    version_script: "libadbd_auth.map.txt",
+    stubs: {
+        symbol_file: "libadbd_auth.map.txt",
+    },
+
+    host_supported: true,
+    recovery_available: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    },
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "liblog",
+    ],
+}
diff --git a/libs/adbd_auth/adbd_auth.cpp b/libs/adbd_auth/adbd_auth.cpp
new file mode 100644
index 0000000..6479109
--- /dev/null
+++ b/libs/adbd_auth/adbd_auth.cpp
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2019 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 ANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION
+
+#include "include/adbd_auth.h"
+
+#include <inttypes.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <sys/uio.h>
+
+#include <chrono>
+#include <deque>
+#include <string>
+#include <string_view>
+#include <tuple>
+#include <unordered_map>
+#include <utility>
+#include <variant>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android-base/strings.h>
+#include <android-base/thread_annotations.h>
+#include <android-base/unique_fd.h>
+#include <cutils/sockets.h>
+
+using android::base::unique_fd;
+
+struct AdbdAuthPacketAuthenticated {
+    std::string public_key;
+};
+
+struct AdbdAuthPacketDisconnected {
+    std::string public_key;
+};
+
+struct AdbdAuthPacketRequestAuthorization {
+    std::string public_key;
+};
+
+using AdbdAuthPacket = std::variant<AdbdAuthPacketAuthenticated, AdbdAuthPacketDisconnected,
+                                    AdbdAuthPacketRequestAuthorization>;
+
+struct AdbdAuthContext {
+    static constexpr uint64_t kEpollConstSocket = 0;
+    static constexpr uint64_t kEpollConstEventFd = 1;
+    static constexpr uint64_t kEpollConstFramework = 2;
+
+public:
+    explicit AdbdAuthContext(AdbdAuthCallbacksV1* callbacks) : next_id_(0), callbacks_(*callbacks) {
+        epoll_fd_.reset(epoll_create1(EPOLL_CLOEXEC));
+        if (epoll_fd_ == -1) {
+            PLOG(FATAL) << "failed to create epoll fd";
+        }
+
+        event_fd_.reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
+        if (event_fd_ == -1) {
+            PLOG(FATAL) << "failed to create eventfd";
+        }
+
+        sock_fd_.reset(android_get_control_socket("adbd"));
+        if (sock_fd_ == -1) {
+            PLOG(ERROR) << "failed to get adbd authentication socket";
+        } else {
+            if (fcntl(sock_fd_.get(), F_SETFD, FD_CLOEXEC) != 0) {
+                PLOG(FATAL) << "failed to make adbd authentication socket cloexec";
+            }
+
+            if (fcntl(sock_fd_.get(), F_SETFL, O_NONBLOCK) != 0) {
+                PLOG(FATAL) << "failed to make adbd authentication socket nonblocking";
+            }
+
+            if (listen(sock_fd_.get(), 4) != 0) {
+                PLOG(FATAL) << "failed to listen on adbd authentication socket";
+            }
+        }
+    }
+
+    AdbdAuthContext(const AdbdAuthContext& copy) = delete;
+    AdbdAuthContext(AdbdAuthContext&& move) = delete;
+    AdbdAuthContext& operator=(const AdbdAuthContext& copy) = delete;
+    AdbdAuthContext& operator=(AdbdAuthContext&& move) = delete;
+
+    uint64_t NextId() { return next_id_++; }
+
+    void DispatchPendingPrompt() REQUIRES(mutex_) {
+        if (dispatched_prompt_) {
+            LOG(INFO) << "adbd_auth: prompt currently pending, skipping";
+            return;
+        }
+
+        if (pending_prompts_.empty()) {
+            LOG(INFO) << "adbd_auth: no prompts to send";
+            return;
+        }
+
+        LOG(INFO) << "adbd_auth: prompting user for adb authentication";
+        auto [id, public_key, arg] = std::move(pending_prompts_.front());
+        pending_prompts_.pop_front();
+
+        this->output_queue_.emplace_back(
+                AdbdAuthPacketRequestAuthorization{.public_key = public_key});
+
+        Interrupt();
+        dispatched_prompt_ = std::make_tuple(id, public_key, arg);
+    }
+
+    void UpdateFrameworkWritable() REQUIRES(mutex_) {
+        // This might result in redundant calls to EPOLL_CTL_MOD if, for example, we get notified
+        // at the same time as a framework connection, but that's unlikely and this doesn't need to
+        // be fast anyway.
+        if (framework_fd_ != -1) {
+            struct epoll_event event;
+            event.events = EPOLLIN;
+            if (!output_queue_.empty()) {
+                LOG(INFO) << "marking framework writable";
+                event.events |= EPOLLOUT;
+            }
+            event.data.u64 = kEpollConstFramework;
+            CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_MOD, framework_fd_.get(), &event));
+        }
+    }
+
+    void ReplaceFrameworkFd(unique_fd new_fd) REQUIRES(mutex_) {
+        LOG(INFO) << "received new framework fd " << new_fd.get()
+                  << " (current = " << framework_fd_.get() << ")";
+
+        // If we already had a framework fd, clean up after ourselves.
+        if (framework_fd_ != -1) {
+            output_queue_.clear();
+            dispatched_prompt_.reset();
+            CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_DEL, framework_fd_.get(), nullptr));
+            framework_fd_.reset();
+        }
+
+        if (new_fd != -1) {
+            struct epoll_event event;
+            event.events = EPOLLIN;
+            if (!output_queue_.empty()) {
+                LOG(INFO) << "marking framework writable";
+                event.events |= EPOLLOUT;
+            }
+            event.data.u64 = kEpollConstFramework;
+            CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, new_fd.get(), &event));
+            framework_fd_ = std::move(new_fd);
+        }
+    }
+
+    void HandlePacket(std::string_view packet) REQUIRES(mutex_) {
+        LOG(INFO) << "received packet: " << packet;
+
+        if (packet.length() < 2) {
+          LOG(ERROR) << "received packet of invalid length";
+          ReplaceFrameworkFd(unique_fd());
+        }
+
+        if (packet[0] == 'O' && packet[1] == 'K') {
+          CHECK(this->dispatched_prompt_.has_value());
+          auto& [id, key, arg] = *this->dispatched_prompt_;
+          keys_.emplace(id, std::move(key));
+
+          this->callbacks_.key_authorized(arg, id);
+          this->dispatched_prompt_ = std::nullopt;
+        } else if (packet[0] == 'N' && packet[1] == 'O') {
+          CHECK_EQ(2UL, packet.length());
+          // TODO: Do we want a callback if the key is denied?
+          this->dispatched_prompt_ = std::nullopt;
+          DispatchPendingPrompt();
+        } else {
+          LOG(ERROR) << "unhandled packet: " << packet;
+          ReplaceFrameworkFd(unique_fd());
+        }
+    }
+
+    bool SendPacket() REQUIRES(mutex_) {
+        if (output_queue_.empty()) {
+            return false;
+        }
+
+        CHECK_NE(-1, framework_fd_.get());
+
+        auto& packet = output_queue_.front();
+        struct iovec iovs[2];
+        if (auto* p = std::get_if<AdbdAuthPacketAuthenticated>(&packet)) {
+            iovs[0].iov_base = const_cast<char*>("CK");
+            iovs[0].iov_len = 2;
+            iovs[1].iov_base = p->public_key.data();
+            iovs[1].iov_len = p->public_key.size();
+        } else if (auto* p = std::get_if<AdbdAuthPacketDisconnected>(&packet)) {
+            iovs[0].iov_base = const_cast<char*>("DC");
+            iovs[0].iov_len = 2;
+            iovs[1].iov_base = p->public_key.data();
+            iovs[1].iov_len = p->public_key.size();
+        } else if (auto* p = std::get_if<AdbdAuthPacketRequestAuthorization>(&packet)) {
+            iovs[0].iov_base = const_cast<char*>("PK");
+            iovs[0].iov_len = 2;
+            iovs[1].iov_base = p->public_key.data();
+            iovs[1].iov_len = p->public_key.size();
+        } else {
+            LOG(FATAL) << "unhandled packet type?";
+        }
+
+        output_queue_.pop_front();
+
+        ssize_t rc = writev(framework_fd_.get(), iovs, 2);
+        if (rc == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
+            PLOG(ERROR) << "failed to write to framework fd";
+            ReplaceFrameworkFd(unique_fd());
+            return false;
+        }
+
+        return true;
+    }
+
+    void Run() {
+        if (sock_fd_ == -1) {
+            LOG(ERROR) << "adbd authentication socket unavailable, disabling user prompts";
+        } else {
+            struct epoll_event event;
+            event.events = EPOLLIN;
+            event.data.u64 = kEpollConstSocket;
+            CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, sock_fd_.get(), &event));
+        }
+
+        {
+            struct epoll_event event;
+            event.events = EPOLLIN;
+            event.data.u64 = kEpollConstEventFd;
+            CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, event_fd_.get(), &event));
+        }
+
+        while (true) {
+            struct epoll_event events[3];
+            int rc = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_.get(), events, 3, -1));
+            if (rc == -1) {
+                PLOG(FATAL) << "epoll_wait failed";
+            } else if (rc == 0) {
+                LOG(FATAL) << "epoll_wait returned 0";
+            }
+
+            bool restart = false;
+            for (int i = 0; i < rc; ++i) {
+                if (restart) {
+                    break;
+                }
+
+                struct epoll_event& event = events[i];
+                switch (event.data.u64) {
+                    case kEpollConstSocket: {
+                        unique_fd new_framework_fd(accept4(sock_fd_.get(), nullptr, nullptr,
+                                                           SOCK_CLOEXEC | SOCK_NONBLOCK));
+                        if (new_framework_fd == -1) {
+                            PLOG(FATAL) << "failed to accept framework fd";
+                        }
+
+                        LOG(INFO) << "adbd_auth: received a new framework connection";
+                        std::lock_guard<std::mutex> lock(mutex_);
+                        ReplaceFrameworkFd(std::move(new_framework_fd));
+
+                        // Stop iterating over events: one of the later ones might be the old
+                        // framework fd.
+                        restart = false;
+                        break;
+                    }
+
+                    case kEpollConstEventFd: {
+                        // We were woken up to write something.
+                        uint64_t dummy;
+                        int rc = TEMP_FAILURE_RETRY(read(event_fd_.get(), &dummy, sizeof(dummy)));
+                        if (rc != 8) {
+                            PLOG(FATAL) << "failed to read from eventfd (rc = " << rc << ")";
+                        }
+
+                        std::lock_guard<std::mutex> lock(mutex_);
+                        UpdateFrameworkWritable();
+                        break;
+                    }
+
+                    case kEpollConstFramework: {
+                        char buf[4096];
+                        if (event.events & EPOLLIN) {
+                            int rc = TEMP_FAILURE_RETRY(read(framework_fd_.get(), buf, sizeof(buf)));
+                            if (rc == -1) {
+                                LOG(FATAL) << "failed to read from framework fd";
+                            } else if (rc == 0) {
+                                LOG(INFO) << "hit EOF on framework fd";
+                                std::lock_guard<std::mutex> lock(mutex_);
+                                ReplaceFrameworkFd(unique_fd());
+                            } else {
+                                std::lock_guard<std::mutex> lock(mutex_);
+                                HandlePacket(std::string_view(buf, rc));
+                            }
+                        }
+
+                        if (event.events & EPOLLOUT) {
+                            std::lock_guard<std::mutex> lock(mutex_);
+                            while (SendPacket()) {
+                                continue;
+                            }
+                            UpdateFrameworkWritable();
+                        }
+
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    static constexpr const char* key_paths[] = {"/adb_keys", "/data/misc/adb/adb_keys"};
+    void IteratePublicKeys(bool (*callback)(const char*, size_t, void*), void* arg) {
+        for (const auto& path : key_paths) {
+            if (access(path, R_OK) == 0) {
+                LOG(INFO) << "Loading keys from " << path;
+                std::string content;
+                if (!android::base::ReadFileToString(path, &content)) {
+                    PLOG(ERROR) << "Couldn't read " << path;
+                    continue;
+                }
+                for (const auto& line : android::base::Split(content, "\n")) {
+                    if (!callback(line.data(), line.size(), arg)) {
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    uint64_t PromptUser(std::string_view public_key, void* arg) EXCLUDES(mutex_) {
+        uint64_t id = NextId();
+
+        std::lock_guard<std::mutex> lock(mutex_);
+        pending_prompts_.emplace_back(id, public_key, arg);
+        DispatchPendingPrompt();
+        return id;
+    }
+
+    uint64_t NotifyAuthenticated(std::string_view public_key) EXCLUDES(mutex_) {
+        uint64_t id = NextId();
+        std::lock_guard<std::mutex> lock(mutex_);
+        keys_.emplace(id, public_key);
+        output_queue_.emplace_back(
+                AdbdAuthPacketDisconnected{.public_key = std::string(public_key)});
+        return id;
+    }
+
+    void NotifyDisconnected(uint64_t id) EXCLUDES(mutex_) {
+        std::lock_guard<std::mutex> lock(mutex_);
+        auto it = keys_.find(id);
+        if (it == keys_.end()) {
+            LOG(DEBUG) << "couldn't find public key to notify disconnection, skipping";
+            return;
+        }
+        output_queue_.emplace_back(AdbdAuthPacketDisconnected{.public_key = std::move(it->second)});
+        keys_.erase(it);
+    }
+
+    // Interrupt the worker thread to do some work.
+    void Interrupt() {
+        uint64_t value = 1;
+        ssize_t rc = write(event_fd_.get(), &value, sizeof(value));
+        if (rc == -1) {
+            PLOG(FATAL) << "write to eventfd failed";
+        } else if (rc != sizeof(value)) {
+            LOG(FATAL) << "write to eventfd returned short (" << rc << ")";
+        }
+    }
+
+    unique_fd epoll_fd_;
+    unique_fd event_fd_;
+    unique_fd sock_fd_;
+    unique_fd framework_fd_;
+
+    std::atomic<uint64_t> next_id_;
+    AdbdAuthCallbacksV1 callbacks_;
+
+    std::mutex mutex_;
+    std::unordered_map<uint64_t, std::string> keys_ GUARDED_BY(mutex_);
+
+    // We keep two separate queues: one to handle backpressure from the socket (output_queue_)
+    // and one to make sure we only dispatch one authrequest at a time (pending_prompts_).
+    std::deque<AdbdAuthPacket> output_queue_;
+
+    std::optional<std::tuple<uint64_t, std::string, void*>> dispatched_prompt_ GUARDED_BY(mutex_);
+    std::deque<std::tuple<uint64_t, std::string, void*>> pending_prompts_ GUARDED_BY(mutex_);
+};
+
+AdbdAuthContext* adbd_auth_new(AdbdAuthCallbacks* callbacks) {
+    if (callbacks->version != 1) {
+      LOG(ERROR) << "received unknown AdbdAuthCallbacks version " << callbacks->version;
+      return nullptr;
+    }
+
+    return new AdbdAuthContext(&callbacks->callbacks.v1);
+}
+
+void adbd_auth_delete(AdbdAuthContext* ctx) {
+    delete ctx;
+}
+
+void adbd_auth_run(AdbdAuthContext* ctx) {
+    return ctx->Run();
+}
+
+void adbd_auth_get_public_keys(AdbdAuthContext* ctx,
+                               bool (*callback)(const char* public_key, size_t len, void* arg),
+                               void* arg) {
+    ctx->IteratePublicKeys(callback, arg);
+}
+
+uint64_t adbd_auth_notify_auth(AdbdAuthContext* ctx, const char* public_key, size_t len) {
+    return ctx->NotifyAuthenticated(std::string_view(public_key, len));
+}
+
+void adbd_auth_notify_disconnect(AdbdAuthContext* ctx, uint64_t id) {
+    return ctx->NotifyDisconnected(id);
+}
+
+void adbd_auth_prompt_user(AdbdAuthContext* ctx, const char* public_key, size_t len,
+                               void* arg) {
+    ctx->PromptUser(std::string_view(public_key, len), arg);
+}
+
+bool adbd_auth_supports_feature(AdbdAuthFeature) {
+    return false;
+}
diff --git a/libs/adbd_auth/include/adbd_auth.h b/libs/adbd_auth/include/adbd_auth.h
new file mode 100644
index 0000000..b7c1cb8
--- /dev/null
+++ b/libs/adbd_auth/include/adbd_auth.h
@@ -0,0 +1,65 @@
+#pragma once
+
+/*
+ * Copyright (C) 2019 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 <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+extern "C" {
+
+struct AdbdAuthCallbacksV1 {
+    // Callback for a successful user authorization.
+    void (*key_authorized)(void* arg, uint64_t id);
+};
+
+struct AdbdAuthCallbacks {
+    uint32_t version;
+    union {
+        AdbdAuthCallbacksV1 v1;
+    } callbacks;
+};
+
+struct AdbdAuthContext;
+
+AdbdAuthContext* adbd_auth_new(AdbdAuthCallbacks* callbacks);
+void adbd_auth_delete(AdbdAuthContext* ctx);
+
+void adbd_auth_run(AdbdAuthContext* ctx);
+
+// Iterate through the list of authorized public keys.
+// Return false from the callback to stop iteration.
+void adbd_auth_get_public_keys(AdbdAuthContext* ctx,
+                               bool (*callback)(const char* public_key, size_t len, void* arg),
+                               void* arg);
+
+// Let system_server know that a key has been successfully used for authentication.
+uint64_t adbd_auth_notify_auth(AdbdAuthContext* ctx, const char* public_key, size_t len);
+
+// Let system_server know that a connection has been closed.
+void adbd_auth_notify_disconnect(AdbdAuthContext* ctx, uint64_t id);
+
+// Prompt the user to authorize a public key.
+// When this happens, a callback will be run on the auth thread with the result.
+void adbd_auth_prompt_user(AdbdAuthContext* ctx, const char* public_key, size_t len, void* arg);
+
+enum AdbdAuthFeature {
+};
+
+bool adbd_auth_supports_feature(AdbdAuthFeature f);
+
+}
diff --git a/libs/adbd_auth/libadbd_auth.map.txt b/libs/adbd_auth/libadbd_auth.map.txt
new file mode 100644
index 0000000..d01233c
--- /dev/null
+++ b/libs/adbd_auth/libadbd_auth.map.txt
@@ -0,0 +1,13 @@
+LIBADBD_AUTH {
+  global:
+    adbd_auth_new; # apex
+    adbd_auth_delete; # apex
+    adbd_auth_run; # apex
+    adbd_auth_get_public_keys; #apex
+    adbd_auth_notify_auth; # apex
+    adbd_auth_notify_disconnect; # apex
+    adbd_auth_prompt_user; # apex
+    adbd_auth_supports_feature; # apex
+  local:
+    *;
+};
diff --git a/libs/arect/Android.bp b/libs/arect/Android.bp
index ad8287c..2518b14 100644
--- a/libs/arect/Android.bp
+++ b/libs/arect/Android.bp
@@ -13,13 +13,18 @@
 // limitations under the License.
 
 ndk_headers {
-    name: "libarect_headers",
+    name: "libarect_headers_for_ndk",
     from: "include/android",
     to: "android",
     srcs: ["include/android/*.h"],
     license: "NOTICE",
 }
 
+cc_library_headers {
+    name: "libarect_headers",
+    export_include_dirs: ["include"],
+}
+
 cc_library_static {
     name: "libarect",
     host_supported: true,
diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp
index 60f047f..4f0b7d3 100644
--- a/libs/binder/AppOpsManager.cpp
+++ b/libs/binder/AppOpsManager.cpp
@@ -115,23 +115,19 @@
 }
 
 int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) {
-    return noteOp(op, uid, callingPackage, String16(), String16());
+    return noteOp(op, uid, callingPackage, std::unique_ptr<String16>(),
+            String16("Legacy AppOpsManager.noteOp call"));
 }
 
 int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage,
-        const String16& featureId, const String16& message) {
+        const std::unique_ptr<String16>& featureId, const String16& message) {
     sp<IAppOpsService> service = getService();
     int32_t mode = service != nullptr
-            ? service->noteOperation(op, uid, callingPackage)
+            ? service->noteOperation(op, uid, callingPackage, featureId)
             : APP_OPS_MANAGER_UNAVAILABLE_MODE;
 
     if (mode == AppOpsManager::MODE_ALLOWED) {
-        if (message.size() == 0) {
-            markAppOpNoted(uid, callingPackage, op, featureId,
-                    String16("noteOp from native code"));
-        } else {
-            markAppOpNoted(uid, callingPackage, op, featureId, message);
-        }
+        markAppOpNoted(uid, callingPackage, op, featureId, message);
     }
 
     return mode;
@@ -139,32 +135,34 @@
 
 int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
         bool startIfModeDefault) {
-    return startOpNoThrow(op, uid, callingPackage, startIfModeDefault, String16(), String16());
+    return startOpNoThrow(op, uid, callingPackage, startIfModeDefault, std::unique_ptr<String16>(),
+            String16("Legacy AppOpsManager.startOpNoThrow call"));
 }
 
 int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
-        bool startIfModeDefault, const String16& featureId, const String16& message) {
+        bool startIfModeDefault, const std::unique_ptr<String16>& featureId,
+        const String16& message) {
     sp<IAppOpsService> service = getService();
     int32_t mode = service != nullptr
             ? service->startOperation(getToken(service), op, uid, callingPackage,
-                    startIfModeDefault) : APP_OPS_MANAGER_UNAVAILABLE_MODE;
+                    featureId, startIfModeDefault) : APP_OPS_MANAGER_UNAVAILABLE_MODE;
 
     if (mode == AppOpsManager::MODE_ALLOWED) {
-        if (message.size() == 0) {
-            markAppOpNoted(uid, callingPackage, op, featureId,
-                    String16("startOp from native code"));
-        } else {
-            markAppOpNoted(uid, callingPackage, op, featureId, message);
-        }
+        markAppOpNoted(uid, callingPackage, op, featureId, message);
     }
 
     return mode;
 }
 
 void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) {
+    finishOp(op, uid, callingPackage, std::unique_ptr<String16>());
+}
+
+void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage,
+        const std::unique_ptr<String16>& callingFeatureId) {
     sp<IAppOpsService> service = getService();
     if (service != nullptr) {
-        service->finishOperation(getToken(service), op, uid, callingPackage);
+        service->finishOperation(getToken(service), op, uid, callingPackage, callingFeatureId);
     }
 }
 
@@ -207,7 +205,7 @@
 }
 
 void AppOpsManager::markAppOpNoted(int32_t uid, const String16& packageName, int32_t opCode,
-         const String16& featureId, const String16& message) {
+         const std::unique_ptr<String16>& featureId, const String16& message) {
     // check it the appops needs to be collected and cache result
     if (appOpsToNote[opCode] == 0) {
         if (shouldCollectNotes(opCode)) {
@@ -221,11 +219,11 @@
         return;
     }
 
-    noteAsyncOp(String16(), uid, packageName, opCode, featureId, message);
+    noteAsyncOp(std::unique_ptr<String16>(), uid, packageName, opCode, featureId, message);
 }
 
-void AppOpsManager::noteAsyncOp(const String16& callingPackageName, int32_t uid,
-         const String16& packageName, int32_t opCode, const String16& featureId,
+void AppOpsManager::noteAsyncOp(const std::unique_ptr<String16>& callingPackageName, int32_t uid,
+         const String16& packageName, int32_t opCode, const std::unique_ptr<String16>& featureId,
          const String16& message) {
     sp<IAppOpsService> service = getService();
     if (service != nullptr) {
diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp
index 9760e13..b85a5f2 100644
--- a/libs/binder/IAppOpsService.cpp
+++ b/libs/binder/IAppOpsService.cpp
@@ -46,12 +46,14 @@
         return reply.readInt32();
     }
 
-    virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) {
+    virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName,
+                const std::unique_ptr<String16>& featureId) {
         Parcel data, reply;
         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
         data.writeInt32(code);
         data.writeInt32(uid);
         data.writeString16(packageName);
+        data.writeString16(featureId);
         remote()->transact(NOTE_OPERATION_TRANSACTION, data, &reply);
         // fail on exception
         if (reply.readExceptionCode() != 0) return MODE_ERRORED;
@@ -59,13 +61,15 @@
     }
 
     virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
-                const String16& packageName, bool startIfModeDefault) {
+                const String16& packageName, const std::unique_ptr<String16>& featureId,
+                bool startIfModeDefault) {
         Parcel data, reply;
         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
         data.writeInt32(code);
         data.writeInt32(uid);
         data.writeString16(packageName);
+        data.writeString16(featureId);
         data.writeInt32(startIfModeDefault ? 1 : 0);
         remote()->transact(START_OPERATION_TRANSACTION, data, &reply);
         // fail on exception
@@ -74,13 +78,14 @@
     }
 
     virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
-            const String16& packageName) {
+            const String16& packageName, const std::unique_ptr<String16>& featureId) {
         Parcel data, reply;
         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
         data.writeInt32(code);
         data.writeInt32(uid);
         data.writeString16(packageName);
+        data.writeString16(featureId);
         remote()->transact(FINISH_OPERATION_TRANSACTION, data, &reply);
     }
 
@@ -144,37 +149,16 @@
         remote()->transact(SET_CAMERA_AUDIO_RESTRICTION_TRANSACTION, data, &reply);
     }
 
-    virtual void noteAsyncOp(const String16& callingPackageName, int32_t uid,
-            const String16& packageName, int32_t opCode, const String16& featureId,
+    virtual void noteAsyncOp(const std::unique_ptr<String16>& callingPackageName, int32_t uid,
+            const String16& packageName, int32_t opCode, const std::unique_ptr<String16>& featureId,
             const String16& message) {
         Parcel data, reply;
         data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
-
-        // Convert empty callingPackage into null string
-        if (callingPackageName.size() != 0) {
-            data.writeString16(callingPackageName);
-        } else {
-            data.writeString16(nullptr, 0);
-        }
-
+        data.writeString16(callingPackageName);
         data.writeInt32(uid);
-
-        // Convert empty packageName into null string
-        if (packageName.size() != 0) {
-            data.writeString16(packageName);
-        } else {
-            data.writeString16(nullptr, 0);
-        }
-
+        data.writeString16(packageName);
         data.writeInt32(opCode);
-
-        // Convert empty featureId into null string
-        if (featureId.size() != 0) {
-            data.writeString16(featureId);
-        } else {
-            data.writeString16(nullptr, 0);
-        }
-
+        data.writeString16(featureId);
         data.writeString16(message);
         remote()->transact(NOTE_ASYNC_OP_TRANSACTION, data, &reply);
     }
@@ -217,7 +201,9 @@
             int32_t code = data.readInt32();
             int32_t uid = data.readInt32();
             String16 packageName = data.readString16();
-            int32_t res = noteOperation(code, uid, packageName);
+            std::unique_ptr<String16> featureId;
+            data.readString16(&featureId);
+            int32_t res = noteOperation(code, uid, packageName, featureId);
             reply->writeNoException();
             reply->writeInt32(res);
             return NO_ERROR;
@@ -228,8 +214,11 @@
             int32_t code = data.readInt32();
             int32_t uid = data.readInt32();
             String16 packageName = data.readString16();
+            std::unique_ptr<String16> featureId;
+            data.readString16(&featureId);
             bool startIfModeDefault = data.readInt32() == 1;
-            int32_t res = startOperation(token, code, uid, packageName, startIfModeDefault);
+            int32_t res = startOperation(token, code, uid, packageName, featureId,
+                    startIfModeDefault);
             reply->writeNoException();
             reply->writeInt32(res);
             return NO_ERROR;
@@ -240,7 +229,9 @@
             int32_t code = data.readInt32();
             int32_t uid = data.readInt32();
             String16 packageName = data.readString16();
-            finishOperation(token, code, uid, packageName);
+            std::unique_ptr<String16> featureId;
+            data.readString16(&featureId);
+            finishOperation(token, code, uid, packageName, featureId);
             reply->writeNoException();
             return NO_ERROR;
         } break;
@@ -296,11 +287,13 @@
         } break;
         case NOTE_ASYNC_OP_TRANSACTION: {
             CHECK_INTERFACE(IAppOpsService, data, reply);
-            String16 callingPackageName = data.readString16();
+            std::unique_ptr<String16> callingPackageName;
+            data.readString16(&callingPackageName);
             int32_t uid = data.readInt32();
             String16 packageName = data.readString16();
             int32_t opCode = data.readInt32();
-            String16 featureId = data.readString16();
+            std::unique_ptr<String16> featureId;
+            data.readString16(&featureId);
             String16 message = data.readString16();
             noteAsyncOp(callingPackageName, uid, packageName, opCode, featureId, message);
             reply->writeNoException();
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h
index 2744ce1..22a0179 100644
--- a/libs/binder/include/binder/AppOpsManager.h
+++ b/libs/binder/include/binder/AppOpsManager.h
@@ -134,21 +134,26 @@
     //              const String16&) instead
     int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage);
     int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage,
-            const String16& featureId, const String16& message);
+            const std::unique_ptr<String16>& featureId, const String16& message);
     // @Deprecated, use startOpNoThrow(int32_t, int32_t, const String16&, bool, const String16&,
     //              const String16&) instead
     int32_t startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
             bool startIfModeDefault);
     int32_t startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage,
-            bool startIfModeDefault, const String16& featureId, const String16& message);
+            bool startIfModeDefault, const std::unique_ptr<String16>& featureId,
+            const String16& message);
+    // @Deprecated, use finishOp(int32_t, int32_t, const String16&, bool, const String16&) instead
     void finishOp(int32_t op, int32_t uid, const String16& callingPackage);
+    void finishOp(int32_t op, int32_t uid, const String16& callingPackage,
+            const std::unique_ptr<String16>& featureId);
     void startWatchingMode(int32_t op, const String16& packageName,
             const sp<IAppOpsCallback>& callback);
     void stopWatchingMode(const sp<IAppOpsCallback>& callback);
     int32_t permissionToOpCode(const String16& permission);
     void setCameraAudioRestriction(int32_t mode);
-    void noteAsyncOp(const String16& callingPackageName, int32_t uid, const String16& packageName,
-            int32_t opCode, const String16& featureId, const String16& message);
+    void noteAsyncOp(const std::unique_ptr<String16>& callingPackageName, int32_t uid,
+            const String16& packageName, int32_t opCode, const std::unique_ptr<String16>& featureId,
+            const String16& message);
 
 private:
     Mutex mLock;
@@ -156,7 +161,7 @@
 
     sp<IAppOpsService> getService();
     void markAppOpNoted(int32_t uid, const String16& packageName, int32_t opCode,
-            const String16& featureId, const String16& message);
+            const std::unique_ptr<String16>& featureId, const String16& message);
     bool shouldCollectNotes(int32_t opCode);
 };
 
diff --git a/libs/binder/include/binder/IAppOpsService.h b/libs/binder/include/binder/IAppOpsService.h
index ad34bc5..15ba005 100644
--- a/libs/binder/include/binder/IAppOpsService.h
+++ b/libs/binder/include/binder/IAppOpsService.h
@@ -35,11 +35,13 @@
     DECLARE_META_INTERFACE(AppOpsService)
 
     virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) = 0;
-    virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) = 0;
+    virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName,
+            const std::unique_ptr<String16>& featureId) = 0;
     virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
-            const String16& packageName, bool startIfModeDefault) = 0;
+            const String16& packageName, const std::unique_ptr<String16>& featureId,
+            bool startIfModeDefault) = 0;
     virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid,
-            const String16& packageName) = 0;
+            const String16& packageName, const std::unique_ptr<String16>& featureId) = 0;
     virtual void startWatchingMode(int32_t op, const String16& packageName,
             const sp<IAppOpsCallback>& callback) = 0;
     virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0;
@@ -48,8 +50,8 @@
     virtual int32_t checkAudioOperation(int32_t code, int32_t usage,int32_t uid,
             const String16& packageName) = 0;
     virtual void setCameraAudioRestriction(int32_t mode) = 0;
-    virtual void noteAsyncOp(const String16& callingPackageName, int32_t uid,
-            const String16& packageName, int32_t opCode, const String16& featureId,
+    virtual void noteAsyncOp(const std::unique_ptr<String16>& callingPackageName, int32_t uid,
+            const String16& packageName, int32_t opCode, const std::unique_ptr<String16>& featureId,
             const String16& message) = 0;
     virtual bool shouldCollectNotes(int32_t opCode) = 0;
 
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index bd77567..2c43263 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -113,6 +113,13 @@
     return interface_cast<INTERFACE>(sm->waitForService(name));
 }
 
+template <typename INTERFACE>
+sp<INTERFACE> checkDeclaredService(const String16& name) {
+    const sp<IServiceManager> sm = defaultServiceManager();
+    if (!sm->isDeclared(name)) return nullptr;
+    return interface_cast<INTERFACE>(sm->checkService(name));
+}
+
 template<typename INTERFACE>
 sp<INTERFACE> waitForVintfService(
         const String16& instance = String16("default")) {
@@ -121,6 +128,13 @@
 }
 
 template<typename INTERFACE>
+sp<INTERFACE> checkVintfService(
+        const String16& instance = String16("default")) {
+    return checkDeclaredService<INTERFACE>(
+        INTERFACE::descriptor + String16("/") + instance);
+}
+
+template<typename INTERFACE>
 status_t getService(const String16& name, sp<INTERFACE>* outService)
 {
     const sp<IServiceManager> sm = defaultServiceManager();
diff --git a/libs/binder/include/binder/ParcelFileDescriptor.h b/libs/binder/include/binder/ParcelFileDescriptor.h
index 662e56e..4635ad8 100644
--- a/libs/binder/include/binder/ParcelFileDescriptor.h
+++ b/libs/binder/include/binder/ParcelFileDescriptor.h
@@ -42,6 +42,24 @@
     android::status_t writeToParcel(android::Parcel* parcel) const override;
     android::status_t readFromParcel(const android::Parcel* parcel) override;
 
+    inline bool operator!=(const ParcelFileDescriptor& rhs) const {
+        return mFd != rhs.mFd;
+    }
+    inline bool operator<(const ParcelFileDescriptor& rhs) const {
+        return mFd < rhs.mFd;
+    }
+    inline bool operator<=(const ParcelFileDescriptor& rhs) const {
+        return mFd <= rhs.mFd;
+    }
+    inline bool operator==(const ParcelFileDescriptor& rhs) const {
+        return mFd == rhs.mFd;
+    }
+    inline bool operator>(const ParcelFileDescriptor& rhs) const {
+        return mFd > rhs.mFd;
+    }
+    inline bool operator>=(const ParcelFileDescriptor& rhs) const {
+        return mFd >= rhs.mFd;
+    }
 private:
     android::base::unique_fd mFd;
 };
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
index 8f37c5e..946ccb7 100644
--- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -159,13 +159,17 @@
      */
     T* getR() { return &mT; }
 
-    // copy-constructing, or move/copy assignment is disallowed
+    // copy-constructing/assignment is disallowed
     ScopedAResource(const ScopedAResource&) = delete;
     ScopedAResource& operator=(const ScopedAResource&) = delete;
-    ScopedAResource& operator=(ScopedAResource&&) = delete;
 
-    // move-constructing is okay
+    // move-constructing/assignment is okay
     ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) { other.mT = DEFAULT; }
+    ScopedAResource& operator=(ScopedAResource&& other) {
+        set(other.mT);
+        other.mT = DEFAULT;
+        return *this;
+    }
 
    private:
     T mT;
@@ -197,6 +201,7 @@
     explicit ScopedAStatus(AStatus* a = nullptr) : ScopedAResource(a) {}
     ~ScopedAStatus() {}
     ScopedAStatus(ScopedAStatus&&) = default;
+    ScopedAStatus& operator=(ScopedAStatus&&) = default;
 
     /**
      * See AStatus_isOk.
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 635ea69..5a7f9a9 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -119,12 +119,7 @@
     srcs: ["binderSafeInterfaceTest.cpp"],
 
     cppflags: [
-        "-Weverything",
-        "-Wno-c++98-compat",
-        "-Wno-c++98-compat-pedantic",
-        "-Wno-global-constructors",
-        "-Wno-padded",
-        "-Wno-weak-vtables",
+        "-Wextra",
     ],
 
     cpp_std: "experimental",
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 9a50175..3c31d74 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -33,6 +33,7 @@
     mBufferItemConsumer->setBufferFreedListener(this);
     mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
     mBufferItemConsumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888);
+    mBufferItemConsumer->setTransformHint(mSurfaceControl->getTransformHint());
 }
 
 void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, int width, int height) {
@@ -41,6 +42,7 @@
     mWidth = width;
     mHeight = height;
     mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
+    mBufferItemConsumer->setTransformHint(mSurfaceControl->getTransformHint());
 }
 
 static void transactionCallbackThunk(void* context, nsecs_t latchTime,
@@ -63,6 +65,7 @@
                                                    ? stats[0].previousReleaseFence
                                                    : Fence::NO_FENCE);
         mNextCallbackBufferItem = BufferItem();
+        mBufferItemConsumer->setTransformHint(stats[0].transformHint);
     }
     mDequeueWaitCV.notify_all();
     decStrong((void*)transactionCallbackThunk);
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index b98e48b..621cf59 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -49,25 +49,28 @@
 
     status_t createSurface(const String8& name, uint32_t width, uint32_t height, PixelFormat format,
                            uint32_t flags, const sp<IBinder>& parent, LayerMetadata metadata,
-                           sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) override {
+                           sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
+                           uint32_t* outTransformHint) override {
         return callRemote<decltype(&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE,
                                                                             name, width, height,
                                                                             format, flags, parent,
                                                                             std::move(metadata),
-                                                                            handle, gbp);
+                                                                            handle, gbp,
+                                                                            outTransformHint);
     }
 
     status_t createWithSurfaceParent(const String8& name, uint32_t width, uint32_t height,
                                      PixelFormat format, uint32_t flags,
                                      const sp<IGraphicBufferProducer>& parent,
                                      LayerMetadata metadata, sp<IBinder>* handle,
-                                     sp<IGraphicBufferProducer>* gbp) override {
+                                     sp<IGraphicBufferProducer>* gbp,
+                                     uint32_t* outTransformHint) override {
         return callRemote<decltype(
                 &ISurfaceComposerClient::createWithSurfaceParent)>(Tag::CREATE_WITH_SURFACE_PARENT,
                                                                    name, width, height, format,
                                                                    flags, parent,
-                                                                   std::move(metadata), handle,
-                                                                   gbp);
+                                                                   std::move(metadata), handle, gbp,
+                                                                   outTransformHint);
     }
 
     status_t clearLayerFrameStats(const sp<IBinder>& handle) const override {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index e9079ef..7023311 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -224,6 +224,8 @@
                                                  surfaceStats.acquireTime,
                                                  surfaceStats.previousReleaseFence,
                                                  surfaceStats.transformHint);
+                surfaceControls[surfaceStats.surfaceControl]->setTransformHint(
+                        surfaceStats.transformHint);
             }
 
             callbackFunction(transactionStats.latchTime, transactionStats.presentFence,
@@ -1451,16 +1453,19 @@
 sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
                                                         PixelFormat format, uint32_t flags,
                                                         SurfaceControl* parent,
-                                                        LayerMetadata metadata) {
+                                                        LayerMetadata metadata,
+                                                        uint32_t* outTransformHint) {
     sp<SurfaceControl> s;
-    createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata));
+    createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata),
+                         outTransformHint);
     return s;
 }
 
 sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& name, uint32_t w,
                                                                   uint32_t h, PixelFormat format,
                                                                   uint32_t flags, Surface* parent,
-                                                                  LayerMetadata metadata) {
+                                                                  LayerMetadata metadata,
+                                                                  uint32_t* outTransformHint) {
     sp<SurfaceControl> sur;
     status_t err = mStatus;
 
@@ -1469,11 +1474,15 @@
         sp<IGraphicBufferProducer> parentGbp = parent->getIGraphicBufferProducer();
         sp<IGraphicBufferProducer> gbp;
 
+        uint32_t transformHint = 0;
         err = mClient->createWithSurfaceParent(name, w, h, format, flags, parentGbp,
-                                               std::move(metadata), &handle, &gbp);
+                                               std::move(metadata), &handle, &gbp, &transformHint);
+        if (outTransformHint) {
+            *outTransformHint = transformHint;
+        }
         ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err));
         if (err == NO_ERROR) {
-            return new SurfaceControl(this, handle, gbp, true /* owned */);
+            return new SurfaceControl(this, handle, gbp, true /* owned */, transformHint);
         }
     }
     return nullptr;
@@ -1482,8 +1491,8 @@
 status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                      PixelFormat format,
                                                      sp<SurfaceControl>* outSurface, uint32_t flags,
-                                                     SurfaceControl* parent,
-                                                     LayerMetadata metadata) {
+                                                     SurfaceControl* parent, LayerMetadata metadata,
+                                                     uint32_t* outTransformHint) {
     sp<SurfaceControl> sur;
     status_t err = mStatus;
 
@@ -1496,11 +1505,15 @@
             parentHandle = parent->getHandle();
         }
 
+        uint32_t transformHint = 0;
         err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
-                                     &handle, &gbp);
+                                     &handle, &gbp, &transformHint);
+        if (outTransformHint) {
+            *outTransformHint = transformHint;
+        }
         ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
         if (err == NO_ERROR) {
-            *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);
+            *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */, transformHint);
         }
     }
     return err;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 071314f..6292388 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -45,20 +45,21 @@
 //  SurfaceControl
 // ============================================================================
 
-SurfaceControl::SurfaceControl(
-        const sp<SurfaceComposerClient>& client,
-        const sp<IBinder>& handle,
-        const sp<IGraphicBufferProducer>& gbp,
-        bool owned)
-    : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)
-{
-}
+SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
+                               const sp<IGraphicBufferProducer>& gbp, bool owned,
+                               uint32_t transform)
+      : mClient(client),
+        mHandle(handle),
+        mGraphicBufferProducer(gbp),
+        mOwned(owned),
+        mTransformHint(transform) {}
 
 SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other) {
     mClient = other->mClient;
     mHandle = other->mHandle;
     mGraphicBufferProducer = other->mGraphicBufferProducer;
     mOwned = false;
+    mTransformHint = other->mTransformHint;
 }
 
 SurfaceControl::~SurfaceControl()
@@ -171,11 +172,22 @@
     return mClient;
 }
 
+uint32_t SurfaceControl::getTransformHint() const {
+    Mutex::Autolock _l(mLock);
+    return mTransformHint;
+}
+
+void SurfaceControl::setTransformHint(uint32_t hint) {
+    Mutex::Autolock _l(mLock);
+    mTransformHint = hint;
+}
+
 void SurfaceControl::writeToParcel(Parcel* parcel)
 {
     parcel->writeStrongBinder(ISurfaceComposerClient::asBinder(mClient->getClient()));
     parcel->writeStrongBinder(mHandle);
     parcel->writeStrongBinder(IGraphicBufferProducer::asBinder(mGraphicBufferProducer));
+    parcel->writeUint32(mTransformHint);
 }
 
 sp<SurfaceControl> SurfaceControl::readFromParcel(const Parcel* parcel) {
@@ -189,10 +201,12 @@
     sp<IBinder> gbp;
     parcel->readNullableStrongBinder(&gbp);
 
+    uint32_t transformHint = parcel->readUint32();
     // We aren't the original owner of the surface.
     return new SurfaceControl(new SurfaceComposerClient(
-                    interface_cast<ISurfaceComposerClient>(client)),
-            handle.get(), interface_cast<IGraphicBufferProducer>(gbp), false /* owned */);
+                                      interface_cast<ISurfaceComposerClient>(client)),
+                              handle.get(), interface_cast<IGraphicBufferProducer>(gbp),
+                              false /* owned */, transformHint);
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index 5fe7ca5..2b65d2f 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -56,7 +56,7 @@
     virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                                    uint32_t flags, const sp<IBinder>& parent,
                                    LayerMetadata metadata, sp<IBinder>* handle,
-                                   sp<IGraphicBufferProducer>* gbp) = 0;
+                                   sp<IGraphicBufferProducer>* gbp, uint32_t* outTransformHint) = 0;
 
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
@@ -65,7 +65,8 @@
                                              PixelFormat format, uint32_t flags,
                                              const sp<IGraphicBufferProducer>& parent,
                                              LayerMetadata metadata, sp<IBinder>* handle,
-                                             sp<IGraphicBufferProducer>* gbp) = 0;
+                                             sp<IGraphicBufferProducer>* gbp,
+                                             uint32_t* outTransformHint) = 0;
 
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 08f4e9e..7a9598c 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -226,18 +226,18 @@
                                      PixelFormat format,               // pixel-format desired
                                      uint32_t flags = 0,               // usage flags
                                      SurfaceControl* parent = nullptr, // parent
-                                     LayerMetadata metadata = LayerMetadata() // metadata
-    );
+                                     LayerMetadata metadata = LayerMetadata(), // metadata
+                                     uint32_t* outTransformHint = nullptr);
 
     status_t createSurfaceChecked(const String8& name, // name of the surface
                                   uint32_t w,          // width in pixel
                                   uint32_t h,          // height in pixel
                                   PixelFormat format,  // pixel-format desired
                                   sp<SurfaceControl>* outSurface,
-                                  uint32_t flags = 0,                      // usage flags
-                                  SurfaceControl* parent = nullptr,        // parent
-                                  LayerMetadata metadata = LayerMetadata() // metadata
-    );
+                                  uint32_t flags = 0,                       // usage flags
+                                  SurfaceControl* parent = nullptr,         // parent
+                                  LayerMetadata metadata = LayerMetadata(), // metadata
+                                  uint32_t* outTransformHint = nullptr);
 
     //! Create a surface
     sp<SurfaceControl> createWithSurfaceParent(const String8& name,       // name of the surface
@@ -246,8 +246,8 @@
                                                PixelFormat format,        // pixel-format desired
                                                uint32_t flags = 0,        // usage flags
                                                Surface* parent = nullptr, // parent
-                                               LayerMetadata metadata = LayerMetadata() // metadata
-    );
+                                               LayerMetadata metadata = LayerMetadata(), // metadata
+                                               uint32_t* outTransformHint = nullptr);
 
     // Creates a mirrored hierarchy for the mirrorFromSurface. This returns a SurfaceControl
     // which is a parent of the root of the mirrored hierarchy.
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index ae4a146..7bc7c68 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -82,10 +82,14 @@
 
     sp<SurfaceComposerClient> getClient() const;
 
+    uint32_t getTransformHint() const;
+
+    void setTransformHint(uint32_t hint);
+
     explicit SurfaceControl(const sp<SurfaceControl>& other);
 
     SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
-                   const sp<IGraphicBufferProducer>& gbp, bool owned);
+                   const sp<IGraphicBufferProducer>& gbp, bool owned, uint32_t transformHint = 0);
 
 private:
     // can't be copied
@@ -106,6 +110,7 @@
     mutable Mutex               mLock;
     mutable sp<Surface>         mSurfaceData;
     bool                        mOwned;
+    uint32_t mTransformHint;
 };
 
 }; // namespace android
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index db1ac24..ff22913 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -26,6 +26,7 @@
 #include <ui/DisplayInfo.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicTypes.h>
+#include <ui/Transform.h>
 
 #include <gtest/gtest.h>
 
@@ -201,6 +202,7 @@
               igbProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
                                    &qbOutput));
     ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(3));
+    ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
 
     int slot;
     sp<Fence> fence;
@@ -222,6 +224,7 @@
                                                    NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
                                                    Fence::NO_FENCE);
     igbProducer->queueBuffer(slot, input, &qbOutput);
+    ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
 
     adapter.waitForCallback();
 
diff --git a/libs/nativedisplay/ADisplay.cpp b/libs/nativedisplay/ADisplay.cpp
new file mode 100644
index 0000000..6665635
--- /dev/null
+++ b/libs/nativedisplay/ADisplay.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2019 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 <apex/display.h>
+#include <gui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+#include <ui/GraphicTypes.h>
+
+#include <algorithm>
+#include <optional>
+#include <type_traits>
+#include <vector>
+
+namespace android::display::impl {
+
+/**
+ * Implementation of ADisplayConfig
+ */
+struct DisplayConfigImpl {
+    /**
+     * The width in pixels of the display configuration.
+     */
+    int32_t width{0};
+
+    /**
+     * The height in pixels of the display configuration.
+     */
+
+    int32_t height{0};
+
+    /**
+     * The display density.
+     */
+    float density{0};
+
+    /**
+     * The refresh rate of the display configuration, in frames per second.
+     */
+    float fps{0.0};
+
+    /**
+     * The vsync offset at which surfaceflinger runs, in nanoseconds.
+     */
+    int64_t sfOffset{0};
+
+    /**
+     * The vsync offset at which applications run, in nanoseconds.
+     */
+    int64_t appOffset{0};
+};
+
+// DisplayConfigImpl allocation is not managed through C++ memory apis, so
+// preventing calling the destructor here.
+static_assert(std::is_trivially_destructible<DisplayConfigImpl>::value);
+
+/**
+ * Implementation of ADisplay
+ */
+struct DisplayImpl {
+    /**
+     * A physical display ID, unique to this display.
+     */
+    PhysicalDisplayId id;
+
+    /**
+     * The type of the display, i.e. whether it is an internal or external
+     * display.
+     */
+    ADisplayType type;
+
+    /**
+     * Number of supported configs
+     */
+    size_t numConfigs;
+
+    /**
+     * Set of supported configs by this display.
+     */
+    DisplayConfigImpl* configs;
+};
+
+// DisplayImpl allocation is not managed through C++ memory apis, so
+// preventing calling the destructor here.
+static_assert(std::is_trivially_destructible<DisplayImpl>::value);
+
+} // namespace android::display::impl
+
+using namespace android;
+using namespace android::display::impl;
+
+#define CHECK_NOT_NULL(name) \
+    LOG_ALWAYS_FATAL_IF(name == nullptr, "nullptr passed as " #name " argument");
+
+namespace {
+sp<IBinder> getToken(ADisplay* display) {
+    DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
+    return SurfaceComposerClient::getPhysicalDisplayToken(impl->id);
+}
+
+int64_t computeSfOffset(const DisplayInfo& info) {
+    // This should probably be part of the config instead of extrapolated from
+    // the presentation deadline and fudged here, but the way the math works out
+    // here we do get the right offset.
+    return static_cast<int64_t>((1000000000 / info.fps) - info.presentationDeadline + 1000000);
+}
+} // namespace
+
+int ADisplay_acquirePhysicalDisplays(ADisplay*** outDisplays) {
+    const std::vector<PhysicalDisplayId> ids = SurfaceComposerClient::getPhysicalDisplayIds();
+    const size_t size = ids.size();
+    if (size == 0) {
+        return NO_INIT;
+    }
+
+    std::vector<DisplayConfigImpl> configsPerDisplay[size];
+    int numConfigs = 0;
+    for (int i = 0; i < size; ++i) {
+        const sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(ids[i]);
+        Vector<DisplayInfo> configs;
+        const status_t status = SurfaceComposerClient::getDisplayConfigs(token, &configs);
+        if (status != OK) {
+            return status;
+        }
+        if (configs.empty()) {
+            return NO_INIT;
+        }
+
+        numConfigs += configs.size();
+        configsPerDisplay[i].reserve(configs.size());
+        for (int j = 0; j < configs.size(); ++j) {
+            const DisplayInfo config = configs[j];
+            configsPerDisplay[i].emplace_back(
+                    DisplayConfigImpl{static_cast<int32_t>(config.w),
+                                      static_cast<int32_t>(config.h), config.density, config.fps,
+                                      computeSfOffset(config), config.appVsyncOffset});
+        }
+    }
+
+    const std::optional<PhysicalDisplayId> internalId =
+            SurfaceComposerClient::getInternalDisplayId();
+
+    // Here we allocate all our required memory in one block. The layout is as
+    // follows:
+    // ------------------------------------------------------------
+    // | DisplayImpl pointers | DisplayImpls | DisplayConfigImpls |
+    // ------------------------------------------------------------
+    //
+    // The caller will be given a DisplayImpl** which points to the beginning of
+    // the block of DisplayImpl pointers.
+    // Each DisplayImpl* points to a DisplayImpl in the second block.
+    // Each DisplayImpl contains a DisplayConfigImpl*, which points to a
+    // contiguous block of DisplayConfigImpls specific to that display.
+    DisplayImpl** const impls = reinterpret_cast<DisplayImpl**>(
+            malloc((sizeof(DisplayImpl) + sizeof(DisplayImpl*)) * size +
+                   sizeof(DisplayConfigImpl) * numConfigs));
+    DisplayImpl* const displayData = reinterpret_cast<DisplayImpl*>(impls + size);
+    DisplayConfigImpl* configData = reinterpret_cast<DisplayConfigImpl*>(displayData + size);
+
+    for (size_t i = 0; i < size; ++i) {
+        const PhysicalDisplayId id = ids[i];
+        const ADisplayType type = (internalId == id) ? ADisplayType::DISPLAY_TYPE_INTERNAL
+                                                     : ADisplayType::DISPLAY_TYPE_EXTERNAL;
+        const std::vector<DisplayConfigImpl>& configs = configsPerDisplay[i];
+        memcpy(configData, configs.data(), sizeof(DisplayConfigImpl) * configs.size());
+
+        displayData[i] = DisplayImpl{id, type, configs.size(), configData};
+        impls[i] = displayData + i;
+        // Advance the configData pointer so that future configs are written to
+        // the correct display.
+        configData += configs.size();
+    }
+
+    *outDisplays = reinterpret_cast<ADisplay**>(impls);
+    return size;
+}
+
+void ADisplay_release(ADisplay** displays) {
+    if (displays == nullptr) {
+        return;
+    }
+    free(displays);
+}
+
+float ADisplay_getMaxSupportedFps(ADisplay* display) {
+    CHECK_NOT_NULL(display);
+    DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
+    float maxFps = 0.0;
+    for (int i = 0; i < impl->numConfigs; ++i) {
+        maxFps = std::max(maxFps, impl->configs[i].fps);
+    }
+    return maxFps;
+}
+
+ADisplayType ADisplay_getDisplayType(ADisplay* display) {
+    CHECK_NOT_NULL(display);
+
+    return reinterpret_cast<DisplayImpl*>(display)->type;
+}
+
+int ADisplay_getCurrentConfig(ADisplay* display, ADisplayConfig** outConfig) {
+    CHECK_NOT_NULL(display);
+
+    sp<IBinder> token = getToken(display);
+    const int index = SurfaceComposerClient::getActiveConfig(token);
+    if (index < 0) {
+        return index;
+    }
+
+    DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
+
+    *outConfig = reinterpret_cast<ADisplayConfig*>(impl->configs + index);
+    return OK;
+}
+
+float ADisplayConfig_getDensity(ADisplayConfig* config) {
+    CHECK_NOT_NULL(config);
+
+    return reinterpret_cast<DisplayConfigImpl*>(config)->density;
+}
+
+int32_t ADisplayConfig_getWidth(ADisplayConfig* config) {
+    CHECK_NOT_NULL(config);
+
+    return reinterpret_cast<DisplayConfigImpl*>(config)->width;
+}
+
+int32_t ADisplayConfig_getHeight(ADisplayConfig* config) {
+    CHECK_NOT_NULL(config);
+
+    return reinterpret_cast<DisplayConfigImpl*>(config)->height;
+}
+
+float ADisplayConfig_getFps(ADisplayConfig* config) {
+    CHECK_NOT_NULL(config);
+
+    return reinterpret_cast<DisplayConfigImpl*>(config)->fps;
+}
+
+int64_t ADisplayConfig_getCompositorOffsetNanos(ADisplayConfig* config) {
+    CHECK_NOT_NULL(config);
+
+    return reinterpret_cast<DisplayConfigImpl*>(config)->sfOffset;
+}
+
+int64_t ADisplayConfig_getAppVsyncOffsetNanos(ADisplayConfig* config) {
+    CHECK_NOT_NULL(config);
+
+    return reinterpret_cast<DisplayConfigImpl*>(config)->appOffset;
+}
diff --git a/libs/nativedisplay/Android.bp b/libs/nativedisplay/Android.bp
new file mode 100644
index 0000000..66ebdfd
--- /dev/null
+++ b/libs/nativedisplay/Android.bp
@@ -0,0 +1,50 @@
+// Copyright 2019 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.
+
+cc_library_headers {
+    name: "libnativedisplay_headers",
+    export_include_dirs: ["include"],
+}
+
+cc_library {
+    name: "libnativedisplay",
+    export_include_dirs: [
+        "include",
+    ],
+
+    clang: true,
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-enum-compare",
+        "-Wno-unused-function",
+    ],
+
+    srcs: [
+        "ADisplay.cpp",
+    ],
+
+    shared_libs: [
+        "libgui",
+        "liblog",
+        "libui",
+        "libutils",
+    ],
+
+    header_libs: [
+        "libnativedisplay_headers",
+    ],
+
+}
diff --git a/libs/nativedisplay/include/apex/display.h b/libs/nativedisplay/include/apex/display.h
new file mode 100644
index 0000000..7af452a
--- /dev/null
+++ b/libs/nativedisplay/include/apex/display.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2019 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 <inttypes.h>
+
+__BEGIN_DECLS
+
+/**
+ * Opaque handle for a native display
+ */
+typedef struct ADisplay ADisplay;
+
+/**
+ * Enum describing the possible types of a display
+ */
+enum ADisplayType {
+    /**
+     * A display that is the internal, or "primary" display for a device.
+     */
+    DISPLAY_TYPE_INTERNAL = 0,
+
+    /**
+     * A display that is externally connected for a device.
+     */
+    DISPLAY_TYPE_EXTERNAL = 1,
+};
+
+/**
+ * Opaque handle for display metadata
+ */
+typedef struct ADisplayConfig ADisplayConfig;
+
+/**
+ * Acquires a list of display handles. Memory is allocated for the list and is
+ * owned by the caller. The caller is responsible for freeing this memory by
+ * calling ADisplayList_release.
+ *
+ * Returns the size of the returned list on success.
+ * Returns -errno on error.
+ */
+int ADisplay_acquirePhysicalDisplays(ADisplay*** outDisplays);
+
+/**
+ * Releases a list of display handles created by
+ * ADisplayList_acquirePhysicalDisplays.
+ */
+void ADisplay_release(ADisplay** displays);
+
+/**
+ * Queries the maximum supported fps for the given display.
+ */
+float ADisplay_getMaxSupportedFps(ADisplay* display);
+
+/**
+ * Queries the display's type.
+ */
+ADisplayType ADisplay_getDisplayType(ADisplay* display);
+
+/**
+ * Gets the current display configuration for the given display.
+ *
+ * Memory is *not* allocated for the caller. As such, the returned output
+ * configuration's lifetime will not be longer than the ADisplay* passed to this
+ * function - if ADisplay_release is called destroying the ADisplay object then
+ * it is invalid to access the ADisplayConfig returned here.
+ *
+ * Note that the current display configuration can change. Listening to updates
+ * to the current display configuration should be done via Choreographer. If
+ * such an update is observed, then this method should be recalled to get the
+ * new current configuration.
+ *
+ * Returns OK on success, -errno on failure.
+ */
+int ADisplay_getCurrentConfig(ADisplay* display, ADisplayConfig** outConfig);
+
+/**
+ * Queries the density for a given display configuration.
+ */
+float ADisplayConfig_getDensity(ADisplayConfig* config);
+
+/**
+ * Queries the width in pixels for a given display configuration.
+ */
+int32_t ADisplayConfig_getWidth(ADisplayConfig* config);
+
+/**
+ * Queries the height in pixels for a given display configuration.
+ */
+int32_t ADisplayConfig_getHeight(ADisplayConfig* config);
+
+/**
+ * Queries the display refresh rate for a given display configuration.
+ */
+float ADisplayConfig_getFps(ADisplayConfig* config);
+
+/**
+ * Queries the vsync offset from which the system compositor is scheduled to
+ * run. If a vsync occurs at time T, and the compositor runs at time T + S, then
+ * this returns S in nanoseconds.
+ */
+int64_t ADisplayConfig_getCompositorOffsetNanos(ADisplayConfig* config);
+
+/**
+ * Queries the vsync offset from which applications are scheduled to run. If a
+ * vsync occurs at time T, and applications run at time T + S, then this returns
+ * S in nanoseconds.
+ */
+int64_t ADisplayConfig_getAppVsyncOffsetNanos(ADisplayConfig* config);
+
+__END_DECLS
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
index 940ff5a..e8154a6 100644
--- a/libs/sensor/Android.bp
+++ b/libs/sensor/Android.bp
@@ -21,22 +21,7 @@
         "-Werror",
     ],
     cppflags: [
-        "-Weverything",
-
-        // The static constructors and destructors in this library have not been noted to
-        // introduce significant overheads
-        "-Wno-exit-time-destructors",
-        "-Wno-global-constructors",
-
-        // We only care about compiling as C++14
-        "-Wno-c++98-compat-pedantic",
-
-        // android/sensors.h uses nested anonymous unions and anonymous structs
-        "-Wno-nested-anon-types",
-        "-Wno-gnu-anonymous-struct",
-
-        // Don't warn about struct padding
-        "-Wno-padded",
+        "-Wextra",
     ],
 
     srcs: [
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 47137f1..a030d73 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -26,28 +26,7 @@
         "-Werror",
     ],
     cppflags: [
-        "-Weverything",
-
-        // The static constructors and destructors in this library have not been noted to
-        // introduce significant overheads
-        "-Wno-exit-time-destructors",
-        "-Wno-global-constructors",
-
-        // We only care about compiling as C++14
-        "-Wno-c++98-compat-pedantic",
-
-        // We are aware of the risks inherent in comparing floats for equality
-        "-Wno-float-equal",
-
-        // We use four-character constants for the GraphicBuffer header, and don't care
-        // that they're non-portable as long as they're consistent within one execution
-        "-Wno-four-char-constants",
-
-        // Don't warn about struct padding
-        "-Wno-padded",
-
-        "-Wno-switch-enum",
-        "-Wno-format-pedantic",
+        "-Wextra",
     ],
 
     sanitize: {
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index d1b4a4e..1fc7927 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -61,7 +61,7 @@
 
 using nsecs_t = int64_t;
 
-struct extention_map_t {
+struct extension_map_t {
     const char* name;
     __eglMustCastToProperFunctionPointerType address;
 };
@@ -154,7 +154,7 @@
  * (keep in sync with gExtensionString above)
  *
  */
-static const extention_map_t sExtensionMap[] = {
+static const extension_map_t sExtensionMap[] = {
     // EGL_KHR_lock_surface
     { "eglLockSurfaceKHR",
             (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
@@ -257,13 +257,14 @@
          !strcmp((procname), "eglAwakenProcessIMG"))
 
 // accesses protected by sExtensionMapMutex
-static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
+static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtensionMap;
+static std::unordered_map<std::string, int> sGLExtensionSlotMap;
 
-static int sGLExtentionSlot = 0;
+static int sGLExtensionSlot = 0;
 static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
 
 static void(*findProcAddress(const char* name,
-        const extention_map_t* map, size_t n))() {
+        const extension_map_t* map, size_t n))() {
     for (uint32_t i=0 ; i<n ; i++) {
         if (!strcmp(name, map[i].name)) {
             return map[i].address;
@@ -1223,7 +1224,7 @@
     addr = findBuiltinWrapper(procname);
     if (addr) return addr;
 
-    // this protects accesses to sGLExtentionMap and sGLExtentionSlot
+    // this protects accesses to sGLExtensionMap, sGLExtensionSlot, and sGLExtensionSlotMap
     pthread_mutex_lock(&sExtensionMapMutex);
 
     /*
@@ -1244,51 +1245,69 @@
      */
 
     const std::string name(procname);
-
-    auto& extentionMap = sGLExtentionMap;
-    auto pos = extentionMap.find(name);
-    addr = (pos != extentionMap.end()) ? pos->second : nullptr;
-    const int slot = sGLExtentionSlot;
-
-    ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
-             "no more slots for eglGetProcAddress(\"%s\")",
-             procname);
-
+    auto& extensionMap = sGLExtensionMap;
+    auto& extensionSlotMap = sGLExtensionSlotMap;
     egl_connection_t* const cnx = &gEGLImpl;
     LayerLoader& layer_loader(LayerLoader::getInstance());
 
-    if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
+    // See if we've already looked up this extension
+    auto pos = extensionMap.find(name);
+    addr = (pos != extensionMap.end()) ? pos->second : nullptr;
 
-        if (cnx->dso && cnx->egl.eglGetProcAddress) {
+    if (!addr) {
+        // This is the first time we've looked this function up
+        // Ensure we have room to track it
+        const int slot = sGLExtensionSlot;
+        if (slot < MAX_NUMBER_OF_GL_EXTENSIONS) {
 
-            // Extensions are independent of the bound context
-            addr = cnx->egl.eglGetProcAddress(procname);
-            if (addr) {
+            if (cnx->dso && cnx->egl.eglGetProcAddress) {
 
-                // purposefully track the bottom of the stack in extensionMap
-                extentionMap[name] = addr;
+                // Extensions are independent of the bound context
+                addr = cnx->egl.eglGetProcAddress(procname);
+                if (addr) {
 
-                // Apply layers
-                addr = layer_loader.ApplyLayers(procname, addr);
+                    // purposefully track the bottom of the stack in extensionMap
+                    extensionMap[name] = addr;
 
-                // Track the top most entry point
-                cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
-                cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr;
-                addr = gExtensionForwarders[slot];
-                sGLExtentionSlot++;
+                    // Apply layers
+                    addr = layer_loader.ApplyLayers(procname, addr);
+
+                    // Track the top most entry point return the extension forwarder
+                    cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
+                    cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr;
+                    addr = gExtensionForwarders[slot];
+
+                    // Remember the slot for this extension
+                    extensionSlotMap[name] = slot;
+
+                    // Increment the global extension index
+                    sGLExtensionSlot++;
+                }
             }
+        } else {
+            // The extension forwarder has a fixed number of slots
+            ALOGE("no more slots for eglGetProcAddress(\"%s\")", procname);
         }
 
-    } else if (slot < MAX_NUMBER_OF_GL_EXTENSIONS) {
+    } else {
+        // We tracked an address, so we've seen this func before
+        // Look up the slot for this extension
+        auto slot_pos = extensionSlotMap.find(name);
+        int ext_slot = (slot_pos != extensionSlotMap.end()) ? slot_pos->second : -1;
+        if (ext_slot < 0) {
+            // Something has gone wrong, this should not happen
+            ALOGE("No extension slot found for %s", procname);
+            return nullptr;
+        }
 
-        // We've seen this func before, but we tracked the bottom, so re-apply layers
-        // More layers might have been enabled
+        // We tracked the bottom of the stack, so re-apply layers since
+        // more layers might have been enabled
         addr = layer_loader.ApplyLayers(procname, addr);
 
-        // Track the top most entry point
-        cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
-        cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr;
-        addr = gExtensionForwarders[slot];
+        // Track the top most entry point and return the extension forwarder
+        cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[ext_slot] =
+        cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[ext_slot] = addr;
+        addr = gExtensionForwarders[ext_slot];
     }
 
     pthread_mutex_unlock(&sExtensionMapMutex);
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 5d52bbc..05f0db1 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -94,8 +94,8 @@
 }
 
 InputReader::~InputReader() {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        delete mDevices.valueAt(i);
+    for (auto& devicePair : mDevices) {
+        delete devicePair.second;
     }
 }
 
@@ -224,8 +224,7 @@
 }
 
 void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex >= 0) {
+    if (mDevices.find(deviceId) != mDevices.end()) {
         ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
         return;
     }
@@ -246,7 +245,7 @@
               device->getSources());
     }
 
-    mDevices.add(deviceId, device);
+    mDevices.insert({deviceId, device});
     bumpGenerationLocked();
 
     if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
@@ -255,15 +254,14 @@
 }
 
 void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
-    InputDevice* device = nullptr;
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex < 0) {
+    auto deviceIt = mDevices.find(deviceId);
+    if (deviceIt == mDevices.end()) {
         ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
         return;
     }
 
-    device = mDevices.valueAt(deviceIndex);
-    mDevices.removeItemsAt(deviceIndex, 1);
+    InputDevice* device = deviceIt->second;
+    mDevices.erase(deviceIt);
     bumpGenerationLocked();
 
     if (device->isIgnored()) {
@@ -360,13 +358,13 @@
 
 void InputReader::processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents,
                                                size_t count) {
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex < 0) {
+    auto deviceIt = mDevices.find(deviceId);
+    if (deviceIt == mDevices.end()) {
         ALOGW("Discarding event for unknown deviceId %d.", deviceId);
         return;
     }
 
-    InputDevice* device = mDevices.valueAt(deviceIndex);
+    InputDevice* device = deviceIt->second;
     if (device->isIgnored()) {
         // ALOGD("Discarding event for ignored deviceId %d.", deviceId);
         return;
@@ -376,8 +374,8 @@
 }
 
 void InputReader::timeoutExpiredLocked(nsecs_t when) {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        InputDevice* device = mDevices.valueAt(i);
+    for (auto& devicePair : mDevices) {
+        InputDevice* device = devicePair.second;
         if (!device->isIgnored()) {
             device->timeoutExpired(when);
         }
@@ -405,8 +403,8 @@
         if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
             mEventHub->requestReopenDevices();
         } else {
-            for (size_t i = 0; i < mDevices.size(); i++) {
-                InputDevice* device = mDevices.valueAt(i);
+            for (auto& devicePair : mDevices) {
+                InputDevice* device = devicePair.second;
                 device->configure(now, &mConfig, changes);
             }
         }
@@ -416,8 +414,8 @@
 void InputReader::updateGlobalMetaStateLocked() {
     mGlobalMetaState = 0;
 
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        InputDevice* device = mDevices.valueAt(i);
+    for (auto& devicePair : mDevices) {
+        InputDevice* device = devicePair.second;
         mGlobalMetaState |= device->getMetaState();
     }
 }
@@ -431,8 +429,8 @@
 }
 
 void InputReader::getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        InputDevice* device = mDevices.valueAt(i);
+    for (auto& devicePair : mDevices) {
+        InputDevice* device = devicePair.second;
         if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) {
             InputDeviceInfo info;
             device->getDeviceInfo(&info);
@@ -442,8 +440,8 @@
 }
 
 void InputReader::dispatchExternalStylusState(const StylusState& state) {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        InputDevice* device = mDevices.valueAt(i);
+    for (auto& devicePair : mDevices) {
+        InputDevice* device = devicePair.second;
         device->updateExternalStylusState(state);
     }
 }
@@ -466,8 +464,8 @@
 }
 
 void InputReader::fadePointerLocked() {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        InputDevice* device = mDevices.valueAt(i);
+    for (auto& devicePair : mDevices) {
+        InputDevice* device = devicePair.second;
         device->fadePointer();
     }
 }
@@ -491,9 +489,8 @@
 void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
     outInputDevices.clear();
 
-    size_t numDevices = mDevices.size();
-    for (size_t i = 0; i < numDevices; i++) {
-        InputDevice* device = mDevices.valueAt(i);
+    for (auto& devicePair : mDevices) {
+        InputDevice* device = devicePair.second;
         if (!device->isIgnored()) {
             InputDeviceInfo info;
             device->getDeviceInfo(&info);
@@ -524,17 +521,16 @@
                                     GetStateFunc getStateFunc) {
     int32_t result = AKEY_STATE_UNKNOWN;
     if (deviceId >= 0) {
-        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-        if (deviceIndex >= 0) {
-            InputDevice* device = mDevices.valueAt(deviceIndex);
+        auto deviceIt = mDevices.find(deviceId);
+        if (deviceIt != mDevices.end()) {
+            InputDevice* device = deviceIt->second;
             if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
                 result = (device->*getStateFunc)(sourceMask, code);
             }
         }
     } else {
-        size_t numDevices = mDevices.size();
-        for (size_t i = 0; i < numDevices; i++) {
-            InputDevice* device = mDevices.valueAt(i);
+        for (auto& devicePair : mDevices) {
+            InputDevice* device = devicePair.second;
             if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
                 // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
                 // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
@@ -551,13 +547,13 @@
 }
 
 void InputReader::toggleCapsLockState(int32_t deviceId) {
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex < 0) {
+    auto deviceIt = mDevices.find(deviceId);
+    if (deviceIt == mDevices.end()) {
         ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
         return;
     }
 
-    InputDevice* device = mDevices.valueAt(deviceIndex);
+    InputDevice* device = deviceIt->second;
     if (device->isIgnored()) {
         return;
     }
@@ -578,17 +574,16 @@
                                               uint8_t* outFlags) {
     bool result = false;
     if (deviceId >= 0) {
-        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-        if (deviceIndex >= 0) {
-            InputDevice* device = mDevices.valueAt(deviceIndex);
+        auto deviceIt = mDevices.find(deviceId);
+        if (deviceIt != mDevices.end()) {
+            InputDevice* device = deviceIt->second;
             if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
                 result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
             }
         }
     } else {
-        size_t numDevices = mDevices.size();
-        for (size_t i = 0; i < numDevices; i++) {
-            InputDevice* device = mDevices.valueAt(i);
+        for (auto& devicePair : mDevices) {
+            InputDevice* device = devicePair.second;
             if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
                 result |= device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
             }
@@ -613,10 +608,9 @@
 void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
                           ssize_t repeat, int32_t token) {
     AutoMutex _l(mLock);
-
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex >= 0) {
-        InputDevice* device = mDevices.valueAt(deviceIndex);
+    auto deviceIt = mDevices.find(deviceId);
+    if (deviceIt != mDevices.end()) {
+        InputDevice* device = deviceIt->second;
         device->vibrate(pattern, patternSize, repeat, token);
     }
 }
@@ -624,9 +618,9 @@
 void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
     AutoMutex _l(mLock);
 
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex >= 0) {
-        InputDevice* device = mDevices.valueAt(deviceIndex);
+    auto deviceIt = mDevices.find(deviceId);
+    if (deviceIt != mDevices.end()) {
+        InputDevice* device = deviceIt->second;
         device->cancelVibrate(token);
     }
 }
@@ -634,9 +628,9 @@
 bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
     AutoMutex _l(mLock);
 
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex >= 0) {
-        InputDevice* device = mDevices.valueAt(deviceIndex);
+    auto deviceIt = mDevices.find(deviceId);
+    if (deviceIt != mDevices.end()) {
+        InputDevice* device = deviceIt->second;
         return device->isEnabled();
     }
     ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
@@ -646,13 +640,13 @@
 bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
     AutoMutex _l(mLock);
 
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex < 0) {
+    auto deviceIt = mDevices.find(deviceId);
+    if (deviceIt == mDevices.end()) {
         ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
         return false;
     }
 
-    InputDevice* device = mDevices.valueAt(deviceIndex);
+    InputDevice* device = deviceIt->second;
     if (!device->isEnabled()) {
         ALOGW("Ignoring disabled device %s", device->getName().c_str());
         return false;
@@ -680,8 +674,9 @@
 
     dump += "Input Reader State:\n";
 
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        mDevices.valueAt(i)->dump(dump);
+    for (const auto& devicePair : mDevices) {
+        InputDevice* const device = devicePair.second;
+        device->dump(dump);
     }
 
     dump += INDENT "Configuration:\n";
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 3cf4535..0a4e808 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -23,9 +23,9 @@
 #include "InputReaderContext.h"
 
 #include <utils/Condition.h>
-#include <utils/KeyedVector.h>
 #include <utils/Mutex.h>
 
+#include <unordered_map>
 #include <vector>
 
 namespace android {
@@ -135,7 +135,7 @@
     static const int EVENT_BUFFER_SIZE = 256;
     RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
 
-    KeyedVector<int32_t, InputDevice*> mDevices;
+    std::unordered_map<int32_t /*deviceId*/, InputDevice*> mDevices;
 
     // With each iteration of the loop, InputReader reads and processes one incoming message from
     // the EventHub.
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 289bb17..8e6a70c 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -63,6 +63,7 @@
     }
     Rect getCrop(const Layer::State& s) const;
 
+    uint32_t getTransformHint() const { return mTransformHint; }
     bool setTransform(uint32_t transform) override;
     bool setTransformToDisplayInverse(bool transformToDisplayInverse) override;
     bool setCrop(const Rect& crop) override;
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index c7ed9b0..f331364 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -75,17 +75,18 @@
 status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                                uint32_t flags, const sp<IBinder>& parentHandle,
                                LayerMetadata metadata, sp<IBinder>* handle,
-                               sp<IGraphicBufferProducer>* gbp) {
+                               sp<IGraphicBufferProducer>* gbp, uint32_t* outTransformHint) {
     // We rely on createLayer to check permissions.
     return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
-                                 parentHandle);
+                                 parentHandle, nullptr, outTransformHint);
 }
 
 status_t Client::createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
                                          PixelFormat format, uint32_t flags,
                                          const sp<IGraphicBufferProducer>& parent,
                                          LayerMetadata metadata, sp<IBinder>* handle,
-                                         sp<IGraphicBufferProducer>* gbp) {
+                                         sp<IGraphicBufferProducer>* gbp,
+                                         uint32_t* outTransformHint) {
     if (mFlinger->authenticateSurfaceTexture(parent) == false) {
         ALOGE("failed to authenticate surface texture");
         // The extra parent layer check below before returning is to help with debugging
@@ -103,7 +104,7 @@
     }
 
     return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
-                                 nullptr, layer);
+                                 nullptr, layer, outTransformHint);
 }
 
 status_t Client::mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle) {
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 7d7cef8..e9063e5 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -54,13 +54,15 @@
     virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                                    uint32_t flags, const sp<IBinder>& parent,
                                    LayerMetadata metadata, sp<IBinder>* handle,
-                                   sp<IGraphicBufferProducer>* gbp);
+                                   sp<IGraphicBufferProducer>* gbp,
+                                   uint32_t* outTransformHint = nullptr);
 
     virtual status_t createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
                                              PixelFormat format, uint32_t flags,
                                              const sp<IGraphicBufferProducer>& parent,
                                              LayerMetadata metadata, sp<IBinder>* handle,
-                                             sp<IGraphicBufferProducer>* gbp);
+                                             sp<IGraphicBufferProducer>* gbp,
+                                             uint32_t* outTransformHint = nullptr);
 
     status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* handle);
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e19b79b..215e240 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1540,8 +1540,10 @@
     mCurrentParent = layer;
 }
 
-int32_t Layer::getZ() const {
-    return mDrawingState.z;
+int32_t Layer::getZ(LayerVector::StateSet stateSet) const {
+    const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    return state.z;
 }
 
 bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) const {
@@ -1601,7 +1603,7 @@
             continue;
         }
 
-        if (relative->getZ() >= 0) {
+        if (relative->getZ(stateSet) >= 0) {
             break;
         }
         relative->traverseInZOrder(stateSet, visitor);
@@ -1635,7 +1637,7 @@
             continue;
         }
 
-        if (relative->getZ() < 0) {
+        if (relative->getZ(stateSet) < 0) {
             break;
         }
         relative->traverseInReverseZOrder(stateSet, visitor);
@@ -1693,7 +1695,7 @@
     size_t i = 0;
     for (; i < list.size(); i++) {
         const auto& relative = list[i];
-        if (relative->getZ() >= 0) {
+        if (relative->getZ(stateSet) >= 0) {
             break;
         }
         relative->traverseChildrenInZOrderInner(layersInTree, stateSet, visitor);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index fdac98f..cdd8d3f 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -672,7 +672,7 @@
     // Copy the current list of children to the drawing state. Called by
     // SurfaceFlinger to complete a transaction.
     void commitChildList();
-    int32_t getZ() const;
+    int32_t getZ(LayerVector::StateSet stateSet) const;
     virtual void pushPendingState();
 
     /**
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1acb2da..96c17a1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3432,8 +3432,8 @@
                                      uint32_t h, PixelFormat format, uint32_t flags,
                                      LayerMetadata metadata, sp<IBinder>* handle,
                                      sp<IGraphicBufferProducer>* gbp,
-                                     const sp<IBinder>& parentHandle,
-                                     const sp<Layer>& parentLayer) {
+                                     const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
+                                     uint32_t* outTransformHint) {
     if (int32_t(w|h) < 0) {
         ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
                 int(w), int(h));
@@ -3470,7 +3470,7 @@
             break;
         case ISurfaceComposerClient::eFXSurfaceBufferState:
             result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
-                                            std::move(metadata), handle, &layer);
+                                            std::move(metadata), handle, outTransformHint, &layer);
             break;
         case ISurfaceComposerClient::eFXSurfaceColor:
             // check if buffer size is set for color layer.
@@ -3585,11 +3585,14 @@
 status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, std::string name,
                                                 uint32_t w, uint32_t h, uint32_t flags,
                                                 LayerMetadata metadata, sp<IBinder>* handle,
-                                                sp<Layer>* outLayer) {
+                                                uint32_t* outTransformHint, sp<Layer>* outLayer) {
     LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
     args.displayDevice = getDefaultDisplayDevice();
     args.textureName = getNewTexture();
     sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);
+    if (outTransformHint) {
+        *outTransformHint = layer->getTransformHint();
+    }
     *handle = layer->getHandle();
     *outLayer = layer;
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index abb8b82..e7ad295 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -602,7 +602,8 @@
     status_t createLayer(const String8& name, const sp<Client>& client, uint32_t w, uint32_t h,
                          PixelFormat format, uint32_t flags, LayerMetadata metadata,
                          sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
-                         const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer = nullptr);
+                         const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer = nullptr,
+                         uint32_t* outTransformHint = nullptr);
 
     status_t createBufferQueueLayer(const sp<Client>& client, std::string name, uint32_t w,
                                     uint32_t h, uint32_t flags, LayerMetadata metadata,
@@ -611,7 +612,8 @@
 
     status_t createBufferStateLayer(const sp<Client>& client, std::string name, uint32_t w,
                                     uint32_t h, uint32_t flags, LayerMetadata metadata,
-                                    sp<IBinder>* outHandle, sp<Layer>* outLayer);
+                                    sp<IBinder>* outHandle, uint32_t* outTransformHint,
+                                    sp<Layer>* outLayer);
 
     status_t createColorLayer(const sp<Client>& client, std::string name, uint32_t w, uint32_t h,
                               uint32_t flags, LayerMetadata metadata, sp<IBinder>* outHandle,
diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
index a48f553..999e82d 100644
--- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
@@ -15,9 +15,9 @@
  */
 
 #include <gui/BufferItemConsumer.h>
+#include <ui/Transform.h>
 #include <thread>
 #include "TransactionTestHarnesses.h"
-
 namespace android {
 
 using android::hardware::graphics::common::V1_1::BufferUsage;
@@ -188,6 +188,15 @@
     getScreenCapture()->expectColor(Rect(0, 0, 64, 64), Color::RED);
 }
 
+TEST_P(LayerRenderTypeTransactionTest, CreateLayer_BufferState) {
+    uint32_t transformHint = ui::Transform::orientation_flags::ROT_INVALID;
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32,
+                                                ISurfaceComposerClient::eFXSurfaceBufferState,
+                                                /*parent*/ nullptr, &transformHint));
+    ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, transformHint);
+}
+
 void LayerRenderTypeTransactionTest::setRelativeZBasicHelper(uint32_t layerType) {
     sp<SurfaceControl> layerR;
     sp<SurfaceControl> layerG;
diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h
index 7edddb6..f7a6d96 100644
--- a/services/surfaceflinger/tests/LayerTransactionTest.h
+++ b/services/surfaceflinger/tests/LayerTransactionTest.h
@@ -53,9 +53,10 @@
 
     virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
                                            const char* name, uint32_t width, uint32_t height,
-                                           uint32_t flags = 0, SurfaceControl* parent = nullptr) {
-        auto layer =
-                createSurface(client, name, width, height, PIXEL_FORMAT_RGBA_8888, flags, parent);
+                                           uint32_t flags = 0, SurfaceControl* parent = nullptr,
+                                           uint32_t* outTransformHint = nullptr) {
+        auto layer = createSurface(client, name, width, height, PIXEL_FORMAT_RGBA_8888, flags,
+                                   parent, outTransformHint);
 
         Transaction t;
         t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
@@ -72,15 +73,18 @@
     virtual sp<SurfaceControl> createSurface(const sp<SurfaceComposerClient>& client,
                                              const char* name, uint32_t width, uint32_t height,
                                              PixelFormat format, uint32_t flags,
-                                             SurfaceControl* parent = nullptr) {
-        auto layer = client->createSurface(String8(name), width, height, format, flags, parent);
+                                             SurfaceControl* parent = nullptr,
+                                             uint32_t* outTransformHint = nullptr) {
+        auto layer = client->createSurface(String8(name), width, height, format, flags, parent,
+                                           LayerMetadata(), outTransformHint);
         EXPECT_NE(nullptr, layer.get()) << "failed to create SurfaceControl";
         return layer;
     }
 
     virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
-                                           uint32_t flags = 0, SurfaceControl* parent = nullptr) {
-        return createLayer(mClient, name, width, height, flags, parent);
+                                           uint32_t flags = 0, SurfaceControl* parent = nullptr,
+                                           uint32_t* outTransformHint = nullptr) {
+        return createLayer(mClient, name, width, height, flags, parent, outTransformHint);
     }
 
     sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
diff --git a/services/surfaceflinger/tests/TransactionTestHarnesses.h b/services/surfaceflinger/tests/TransactionTestHarnesses.h
index 8fdcde4..5612bb2 100644
--- a/services/surfaceflinger/tests/TransactionTestHarnesses.h
+++ b/services/surfaceflinger/tests/TransactionTestHarnesses.h
@@ -114,12 +114,14 @@
     LayerTypeTransactionHarness(uint32_t layerType) : mLayerType(layerType) {}
 
     sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
-                                   uint32_t flags = 0, SurfaceControl* parent = nullptr) {
+                                   uint32_t flags = 0, SurfaceControl* parent = nullptr,
+                                   uint32_t* outTransformHint = nullptr) {
         // if the flags already have a layer type specified, return an error
         if (flags & ISurfaceComposerClient::eFXSurfaceMask) {
             return nullptr;
         }
-        return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent);
+        return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent,
+                                                 outTransformHint);
     }
 
     void fillLayerColor(const sp<SurfaceControl>& layer, const Color& color, int32_t bufferWidth,
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 5686891..018f200 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -41,12 +41,13 @@
         "-DVK_NO_PROTOTYPES",
         "-fvisibility=hidden",
         "-fstrict-aliasing",
-        "-Weverything",
+        "-Wextra",
         "-Werror",
         "-Wno-padded",
+        "-Wno-sign-compare",
         "-Wno-switch-enum",
-        "-Wno-undef",
-        "-Wno-format-pedantic",
+        "-Wno-unused-variable",
+        "-Wno-unused-function",
 
         // Have clang emit complete debug_info.
         "-fstandalone-debug",
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index 24039b1..4725344 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -144,7 +144,7 @@
     }
 
     void GetLayersFromSettings() {
-        // These will only be available if conditions are met in GraphicsEnvironemnt
+        // These will only be available if conditions are met in GraphicsEnvironment
         // gpu_debug_layers = layer1:layer2:layerN
         const std::string layers = android::GraphicsEnv::getInstance().getDebugLayers();
         if (!layers.empty()) {
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index d92f35a..0fb3a29 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -754,7 +754,7 @@
 }  // anonymous namespace
 
 bool Debuggable() {
-    return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0);
+    return prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) > 0;
 }
 
 bool OpenHAL() {
diff --git a/vulkan/nulldrv/Android.bp b/vulkan/nulldrv/Android.bp
index dedf419..ba02504 100644
--- a/vulkan/nulldrv/Android.bp
+++ b/vulkan/nulldrv/Android.bp
@@ -23,18 +23,11 @@
         "-fvisibility=hidden",
         "-fstrict-aliasing",
         "-DLOG_TAG=\"vknulldrv\"",
-        "-Weverything",
+        "-Wextra",
         "-Werror",
-        "-Wno-padded",
-        "-Wno-undef",
-        "-Wno-zero-length-array",
 
         "-DLOG_NDEBUG=0",
     ],
-    cppflags: [
-        "-Wno-c++98-compat-pedantic",
-        "-Wno-c99-extensions",
-    ],
 
     srcs: [
         "null_driver.cpp",