1 /* ide-deploy-strategy.c
2  *
3  * Copyright 2018-2019 Christian Hergert <chergert@redhat.com>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  * SPDX-License-Identifier: GPL-3.0-or-later
19  */
20 
21 #define G_LOG_DOMAIN "ide-deploy-strategy"
22 
23 #include "config.h"
24 
25 #include "ide-pipeline.h"
26 #include "ide-deploy-strategy.h"
27 
G_DEFINE_ABSTRACT_TYPE(IdeDeployStrategy,ide_deploy_strategy,IDE_TYPE_OBJECT)28 G_DEFINE_ABSTRACT_TYPE (IdeDeployStrategy, ide_deploy_strategy, IDE_TYPE_OBJECT)
29 
30 static void
31 ide_deploy_strategy_real_load_async (IdeDeployStrategy   *self,
32                                      IdePipeline    *pipeline,
33                                      GCancellable        *cancellable,
34                                      GAsyncReadyCallback  callback,
35                                      gpointer             user_data)
36 {
37   g_task_report_new_error (self, callback, user_data,
38                            ide_deploy_strategy_real_load_async,
39                            G_IO_ERROR,
40                            G_IO_ERROR_NOT_SUPPORTED,
41                            "%s does not support the current pipeline",
42                            G_OBJECT_TYPE_NAME (self));
43 }
44 
45 static gboolean
ide_deploy_strategy_real_load_finish(IdeDeployStrategy * self,GAsyncResult * result,GError ** error)46 ide_deploy_strategy_real_load_finish (IdeDeployStrategy  *self,
47                                       GAsyncResult       *result,
48                                       GError            **error)
49 {
50   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
51   g_assert (G_IS_TASK (result));
52   g_assert (g_task_is_valid (G_TASK (result), self));
53 
54   return g_task_propagate_boolean (G_TASK (result), error);
55 }
56 
57 static void
ide_deploy_strategy_real_deploy_async(IdeDeployStrategy * self,IdePipeline * pipeline,GFileProgressCallback progress,gpointer progress_data,GDestroyNotify progress_data_destroy,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)58 ide_deploy_strategy_real_deploy_async (IdeDeployStrategy     *self,
59                                        IdePipeline      *pipeline,
60                                        GFileProgressCallback  progress,
61                                        gpointer               progress_data,
62                                        GDestroyNotify         progress_data_destroy,
63                                        GCancellable          *cancellable,
64                                        GAsyncReadyCallback    callback,
65                                        gpointer               user_data)
66 {
67   g_task_report_new_error (self, callback, user_data,
68                            ide_deploy_strategy_real_deploy_async,
69                            G_IO_ERROR,
70                            G_IO_ERROR_NOT_SUPPORTED,
71                            "%s does not support the current pipeline",
72                            G_OBJECT_TYPE_NAME (self));
73 }
74 
75 static gboolean
ide_deploy_strategy_real_deploy_finish(IdeDeployStrategy * self,GAsyncResult * result,GError ** error)76 ide_deploy_strategy_real_deploy_finish (IdeDeployStrategy  *self,
77                                         GAsyncResult       *result,
78                                         GError            **error)
79 {
80   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
81   g_assert (G_IS_TASK (result));
82   g_assert (g_task_is_valid (G_TASK (result), self));
83 
84   return g_task_propagate_boolean (G_TASK (result), error);
85 }
86 
87 static void
ide_deploy_strategy_real_create_runner_async(IdeDeployStrategy * self,IdePipeline * pipeline,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)88 ide_deploy_strategy_real_create_runner_async (IdeDeployStrategy   *self,
89                                               IdePipeline         *pipeline,
90                                               GCancellable        *cancellable,
91                                               GAsyncReadyCallback  callback,
92                                               gpointer             user_data)
93 {
94   g_autoptr(IdeTask) task = NULL;
95 
96   g_return_if_fail (IDE_IS_DEPLOY_STRATEGY (self));
97   g_return_if_fail (IDE_IS_PIPELINE (pipeline));
98   g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
99 
100   task = ide_task_new (self, cancellable, callback, user_data);
101   ide_task_return_new_error (task,
102                              G_IO_ERROR,
103                              G_IO_ERROR_NOT_SUPPORTED,
104                              "Not supported");
105 
106 }
107 
108 static IdeRunner *
ide_deploy_strategy_real_create_runner_finish(IdeDeployStrategy * self,GAsyncResult * result,GError ** error)109 ide_deploy_strategy_real_create_runner_finish (IdeDeployStrategy  *self,
110                                                GAsyncResult       *result,
111                                                GError            **error)
112 {
113   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
114   g_assert (IDE_IS_TASK (result));
115   g_assert (ide_task_is_valid (G_TASK (result), self));
116 
117   return g_task_propagate_pointer (G_TASK (result), error);
118 }
119 
120 static void
ide_deploy_strategy_class_init(IdeDeployStrategyClass * klass)121 ide_deploy_strategy_class_init (IdeDeployStrategyClass *klass)
122 {
123   klass->load_async = ide_deploy_strategy_real_load_async;
124   klass->load_finish = ide_deploy_strategy_real_load_finish;
125   klass->deploy_async = ide_deploy_strategy_real_deploy_async;
126   klass->deploy_finish = ide_deploy_strategy_real_deploy_finish;
127   klass->create_runner_async = ide_deploy_strategy_real_create_runner_async;
128   klass->create_runner_finish = ide_deploy_strategy_real_create_runner_finish;
129 }
130 
131 static void
ide_deploy_strategy_init(IdeDeployStrategy * self)132 ide_deploy_strategy_init (IdeDeployStrategy *self)
133 {
134 }
135 
136 /**
137  * ide_deploy_strategy_load_async:
138  * @self: an #IdeDeployStrategy
139  * @pipeline: an #IdePipeline
140  * @cancellable: (nullable): a #GCancellable, or %NULL
141  * @callback: a callback to execute upon completion
142  * @user_data: closure data for @callback
143  *
144  * Asynchronously requests that the #IdeDeployStrategy load anything
145  * necessary to support deployment for @pipeline. If the strategy cannot
146  * support the pipeline, it should fail with %G_IO_ERROR error domain
147  * and %G_IO_ERROR_NOT_SUPPORTED error code.
148  *
149  * Generally, the deployment strategy is responsible for checking if
150  * it can support deployment to the given device, and determine how to
151  * get the install data out of the pipeline. Given so many moving parts
152  * in build systems, how to determine that is an implementation detail of
153  * the specific #IdeDeployStrategy.
154  *
155  * Since: 3.32
156  */
157 void
ide_deploy_strategy_load_async(IdeDeployStrategy * self,IdePipeline * pipeline,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)158 ide_deploy_strategy_load_async (IdeDeployStrategy   *self,
159                                 IdePipeline    *pipeline,
160                                 GCancellable        *cancellable,
161                                 GAsyncReadyCallback  callback,
162                                 gpointer             user_data)
163 {
164   IDE_ENTRY;
165 
166   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
167   g_assert (IDE_IS_PIPELINE (pipeline));
168   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
169 
170   IDE_DEPLOY_STRATEGY_GET_CLASS (self)->load_async (self, pipeline, cancellable, callback, user_data);
171 
172   IDE_EXIT;
173 }
174 
175 /**
176  * ide_deploy_strategy_load_finish:
177  * @self: an #IdeDeployStrategy
178  * @result: a #GAsyncResult provided to callback
179  * @error: a location for a #GError, or %NULL
180  *
181  * Completes an asynchronous request to load the #IdeDeployStrategy.
182  *
183  * Returns: %TRUE if successful and the pipeline was supported; otherwise
184  *   %FALSE and @error is set.
185  *
186  * Since: 3.32
187  */
188 gboolean
ide_deploy_strategy_load_finish(IdeDeployStrategy * self,GAsyncResult * result,GError ** error)189 ide_deploy_strategy_load_finish (IdeDeployStrategy  *self,
190                                  GAsyncResult       *result,
191                                  GError            **error)
192 {
193   gboolean ret;
194 
195   IDE_ENTRY;
196 
197   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
198   g_assert (G_IS_ASYNC_RESULT (result));
199 
200   ret = IDE_DEPLOY_STRATEGY_GET_CLASS (self)->load_finish (self, result, error);
201 
202   IDE_RETURN (ret);
203 }
204 
205 /**
206  * ide_deploy_strategy_deploy_async:
207  * @self: a #IdeDeployStrategy
208  * @pipeline: an #IdePipeline
209  * @progress: (nullable) (closure progress_data) (scope notified):
210  *   a #GFileProgressCallback or %NULL
211  * @progress_data: (nullable): closure data for @progress or %NULL
212  * @progress_data_destroy: (nullable): destroy callback for @progress_data
213  * @cancellable: (nullable): a #GCancellable or %NULL
214  * @callback: (closure user_data): a callback to execute upon completion
215  * @user_data: closure data for @callback
216  *
217  * Requests that the #IdeDeployStrategy deploy the application to the
218  * configured device in the build pipeline.
219  *
220  * If supported, the strategy will call @progress with periodic updates as
221  * the application is deployed.
222  *
223  * Since: 3.32
224  */
225 void
ide_deploy_strategy_deploy_async(IdeDeployStrategy * self,IdePipeline * pipeline,GFileProgressCallback progress,gpointer progress_data,GDestroyNotify progress_data_destroy,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)226 ide_deploy_strategy_deploy_async (IdeDeployStrategy     *self,
227                                   IdePipeline      *pipeline,
228                                   GFileProgressCallback  progress,
229                                   gpointer               progress_data,
230                                   GDestroyNotify         progress_data_destroy,
231                                   GCancellable          *cancellable,
232                                   GAsyncReadyCallback    callback,
233                                   gpointer               user_data)
234 {
235   IDE_ENTRY;
236 
237   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
238   g_assert (IDE_IS_PIPELINE (pipeline));
239   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
240 
241   IDE_DEPLOY_STRATEGY_GET_CLASS (self)->deploy_async (self,
242                                                       pipeline,
243                                                       progress,
244                                                       progress_data,
245                                                       progress_data_destroy,
246                                                       cancellable,
247                                                       callback,
248                                                       user_data);
249 
250   IDE_EXIT;
251 }
252 
253 /**
254  * ide_deploy_strategy_deploy_finish:
255  * @self: an #IdeDeployStrategy
256  * @result: a #GAsyncResult provided to callback
257  * @error: a location for a #GError or %NULL
258  *
259  * Completes an asynchronous request to deploy the application to the
260  * build pipeline's device.
261  *
262  * Returns: %TRUE if successful; otherwise %FALSE and @error is set
263  *
264  * Since: 3.32
265  */
266 gboolean
ide_deploy_strategy_deploy_finish(IdeDeployStrategy * self,GAsyncResult * result,GError ** error)267 ide_deploy_strategy_deploy_finish (IdeDeployStrategy  *self,
268                                    GAsyncResult       *result,
269                                    GError            **error)
270 {
271   gboolean ret;
272 
273   IDE_ENTRY;
274 
275   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
276   g_assert (G_IS_ASYNC_RESULT (result));
277 
278   ret = IDE_DEPLOY_STRATEGY_GET_CLASS (self)->deploy_finish (self, result, error);
279 
280   IDE_RETURN (ret);
281 }
282 
283 /**
284  * ide_deploy_strategy_create_runner_async:
285  * @self: a #IdeDeployStrategy
286  * @pipeline: an #IdePipeline
287  * @cancellable: (nullable): a #GCancellable or %NULL
288  * @callback: (closure user_data): a callback to execute upon completion
289  * @user_data: closure data for @callback
290  *
291  * Gets an #IdeRunner that runs apps deployed to the device, if a
292  * runner other than the default is needed.
293  *
294  * Since: 41
295  */
296 void
ide_deploy_strategy_create_runner_async(IdeDeployStrategy * self,IdePipeline * pipeline,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)297 ide_deploy_strategy_create_runner_async (IdeDeployStrategy   *self,
298                                          IdePipeline         *pipeline,
299                                          GCancellable        *cancellable,
300                                          GAsyncReadyCallback  callback,
301                                          gpointer             user_data)
302 {
303   IDE_ENTRY;
304 
305   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
306   g_assert (IDE_IS_PIPELINE (pipeline));
307   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
308 
309   IDE_DEPLOY_STRATEGY_GET_CLASS (self)->create_runner_async (self,
310                                                              pipeline,
311                                                              cancellable,
312                                                              callback,
313                                                              user_data);
314 
315   IDE_EXIT;
316 }
317 
318 /**
319  * ide_deploy_strategy_create_runner_finish:
320  * @self: an #IdeDeployStrategy
321  * @result: a #GAsyncResult provided to callback
322  * @error: a location for a #GError, or %NULL
323  *
324  * Completes an asynchronous request to get an #IdeRunner for the current
325  * device.
326  *
327  * Returns: (transfer full): An #IdeRunner or %NULL
328  *
329  * Since: 41
330  */
331 IdeRunner *
ide_deploy_strategy_create_runner_finish(IdeDeployStrategy * self,GAsyncResult * result,GError ** error)332 ide_deploy_strategy_create_runner_finish (IdeDeployStrategy  *self,
333                                           GAsyncResult       *result,
334                                           GError            **error)
335 {
336   IdeRunner *ret;
337 
338   IDE_ENTRY;
339 
340   g_assert (IDE_IS_DEPLOY_STRATEGY (self));
341   g_assert (G_IS_ASYNC_RESULT (result));
342 
343   ret = IDE_DEPLOY_STRATEGY_GET_CLASS (self)->create_runner_finish (self, result, error);
344 
345   IDE_RETURN (ret);
346 }
347