Merge "Use correct state when calling getZ"
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/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/include/input/InputTransport.h b/include/input/InputTransport.h
index 1822e4a..94d90ad 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -167,11 +167,15 @@
     virtual ~InputChannel();
 
 public:
-    static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd);
+    static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd,
+                                   sp<IBinder> token);
 
-    /* Creates a pair of input channels.
+    /**
+     * Create a pair of input channels.
+     * The two returned input channels are equivalent, and are labeled as "server" and "client"
+     * for convenience. The two input channels share the same token.
      *
-     * Returns OK on success.
+     * Return OK on success.
      */
     static status_t openInputChannelPair(const std::string& name,
             sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
@@ -179,46 +183,57 @@
     inline std::string getName() const { return mName; }
     inline int getFd() const { return mFd.get(); }
 
-    /* Sends a message to the other endpoint.
+    /* Send a message to the other endpoint.
      *
      * If the channel is full then the message is guaranteed not to have been sent at all.
      * Try again after the consumer has sent a finished signal indicating that it has
      * consumed some of the pending messages from the channel.
      *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if the channel is full.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Return OK on success.
+     * Return WOULD_BLOCK if the channel is full.
+     * Return DEAD_OBJECT if the channel's peer has been closed.
      * Other errors probably indicate that the channel is broken.
      */
     status_t sendMessage(const InputMessage* msg);
 
-    /* Receives a message sent by the other endpoint.
+    /* Receive a message sent by the other endpoint.
      *
      * If there is no message present, try again after poll() indicates that the fd
      * is readable.
      *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if there is no message present.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Return OK on success.
+     * Return WOULD_BLOCK if there is no message present.
+     * Return DEAD_OBJECT if the channel's peer has been closed.
      * Other errors probably indicate that the channel is broken.
      */
     status_t receiveMessage(InputMessage* msg);
 
-    /* Returns a new object that has a duplicate of this channel's fd. */
+    /* Return a new object that has a duplicate of this channel's fd. */
     sp<InputChannel> dup() const;
 
     status_t write(Parcel& out) const;
     static sp<InputChannel> read(const Parcel& from);
 
-    sp<IBinder> getToken() const;
-    void setToken(const sp<IBinder>& token);
+    /**
+     * The connection token is used to identify the input connection, i.e.
+     * the pair of input channels that were created simultaneously. Input channels
+     * are always created in pairs, and the token can be used to find the server-side
+     * input channel from the client-side input channel, and vice versa.
+     *
+     * Do not use connection token to check equality of a specific input channel object
+     * to another, because two different (client and server) input channels will share the
+     * same connection token.
+     *
+     * Return the token that identifies this connection.
+     */
+    sp<IBinder> getConnectionToken() const;
 
 private:
-    InputChannel(const std::string& name, android::base::unique_fd fd);
+    InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token);
     std::string mName;
     android::base::unique_fd mFd;
 
-    sp<IBinder> mToken = nullptr;
+    sp<IBinder> mToken;
 };
 
 /*
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/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/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/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 09c74de..a307d04 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -512,6 +512,12 @@
             mCore->mSharedBufferSlot = found;
             mSlots[found].mBufferState.mShared = true;
         }
+
+        if (!(returnFlags & BUFFER_NEEDS_REALLOCATION)) {
+            if (mCore->mConsumerListener != nullptr) {
+                mCore->mConsumerListener->onFrameDequeued(mSlots[*outSlot].mGraphicBuffer->getId());
+            }
+        }
     } // Autolock scope
 
     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
@@ -528,6 +534,10 @@
             if (error == NO_ERROR && !mCore->mIsAbandoned) {
                 graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
                 mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
+                if (mCore->mConsumerListener != nullptr) {
+                    mCore->mConsumerListener->onFrameDequeued(
+                            mSlots[*outSlot].mGraphicBuffer->getId());
+                }
             }
 
             mCore->mIsAllocating = false;
@@ -580,11 +590,6 @@
     }
     addAndGetFrameTimestamps(nullptr, outTimestamps);
 
-    { // Autolock scope
-        std::lock_guard<std::mutex> lock(mCore->mMutex);
-        mCore->mConsumerListener->onFrameDequeued(mSlots[*outSlot].mGraphicBuffer->getId());
-    }
-
     return returnFlags;
 }
 
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..3178b6a 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,8 +1474,12 @@
         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 */);
@@ -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/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 06be1b3..f2bae98 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -30,6 +30,7 @@
 #include <ui/FrameStats.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicTypes.h>
+#include <ui/PhysicalDisplayId.h>
 #include <ui/PixelFormat.h>
 
 #include <utils/Errors.h>
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/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 03b9cd7..8d36ba7 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -69,7 +69,6 @@
         mSurfaceControl = sc;
 
         InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);
