| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TOOLS_ANDROID_FORWARDER2_HOST_CONTROLLERS_MANAGER_H_ |
| #define TOOLS_ANDROID_FORWARDER2_HOST_CONTROLLERS_MANAGER_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <unordered_map> |
| |
| #include "base/at_exit.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/weak_ptr.h" |
| #include "tools/android/forwarder2/host_controller.h" |
| #include "tools/android/forwarder2/socket.h" |
| |
| namespace forwarder2 { |
| |
| enum : int { |
| MAP = 0, |
| UNMAP = 1, |
| UNMAP_ALL = 2, |
| }; |
| |
| // Manages HostController instances. There is one HostController instance for |
| // each connection being forwarded. Note that forwarding can happen with many |
| // devices (identified with a serial id). |
| class HostControllersManager { |
| public: |
| explicit HostControllersManager( |
| base::Callback<int()> exit_notifier_fd_callback); |
| ~HostControllersManager(); |
| void HandleRequest(const std::string& adb_path, |
| const std::string& device_serial, |
| int command, |
| int device_port, |
| int host_port, |
| std::unique_ptr<Socket> client_socket); |
| bool has_failed() const { return has_failed_; } |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(HostControllersManagerTest, AdbNoExtraFds); |
| FRIEND_TEST_ALL_PREFIXES(HostControllersManagerTest, AdbArgumentSequence); |
| |
| using HostControllerMap = |
| std::unordered_map<std::string, std::unique_ptr<HostController>>; |
| |
| static std::string MakeHostControllerMapKey(int adb_port, int device_port); |
| |
| void InitOnce(); |
| |
| // Invoked when a HostController instance reports an error (e.g. due to a |
| // device connectivity issue). Note that this could be called after the |
| // controller manager was destroyed which is why a weak pointer is used. |
| static void DeleteHostController( |
| const base::WeakPtr<HostControllersManager>& manager_ptr, |
| std::unique_ptr<HostController> host_controller); |
| |
| void Map(const std::string& adb_path, |
| const std::string& device_serial, |
| int adb_port, |
| int device_port, |
| int host_port, |
| Socket* client_socket); |
| |
| void Unmap(const std::string& adb_path, |
| const std::string& device_serial, |
| int adb_port, |
| int device_port, |
| Socket* client_socket); |
| |
| void UnmapAll(const std::string& adb_path, |
| const std::string& device_serial, |
| int adb_port, |
| Socket* client_socket); |
| |
| bool Adb(const std::string& adb_path, |
| const std::string& device_serial, |
| const std::string& command, |
| std::string* output_and_error); |
| |
| void HandleRequestOnInternalThread(const std::string& adb_path, |
| const std::string& device_serial, |
| int command, |
| int device_port, |
| int host_port, |
| std::unique_ptr<Socket> client_socket); |
| |
| void LogExistingControllers(Socket* client_socket); |
| |
| void RemoveAdbPortForDeviceIfNeeded(const std::string& adb_path, |
| const std::string& device_serial); |
| |
| int GetAdbPortForDevice(const std::string adb_path, |
| const std::string& device_serial); |
| |
| bool SendMessage(const std::string& msg, Socket* client_socket); |
| |
| // This is a separate virtual method solely for easy mocking. The default |
| // implementation is a wrapper around base::GetAppOutputAndError. |
| virtual bool GetAppOutputAndError(const std::vector<std::string>& argv, |
| std::string* output); |
| |
| std::unordered_map<std::string, int> device_serial_to_adb_port_map_; |
| std::unique_ptr<HostControllerMap> controllers_; |
| std::unique_ptr<base::AtExitManager> |
| at_exit_manager_; // Needed by base::Thread. |
| std::unique_ptr<base::Thread> thread_; |
| base::Callback<int()> exit_notifier_fd_callback_; |
| bool has_failed_; |
| base::WeakPtrFactory<HostControllersManager> weak_ptr_factory_; |
| }; |
| |
| } // namespace forwarder2 |
| |
| #endif // TOOLS_ANDROID_FORWARDER2_HOST_CONTROLLERS_MANAGER_H_ |