Index: source/Plugins/Platform/Android/AdbClient.h =================================================================== --- source/Plugins/Platform/Android/AdbClient.h +++ source/Plugins/Platform/Android/AdbClient.h @@ -14,6 +14,7 @@ // C++ Includes +#include #include #include #include @@ -57,6 +58,9 @@ Error Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime); + bool + IsConnected () const; + private: explicit SyncService (std::unique_ptr &&conn); @@ -72,8 +76,19 @@ Error ReadAllBytes (void *buffer, size_t size); + Error + internalPullFile (const FileSpec &remote_file, const FileSpec &local_file); + + Error + internalPushFile (const FileSpec &local_file, const FileSpec &remote_file); + + Error + internalStat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime); + + Error + executeCommand (const std::function &cmd); - const std::unique_ptr m_conn; + std::unique_ptr m_conn; }; static Error @@ -118,7 +133,7 @@ SetDeviceID (const std::string &device_id); Error - SendMessage (const std::string &packet); + SendMessage (const std::string &packet, const bool reconnect = true); Error SendDeviceMessage (const std::string &packet); Index: source/Plugins/Platform/Android/AdbClient.cpp =================================================================== --- source/Plugins/Platform/Android/AdbClient.cpp +++ source/Plugins/Platform/Android/AdbClient.cpp @@ -225,10 +225,10 @@ } Error -AdbClient::SendMessage (const std::string &packet) +AdbClient::SendMessage (const std::string &packet, const bool reconnect) { Error error; - if (!m_conn || !m_conn->IsConnected()) + if (!m_conn || reconnect) { error = Connect (); if (error.Fail ()) @@ -364,7 +364,7 @@ Error AdbClient::Sync () { - auto error = SendMessage ("sync:"); + auto error = SendMessage ("sync:", false); if (error.Fail ()) return error; @@ -380,9 +380,13 @@ Error AdbClient::Shell (const char* command, uint32_t timeout_ms, std::string* output) { + auto error = SwitchDeviceTransport (); + if (error.Fail ()) + return Error ("Failed to switch to device transport: %s", error.AsCString ()); + StreamString adb_command; adb_command.Printf("shell:%s", command); - auto error = SendMessage (adb_command.GetData()); + error = SendMessage (adb_command.GetData(), false); if (error.Fail ()) return error; @@ -412,7 +416,7 @@ } Error -AdbClient::SyncService::PullFile (const FileSpec &remote_file, const FileSpec &local_file) +AdbClient::SyncService::internalPullFile (const FileSpec &remote_file, const FileSpec &local_file) { const auto local_file_path = local_file.GetPath (); llvm::FileRemover local_file_remover (local_file_path.c_str ()); @@ -442,7 +446,7 @@ } Error -AdbClient::SyncService::PushFile (const FileSpec &local_file, const FileSpec &remote_file) +AdbClient::SyncService::internalPushFile (const FileSpec &local_file, const FileSpec &remote_file) { const auto local_file_path (local_file.GetPath ()); std::ifstream src (local_file_path.c_str(), std::ios::in | std::ios::binary); @@ -492,7 +496,7 @@ } Error -AdbClient::SyncService::Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime) +AdbClient::SyncService::internalStat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime) { const std::string remote_file_path (remote_file.GetPath (false)); auto error = SendSyncRequest (kSTAT, remote_file_path.length (), remote_file_path.c_str ()); @@ -523,11 +527,54 @@ return Error (); } +Error +AdbClient::SyncService::PullFile (const FileSpec &remote_file, const FileSpec &local_file) +{ + return executeCommand ([this, &remote_file, &local_file]() { + return internalPullFile (remote_file, local_file); + }); +} + +Error +AdbClient::SyncService::PushFile (const FileSpec &local_file, const FileSpec &remote_file) +{ + return executeCommand ([this, &local_file, &remote_file]() { + return internalPushFile (local_file, remote_file); + }); +} + +Error +AdbClient::SyncService::Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime) +{ + return executeCommand ([this, &remote_file, &mode, &size, &mtime]() { + return internalStat (remote_file, mode, size, mtime); + }); +} + +bool +AdbClient::SyncService::IsConnected () const +{ + return m_conn && m_conn->IsConnected (); +} + AdbClient::SyncService::SyncService(std::unique_ptr &&conn): m_conn(std::move(conn)) { } +Error +AdbClient::SyncService::executeCommand (const std::function &cmd) +{ + if (!m_conn) + return Error ("SyncService is disconnected"); + + const auto error = cmd (); + if (error.Fail ()) + m_conn.reset (); + + return error; +} + AdbClient::SyncService::~SyncService () {} Error Index: source/Plugins/Platform/Android/PlatformAndroid.h =================================================================== --- source/Plugins/Platform/Android/PlatformAndroid.h +++ source/Plugins/Platform/Android/PlatformAndroid.h @@ -105,7 +105,8 @@ GetLibdlFunctionDeclarations() const override; private: - std::unique_ptr m_adb; + AdbClient::SyncService* GetSyncService (Error &error); + std::unique_ptr m_adb_sync_svc; std::string m_device_id; uint32_t m_sdk_version; Index: source/Plugins/Platform/Android/PlatformAndroid.cpp =================================================================== --- source/Plugins/Platform/Android/PlatformAndroid.cpp +++ source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -204,17 +204,12 @@ auto error = PlatformLinux::ConnectRemote(args); if (error.Success()) { - m_adb.reset(new AdbClient); - error = AdbClient::CreateByDeviceID(m_device_id, *m_adb); + AdbClient adb; + error = AdbClient::CreateByDeviceID(m_device_id, adb); if (error.Fail()) return error; - m_device_id = m_adb->GetDeviceID(); - m_adb_sync_svc = m_adb->GetSyncService(error); - if (error.Fail()) - return error; - - error = m_adb->SwitchDeviceTransport(); + m_device_id = adb.GetDeviceID(); } return error; } @@ -230,7 +225,12 @@ if (source_spec.IsRelative()) source_spec = GetRemoteWorkingDirectory ().CopyByAppendingPathComponent (source_spec.GetCString (false)); - return m_adb_sync_svc->PullFile (source_spec, destination); + Error error; + auto sync_service = GetSyncService (error); + if (error.Fail ()) + return error; + + return sync_service->PullFile (source_spec, destination); } Error @@ -247,7 +247,11 @@ destination_spec = GetRemoteWorkingDirectory ().CopyByAppendingPathComponent (destination_spec.GetCString (false)); // TODO: Set correct uid and gid on remote file. - return m_adb_sync_svc->PushFile(source, destination_spec); + Error error; + auto sync_service = GetSyncService (error); + if (error.Fail ()) + return error; + return sync_service->PushFile(source, destination_spec); } const char * @@ -296,7 +300,8 @@ return m_sdk_version; std::string version_string; - Error error = m_adb->Shell("getprop ro.build.version.sdk", 5000 /* ms */, &version_string); + AdbClient adb(m_device_id); + Error error = adb.Shell("getprop ro.build.version.sdk", 5000 /* ms */, &version_string); version_string = llvm::StringRef(version_string).trim().str(); if (error.Fail() || version_string.empty()) @@ -332,8 +337,9 @@ if (module_sp->GetSectionList()->FindSectionByName(ConstString(".symtab")) != nullptr) return Error("Symtab already available in the module"); + AdbClient adb(m_device_id); std::string tmpdir; - Error error = m_adb->Shell("mktemp --directory --tmpdir /data/local/tmp", 5000 /* ms */, &tmpdir); + Error error = adb.Shell("mktemp --directory --tmpdir /data/local/tmp", 5000 /* ms */, &tmpdir); if (error.Fail() || tmpdir.empty()) return Error("Failed to generate temporary directory on the device (%s)", error.AsCString()); tmpdir = llvm::StringRef(tmpdir).trim().str(); @@ -341,10 +347,10 @@ // Create file remover for the temporary directory created on the device std::unique_ptr> tmpdir_remover( &tmpdir, - [this](std::string* s) { + [this, &adb](std::string* s) { StreamString command; command.Printf("rm -rf %s", s->c_str()); - Error error = m_adb->Shell(command.GetData(), 5000 /* ms */, nullptr); + Error error = adb.Shell(command.GetData(), 5000 /* ms */, nullptr); Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); if (error.Fail()) @@ -360,7 +366,7 @@ command.Printf("oatdump --symbolize=%s --output=%s", module_sp->GetPlatformFileSpec().GetCString(false), symfile_platform_filespec.GetCString(false)); - error = m_adb->Shell(command.GetData(), 60000 /* ms */, nullptr); + error = adb.Shell(command.GetData(), 60000 /* ms */, nullptr); if (error.Fail()) return Error("Oatdump failed: %s", error.AsCString()); @@ -387,3 +393,15 @@ extern "C" char* dlerror(void) asm("__dl_dlerror"); )"; } + +AdbClient::SyncService* +PlatformAndroid::GetSyncService (Error &error) +{ + if (m_adb_sync_svc && m_adb_sync_svc->IsConnected ()) + return m_adb_sync_svc.get (); + + AdbClient adb (m_device_id); + m_adb_sync_svc = adb.GetSyncService (error); + return (error.Success ()) ? m_adb_sync_svc.get () : nullptr; +} +