1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 BogDan Vatra <bog_dan_ro@yahoo.com>
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 
27 #pragma once
28 
29 #include <projectexplorer/runcontrol.h>
30 
31 #include <qmldebug/qmldebugcommandlinearguments.h>
32 
33 #include <QFuture>
34 
35 namespace Android {
36 
37 class AndroidDeviceInfo;
38 
39 namespace Internal {
40 
41 const int MIN_SOCKET_HANDSHAKE_PORT = 20001;
42 
43 class AndroidRunnerWorker : public QObject
44 {
45     Q_OBJECT
46 public:
47     AndroidRunnerWorker(ProjectExplorer::RunWorker *runner, const QString &packageName);
48     ~AndroidRunnerWorker() override;
49 
50     bool runAdb(const QStringList &args, QString *stdOut = nullptr, const QByteArray &writeData = {});
51     void adbKill(qint64 pid);
52     QStringList selector() const;
53     void forceStop();
54     void logcatReadStandardError();
55     void logcatReadStandardOutput();
56     void logcatProcess(const QByteArray &text, QByteArray &buffer, bool onlyError);
57     void setAndroidDeviceInfo(const AndroidDeviceInfo &info);
setIsPreNougat(bool isPreNougat)58     void setIsPreNougat(bool isPreNougat) { m_isPreNougat = isPreNougat; }
setIntentName(const QString & intentName)59     void setIntentName(const QString &intentName) { m_intentName = intentName; }
60 
61     void asyncStart();
62     void asyncStop();
63     void handleJdbWaiting();
64     void handleJdbSettled();
65 
66     void removeForwardPort(const QString &port);
67 
68 signals:
69     void remoteProcessStarted(Utils::Port debugServerPort, const QUrl &qmlServer, qint64 pid);
70     void remoteProcessFinished(const QString &errString = QString());
71 
72     void remoteOutput(const QString &output);
73     void remoteErrorOutput(const QString &output);
74 
75 private:
76     void asyncStartHelper();
77     bool startDebuggerServer(const QString &packageDir, const QString &debugServerFile, QString *errorStr = nullptr);
78     bool deviceFileExists(const QString &filePath);
79     bool packageFileExists(const QString& filePath);
80     bool uploadDebugServer(const QString &debugServerFileName);
81     void asyncStartLogcat();
82 
83     enum class JDBState {
84         Idle,
85         Waiting,
86         Settled
87     };
88     void onProcessIdChanged(qint64 pid);
89     using Deleter = void (*)(QProcess *);
90 
91     // Create the processes and timer in the worker thread, for correct thread affinity
92     bool m_isPreNougat = false;
93     QString m_packageName;
94     QString m_intentName;
95     QStringList m_beforeStartAdbCommands;
96     QStringList m_afterFinishAdbCommands;
97     QStringList m_amStartExtraArgs;
98     qint64 m_processPID = -1;
99     std::unique_ptr<QProcess, Deleter> m_adbLogcatProcess;
100     std::unique_ptr<QProcess, Deleter> m_psIsAlive;
101     QByteArray m_stdoutBuffer;
102     QByteArray m_stderrBuffer;
103     QFuture<qint64> m_pidFinder;
104     bool m_useCppDebugger = false;
105     bool m_useLldb = false; // FIXME: Un-implemented currently.
106     QmlDebug::QmlDebugServicesPreset m_qmlDebugServices;
107     Utils::Port m_localDebugServerPort; // Local end of forwarded debug socket.
108     QUrl m_qmlServer;
109     JDBState m_jdbState = JDBState::Idle;
110     Utils::Port m_localJdbServerPort;
111     std::unique_ptr<QProcess, Deleter> m_debugServerProcess; // gdbserver or lldb-server
112     std::unique_ptr<QProcess, Deleter> m_jdbProcess;
113     QString m_deviceSerialNumber;
114     int m_apiLevel = -1;
115     QString m_extraAppParams;
116     Utils::Environment m_extraEnvVars;
117     QString m_debugServerPath;
118     bool m_useAppParamsForQmlDebugger = false;
119 };
120 
121 } // namespace Internal
122 } // namespace Android
123