Add:android:Test for free space in MapDownloader and present usefull error messages...
[profile/ivi/navit.git] / navit / navit / android / src / org / navitproject / navit / NavitMapDownloader.java
1 /**\r
2  * Navit, a modular navigation system.\r
3  * Copyright (C) 2005-2008 Navit Team\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * version 2 as published by the Free Software Foundation.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License\r
15  * along with this program; if not, write to the\r
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
17  * Boston, MA  02110-1301, USA.\r
18  */\r
19 \r
20 package org.navitproject.navit;\r
21 \r
22 import java.io.BufferedInputStream;\r
23 import java.io.BufferedOutputStream;\r
24 import java.io.File;\r
25 import java.io.FileInputStream;\r
26 import java.io.FileOutputStream;\r
27 import java.io.IOException;\r
28 import java.io.ObjectInputStream;\r
29 import java.io.ObjectOutputStream;\r
30 import java.net.HttpURLConnection;\r
31 import java.net.URL;\r
32 \r
33 import android.os.Handler;\r
34 import android.os.StatFs;\r
35 import android.util.Log;\r
36 \r
37 public class NavitMapDownloader extends Thread\r
38 {\r
39         private static class osm_map_values\r
40         {\r
41                 String  lon1;\r
42                 String  lat1;\r
43                 String  lon2;\r
44                 String  lat2;\r
45                 String  map_name                     = "";\r
46                 long    est_size_bytes               = 0;\r
47                 int     level                        = 0;\r
48 \r
49 \r
50                 public osm_map_values(String mapname, String lon_1, String lat_1, String lon_2, String lat_2,\r
51                                 long bytes_est, int level)\r
52                 {\r
53                         this.map_name = mapname;\r
54                         this.lon1 = lon_1;\r
55                         this.lat1 = lat_1;\r
56                         this.lon2 = lon_2;\r
57                         this.lat2 = lat_2;\r
58                         this.est_size_bytes = bytes_est;\r
59                         this.level = level;\r
60                 }\r
61         }\r
62         //\r
63         // define the maps here\r
64         //\r
65         private static final osm_map_values[] osm_maps = {\r
66                 new osm_map_values("Whole Planet", "-180", "-90", "180", "90", 5985878379L, 0),\r
67                 new osm_map_values("Africa", "-20.8", "-35.2", "52.5", "37.4", 180836389L, 0),\r
68                 new osm_map_values("Angola", "11.4", "-18.1", "24.2", "-5.3", 56041641L, 1),\r
69                 new osm_map_values("Burundi", "28.9", "-4.5", "30.9", "-2.2", 56512924L, 1),\r
70                 new osm_map_values("Democratic Republic of the Congo", "11.7", "-13.6", "31.5", "5.7",65026791L, 1),\r
71                 new osm_map_values("Kenya", "33.8","-5.2", "42.4", "4.9", 58545273L, 1),\r
72                 new osm_map_values("Lesotho", "26.9", "-30.7", "29.6","-28.4", 54791041L, 1),\r
73                 new osm_map_values("Madagascar", "43.0","-25.8", "50.8","-11.8", 56801099L, 1),\r
74                 new osm_map_values("Nambia+Botswana","11.4", "-29.1","29.5", "-16.9", 61807049L, 1),\r
75                 new osm_map_values("Reunion", "55.2","-21.4", "55.9","-20.9", 58537419L, 1),\r
76                 new osm_map_values("Rwanda", "28.8","-2.9", "30.9","-1.0", 56313710L, 1),\r
77                 new osm_map_values("South Africa","15.6", "-35.2","33.3", "-21.9", 73545245L, 1),\r
78                 new osm_map_values("Uganda", "29.3","-1.6", "35.1","4.3", 57376589L, 1),\r
79                 new osm_map_values("Asia", "23.8","0.1", "195.0","82.4", 797725952L, 0),\r
80                 new osm_map_values("China", "67.3","5.3", "135.0","54.5", 259945160L, 1),\r
81                 new osm_map_values("Cyprus", "32.0","34.5", "34.9","35.8", 58585278L, 1),\r
82                 new osm_map_values("India+Nepal","67.9", "5.5","89.6", "36.0", 82819344L, 1),\r
83                 new osm_map_values("Indonesia", "93.7","-17.3", "155.5","7.6", 74648081L, 1),\r
84                 new osm_map_values("Iran", "43.5","24.4", "63.6","40.4", 69561312L, 1),\r
85                 new osm_map_values("Iraq", "38.7","28.5", "49.2","37.4", 59146383L, 1),\r
86                 new osm_map_values("Israel", "33.99","29.8", "35.95","33.4", 65065351L, 1),\r
87                 new osm_map_values("Japan+Korea+Taiwan","117.6", "20.5","151.3", "47.1", 305538751L, 1),\r
88                 new osm_map_values("Malasia+Singapore","94.3", "-5.9","108.6", "6.8", 58849792L, 1),\r
89                 new osm_map_values("Mongolia", "87.5","41.4", "120.3","52.7", 60871187L, 1),\r
90                 new osm_map_values("Thailand", "97.5","5.7", "105.2","19.7", 62422864L, 1),\r
91                 new osm_map_values("Turkey", "25.1","35.8", "46.4","42.8", 81758047L, 1),\r
92                 new osm_map_values("UAE+Other", "51.5","22.6", "56.7","26.5", 57419510L, 1),\r
93                 new osm_map_values("Australia", "110.5","-44.2", "154.9","-9.2", 128502185L, 0),\r
94                 new osm_map_values("Australia", "110.5","-44.2", "154.9","-9.2", 128502185L, 1),\r
95                 new osm_map_values("Tasmania", "144.0","-45.1", "155.3","-24.8", 103573989L, 1),\r
96                 new osm_map_values("Victoria+New South Wales","140.7", "-39.4","153.7", "-26.9", 99307594L, 1),\r
97                 new osm_map_values("New Zealand","165.2", "-47.6","179.1", "-33.7", 64757454L, 1),\r
98                 new osm_map_values("Europe", "-12.97","33.59", "34.15","72.10", 2753910015L, 0),\r
99                 new osm_map_values("Western Europe","-17.6", "34.5","42.9", "70.9", 2832986851L, 1),\r
100                 new osm_map_values("Austria", "9.4","46.32", "17.21","49.1", 222359992L, 1),\r
101                 new osm_map_values("BeNeLux", "2.08","48.87", "7.78","54.52", 533865194L, 1),\r
102                 new osm_map_values("Faroe Islands","-7.8", "61.3","-6.1", "62.5", 54526101L, 1),\r
103                 new osm_map_values("France", "-5.45","42.00", "8.44","51.68", 1112047845L, 1),\r
104                 new osm_map_values("Germany", "5.18","46.84", "15.47","55.64", 944716238L, 1),\r
105                 new osm_map_values("Bavaria", "10.3","47.8", "13.6","49.7", 131799419L, 2),\r
106                 new osm_map_values("Saxonia", "11.8","50.1", "15.0","51.7", 112073909L, 2),\r
107                 new osm_map_values("Germany+Austria+Switzerland","3.4", "44.5","18.6", "55.1", 1385785353L, 1),\r
108                 new osm_map_values("Iceland", "-25.3","62.8", "-11.4","67.5", 57281405L, 1),\r
109                 new osm_map_values("Ireland", "-11.17","51.25", "-5.23","55.9", 70186936L, 1),\r
110                 new osm_map_values("Italy", "6.52","36.38", "18.96","47.19", 291401314L, 1),\r
111                 new osm_map_values("Spain+Portugal","-11.04", "34.87","4.62", "44.41", 292407746L, 1),\r
112                 new osm_map_values("Mallorca", "2.2","38.8", "4.7","40.2", 88100718L, 2),\r
113                 new osm_map_values("Galicia", "-10.0","41.7", "-6.3","44.1", 64605237L, 2),\r
114                 new osm_map_values("Scandinavia", "4.0","54.4", "32.1","71.5", 299021928L, 1),\r
115                 new osm_map_values("Finland", "18.6","59.2", "32.3","70.3", 128871467L, 1),\r
116                 new osm_map_values("Denmark", "7.49","54.33", "13.05","57.88", 120025875L, 1),\r
117                 new osm_map_values("Switzerland","5.79", "45.74","10.59", "47.84", 162616817L, 1),\r
118                 new osm_map_values("UK", "-9.7", "49.6","2.2", "61.2", 245161510L, 1),\r
119                 new osm_map_values("Bulgaria", "24.7","42.1", "24.8","42.1", 56607427L, 1),\r
120                 new osm_map_values("Czech Republic","11.91", "48.48","19.02", "51.17", 234138824L, 1),\r
121                 new osm_map_values("Croatia", "13.4","42.1", "19.4","46.9", 99183280L, 1),\r
122                 new osm_map_values("Estonia", "21.5","57.5", "28.2","59.6", 79276178L, 1),\r
123                 new osm_map_values("Greece", "28.9","37.8", "29.0","37.8", 55486527L, 1),\r
124                 new osm_map_values("Crete", "23.3","34.5", "26.8","36.0", 57032630L, 1),\r
125                 new osm_map_values("Hungary", "16.08","45.57", "23.03","48.39", 109831319L, 1),\r
126                 new osm_map_values("Latvia", "20.7","55.6", "28.3","58.1", 71490706L, 1),\r
127                 new osm_map_values("Lithuania", "20.9","53.8", "26.9","56.5", 67992457L, 1),\r
128                 new osm_map_values("Poland", "13.6","48.8", "24.5","55.0", 266136768L, 1),\r
129                 new osm_map_values("Romania", "20.3","43.5", "29.9","48.4", 134525863L, 1),\r
130                 new osm_map_values("North America","-178.1", "6.5","-10.4", "84.0", 2477309662L, 0),\r
131                 new osm_map_values("Alaska", "-179.5","49.5", "-129","71.6", 72320027L, 1),\r
132                 new osm_map_values("Canada", "-141.3","41.5", "-52.2","70.2", 937813467L, 1),\r
133                 new osm_map_values("Hawaii", "-161.07","18.49", "-154.45","22.85", 57311788L, 1),\r
134                 new osm_map_values("USA (except Alaska and Hawaii)","-125.4", "24.3","-66.5", "49.3", 2216912004L, 1),\r
135                 new osm_map_values("Nevada", "-120.2","35.0", "-113.8","42.1", 136754975L, 2),\r
136                 new osm_map_values("Oregon", "-124.8","41.8", "-116.3","46.3", 101627308L, 2),\r
137                 new osm_map_values("Washington State","-125.0", "45.5","-116.9", "49.0", 98178877L, 2),\r
138                 new osm_map_values("South+Middle America","-83.5", "-56.3","-30.8", "13.7", 159615197L, 0),\r
139                 new osm_map_values("Argentina", "-73.9","-57.3", "-51.6","-21.0", 87516152L, 1),\r
140                 new osm_map_values("Argentina+Chile","-77.2", "-56.3","-52.7", "-16.1", 91976696L, 1),\r
141                 new osm_map_values("Bolivia", "-70.5","-23.1", "-57.3","-9.3", 58242168L, 1),\r
142                 new osm_map_values("Brazil", "-71.4","-34.7", "-32.8","5.4", 105527899L, 1),\r
143                 new osm_map_values("Cuba", "-85.3","19.6", "-74.0","23.6", 56608942L, 1),\r
144                 new osm_map_values("Colombia", "-79.1","-4.0", "-66.7","12.6", 78658454L, 1),\r
145                 new osm_map_values("Ecuador", "-82.6","-5.4", "-74.4","2.3", 61501914L, 1),\r
146                 new osm_map_values("Guyana+Suriname+Guyane Francaise","-62.0", "1.0","-51.2", "8.9", 57040689L, 1),\r
147                 new osm_map_values("Haiti+Republica Dominicana","-74.8", "17.3","-68.2", "20.1", 63528584L, 1),\r
148                 new osm_map_values("Jamaica", "-78.6","17.4", "-75.9","18.9", 53958307L, 1),\r
149                 new osm_map_values("Mexico", "-117.6","14.1", "-86.4","32.8", 251108617L, 1),\r
150                 new osm_map_values("Paraguay", "-63.8","-28.1", "-53.6","-18.8", 57188715L, 1),\r
151                 new osm_map_values("Peru", "-82.4","-18.1", "-67.5","0.4", 65421441L, 1),\r
152                 new osm_map_values("Uruguay", "-59.2","-36.5", "-51.7","-29.7", 63542225L, 1),\r
153                 new osm_map_values("Venezuela", "-73.6","0.4", "-59.7","12.8", 64838882L, 1)\r
154         };\r
155 \r
156         private static String[]             OSM_MAP_NAME_LIST_inkl_SIZE_ESTIMATE    = null;\r
157 \r
158         public static int[]                 OSM_MAP_NAME_ORIG_ID_LIST               = null;\r
159 \r
160         private Boolean                     stop_me                                 = false;\r
161         private static final int            SOCKET_CONNECT_TIMEOUT                  = 25000;                    // 25 secs.\r
162         private static final int            SOCKET_READ_TIMEOUT                     = 15000;                    // 15 secs.\r
163         private static final int            MAP_WRITE_FILE_BUFFER                   = 1024 * 64;\r
164         private static final int            MAP_WRITE_MEM_BUFFER                    = 1024 * 64;\r
165         private static final int            MAP_READ_FILE_BUFFER                    = 1024 * 64;\r
166         private static final int            UPDATE_PROGRESS_EVERY_CYCLE             = 8;\r
167         private static final int            MAX_RETRIES                             = 5;\r
168         private static final String         MAP_FILENAME_PRI                        = "navitmap.bin";\r
169         private static final String         MAP_FILENAME_NUM                        = "navitmap_%03d.bin";\r
170         private static final String         MAP_FILENAME_PATH                       = Navit.MAP_FILENAME_PATH;\r
171         private static final String             TAG                                                                     = "NavitMapDownloader";\r
172 \r
173         private Handler                     mHandler;\r
174         private osm_map_values              map_values;\r
175         private int                         map_slot;\r
176         private int                         dialog_num;\r
177         \r
178         public static final int             EXIT_SUCCESS                            = 0;\r
179         public static final int             EXIT_RECOVERABLE_ERROR                  = 1;\r
180         public static final int             EXIT_UNRECOVERABLE_ERROR                = 2;\r
181         \r
182         public static int                   retry_counter                           = 0;\r
183 \r
184         public void run()\r
185         {\r
186                 stop_me = false;\r
187                 int exit_code;\r
188                 retry_counter = 0;\r
189 \r
190                 Log.v(TAG, "map_num3=" + this.map_slot);\r
191 \r
192                 NavitMessages.sendDialogMessage( mHandler, NavitMessages.DIALOG_PROGRESS_BAR\r
193                                 , Navit.get_text("Mapdownload"), Navit.get_text("downloading") + ": " + map_values.map_name\r
194                                 , Navit.MAPDOWNLOAD_DIALOG, 20 , 0);\r
195 \r
196                 do\r
197                 {\r
198                         try\r
199                         {\r
200                                 Thread.sleep(10 + retry_counter * 1000);\r
201                         } catch (InterruptedException e1)       {}\r
202                 } while ( ( exit_code = download_osm_map(mHandler, map_values, map_slot)) == EXIT_RECOVERABLE_ERROR\r
203                                 && retry_counter++ < MAX_RETRIES\r
204                                 && !stop_me);\r
205 \r
206                 if (exit_code == EXIT_SUCCESS)\r
207                 {\r
208                         NavitMessages.sendDialogMessage( mHandler, NavitMessages.DIALOG_TOAST\r
209                                         , null, map_values.map_name + " " + Navit.get_text("ready")\r
210                                         , dialog_num , 0 , 0);\r
211 \r
212                         Log.d(TAG, "success");\r
213                 }\r
214                 \r
215                 if (exit_code == EXIT_SUCCESS || stop_me )\r
216                 {\r
217                         NavitMessages.sendDialogMessage( mHandler , NavitMessages.DIALOG_REMOVE_PROGRESS_BAR, null, null, dialog_num \r
218                                                 , exit_code , 0 );\r
219                 }\r
220         }\r
221 \r
222         public void stop_thread()\r
223         {\r
224                 stop_me = true;\r
225                 Log.d(TAG, "stop_me -> true");\r
226         }\r
227 \r
228         public NavitMapDownloader(Navit main, Handler h, int map_id, int dialog_num, int map_slot)\r
229         {\r
230                 this.mHandler = h;\r
231                 this.map_values = osm_maps[map_id];\r
232                 this.map_slot = map_slot;\r
233         }\r
234 \r
235         public static String[] getMenu()\r
236         {\r
237                 // need only init once\r
238                 if (OSM_MAP_NAME_LIST_inkl_SIZE_ESTIMATE != null) \r
239                 { \r
240                         return OSM_MAP_NAME_LIST_inkl_SIZE_ESTIMATE;\r
241                 }\r
242                 \r
243                 String menu_temp[] = new String[osm_maps.length*2];\r
244                 OSM_MAP_NAME_ORIG_ID_LIST = new int[osm_maps.length*2];\r
245                 int counter = 0;\r
246                 int previous_level = -1;\r
247                 for (int i = 0; i < osm_maps.length; i++)\r
248                 {\r
249                         switch (osm_maps[i].level)\r
250                         {\r
251                         case 0: \r
252                                 if (previous_level > 0)\r
253                                 {\r
254                                         OSM_MAP_NAME_ORIG_ID_LIST[counter] = -1;\r
255                                         menu_temp[counter++] = "======";\r
256                                 }\r
257                                 menu_temp[counter] = "";\r
258                                 break;\r
259                         case 1:\r
260                                 menu_temp[counter] = new String(" * ");\r
261                                 break;\r
262                         default:\r
263                                 menu_temp[counter] = new String(" ** ");\r
264                         }\r
265                         \r
266                         menu_temp[counter] = menu_temp[counter].concat(osm_maps[i].map_name + " " + (osm_maps[i].est_size_bytes / 1024 / 1024) + "MB");\r
267                         counter++;\r
268                         OSM_MAP_NAME_ORIG_ID_LIST[counter-1] = i;\r
269                         \r
270                         previous_level = osm_maps[i].level;\r
271                 }\r
272                 \r
273                 OSM_MAP_NAME_LIST_inkl_SIZE_ESTIMATE = new String[counter];\r
274                 for (int i = 0; i < counter; i++)\r
275                 {\r
276                         OSM_MAP_NAME_LIST_inkl_SIZE_ESTIMATE[i] = menu_temp[i];\r
277                 }\r
278                 return OSM_MAP_NAME_LIST_inkl_SIZE_ESTIMATE;\r
279         }\r
280 \r
281         public int download_osm_map(Handler handler, osm_map_values map_values, int map_number)\r
282         {\r
283                 int exit_code = EXIT_SUCCESS;\r
284                 boolean resume = false;\r
285                 HttpURLConnection c = null;\r
286                 BufferedOutputStream buf = null;\r
287                 BufferedInputStream bif = null;\r
288                 File outputFile = null;\r
289                 long already_read = 0;\r
290                 long real_size_bytes = 0;\r
291 \r
292                 String fileName = map_values.map_name + ".tmp";\r
293 \r
294                 try\r
295                 {\r
296                         long file_size_expected = -1;\r
297                         long file_time_expected = -1;\r
298                         outputFile = new File(MAP_FILENAME_PATH, fileName);\r
299 \r
300                         long old_download_size = outputFile.length();\r
301                         long start_timestamp = System.nanoTime();\r
302 \r
303                         outputFile.mkdir();\r
304                         if (old_download_size > 0)\r
305                         {\r
306                                 ObjectInputStream infoStream = new ObjectInputStream(new FileInputStream(MAP_FILENAME_PATH + fileName + ".info"));\r
307                                 file_size_expected = infoStream.readLong();\r
308                                 file_time_expected = infoStream.readLong();\r
309                                 infoStream.close();\r
310                         }\r
311                         URL url = new URL("http://maps.navit-project.org/api/map/?bbox=" + map_values.lon1 + ","\r
312                                         + map_values.lat1 + "," + map_values.lon2 + "," + map_values.lat2);\r
313 \r
314 //                      URL url = new URL("http://192.168.2.101:8080/zweibruecken.bin");\r
315                         c = (HttpURLConnection) url.openConnection();\r
316                         c.setRequestMethod("GET");\r
317                         c.setDoOutput(true);\r
318                         c.setReadTimeout(SOCKET_READ_TIMEOUT);\r
319                         c.setConnectTimeout(SOCKET_CONNECT_TIMEOUT);\r
320 \r
321                         if ( file_size_expected > 0 || file_time_expected > 0 )\r
322                         {\r
323                                 // looks like the same file, try to resume\r
324                                 Log.v(TAG, "Try to resume download");\r
325                                 resume = true;\r
326                                 c.setRequestProperty("Range", "bytes=" + old_download_size + "-");\r
327                                 already_read = old_download_size;\r
328                         }\r
329 \r
330                         real_size_bytes = c.getContentLength();\r
331                         long fileTime = c.getLastModified();\r
332                         Log.d(TAG, "size: " + real_size_bytes \r
333                                         + ", expected: " + file_size_expected\r
334                                         + ", read: " + already_read\r
335                                         + ", timestamp: " + fileTime\r
336                                         + ", timestamp_old: " + file_time_expected);\r
337                         \r
338                         if (resume && (fileTime != file_time_expected\r
339                                         // some server return the remaining size to dl, other the file size\r
340                                         || ((real_size_bytes + already_read != file_size_expected) && real_size_bytes != file_size_expected)\r
341                                     || (real_size_bytes == -1 && fileTime == -1)))\r
342                         {\r
343                                 Log.w(TAG, "Downloaded content to old. Resume not possible");\r
344                                 outputFile.delete();\r
345                                 return EXIT_RECOVERABLE_ERROR;\r
346                         }\r
347 \r
348                         if (!resume)\r
349                         {\r
350                                 outputFile.delete();\r
351                                 old_download_size = 0;\r
352                                 File infoFile = new File(MAP_FILENAME_PATH, fileName + ".info");\r
353                                 ObjectOutputStream infoStream = new ObjectOutputStream(new FileOutputStream(infoFile));\r
354                                 infoStream.writeLong(real_size_bytes);\r
355                                 infoStream.writeLong(fileTime);\r
356                                 infoStream.close();\r
357                         }\r
358                         else\r
359                         {\r
360                                 real_size_bytes = file_size_expected;\r
361                         }\r
362                         \r
363                         if ( real_size_bytes <= 0)\r
364                                 real_size_bytes = map_values.est_size_bytes;\r
365                         \r
366                         if (!checkFreeSpace(real_size_bytes - already_read))\r
367                         {\r
368                                 return EXIT_UNRECOVERABLE_ERROR;\r
369                         }\r
370                         \r
371                         Log.d(TAG, "real size in bytes: " + real_size_bytes);\r
372 \r
373                         buf = new BufferedOutputStream(new FileOutputStream(outputFile, resume) , MAP_WRITE_FILE_BUFFER);\r
374                         bif = new BufferedInputStream(c.getInputStream(), MAP_READ_FILE_BUFFER);\r
375 \r
376                         byte[] buffer = new byte[MAP_WRITE_MEM_BUFFER];\r
377                         int len1 = 0;\r
378                         int alt_cur = 0;\r
379                         String eta_string = "";\r
380                         String info;\r
381                         float per_second_overall;\r
382                         long bytes_remaining = 0;\r
383                         int eta_seconds = 0;\r
384                         while (!stop_me && (len1 = bif.read(buffer)) != -1)\r
385                         {\r
386                                 already_read += len1;\r
387                                 if (alt_cur++ % UPDATE_PROGRESS_EVERY_CYCLE == 0)\r
388                                 {\r
389 \r
390                                         if (already_read > real_size_bytes)\r
391                                         {\r
392                                                 real_size_bytes = already_read;\r
393                                         }\r
394                                         \r
395                                         bytes_remaining = real_size_bytes - already_read;\r
396                                         per_second_overall = (already_read - old_download_size) / ((System.nanoTime() - start_timestamp) / 1000000000f);\r
397                                         eta_seconds = (int) (bytes_remaining / per_second_overall);\r
398                                         if (eta_seconds > 60)\r
399                                         {\r
400                                                 eta_string = (int) (eta_seconds / 60f) + " m";\r
401                                         }\r
402                                         else\r
403                                         {\r
404                                                 eta_string = eta_seconds + " s";\r
405                                         }\r
406                                         info = String.format("%s: %s\n %dMb / %dMb\n %.1f kb/s %s: %s"\r
407                                                         , Navit.get_text("downloading")\r
408                                                         , map_values.map_name\r
409                                                         , already_read / 1024 / 1024\r
410                                                         , real_size_bytes / 1024 / 1024\r
411                                                         , per_second_overall / 1024f\r
412                                                         , Navit.get_text("ETA")\r
413                                                         , eta_string);\r
414                                         \r
415                                         if (retry_counter > 0)\r
416                                         {\r
417                                                 info += "\n Retry " + retry_counter + "/" + MAX_RETRIES;\r
418                                         }\r
419                                         Log.e(TAG, "info: " + info);\r
420 \r
421                                         NavitMessages.sendDialogMessage( handler, NavitMessages.DIALOG_PROGRESS_BAR\r
422                                                         , Navit.get_text("Mapdownload"), info\r
423                                                         , dialog_num, (int) (real_size_bytes / 1024), (int) (already_read / 1024));\r
424                                 }\r
425                                 buf.write(buffer, 0, len1);\r
426                         }\r
427 \r
428                         Log.d(TAG, "Connectionerror: " + c.getResponseCode ());\r
429 \r
430                         if (stop_me)\r
431                         {\r
432                                 NavitMessages.sendDialogMessage( handler, NavitMessages.DIALOG_TOAST\r
433                                                                 , null, Navit.get_text("Map download aborted!")\r
434                                                                 , dialog_num , 0 , 0);\r
435                                                 \r
436                                 exit_code = EXIT_UNRECOVERABLE_ERROR;\r
437                         }\r
438                         else if ( already_read < real_size_bytes )\r
439                         {\r
440                                 Log.d(TAG, "Server send only " + already_read + " bytes of " + real_size_bytes);\r
441                                 exit_code = EXIT_RECOVERABLE_ERROR;\r
442                         }\r
443                         else\r
444                         {\r
445                                 exit_code = EXIT_SUCCESS;\r
446                         }\r
447                 }\r
448                 catch (IOException e)\r
449                 {\r
450                         Log.d(TAG, "Error: " + e);\r
451                         \r
452                         if ( !checkFreeSpace(real_size_bytes - already_read))\r
453                         {\r
454                                 exit_code = EXIT_UNRECOVERABLE_ERROR;\r
455                         }\r
456                         else\r
457                         {\r
458                                 NavitMessages.sendDialogMessage( mHandler, NavitMessages.DIALOG_PROGRESS_BAR\r
459                                                 , Navit.get_text("Mapdownload")\r
460                                                 , Navit.get_text("Error downloading map!")\r
461                                                 , dialog_num, (int) (real_size_bytes / 1024), (int) (already_read / 1024));\r
462                                 exit_code = EXIT_RECOVERABLE_ERROR;\r
463                         }\r
464                 }\r
465                 catch (Exception e)\r
466                 {\r
467                         NavitMessages.sendDialogMessage( mHandler, NavitMessages.DIALOG_PROGRESS_BAR\r
468                                         , Navit.get_text("Mapdownload")\r
469                                         , Navit.get_text("Error downloading map!")\r
470                                         , dialog_num, (int) (real_size_bytes / 1024), (int) (already_read / 1024));\r
471                         Log.d(TAG, "gerneral Error: " + e);\r
472                         exit_code = EXIT_RECOVERABLE_ERROR;\r
473                 }\r
474 \r
475                 // always cleanup, as we might get errors when trying to resume\r
476                 if (buf!=null && bif!=null)\r
477                 {\r
478                         try {\r
479                                 buf.flush();\r
480                                 buf.close();\r
481         \r
482                                 bif.close();\r
483                         } catch (IOException e) { }\r
484                 }\r
485 \r
486                 if (exit_code == EXIT_SUCCESS)\r
487                 {\r
488                         String final_fileName = MAP_FILENAME_PRI;\r
489                         \r
490                         if (map_number>0)\r
491                         {\r
492                                 final_fileName = String.format(MAP_FILENAME_NUM, map_number);\r
493                         }\r
494 \r
495                         File final_outputFile = new File(MAP_FILENAME_PATH, final_fileName);\r
496                         // delete an already final filename, first\r
497                         final_outputFile.delete();\r
498                         // rename file to final name\r
499                         outputFile.renameTo(final_outputFile);\r
500                 }\r
501                 \r
502                 return exit_code;\r
503         }\r
504         \r
505         private boolean checkFreeSpace(long needed_bytes)\r
506         {\r
507                 StatFs fsInfo = new StatFs(MAP_FILENAME_PATH);\r
508                 \r
509                 long free_space = fsInfo.getAvailableBlocks() * fsInfo.getBlockSize();\r
510                 \r
511                 if ( needed_bytes <= 0 )\r
512                         needed_bytes = MAP_WRITE_FILE_BUFFER;\r
513 \r
514                 if (free_space < needed_bytes )\r
515                 {\r
516                         Log.e(TAG, "Not enough free space. Please free at least " + needed_bytes / 1024 /1024 + "Mb.");\r
517                         \r
518                         NavitMessages.sendDialogMessage( mHandler, NavitMessages.DIALOG_PROGRESS_BAR\r
519                                         , Navit.get_text("Mapdownload")\r
520                                         , Navit.get_text("Error downloading map!") + "\n" + Navit.get_text("Not enough free space")\r
521                                         , dialog_num, (int)(needed_bytes / 1024), (int)(free_space / 1024));\r
522                         \r
523                         return false;\r
524                 }\r
525                 return true;\r
526         }\r
527 }\r