24eab9f98bacef61860e47131b749c578472b44d
[platform/core/csapi/tizenfx.git] / src / Tizen.Content.Download / Tizen.Content.Download / Request.cs
1 /*
2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Content.Download
22 {
23     /// <summary>
24     /// The Request class provides the functions to create and manage a single download request.
25     /// </summary>
26     /// <since_tizen> 3 </since_tizen>
27     public class Request : IDisposable
28     {
29         private int _downloadId;
30         private Notification _notificationProperties;
31         private IDictionary<string, string> _httpHeaders;
32         private EventHandler<StateChangedEventArgs> _downloadStateChanged;
33         private Interop.Download.StateChangedCallback _downloadStateChangedCallback;
34         private EventHandler<ProgressChangedEventArgs> _downloadProgressChanged;
35         private Interop.Download.ProgressChangedCallback _downloadProgressChangedCallback;
36         private bool _disposed = false;
37
38         /// <summary>
39         /// Creates a Request object.
40         /// </summary>
41         /// <since_tizen> 3 </since_tizen>
42         /// <param name="url">The URL to download.</param>
43         /// <privilege>http://tizen.org/privilege/download</privilege>
44         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
45         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
46         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
47         public Request(string url)
48         {
49             if (String.IsNullOrEmpty(url))
50             {
51                 DownloadErrorFactory.ThrowException((int)DownloadError.InvalidParameter, "url cannot be null or empty");
52             }
53             int ret = Interop.Download.CreateRequest(out _downloadId);
54             if (ret != (int)DownloadError.None)
55             {
56                 DownloadErrorFactory.ThrowException(ret, "Request creation failed");
57             }
58             ret = Interop.Download.SetUrl(_downloadId, url);
59             if (ret != (int)DownloadError.None)
60             {
61                 DownloadErrorFactory.ThrowException(ret, "Setting Url failed");
62             }
63             _notificationProperties = new Notification(_downloadId);
64             _httpHeaders = new Dictionary<string, string>();
65         }
66
67         /// <summary>
68         /// Creates a Request object.
69         /// </summary>
70         /// <since_tizen> 3 </since_tizen>
71         /// <param name="url">The URL to download</param>
72         /// <param name="destinationPath">The directory path where downloaded file is stored.</param>
73         /// <param name="fileName">The name of the downloaded file.</param>
74         /// <param name="type">The network type which the download request must adhere to.</param>
75         /// <privilege>http://tizen.org/privilege/download</privilege>
76         /// <feature>http://tizen.org/feature/network.wifi</feature>
77         /// <feature>http://tizen.org/feature/network.wifi.direct</feature>
78         /// <feature>http://tizen.org/feature/network.telephony</feature>
79         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
80         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
81         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
82         /// <exception cref="NotSupportedException">Thrown when a feature is not supported.</exception>
83         public Request(string url, string destinationPath, string fileName, NetworkType type)
84         {
85             if (String.IsNullOrEmpty(url))
86             {
87                 DownloadErrorFactory.ThrowException((int)DownloadError.InvalidParameter, "url cannot be null or empty");
88             }
89             int ret = Interop.Download.CreateRequest(out _downloadId);
90             if (ret != (int)DownloadError.None)
91             {
92                 DownloadErrorFactory.ThrowException(ret, "Request creation failed");
93             }
94
95             ret = Interop.Download.SetUrl(_downloadId, url);
96             if (ret != (int)DownloadError.None)
97             {
98                 DownloadErrorFactory.ThrowException(ret, "Setting Url failed");
99             }
100
101             ret = Interop.Download.SetDestination(_downloadId, destinationPath);
102             if (ret != (int)DownloadError.None)
103             {
104                 DownloadErrorFactory.ThrowException(ret, "Setting DestinationPath failed");
105             }
106
107             ret = Interop.Download.SetFileName(_downloadId, fileName);
108             if (ret != (int)DownloadError.None)
109             {
110                 DownloadErrorFactory.ThrowException(ret, "Setting FileName failed");
111             }
112
113             ret = Interop.Download.SetNetworkType(_downloadId, (int)type);
114             if (ret != (int)DownloadError.None)
115             {
116                 DownloadErrorFactory.ThrowException(ret, "Setting NetworkType failed");
117             }
118
119             _notificationProperties = new Notification(_downloadId);
120             _httpHeaders = new Dictionary<string, string>();
121         }
122
123         /// <summary>
124         /// Creates a Request object.
125         /// </summary>
126         /// <since_tizen> 3 </since_tizen>
127         /// <param name="url">The URL to download.</param>
128         /// <param name="destinationPath">The directory path where the downloaded file is stored.</param>
129         /// <param name="fileName">The name of the downloaded file.</param>
130         /// <param name="type">The network type which the download request must adhere to.</param>
131         /// <param name="httpHeaders">HTTP header fields for the download request.</param>
132         /// <privilege>http://tizen.org/privilege/download</privilege>
133         /// <feature>http://tizen.org/feature/network.wifi</feature>
134         /// <feature>http://tizen.org/feature/network.wifi.direct</feature>
135         /// <feature>http://tizen.org/feature/network.telephony</feature>
136         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
137         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
138         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
139         /// <exception cref="NotSupportedException">Thrown when a feature is not supported.</exception>
140         public Request(string url, string destinationPath, string fileName, NetworkType type, IDictionary<string, string> httpHeaders)
141         {
142             if (String.IsNullOrEmpty(url))
143             {
144                 DownloadErrorFactory.ThrowException((int)DownloadError.InvalidParameter, "url cannot be null or empty");
145             }
146             int ret = Interop.Download.CreateRequest(out _downloadId);
147             if (ret != (int)DownloadError.None)
148             {
149                 DownloadErrorFactory.ThrowException(ret, "Request creation failed");
150             }
151
152             ret = Interop.Download.SetUrl(_downloadId, url);
153             if (ret != (int)DownloadError.None)
154             {
155                 DownloadErrorFactory.ThrowException(ret, "Setting Url failed");
156             }
157
158             ret = Interop.Download.SetDestination(_downloadId, destinationPath);
159             if (ret != (int)DownloadError.None)
160             {
161                 DownloadErrorFactory.ThrowException(ret, "Setting DestinationPath failed");
162             }
163
164             ret = Interop.Download.SetFileName(_downloadId, fileName);
165             if (ret != (int)DownloadError.None)
166             {
167                 DownloadErrorFactory.ThrowException(ret, "Setting FileName failed");
168             }
169
170             ret = Interop.Download.SetNetworkType(_downloadId, (int)type);
171             if (ret != (int)DownloadError.None)
172             {
173                 DownloadErrorFactory.ThrowException(ret, "Setting NetworkType failed");
174             }
175
176             _notificationProperties = new Notification(_downloadId);
177             _httpHeaders = httpHeaders;
178         }
179
180         /// <summary>
181         /// Destructor of the Request class.
182         /// </summary>
183         ~Request()
184         {
185             Dispose(false);
186         }
187
188         /// <summary>
189         /// An event that occurs when the download state changes.
190         /// </summary>
191         /// <since_tizen> 3 </since_tizen>
192         /// <privilege>http://tizen.org/privilege/download</privilege>
193         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
194         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
195         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
196         public event EventHandler<StateChangedEventArgs> StateChanged
197         {
198             add
199             {
200                 if (_downloadStateChanged == null)
201                 {
202                     RegisterStateChangedEvent();
203                 }
204                 _downloadStateChanged += value;
205             }
206             remove
207             {
208                 _downloadStateChanged -= value;
209                 if (_downloadStateChanged == null)
210                 {
211                     UnregisterStateChangedEvent();
212                 }
213             }
214         }
215
216         /// <summary>
217         /// An event that occurs when the download progress changes.
218         /// </summary>
219         /// <since_tizen> 3 </since_tizen>
220         /// <privilege>http://tizen.org/privilege/download</privilege>
221         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
222         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
223         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
224         public event EventHandler<ProgressChangedEventArgs> ProgressChanged
225         {
226             add
227             {
228                 if (_downloadProgressChanged == null)
229                 {
230                     RegisterProgressChangedEvent();
231                 }
232                 _downloadProgressChanged += value;
233             }
234             remove
235             {
236                 _downloadProgressChanged -= value;
237                 if (_downloadProgressChanged == null)
238                 {
239                     UnregisterProgressChangedEvent();
240                 }
241             }
242         }
243
244         /// <summary>
245         /// The absolute path where the file will be downloaded.
246         /// If you try to get this property value before calling Start(), an empty string is returned.
247         /// </summary>
248         /// <since_tizen> 3 </since_tizen>
249         /// <privilege>http://tizen.org/privilege/download</privilege>
250         /// <remarks>
251         /// Returns an empty string if the download is not completed or if a state has not yet changed to completed or if any other error occurs.
252         /// </remarks>
253         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
254         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
255         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
256         public string DownloadedPath
257         {
258             get
259             {
260                 string path;
261                 int ret = Interop.Download.GetDownloadedPath(_downloadId, out path);
262                 if (ret != (int)DownloadError.None)
263                 {
264                     Log.Error(Globals.LogTag, "Failed to get DownloadedPath, " + (DownloadError)ret);
265                     return String.Empty;
266                 }
267                 return path;
268             }
269         }
270
271         /// <summary>
272         /// The MIME type of the downloaded content.
273         /// If you try to get this property value before calling Start(), an empty string is returned.
274         /// </summary>
275         /// <since_tizen> 3 </since_tizen>
276         /// <privilege>http://tizen.org/privilege/download</privilege>
277         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
278         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
279         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
280         public string MimeType
281         {
282             get
283             {
284                 string mime;
285                 int ret = Interop.Download.GetMimeType(_downloadId, out mime);
286                 if (ret != (int)DownloadError.None)
287                 {
288                     Log.Error(Globals.LogTag, "Failed to get MimeType, " + (DownloadError)ret);
289                     return String.Empty;
290                 }
291                 return mime;
292             }
293         }
294
295         /// <summary>
296         /// The current state of the download.
297         /// </summary>
298         /// <since_tizen> 3 </since_tizen>
299         /// <privilege>http://tizen.org/privilege/download</privilege>
300         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
301         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
302         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
303         public DownloadState State
304         {
305             get
306             {
307                 int state;
308                 int ret = Interop.Download.GetState(_downloadId, out state);
309                 if (ret != (int)DownloadError.None)
310                 {
311                     Log.Error(Globals.LogTag, "Failed to get DownloadState, " + (DownloadError)ret);
312                     return DownloadState.None;
313                 }
314                 return (DownloadState)state;
315             }
316         }
317
318         /// <summary>
319         /// The content name of the downloaded file.
320         /// This can be defined with reference of the HTTP response header data. The content name can be received when the HTTP response header is received.
321         /// If you try to get this property value before calling Start(), an empty string is returned.
322         /// </summary>
323         /// <since_tizen> 3 </since_tizen>
324         /// <privilege>http://tizen.org/privilege/download</privilege>
325         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
326         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
327         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
328         public string ContentName
329         {
330             get
331             {
332                 string name;
333                 int ret = Interop.Download.GetContentName(_downloadId, out name);
334                 if (ret != (int)DownloadError.None)
335                 {
336                     Log.Error(Globals.LogTag, "Failed to get ContentName, " + (DownloadError)ret);
337                     return String.Empty;
338                 }
339                 return name;
340             }
341         }
342
343         /// <summary>
344         /// The total size of the downloaded content.
345         /// This information is received from the server. If the server does not send the total size of the content, the content size is set to zero.
346         /// If you try to get this property value before calling Start(), 0 is returned.
347         /// </summary>
348         /// <since_tizen> 3 </since_tizen>
349         /// <privilege>http://tizen.org/privilege/download</privilege>
350         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
351         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
352         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
353         public ulong ContentSize
354         {
355             get
356             {
357                 ulong size;
358                 int ret = Interop.Download.GetContentSize(_downloadId, out size);
359                 if (ret != (int)DownloadError.None)
360                 {
361                     Log.Error(Globals.LogTag, "Failed to get ContentSize, " + (DownloadError)ret);
362                     return 0;
363                 }
364                 return size;
365             }
366         }
367
368         /// <summary>
369         /// The HTTP status code when a download exception occurs.
370         /// If you try to get this property value before calling Start(), 0 is returned.
371         /// </summary>
372         /// <since_tizen> 3 </since_tizen>
373         /// <privilege>http://tizen.org/privilege/download</privilege>
374         /// <remarks>
375         /// The state of the download request must be DownlodState.Failed.
376         /// </remarks>
377         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
378         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
379         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
380         public int HttpStatus
381         {
382             get
383             {
384                 int status;
385                 int ret = Interop.Download.GetHttpStatus(_downloadId, out status);
386                 if (ret != (int)DownloadError.None)
387                 {
388                     Log.Error(Globals.LogTag, "Failed to get HttpStatus, " + (DownloadError)ret);
389                     return 0;
390                 }
391                 return status;
392             }
393         }
394
395         /// <summary>
396         /// The ETag value from the HTTP response header when making a HTTP request for resume.
397         /// If you try to get this property value before calling Start() or if any other error occurs, an empty string is returned.
398         /// </summary>
399         /// <since_tizen> 3 </since_tizen>
400         /// <privilege>http://tizen.org/privilege/download</privilege>
401         /// <remarks>
402         /// The ETag value is either available or not dependent on the web server. If not available, then, on getting the property, a null value is returned.
403         /// After the download is started, it can get the ETag value.
404         /// </remarks>
405         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
406         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation</exception>
407         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
408         public string ETagValue
409         {
410             get
411             {
412                 string etag;
413                 int ret = Interop.Download.GetETag(_downloadId, out etag);
414                 if (ret != (int)DownloadError.None)
415                 {
416                     Log.Error(Globals.LogTag, "Failed to get ETagValue, " + (DownloadError)ret);
417                     return String.Empty;
418                 }
419                 return etag;
420             }
421         }
422
423         /// <summary>
424         /// Contains properties required for creating download notifications.
425         /// </summary>
426         /// <since_tizen> 3 </since_tizen>
427         /// <remarks>
428         /// When the notification message is clicked, the action taken by the system is decided by the application control properties of the NotificationProperties instance.
429         /// If the app control is not set, the following default operation is executed when the notification message is clicked:
430         ///  1) The download completed state - the viewer application is executed according to the extension name of the downloaded content.
431         ///  2) The download failed state and ongoing state - the client application is executed.
432         /// This property should be set before calling Start().
433         /// </remarks>
434         public Notification NotificationProperties
435         {
436             get
437             {
438                 return _notificationProperties;
439             }
440         }
441
442         /// <summary>
443         /// The full path of the temporary file stores the downloaded content.
444         /// </summary>
445         /// <since_tizen> 3 </since_tizen>
446         /// <privilege>http://tizen.org/privilege/download</privilege>
447         /// <remarks>
448         /// The download state must be one of the states after downloading.
449         /// </remarks>
450         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
451         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
452         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
453         public string TemporaryPath
454         {
455             get
456             {
457                 string path;
458                 int ret = Interop.Download.GetTempFilePath(_downloadId, out path);
459                 if (ret != (int)DownloadError.None)
460                 {
461                     Log.Error(Globals.LogTag, "Failed to get TemporaryPath, " + (DownloadError)ret);
462                     return String.Empty;
463                 }
464                 return path;
465             }
466         }
467
468         /// <summary>
469         /// The URL to download.
470         /// </summary>
471         /// <since_tizen> 3 </since_tizen>
472         /// <privilege>http://tizen.org/privilege/download</privilege>
473         /// <remarks>
474         /// Should be set before calling Start().
475         /// If you try to get this property value before setting or if any other error occurs, an empty string is returned.
476         /// </remarks>
477         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
478         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
479         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
480         public string Url
481         {
482             get
483             {
484                 string url;
485                 int ret = Interop.Download.GetUrl(_downloadId, out url);
486                 if (ret != (int)DownloadError.None)
487                 {
488                     Log.Error(Globals.LogTag, "Failed to get Url, " + (DownloadError)ret);
489                     return String.Empty;
490                 }
491                 return url;
492             }
493             set
494             {
495                 int ret = Interop.Download.SetUrl(_downloadId, value);
496                 if (ret != (int)DownloadError.None)
497                 {
498                     DownloadErrorFactory.ThrowException(ret, "Failed to set Url");
499                 }
500             }
501         }
502
503         /// <summary>
504         /// The allowed network type for downloading the file.
505         /// The file will be downloaded only under the allowed network.
506         /// If you try to get this property value before setting or if any other error occurs, the default value NetworkType All is returned.
507         /// </summary>
508         /// <since_tizen> 3 </since_tizen>
509         /// <privilege>http://tizen.org/privilege/download</privilege>
510         /// <feature>http://tizen.org/feature/network.wifi</feature>
511         /// <feature>http://tizen.org/feature/network.wifi.direct</feature>
512         /// <feature>http://tizen.org/feature/network.telephony</feature>
513         /// <remarks>
514         /// Should be set before calling Start().
515         /// </remarks>
516         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
517         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
518         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
519         /// <exception cref="NotSupportedException">Thrown when feature is not supported.</exception>
520         public NetworkType AllowedNetworkType
521         {
522             get
523             {
524                 int type;
525                 int ret = Interop.Download.GetNetworkType(_downloadId, out type);
526                 if (ret != (int)DownloadError.None)
527                 {
528                     Log.Error(Globals.LogTag, "Failed to get AllowedNetworkType, " + (DownloadError)ret);
529                     return NetworkType.All;
530                 }
531                 return (NetworkType)type;
532             }
533             set
534             {
535                 int ret = Interop.Download.SetNetworkType(_downloadId, (int)value);
536                 if (ret != (int)DownloadError.None)
537                 {
538                     DownloadErrorFactory.ThrowException(ret, "Failed to set AllowedNetworkType");
539                 }
540             }
541         }
542
543         /// <summary>
544         /// The file will be downloaded to the set the destination file path. The downloaded file is saved to an auto-generated file name in the destination. If the destination is not specified, the file will be downloaded to the default storage.
545         /// If you try to get this property value before setting or if any other error occurs, an empty string is returned.
546         /// </summary>
547         /// <since_tizen> 3 </since_tizen>
548         /// <privilege>http://tizen.org/privilege/download</privilege>
549         /// <remarks>
550         /// Should be set before calling Start().
551         /// </remarks>
552         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
553         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
554         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
555         public string DestinationPath
556         {
557             get
558             {
559                 string path;
560                 int ret = Interop.Download.GetDestination(_downloadId, out path);
561                 if (ret != (int)DownloadError.None)
562                 {
563                     Log.Error(Globals.LogTag, "Failed to get DestinationPath, " + (DownloadError)ret);
564                     return String.Empty;
565                 }
566                 return path;
567             }
568             set
569             {
570                 int ret = Interop.Download.SetDestination(_downloadId, value.ToString());
571                 if (ret != (int)DownloadError.None)
572                 {
573                     DownloadErrorFactory.ThrowException(ret, "Failed to set DestinationPath");
574                 }
575             }
576         }
577
578         /// <summary>
579         /// The file will be saved in the specified destination or the default storage with the set file name. If the file name is not specified, the downloaded file will be saved with an auto-generated file name in the destination.
580         /// If you try to get this property value before setting or if any other error occurs, an empty string is returned.
581         /// </summary>
582         /// <since_tizen> 3 </since_tizen>
583         /// <privilege>http://tizen.org/privilege/download</privilege>
584         /// <remarks>
585         /// Should be set before calling Start().
586         /// </remarks>
587         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
588         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
589         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
590         public string FileName
591         {
592             get
593             {
594                 string name;
595                 int ret = Interop.Download.GetFileName(_downloadId, out name);
596                 if (ret != (int)DownloadError.None)
597                 {
598                     Log.Error(Globals.LogTag, "Failed to get FileName, " + (DownloadError)ret);
599                     return String.Empty;
600                 }
601                 return name;
602             }
603             set
604             {
605                 int ret = Interop.Download.SetFileName(_downloadId, value.ToString());
606                 if (ret != (int)DownloadError.None)
607                 {
608                     DownloadErrorFactory.ThrowException(ret, "Failed to set FileName");
609                 }
610             }
611         }
612
613         /// <summary>
614         /// Enables or disables auto download.
615         /// If this option is enabled, the previous downloading item is restarted automatically as soon as the download daemon is restarted. The download progress continues after the client process is terminated.
616         /// If you try to get this property value before setting, the default value false is returned.
617         /// </summary>
618         /// <since_tizen> 3 </since_tizen>
619         /// <privilege>http://tizen.org/privilege/download</privilege>
620         /// <remarks>
621         /// The default value is false.
622         /// </remarks>
623         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
624         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
625         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
626         public bool AutoDownload
627         {
628             get
629             {
630                 bool value;
631                 int ret = Interop.Download.GetAutoDownload(_downloadId, out value);
632                 if (ret != (int)DownloadError.None)
633                 {
634                     Log.Error(Globals.LogTag, "Failed to get AutoDownload, " + (DownloadError)ret);
635                     return false;
636                 }
637                 return value;
638             }
639             set
640             {
641                 int ret = Interop.Download.SetAutoDownload(_downloadId, value);
642                 if (ret != (int)DownloadError.None)
643                 {
644                     DownloadErrorFactory.ThrowException(ret, "Failed to set AutoDownload");
645                 }
646             }
647         }
648
649         /// <summary>
650         /// The HTTP header field and value pairs to the download request.
651         /// The HTTP header &lt;field,value&gt; pair is the &lt;key,value&gt; pair in the dictionary HttpHeaders.
652         /// The given HTTP header field will be included with the HTTP request of the download request.
653         /// If you try to get this property value before setting, an empty dictionary is returned.
654         /// </summary>
655         /// <since_tizen> 3 </since_tizen>
656         /// <remarks>
657         /// HTTP header fields should be set before calling Start().
658         /// HTTP header fields can be removed before calling Start().
659         /// </remarks>
660         public IDictionary<string, string> HttpHeaders
661         {
662             get
663             {
664                 return _httpHeaders;
665             }
666         }
667
668         /// <summary>
669         /// Sets the directory path of a temporary file used in a previous download request.
670         /// This is only useful when resuming download to make the HTTP request header at the client side. Otherwise, the path is ignored.
671         /// </summary>
672         /// <since_tizen> 3 </since_tizen>
673         /// <privilege>http://tizen.org/privilege/download</privilege>
674         /// <remarks>
675         /// If the ETag value is not present in the download database, it is not useful to set the temporary file path.
676         /// When resuming the download request, the data is attached at the end of this temporary file.
677         /// </remarks>
678         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
679         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
680         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
681         public void SetTemporaryFilePath(string path)
682         {
683                 int ret = Interop.Download.SetTempFilePath(_downloadId, path);
684                 if (ret != (int)DownloadError.None)
685                 {
686                     DownloadErrorFactory.ThrowException(ret, "Failed to set TemporaryFilePath");
687                 }
688         }
689
690         /// <summary>
691         /// Starts or resumes the download.
692         /// Starts to download the current URL, or resumes the download if paused.
693         /// </summary>
694         /// <since_tizen> 3 </since_tizen>
695         /// <privilege>http://tizen.org/privilege/download</privilege>
696         /// <remarks>
697         /// The URL is the mandatory information to start the download.
698         /// </remarks>
699         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
700         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
701         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
702         public void Start()
703         {
704             int ret = (int)DownloadError.None;
705             foreach (KeyValuePair<string, string> entry in _httpHeaders)
706             {
707                 ret = Interop.Download.AddHttpHeaderField(_downloadId, entry.Key, entry.Value);
708                 if (ret != (int)DownloadError.None)
709                 {
710                     DownloadErrorFactory.ThrowException(ret, "Failed to set HttpHeaders");
711                 }
712             }
713
714             ret = Interop.Download.StartDownload(_downloadId);
715             if (ret != (int)DownloadError.None)
716             {
717                 DownloadErrorFactory.ThrowException(ret, "Failed to start download request");
718             }
719         }
720
721         /// <summary>
722         /// Pauses the download request.
723         /// </summary>
724         /// <since_tizen> 3 </since_tizen>
725         /// <privilege>http://tizen.org/privilege/download</privilege>
726         /// <remarks>
727         /// The paused download request can be restarted with Start() or canceled with Cancel().
728         /// </remarks>
729         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
730         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
731         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
732         public void Pause()
733         {
734             int ret = Interop.Download.PauseDownload(_downloadId);
735             if (ret != (int)DownloadError.None)
736             {
737                 DownloadErrorFactory.ThrowException(ret, "Failed to pause download request");
738             }
739         }
740
741         /// <summary>
742         /// Cancels the download request.
743         /// </summary>
744         /// <since_tizen> 3 </since_tizen>
745         /// <privilege>http://tizen.org/privilege/download</privilege>
746         /// <remarks>
747         /// The canceled download can be restarted with Start().
748         /// </remarks>
749         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
750         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
751         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
752         public void Cancel()
753         {
754             int ret = Interop.Download.CancelDownload(_downloadId);
755             if (ret != (int)DownloadError.None)
756             {
757                 DownloadErrorFactory.ThrowException(ret, "Failed to cancel download request");
758             }
759         }
760
761         /// <summary>
762         /// Releases all the resources used by the Request class.
763         /// </summary>
764         /// <since_tizen> 3 </since_tizen>
765         /// <privilege>http://tizen.org/privilege/download</privilege>
766         /// <remarks>
767         /// After calling this method, the download request related data exists in the download database for a certain period of time. Within that time, it is possible to use other APIs with this data.
768         /// </remarks>
769         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
770         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
771         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
772         public void Dispose()
773         {
774             Dispose(true);
775             GC.SuppressFinalize(this);
776         }
777
778         /// <summary>
779         /// Deletes the corresponding download request.
780         /// </summary>
781         /// <since_tizen> 3 </since_tizen>
782         /// <privilege>http://tizen.org/privilege/download</privilege>
783         /// <exception cref="ArgumentException">Thrown when it is failed due to an invalid parameter.</exception>
784         /// <exception cref="InvalidOperationException">Thrown when it is failed due to an invalid operation.</exception>
785         /// <exception cref="UnauthorizedAccessException">Thrown when a permission is denied.</exception>
786         protected virtual void Dispose(bool disposing)
787         {
788             if (_disposed)
789                 return;
790
791             if (disposing)
792             {
793                 // Free managed objects.
794             }
795             Interop.Download.DestroyRequest(_downloadId);
796             _disposed = true;
797         }
798
799         static private void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
800         {
801             managedArray = new string[size];
802             IntPtr[] IntPtrArray = new IntPtr[size];
803
804             Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
805
806             for (int iterator = 0; iterator < size; iterator++)
807             {
808                 managedArray[iterator] = Marshal.PtrToStringAnsi(IntPtrArray[iterator]);
809             }
810         }
811
812         private void RegisterStateChangedEvent()
813         {
814             _downloadStateChangedCallback = (int downloadId, int downloadState, IntPtr userData) =>
815             {
816                 StateChangedEventArgs eventArgs = new StateChangedEventArgs((DownloadState)downloadState);
817                 _downloadStateChanged?.Invoke(this, eventArgs);
818             };
819
820             int ret = Interop.Download.SetStateChangedCallback(_downloadId, _downloadStateChangedCallback, IntPtr.Zero);
821             if (ret != (int)DownloadError.None)
822             {
823                 DownloadErrorFactory.ThrowException(ret, "Setting StateChanged callback failed");
824             }
825         }
826
827         private void UnregisterStateChangedEvent()
828         {
829             int ret = Interop.Download.UnsetStateChangedCallback(_downloadId);
830             if (ret != (int)DownloadError.None)
831             {
832                 DownloadErrorFactory.ThrowException(ret, "Unsetting StateChanged callback failed");
833             }
834         }
835
836         private void RegisterProgressChangedEvent()
837         {
838             _downloadProgressChangedCallback = (int downloadId, ulong size, IntPtr userData) =>
839             {
840                 ProgressChangedEventArgs eventArgs = new ProgressChangedEventArgs(size);
841                 _downloadProgressChanged?.Invoke(this, eventArgs);
842             };
843
844             int ret = Interop.Download.SetProgressCallback(_downloadId, _downloadProgressChangedCallback, IntPtr.Zero);
845             if (ret != (int)DownloadError.None)
846             {
847                 DownloadErrorFactory.ThrowException(ret, "Setting ProgressChanged callback failed");
848             }
849         }
850
851         private void UnregisterProgressChangedEvent()
852         {
853             int ret = Interop.Download.UnsetProgressCallback(_downloadId);
854             if (ret != (int)DownloadError.None)
855             {
856                 DownloadErrorFactory.ThrowException(ret, "Unsetting ProgressChanged callback failed");
857             }
858         }
859     }
860 }
861