-        mServerChannel->setToken(new BBinder());
 
         mInputFlinger = getInputFlinger();
         mInputFlinger->registerInputChannel(mServerChannel);
@@ -165,7 +164,7 @@
     }
 
     void populateInputInfo(int width, int height) {
-        mInputInfo.token = mServerChannel->getToken();
+        mInputInfo.token = mServerChannel->getConnectionToken();
         mInputInfo.name = "Test info";
         mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
         mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index c4f7fe0..a5dd3c0 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -11,7 +11,7 @@
 #define DEBUG_CHANNEL_MESSAGES 0
 
 // Log debug messages whenever InputChannel objects are created/destroyed
-#define DEBUG_CHANNEL_LIFECYCLE 0
+static constexpr bool DEBUG_CHANNEL_LIFECYCLE = false;
 
 // Log debug messages about transport actions
 #define DEBUG_TRANSPORT_ACTIONS 0
@@ -225,28 +225,28 @@
 
 // --- InputChannel ---
 
-sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd) {
+sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd,
+                                      sp<IBinder> token) {
     const int result = fcntl(fd, F_SETFL, O_NONBLOCK);
     if (result != 0) {
         LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(),
                          strerror(errno));
         return nullptr;
     }
-    return new InputChannel(name, std::move(fd));
+    return new InputChannel(name, std::move(fd), token);
 }
 
-InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd)
-      : mName(name), mFd(std::move(fd)) {
-#if DEBUG_CHANNEL_LIFECYCLE
-    ALOGD("Input channel constructed: name='%s', fd=%d",
-            mName.c_str(), fd);
-#endif
+InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token)
+      : mName(name), mFd(std::move(fd)), mToken(token) {
+    if (DEBUG_CHANNEL_LIFECYCLE) {
+        ALOGD("Input channel constructed: name='%s', fd=%d", mName.c_str(), mFd.get());
+    }
 }
 
 InputChannel::~InputChannel() {
-#if DEBUG_CHANNEL_LIFECYCLE
-    ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get());
-#endif
+    if (DEBUG_CHANNEL_LIFECYCLE) {
+        ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get());
+    }
 }
 
 status_t InputChannel::openInputChannelPair(const std::string& name,
@@ -267,13 +267,15 @@
     setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
     setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
 
+    sp<IBinder> token = new BBinder();
+
     std::string serverChannelName = name + " (server)";
     android::base::unique_fd serverFd(sockets[0]);
-    outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd));
+    outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd), token);
 
     std::string clientChannelName = name + " (client)";
     android::base::unique_fd clientFd(sockets[1]);
-    outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd));
+    outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd), token);
     return OK;
 }
 
@@ -369,7 +371,7 @@
                             getName().c_str());
         return nullptr;
     }
-    return InputChannel::create(mName, std::move(newFd));
+    return InputChannel::create(mName, std::move(newFd), mToken);
 }
 
 status_t InputChannel::write(Parcel& out) const {
@@ -396,24 +398,13 @@
         return nullptr;
     }
 
-    sp<InputChannel> channel = InputChannel::create(name, std::move(rawFd));
-    if (channel != nullptr) {
-        channel->setToken(token);
-    }
-    return channel;
+    return InputChannel::create(name, std::move(rawFd), token);
 }
 
