• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Flutter Daemon
2
3## Overview
4
5The `flutter` command-line tool supports a daemon server mode for use by IDEs and other tools.
6
7```
8flutter daemon
9```
10
11It runs a persistent, JSON-RPC based server to communicate with devices. IDEs and other tools can start the flutter tool in this mode and get device addition and removal notifications, as well as being able to programmatically start and stop apps on those devices.
12
13A set of `flutter daemon` commands/events are also exposed via `flutter run --machine` and `flutter attach --machine` which allow IDEs and tools to launch and attach to flutter applications and interact to send commands like Hot Reload. The command and events that are available in these modes are documented at the bottom of this document.
14
15## Protocol
16
17The daemon speaks [JSON-RPC](http://json-rpc.org/) to clients. It uses stdin and stdout as the protocol transport. To send a command to the server, create your command as a JSON-RPC message, encode it to json, surround the encoded text with square brackets, and write it as one line of text to the stdin of the process:
18
19```
20[{"method":"daemon.version","id":0}]
21```
22
23The response will come back as a single line from stdout:
24
25```
26[{"id":0,"result":"0.1.0"}]
27```
28
29All requests and responses should be wrapped in square brackets. This ensures that the communications are resilient to stray output in the stdout/stdin stream.
30
31`id` is an opaque type to the server, but ids should be unique for the life of the server. A response to a particular command will contain the id that was passed in for that command.
32
33Each command should have a `method` field. This is in the form '`domain.command`'.
34
35Any params for that command should be passed in through a `params` field. Here's a example request/response for the `device.getDevices` method:
36
37```
38[{"method":"device.getDevices","id":2}]
39```
40
41```
42[{"id":2,"result":[{"id":"702ABC1F-5EA5-4F83-84AB-6380CA91D39A","name":"iPhone 6","platform":"ios_x64","available":true}]}]
43```
44
45Events that come from the server will have an `event` field containing the type of event, along with a `params` field.
46
47```
48[{"event":"device.added","params":{"id":"1DD6786B-37D4-4355-AA15-B818A87A18B4","name":"iPhone XS Max","platform":"ios","emulator":true,"ephemeral":false,"platformType":"ios","category":"mobile"}}]
49```
50
51## Domains and Commands
52
53### daemon domain
54
55#### daemon.version
56
57The `version()` command responds with a String with the protocol version.
58
59#### daemon.shutdown
60
61The `shutdown()` command will terminate the flutter daemon. It is not necessary to call this before shutting down the daemon; it is perfectly acceptable to just kill the daemon process.
62
63### daemon.getSupportedPlatforms
64
65The `getSupportedPlatforms()` command will enumerate all platforms supported by the project located at the provided `projectRoot`. It returns a Map with the key 'platforms' containing a List of strings which describe the set of all possibly supported platforms. Possible values include:
66   - android
67   - ios
68   - linux #experimental
69   - macos #experimental
70   - windows #experimental
71   - fuchsia #experimental
72   - web #experimental
73
74#### Events
75
76#### daemon.connected
77
78The `daemon.connected` event is sent when the daemon starts. The `params` field will be a map with the following fields:
79
80- `version`: The protocol version. This is the same version returned by the `version()` command.
81- `pid`: The `pid` of the daemon process.
82
83#### daemon.log
84
85This is sent when user-facing output is received. The `params` field will be a map with the field `log`. The `log` field is a string with the output text. If the output indicates an error, an `error` boolean field will be present, and set to `true`.
86
87#### daemon.showMessage
88
89The `daemon.showMessage` event is sent by the daemon when some if would be useful to show a message to the user. This could be an error notification or a notification that some development tools are not configured or not installed. The JSON message will contain an `event` field with the value `daemon.showMessage`, and an `params` field containing a map with `level`, `title`, and `message` fields. The valid options for `level` are `info`, `warning`, and `error`.
90
91It is up to the client to decide how best to display the message; for some clients, it may map well to a toast style notification. There is an implicit contract that the daemon will not send too many messages over some reasonable period of time.
92
93#### daemon.logMessage
94
95The `daemon.logMessage` event is sent whenever a log message is created - either a status level message or an error. The JSON message will contain an `event` field with the value `daemon.logMessage`, and an `params` field containing a map with `level`, `message`, and (optionally) `stackTrace` fields.
96
97Generally, clients won't display content from `daemon.logMessage` events unless they're set to a more verbose output mode.
98
99### app domain
100
101#### app.restart
102
103The `restart()` restarts the given application. It returns a Map of `{ int code, String message }` to indicate success or failure in restarting the app. A `code` of `0` indicates success, and non-zero indicates a failure.
104
105- `appId`: the id of a previously started app; this is required.
106- `fullRestart`: optional; whether to do a full (rather than an incremental) restart of the application
107- `reason`: optional; the reason for the full restart (eg. `save`, `manual`) for reporting purposes
108- `pause`: optional; when doing a hot restart the isolate should enter a paused mode
109
110#### app.callServiceExtension
111
112The `callServiceExtension()` allows clients to make arbitrary calls to service protocol extensions. It returns a `Map` - the result returned by the service protocol method.
113
114- `appId`: the id of a previously started app; this is required.
115- `methodName`: the name of the service protocol extension to invoke; this is required.
116- `params`: an optional Map of parameters to pass to the service protocol extension.
117
118#### app.detach
119
120The `detach()` command takes one parameter, `appId`. It returns a `bool` to indicate success or failure in detaching from an app without stopping it.
121
122- `appId`: the id of a previously started app; this is required.
123
124#### app.stop
125
126The `stop()` command takes one parameter, `appId`. It returns a `bool` to indicate success or failure in stopping an app.
127
128- `appId`: the id of a previously started app; this is required.
129
130#### Events
131
132#### app.start
133
134This is sent when an app is starting. The `params` field will be a map with the fields `appId`, `directory`, `deviceId`, and `launchMode`.
135
136#### app.debugPort
137
138This is sent when an observatory port is available for a started app. The `params` field will be a map with the fields `appId`, `port`, and `wsUri`. Clients should prefer using the `wsUri` field in preference to synthesizing a uri using the `port` field. An optional field, `baseUri`, is populated if a path prefix is required for setting breakpoints on the target device.
139
140#### app.started
141
142This is sent once the application launch process is complete and the app is either paused before main() (if `startPaused` is true) or main() has begun running. When attaching, this even will be fired once attached. The `params` field will be a map containing the field `appId`.
143
144#### app.log
145
146This is sent when output is logged for a running application. The `params` field will be a map with the fields `appId` and `log`. The `log` field is a string with the output text. If the output indicates an error, an `error` boolean field will be present, and set to `true`.
147
148#### app.progress
149
150This is sent when an operation starts and again when it stops. When an operation starts, the event contains the fields `id`, an opaque identifier, and `message` containing text describing the operation. When that same operation ends, the event contains the same `id` field value as when the operation started, along with a `finished` bool field with the value true, but no `message` field.
151
152#### app.stop
153
154This is sent when an app is stopped or detached from. The `params` field will be a map with the field `appId`.
155
156### device domain
157
158#### device.getDevices
159
160Return a list of all connected devices. The `params` field will be a List; each item is a map with the fields `id`, `name`, `platform`, `category`, `platformType`, `ephemeral`, `emulator` (a boolean) and `emulatorId`.
161
162`category` is string description of the kind of workflow the device supports. The current categories are "mobile", "web" and "desktop", or null if none.
163
164`platformType` is a string description of the platform sub-folder the device
165supports. The current catgetories are "android", "ios", "linux", "macos",
166"fuchsia", "windows", and "web". These are kept in sync with the response from `daemon.getSupportedPlatforms`.
167
168`ephemeral` is a boolean which indicates where the device needs to be manually connected to a development machine. For example, a physical Android device is ephemeral, but the "web" device (that is always present) is not.
169
170`emulatorId` is an string ID that matches the ID from `getEmulators` to allow clients to match running devices to the emulators that started them (for example to hide emulators that are already running). This field is not guaranteed to be populated even if a device was spawned from an emulator as it may require a successful connection to the device to retrieve it. In the case of a failed connection or the device is not an emulator, this field will be null.
171
172#### device.enable
173
174Turn on device polling. This will poll for newly connected devices, and fire `device.added` and `device.removed` events.
175
176#### device.disable
177
178Turn off device polling.
179
180#### device.forward
181
182Forward a host port to a device port. This call takes two required arguments, `deviceId` and `devicePort`, and one optional argument, `hostPort`. If `hostPort` is not specified, the host port will be any available port.
183
184This method returns a map with a `hostPort` field set.
185
186#### device.unforward
187
188Removed a forwarded port. It takes `deviceId`, `devicePort`, and `hostPort` as required arguments.
189
190#### Events
191
192#### device.added
193
194This is sent when a device is connected (and polling has been enabled via `enable()`). The `params` field will be a map with the fields `id`, `name`, `platform`, `category`, `platformType`, `ephemeral`, and  `emulator`. For more information on `platform`, `category`, `platformType`, and `ephemeral` see `device.getDevices`.
195
196#### device.removed
197
198This is sent when a device is disconnected (and polling has been enabled via `enable()`). The `params` field will be a map with the fields `id`, `name`, `platform`, `category`, `platformType`, `ephemeral`, and  `emulator`. For more information on `platform`, `category`, `platformType`, and `ephemeral` see `device.getDevices`.
199
200### emulator domain
201
202#### emulator.getEmulators
203
204Return a list of all available emulators. The `params` field will be a List; each item is a map with the fields `id`, `name`, `category` and `platformType`. `category` and `platformType` values match the values described in `device.getDevices`.
205
206#### emulator.launch
207
208The `launch()` command allows launching an emulator/simulator by its `id`.
209
210- `emulatorId`: the id of an emulator as returned by `getEmulators`.
211
212#### emulator.create
213
214The `create()` command creates a new Android emulator with an optional `name`.
215
216- `name`: an optional name for this emulator
217
218The returned `params` will contain:
219
220- `success` - whether the emulator was successfully created
221- `emulatorName` - the name of the emulator created; this will have been auto-generated if you did not supply one
222- `error` - when `success`=`false`, a message explaining why the creation of the emulator failed
223
224## 'flutter run --machine' and 'flutter attach --machine'
225
226When running `flutter run --machine` or `flutter attach --machine` the following subset of the daemon is available:
227
228### daemon domain
229
230The following subset of the daemon domain is available in `flutter run --machine`. Refer to the documentation above for details.
231
232- Commands
233  - [`version`](#daemonversion)
234  - [`shutdown`](#daemonshutdown)
235- Events
236  - [`connected`](#daemonconnected)
237  - [`log`](#daemonlog)
238  - [`logMessage`](#daemonlogmessage)
239
240### app domain
241
242The following subset of the app domain is available in `flutter run --machine`. Refer to the documentation above for details.
243
244- Commands
245  - [`restart`](#apprestart)
246  - [`callServiceExtension`](#appcallserviceextension)
247  - [`detach`](#appdetach)
248  - [`stop`](#appstop)
249- Events
250  - [`start`](#appstart)
251  - [`debugPort`](#appdebugport)
252  - [`started`](#appstarted)
253  - [`log`](#applog)
254  - [`progress`](#appprogress)
255  - [`stop`](#appstop)
256
257## Source
258
259See the [source](https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/commands/daemon.dart) for the daemon protocol and implementation.
260
261## Changelog
262
263- 0.5.3: Added `emulatorId` field to device.
264- 0.5.2: Added `platformType` and `category` fields to emulator.
265- 0.5.1: Added `platformType`, `ephemeral`, and `category` fields to device.
266- 0.5.0: Added `daemon.getSupportedPlatforms` command
267- 0.4.2: Added `app.detach` command
268- 0.4.1: Added `flutter attach --machine`
269- 0.4.0: Added `emulator.create` command
270- 0.3.0: Added `daemon.connected` event at startup
271