1 /* 2 * RSession.hpp 3 * 4 * Copyright (C) 2021 by RStudio, PBC 5 * 6 * Unless you have received this program directly from RStudio pursuant 7 * to the terms of a commercial license agreement with RStudio, then 8 * this program is licensed to you under the terms of version 3 of the 9 * GNU Affero General Public License. This program is distributed WITHOUT 10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. 13 * 14 */ 15 16 #ifndef R_RSESSION_HPP 17 #define R_RSESSION_HPP 18 19 #include <string> 20 21 #include <boost/function.hpp> 22 23 #include <shared_core/json/Json.hpp> 24 #include <shared_core/FilePath.hpp> 25 26 #include <core/r_util/RSessionContext.hpp> 27 28 #include <R_ext/RStartup.h> 29 #include <r/session/RSessionUtils.hpp> 30 31 #define kConsoleInputCancel 1 32 #define kConsoleInputEof 2 33 34 #define EX_CONTINUE 100 35 #define EX_FORCE 101 36 #define EX_SUSPEND_RESTART_LAUNCHER_SESSION 102 37 38 namespace rstudio { 39 namespace core { 40 class Error; 41 class Settings; 42 } 43 } 44 45 namespace rstudio { 46 namespace r { 47 namespace session { 48 49 struct RClientMetrics 50 { RClientMetricsrstudio::r::session::RClientMetrics51 RClientMetrics() 52 : consoleWidth(0), buildConsoleWidth(0), graphicsWidth(0), 53 graphicsHeight(0), devicePixelRatio(1.0) 54 { 55 } 56 int consoleWidth; 57 int buildConsoleWidth; 58 int graphicsWidth; 59 int graphicsHeight; 60 double devicePixelRatio; 61 }; 62 63 struct ROptions 64 { ROptionsrstudio::r::session::ROptions65 ROptions() : 66 useInternet2(true), 67 rCompatibleGraphicsEngineVersion(14), 68 serverMode(false), 69 autoReloadSource(false), 70 restoreWorkspace(true), 71 saveWorkspace(SA_SAVEASK), 72 disableRProfileOnStart(false), 73 rProfileOnResume(false), 74 restoreEnvironmentOnResume(true), 75 packratEnabled(false), 76 suspendOnIncompleteStatement(false) 77 { 78 } 79 core::FilePath userHomePath; 80 core::FilePath userScratchPath; 81 core::FilePath scopedScratchPath; 82 core::FilePath sessionScratchPath; 83 core::FilePath logPath; 84 core::FilePath startupEnvironmentFilePath; 85 std::string sessionPort; 86 boost::function<core::FilePath()> rEnvironmentDir; 87 boost::function<core::FilePath()> rHistoryDir; 88 boost::function<bool()> alwaysSaveHistory; 89 core::FilePath rSourcePath; 90 std::string rLibsUser; 91 std::string rCRANUrl; 92 std::string rCRANSecondary; 93 std::string runScript; 94 bool useInternet2; 95 int rCompatibleGraphicsEngineVersion; 96 bool serverMode; 97 bool autoReloadSource; 98 bool restoreWorkspace; 99 SA_TYPE saveWorkspace; 100 bool disableRProfileOnStart; 101 bool rProfileOnResume; 102 bool restoreEnvironmentOnResume; 103 core::r_util::SessionScope sessionScope; 104 bool packratEnabled; 105 bool suspendOnIncompleteStatement; 106 }; 107 108 struct RInitInfo 109 { RInitInforstudio::r::session::RInitInfo110 RInitInfo() 111 : resumed(false) 112 { 113 } RInitInforstudio::r::session::RInitInfo114 RInitInfo(bool resumed) 115 : resumed(resumed) 116 { 117 } 118 bool resumed; 119 }; 120 121 struct RConsoleInput 122 { RConsoleInputrstudio::r::session::RConsoleInput123 explicit RConsoleInput() 124 : flags(0) 125 { 126 } 127 RConsoleInputrstudio::r::session::RConsoleInput128 explicit RConsoleInput(int flags) 129 : flags(flags) 130 { 131 } 132 RConsoleInputrstudio::r::session::RConsoleInput133 explicit RConsoleInput(const std::string& text, 134 const std::string& console = "", 135 int flags = 0) 136 : text(text), 137 console(console), 138 flags(flags) 139 { 140 } 141 isCancelrstudio::r::session::RConsoleInput142 bool isCancel() 143 { 144 return (flags & kConsoleInputCancel) != 0; 145 } 146 isEofrstudio::r::session::RConsoleInput147 bool isEof() 148 { 149 return (flags & kConsoleInputEof) != 0; 150 } 151 152 // typically used for hand-constructed RPC requests toJsonArrayrstudio::r::session::RConsoleInput153 core::json::Array toJsonArray() 154 { 155 core::json::Array jsonArray; 156 jsonArray.push_back(text); 157 jsonArray.push_back(console); 158 jsonArray.push_back(flags); 159 return jsonArray; 160 } 161 162 std::string text; 163 std::string console; 164 int flags; 165 }; 166 167 // forward declare DisplayState 168 namespace graphics { 169 struct DisplayState; 170 } 171 172 // serialization actions 173 extern const int kSerializationActionSaveDefaultWorkspace; 174 extern const int kSerializationActionLoadDefaultWorkspace; 175 extern const int kSerializationActionSuspendSession; 176 extern const int kSerializationActionResumeSession; 177 extern const int kSerializationActionCompleted; 178 179 struct RSuspendOptions; 180 struct RCallbacks 181 { 182 boost::function<core::Error(const RInitInfo&)> init; 183 boost::function<void()> initComplete; 184 boost::function<bool(const std::string&, bool, RConsoleInput*)> consoleRead; 185 boost::function<void(const std::string&)> browseURL; 186 boost::function<void(const core::FilePath&)> browseFile; 187 boost::function<void(const std::string&)> showHelp; 188 boost::function<void(const std::string&, core::FilePath&, bool)> showFile; 189 boost::function<void(const std::string&, int)> consoleWrite; 190 boost::function<void()> consoleHistoryReset; 191 boost::function<bool(double*, double*)> locator; 192 boost::function<core::FilePath(bool)> chooseFile; 193 boost::function<int(const std::string&)> editFile; 194 boost::function<void(const std::string&)> showMessage; 195 boost::function<void(bool)> busy; 196 boost::function<void(bool)> deferredInit; 197 boost::function<void(const r::session::RSuspendOptions& options)> suspended; 198 boost::function<void()> resumed; 199 boost::function<bool()> handleUnsavedChanges; 200 boost::function<void()> quit; 201 boost::function<void(const std::string&)> suicide; 202 boost::function<void(bool)> cleanup; 203 boost::function<void(int, const core::FilePath&)> serialization; 204 boost::function<void()> runTests; 205 }; 206 207 // run the session 208 core::Error run(const ROptions& options, const RCallbacks& callbacks); 209 210 // deferred deserialization of the session 211 void ensureDeserialized(); 212 213 // set client metrics 214 void setClientMetrics(const RClientMetrics& metrics); 215 216 // report a warning to the user and also log it 217 void reportAndLogWarning(const std::string& warning); 218 219 // suspend/resume 220 bool isSuspendable(const std::string& prompt); 221 bool suspend(bool force, int status, const std::string& ephemeralEnvVars); 222 223 struct RSuspendOptions 224 { RSuspendOptionsrstudio::r::session::RSuspendOptions225 RSuspendOptions(int exitStatus) 226 : status(exitStatus) 227 { 228 } 229 RSuspendOptionsrstudio::r::session::RSuspendOptions230 RSuspendOptions(int exitStatus, const std::string& ephemeral) 231 : status(exitStatus), 232 ephemeralEnvVars(ephemeral) 233 { 234 } 235 int status; 236 bool saveMinimal { false }; 237 bool saveWorkspace { false }; 238 bool excludePackages { false }; 239 std::string ephemeralEnvVars; 240 }; 241 void suspendForRestart(const RSuspendOptions& options); 242 243 // set save action 244 extern const int kSaveActionNoSave; 245 extern const int kSaveActionSave; 246 extern const int kSaveActionAsk; 247 void setSaveAction(int saveAction); 248 249 // image dirty state 250 void setImageDirty(bool imageDirty); 251 bool imageIsDirty(); 252 253 // check whether there is a browser context active 254 bool browserContextActive(); 255 256 // quit 257 void quit(bool saveWorkspace, int status = EXIT_SUCCESS); 258 259 } // namespace session 260 } // namespace r 261 } // namespace rstudio 262 263 #endif // R_RSESSION_HPP 264 265