-sp<IBinder> InputChannel::getToken() const {
+sp<IBinder> InputChannel::getConnectionToken() const {
     return mToken;
 }
 
-void InputChannel::setToken(const sp<IBinder>& token) {
-    if (mToken != nullptr) {
-        ALOGE("Assigning InputChannel (%s) a second handle?", mName.c_str());
-    }
-    mToken = token;
-}
-
 // --- InputPublisher ---
 
 InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp
index 7c331e1..ada275d 100644
--- a/libs/input/tests/InputChannel_test.cpp
+++ b/libs/input/tests/InputChannel_test.cpp
@@ -46,7 +46,8 @@
 
     android::base::unique_fd sendFd(pipe.sendFd);
 
-    sp<InputChannel> inputChannel = InputChannel::create("channel name", std::move(sendFd));
+    sp<InputChannel> inputChannel =
+            InputChannel::create("channel name", std::move(sendFd), new BBinder());
 
     EXPECT_NE(inputChannel, nullptr) << "channel should be successfully created";
     EXPECT_STREQ("channel name", inputChannel->getName().c_str())
@@ -59,13 +60,11 @@
 
 TEST_F(InputChannelTest, SetAndGetToken) {
     Pipe pipe;
-    sp<InputChannel> channel =
-            InputChannel::create("test channel", android::base::unique_fd(pipe.sendFd));
-    EXPECT_EQ(channel->getToken(), nullptr);
-
     sp<IBinder> token = new BBinder();
-    channel->setToken(token);
-    EXPECT_EQ(token, channel->getToken());
+    sp<InputChannel> channel =
+            InputChannel::create("test channel", android::base::unique_fd(pipe.sendFd), token);
+
+    EXPECT_EQ(token, channel->getConnectionToken());
 }
 
 TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
diff --git a/libs/ui/include/ui/GraphicTypes.h b/libs/ui/include/ui/GraphicTypes.h
index 5dc56c8..d7411ea 100644
--- a/libs/ui/include/ui/GraphicTypes.h
+++ b/libs/ui/include/ui/GraphicTypes.h
@@ -16,19 +16,12 @@
 
 #pragma once
 
-#include <cinttypes>
-#include <cstdint>
-
 #include <android/hardware/graphics/common/1.1/types.h>
 #include <android/hardware/graphics/common/1.2/types.h>
 #include <system/graphics.h>
 
-#define ANDROID_PHYSICAL_DISPLAY_ID_FORMAT PRIu64
-
 namespace android {
 
-using PhysicalDisplayId = uint64_t;
-
 // android::ui::* in this header file will alias different types as
 // the HIDL interface is updated.
 namespace ui {
diff --git a/libs/ui/include/ui/PhysicalDisplayId.h b/libs/ui/include/ui/PhysicalDisplayId.h
new file mode 100644
index 0000000..1a345ac
--- /dev/null
+++ b/libs/ui/include/ui/PhysicalDisplayId.h
@@ -0,0 +1,32 @@
+/*
+ * 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 <cinttypes>
+#include <cstdint>
+
+#define ANDROID_PHYSICAL_DISPLAY_ID_FORMAT PRIu64
+
+namespace android {
+
+using PhysicalDisplayId = uint64_t;
+
+constexpr uint8_t getPhysicalDisplayPort(PhysicalDisplayId displayId) {
+    return static_cast<uint8_t>(displayId);
+}
+
+} // namespace android
diff --git a/libs/ui/include_vndk/ui/PhysicalDisplayId.h b/libs/ui/include_vndk/ui/PhysicalDisplayId.h
new file mode 120000
index 0000000..6e3fb1e
--- /dev/null
+++ b/libs/ui/include_vndk/ui/PhysicalDisplayId.h
@@ -0,0 +1 @@
+../../include/ui/PhysicalDisplayId.h
\ No newline at end of file
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 24b27b9..58a5b3c 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1038,7 +1038,8 @@
     pokeUserActivityLocked(*eventEntry);
 
     for (const InputTarget& inputTarget : inputTargets) {
-        sp<Connection> connection = getConnectionLocked(inputTarget.inputChannel->getToken());
+        sp<Connection> connection =
+                getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
         if (connection != nullptr) {
             prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
         } else {
@@ -2142,7 +2143,7 @@
             }
 
             dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
-                                            inputTarget->inputChannel->getToken());
+                                            inputTarget->inputChannel->getConnectionToken());
 
             break;
         }
@@ -2472,7 +2473,7 @@
 
 void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
         const sp<InputChannel>& channel, const CancelationOptions& options) {
-    sp<Connection> connection = getConnectionLocked(channel->getToken());
+    sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
     if (connection == nullptr) {
         return;
     }
@@ -2514,7 +2515,7 @@
 
             InputTarget target;
             sp<InputWindowHandle> windowHandle =
-                    getWindowHandleLocked(connection->inputChannel->getToken());
+                    getWindowHandleLocked(connection->inputChannel->getConnectionToken());
             if (windowHandle != nullptr) {
                 const InputWindowInfo* windowInfo = windowHandle->getInfo();
                 target.xOffset = -windowInfo->frameLeft;
@@ -3866,7 +3867,7 @@
 
     { // acquire lock
         std::scoped_lock _l(mLock);
-        sp<Connection> existingConnection = getConnectionLocked(inputChannel->getToken());
+        sp<Connection> existingConnection = getConnectionLocked(inputChannel->getConnectionToken());
         if (existingConnection != nullptr) {
             ALOGW("Attempted to register already registered input channel '%s'",
                   inputChannel->getName().c_str());
@@ -3877,7 +3878,7 @@
 
         int fd = inputChannel->getFd();
         mConnectionsByFd[fd] = connection;
-        mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
+        mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
 
         mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
     } // release lock
@@ -3897,7 +3898,7 @@
             return BAD_VALUE;
         }
 
-        if (inputChannel->getToken() == nullptr) {
+        if (inputChannel->getConnectionToken() == nullptr) {
             ALOGW("Attempted to register input monitor without an identifying token.");
             return BAD_VALUE;
         }
@@ -3906,7 +3907,7 @@
 
         const int fd = inputChannel->getFd();
         mConnectionsByFd[fd] = connection;
-        mInputChannelsByToken[inputChannel->getToken()] = inputChannel;
+        mInputChannelsByToken[inputChannel->getConnectionToken()] = inputChannel;
 
         auto& monitorsByDisplay =
                 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
@@ -3941,7 +3942,7 @@
 
 status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
                                                        bool notify) {
-    sp<Connection> connection = getConnectionLocked(inputChannel->getToken());
+    sp<Connection> connection = getConnectionLocked(inputChannel->getConnectionToken());
     if (connection == nullptr) {
         ALOGW("Attempted to unregister already unregistered input channel '%s'",
               inputChannel->getName().c_str());
@@ -3950,7 +3951,7 @@
 
     [[maybe_unused]] const bool removed = removeByValue(mConnectionsByFd, connection);
     ALOG_ASSERT(removed);
-    mInputChannelsByToken.erase(inputChannel->getToken());
+    mInputChannelsByToken.erase(inputChannel->getConnectionToken());
 
     if (connection->monitor) {
         removeMonitorChannelLocked(inputChannel);
@@ -4010,7 +4011,7 @@
         TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
         std::optional<int32_t> foundDeviceId;
         for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
-            if (touchedMonitor.monitor.inputChannel->getToken() == token) {
+            if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
                 foundDeviceId = state.deviceId;
             }
         }
@@ -4041,7 +4042,7 @@
     for (const auto& it : mGestureMonitorsByDisplay) {
         const std::vector<Monitor>& monitors = it.second;
         for (const Monitor& monitor : monitors) {
-            if (monitor.inputChannel->getToken() == token) {
+            if (monitor.inputChannel->getConnectionToken() == token) {
                 return it.first;
             }
         }
@@ -4056,7 +4057,7 @@
 
     for (const auto& pair : mConnectionsByFd) {
         const sp<Connection>& connection = pair.second;
-        if (connection->inputChannel->getToken() == inputConnectionToken) {
+        if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
             return connection;
         }
     }
@@ -4149,7 +4150,7 @@
     if (connection->status != Connection::STATUS_ZOMBIE) {
         mLock.unlock();
 
-        mPolicy->notifyInputChannelBroken(connection->inputChannel->getToken());
+        mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
 
         mLock.lock();
     }
@@ -4165,7 +4166,7 @@
 
 void InputDispatcher::doNotifyANRLockedInterruptible(CommandEntry* commandEntry) {
     sp<IBinder> token =
-            commandEntry->inputChannel ? commandEntry->inputChannel->getToken() : nullptr;
+            commandEntry->inputChannel ? commandEntry->inputChannel->getConnectionToken() : nullptr;
     mLock.unlock();
 
     nsecs_t newTimeout =
@@ -4186,7 +4187,7 @@
 
     android::base::Timer t;
     sp<IBinder> token = commandEntry->inputChannel != nullptr
-            ? commandEntry->inputChannel->getToken()
+            ? commandEntry->inputChannel->getConnectionToken()
             : nullptr;
     nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry->policyFlags);
     if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
@@ -4305,7 +4306,7 @@
 
             mLock.unlock();
 
-            mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(), &event,
+            mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
                                           keyEntry->policyFlags, &event);
 
             mLock.lock();
@@ -4346,8 +4347,9 @@
 
         mLock.unlock();
 
-        bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel->getToken(), &event,
-                                                      keyEntry->policyFlags, &event);
+        bool fallback =
+                mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
+                                              &event, keyEntry->policyFlags, &event);
 
         mLock.lock();
 
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 7d69854..b706a74 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -470,7 +470,6 @@
         const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
             FakeInputReceiver(dispatcher, name, displayId),
             mFocused(false), mFrame(Rect(0, 0, WIDTH, HEIGHT)), mLayoutParamFlags(0) {
-            mServerChannel->setToken(new BBinder());
             mDispatcher->registerInputChannel(mServerChannel);
 
             inputApplicationHandle->updateInfo();
@@ -478,7 +477,7 @@
     }
 
     virtual bool updateInfo() {
-        mInfo.token = mServerChannel ? mServerChannel->getToken() : nullptr;
+        mInfo.token = mServerChannel ? mServerChannel->getConnectionToken() : nullptr;
         mInfo.name = mName;
         mInfo.layoutParamsFlags = mLayoutParamFlags;
         mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
@@ -859,7 +858,6 @@
     FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
             int32_t displayId, bool isGestureMonitor = false)
             : FakeInputReceiver(dispatcher, name, displayId) {
-        mServerChannel->setToken(new BBinder());
         mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
     }
 };
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/DisplayHardware/DisplayIdentification.h b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
index d63cd79..22b268a 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
@@ -23,7 +23,7 @@
 #include <string_view>
 #include <vector>
 
-#include <ui/GraphicTypes.h>
+#include <ui/PhysicalDisplayId.h>
 
 namespace android {
 
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,