SplashScreen redesigned, um Aufgaben parallel abzuarbeiten
[DHBWCampusApp.git] / app / src / main / java / de / dhbwloe / campusapp / fragments / SplashScreen.java
1 /* SplashScreen.java
2  *
3  * This program is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 package de.dhbwloe.campusapp.fragments;
17 import android.graphics.Bitmap;
18 import android.graphics.BitmapFactory;
19 import android.graphics.Point;
20 import android.os.Bundle;
21 import android.os.Handler;
22 import android.support.v4.app.Fragment;
23 import android.view.Display;
24 import android.view.LayoutInflater;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.widget.ImageView;
28 import android.widget.ProgressBar;
29 import android.widget.TextView;
30
31 import java.util.Date;
32
33 import de.dhbwloe.campusapp.CampusApp;
34 import de.dhbwloe.campusapp.CampusAppContext;
35 import de.dhbwloe.campusapp.CampusAppFragment;
36 import de.dhbwloe.campusapp.R;
37 import de.dhbwloe.campusapp.coursenames.CourseNameManager;
38 import de.dhbwloe.campusapp.coursenames.CourseNameManagerInterface;
39 import de.dhbwloe.campusapp.mensaplan.MensaplanManager;
40 import de.dhbwloe.campusapp.mensaplan.MensaplanManagerInterface;
41 import de.dhbwloe.campusapp.news.NewsManager;
42 import de.dhbwloe.campusapp.news.NewsManagerInterface;
43 import de.dhbwloe.campusapp.search.SearchIndices;
44 import de.dhbwloe.campusapp.vorlesungen.CalendarManager;
45 import de.dhbwloe.campusapp.vorlesungen.CalendarManagerInterface;
46 import de.dhbwloe.campusapp.vorlesungen.CourseEvent;
47 import de.dhbwloe.campusapp.vorlesungen.CourseGroup;
48
49 /**
50  * A simple {@link Fragment} subclass.
51  */
52 public class SplashScreen extends CampusAppFragment {
53     private static final int PARALLELIZE_SPLASHTASKS = 4;
54     private static final int SPLASHTASK_COUNT = 9;
55
56     private ProgressBar splashProgress;
57     private int progressCounter;
58     private int pendingSplashTasks;
59     private int lastTaskId;
60     private boolean[] pendingSplashTask = new boolean[SPLASHTASK_COUNT+1];
61     private Handler timerHandler = new Handler();
62     private Runnable timerRunnable;
63
64     @Override
65     public void onCreate(Bundle savedInstanceState) {
66         super.onCreate(savedInstanceState);
67
68
69     }
70
71     @Override
72     public void onSaveInstanceState(Bundle savedInstanceState) {
73         timerHandler.removeCallbacksAndMessages(null);
74         super.onSaveInstanceState(savedInstanceState);
75     }
76
77     @Override
78     public View onCreateView(LayoutInflater inflater, ViewGroup container,
79                              Bundle savedInstanceState) {
80         View view = inflater.inflate(R.layout.fragment_splashscreen, container, false);
81
82         TextView versionView = (TextView) view.findViewById(R.id.version);
83         versionView.setText(CampusAppContext.APPVERSION);
84
85         splashProgress = (ProgressBar)view.findViewById(R.id.splashProgress);
86
87         AppContext.setTitle("DHBW Lörrach");
88
89         timerRunnable = new Runnable() {
90             @Override
91             public void run() {
92                 runSplashTasks();
93             }
94         };
95
96         return view;
97     }
98
99     @Override
100     public void onResume() {
101         super.onResume();
102         timerHandler.postDelayed(timerRunnable, 500);
103     }
104
105     private void runSplashTasks() {
106         /*
107          Dieser Taskhandler, bestehend aus den Methoden runSplashTasks, runSplashTask, onSplashTaskComplete, onSplashTasksFinished
108          soll möglichst effizient alle durchzuführenden Aufgaben (Tasks) beim Ladevorgang der App durchführen.
109
110          Die Tasks werden innerhalb der Methode runSplashTask definiert.
111          Es können beliebig tasks parallel durchgeführt werden, solange diese Asnychron arbeiten. Siehe PARALLELIZE_SPLASHTASKS
112          */
113         progressCounter = 0;
114         lastTaskId = 0;
115         pendingSplashTasks = 1; // 1 (Timer Task)
116         splashProgress.setMax(SPLASHTASK_COUNT+1);
117         splashProgress.setProgress(0);
118         pendingSplashTask[0] = true;
119         for(int i = 0; i < PARALLELIZE_SPLASHTASKS; i++) {
120             if(lastTaskId >= SPLASHTASK_COUNT)
121                 break;
122             pendingSplashTasks++;
123             lastTaskId++;
124             pendingSplashTask[lastTaskId] = true;
125             runSplashTask(lastTaskId);
126         }
127         timerRunnable = new Runnable() {
128             @Override
129             public void run() {
130                 onSplashTaskComplete(0, true);
131             }
132         };
133         timerHandler.postDelayed(timerRunnable, 3000); // Show Splashscreen at least 3 seconds
134     }
135
136     private void onSplashTaskComplete(int taskId, boolean success) {
137         if(!pendingSplashTask[taskId])
138             return; // double callback call?
139         pendingSplashTask[taskId] = false;
140         pendingSplashTasks--;
141         progressCounter++;
142         splashProgress.setProgress(progressCounter);
143
144         if(lastTaskId < SPLASHTASK_COUNT) {
145             pendingSplashTasks++;
146             lastTaskId++;
147             pendingSplashTask[lastTaskId] = true;
148             runSplashTask(lastTaskId);
149         } else if(pendingSplashTasks == 0) {
150             onSplashTasksFinished();
151         }
152     }
153
154     private void onSplashTasksFinished() {
155         ((CampusApp) AppContext.getMainActivity()).loadMainUi();
156         AppContext.getNavigationManager().navigatePage("Dashboard", null, false);
157     }
158
159     private void runSplashTask(int taskId) {
160         long now = (new Date()).getTime() / 1000;
161         switch (taskId) {
162             case 1:
163                 AppContext.getDatabaseManager().initializeDatabase();
164                 onSplashTaskComplete(1, true);
165                 break;
166             case 2:
167                 AppContext.addDefaultSearchIndexes();
168                 onSplashTaskComplete(2, true);
169                 break;
170             case 3:
171                 String lastCNSyncStr = AppContext.getDatabaseManager().getRuntimeCache("LastCNSync");
172                 long lastCNSync;
173                 if (lastCNSyncStr != null)
174                     lastCNSync = Long.parseLong(lastCNSyncStr);
175                 else
176                     lastCNSync = 0;
177
178                 CourseNameManager cnm = new CourseNameManager();
179
180                 if (lastCNSync == 0 || now - lastCNSync > (86400 * 7)) { //sync every 7 days
181                     cnm.synchronizeCourseNames(new CourseNameManagerInterface() {
182                         @Override
183                         public void onCourseNamesSynchronized() {
184                             long now = (new Date()).getTime() / 1000;
185                             AppContext.getDatabaseManager().setRuntimeCache("LastCNSync", Long.toString(now));
186                             onSplashTaskComplete(3, true);
187
188                         }
189
190                         @Override
191                         public void onCourseNamesFailed(String errorMessage) {
192                             onSplashTaskComplete(3, false);
193                         }
194                     });
195                 } else
196                     onSplashTaskComplete(3, true);
197                 break;
198             case 4:
199                 String startCounter = AppContext.getDatabaseManager().getRuntimeCache("AppStartCounter");
200                 if (startCounter == null || Integer.parseInt(startCounter) == 0) {
201                     AppContext.getNavigationManager().navigatePage("FirstRun", null, false);
202                     return;
203                 }
204                 AppContext.getDatabaseManager().setRuntimeCache("AppStartCounter", Integer.toString(Integer.parseInt(startCounter) + 1));
205                 onSplashTaskComplete(4, true);
206                 break;
207             case 5:
208                 String lastVLMFullSyncStr = AppContext.getDatabaseManager().getRuntimeCache("LastVLMFullSync");
209                 String lastVLMPartialSyncStr = AppContext.getDatabaseManager().getRuntimeCache("LastVLMPartialSync");
210                 long lastVLMFullSync, lastVLMPartialSync;
211                 if (lastVLMFullSyncStr != null)
212                     lastVLMFullSync = Long.parseLong(lastVLMFullSyncStr);
213                 else
214                     lastVLMFullSync = 0;
215                 if (lastVLMPartialSyncStr != null)
216                     lastVLMPartialSync = Long.parseLong(lastVLMPartialSyncStr);
217                 else
218                     lastVLMPartialSync = 0;
219
220                 final String kursTag = AppContext.getDatabaseManager().getRuntimeCache("CourseName");
221                 if (kursTag == null || kursTag.isEmpty()) {
222                     onSplashTaskComplete(5, true);
223                     break;
224                 }
225                 CalendarManager vpm = new CalendarManager(AppContext, kursTag);
226
227                 if (lastVLMFullSync == 0 || now - lastVLMFullSync > (86400 * 14)) { // full sync every 14 days
228                     vpm.performFullSynchronisation(new CalendarManagerInterface() {
229                         @Override
230                         public void onCalendarUpdateDone() {
231                             if (!AppContext.getDatabaseManager().haveCourseName(kursTag)) {
232                                 CourseNameManager cnm = new CourseNameManager();
233                                 cnm.addCourseName(kursTag);
234                             }
235
236                             long now = (new Date()).getTime() / 1000;
237                             AppContext.getDatabaseManager().setRuntimeCache("LastVLMFullSync", Long.toString(now));
238                             AppContext.getDatabaseManager().setRuntimeCache("LastVLMPartialSync", Long.toString(now));
239                             onSplashTaskComplete(5, true);
240                         }
241
242                         @Override
243                         public void onCalendarUpdateFail(String errorMessage) {
244                             onSplashTaskComplete(5, false);
245                         }
246
247                         @Override
248                         public SearchIndices onGenerateCalendarSearchIndices(CourseEvent event) {
249                             CourseGroup group = event.getCourseGroup();
250                             SearchIndices indices = new SearchIndices("Vorlesungsplan#Group" + group.getGroupId(), false);
251                             indices.setUpdateTime(event.getEventFrom());
252                             indices.setTarget("#Vorlesungsplan#groupid=" + group.getGroupId());
253                             indices.setTitle("Vorlesungsplan " + event.getCourseName());
254                             indices.setDescription("Vorlesung " + event.getEventTitle());
255                             indices.addKeyWord(event.getGroupTitle());
256                             indices.addKeyWord(event.getEventLocation());
257                             return indices;
258                         }
259                     });
260                 } else if (lastVLMPartialSync == 0 || now - lastVLMPartialSync > (86400)) { // partial sync every day
261                     vpm.performFastSynchronisation(new CalendarManagerInterface() {
262                         @Override
263                         public void onCalendarUpdateDone() {
264                             if (!AppContext.getDatabaseManager().haveCourseName(kursTag)) {
265                                 CourseNameManager cnm = new CourseNameManager();
266                                 cnm.addCourseName(kursTag);
267                             }
268
269                             long now = (new Date()).getTime() / 1000;
270                             AppContext.getDatabaseManager().setRuntimeCache("LastVLMPartialSync", Long.toString(now));
271                             onSplashTaskComplete(5, true);
272                         }
273
274                         @Override
275                         public void onCalendarUpdateFail(String errorMessage) {
276                             onSplashTaskComplete(5, false);
277                         }
278
279                         @Override
280                         public SearchIndices onGenerateCalendarSearchIndices(CourseEvent event) {
281                             CourseGroup group = event.getCourseGroup();
282                             SearchIndices indices = new SearchIndices("Vorlesungsplan#Group" + group.getGroupId(), false);
283                             indices.setUpdateTime(event.getEventFrom());
284                             indices.setTarget("#Vorlesungsplan#groupid=" + group.getGroupId());
285                             indices.setTitle(AppContext.getResString(R.string.search_vorlesungsplan_group_title, event.getCourseName()));
286                             indices.setDescription(event.getEventTitle());
287                             indices.addKeyWord(event.getGroupTitle());
288                             indices.addKeyWord(event.getEventLocation());
289                             return indices;
290                         }
291                     });
292                 } else
293                     onSplashTaskComplete(5, true);
294                 break;
295             case 6:
296                 String lastMPMSyncStr = AppContext.getDatabaseManager().getRuntimeCache("LastMPSync");
297                 long lastMPMSync;
298                 if (lastMPMSyncStr != null)
299                     lastMPMSync = Long.parseLong(lastMPMSyncStr);
300                 else
301                     lastMPMSync = 0;
302
303                 MensaplanManager mpm = new MensaplanManager(AppContext);
304
305                 if (lastMPMSync == 0 || now - lastMPMSync > (86400 * 2)) { //sync every 2 days
306                     mpm.performSynchronisation(new MensaplanManagerInterface() {
307                         @Override
308                         public void onMensaplanUpdateDone() {
309                             long now = (new Date()).getTime() / 1000;
310                             AppContext.getDatabaseManager().setRuntimeCache("LastMPSync", Long.toString(now));
311                             onSplashTaskComplete(6, true);
312                         }
313
314                         @Override
315                         public void onMensaplanUpdateFail(String errorMessage) {
316                             onSplashTaskComplete(6, false);
317                         }
318                     });
319                 } else
320                     onSplashTaskComplete(6, true);
321                 break;
322             case 7:
323                 final String syncSource = "DHBW";
324                 String lastNewsSyncStr = AppContext.getDatabaseManager().getRuntimeCache("LastNewsSync_" + syncSource);
325                 long lastNewsSync;
326                 if (lastNewsSyncStr != null)
327                     lastNewsSync = Long.parseLong(lastNewsSyncStr);
328                 else
329                     lastNewsSync = 0;
330
331                 NewsManager nm = new NewsManager(AppContext, syncSource);
332
333                 if (lastNewsSync == 0 || now - lastNewsSync > (86400 * 1)) { //sync every day
334                     nm.performSynchronisation(new NewsManagerInterface() {
335                         @Override
336                         public void onNewsUpdateDone() {
337                             long now = (new Date()).getTime() / 1000;
338                             AppContext.getDatabaseManager().setRuntimeCache("LastNewsSync_" + syncSource, Long.toString(now));
339                             onSplashTaskComplete(7, true);
340                         }
341
342                         @Override
343                         public void onNewsUpdateFail(String errorMessage) {
344                             onSplashTaskComplete(7, false);
345                         }
346                     });
347                 } else
348                     onSplashTaskComplete(7, true);
349                 break;
350             case 8:
351                 final String syncSource2 = "STUV";
352                 String lastNewsSyncStr2 = AppContext.getDatabaseManager().getRuntimeCache("LastNewsSync_" + syncSource2);
353                 long lastNewsSync2;
354                 if (lastNewsSyncStr2 != null)
355                     lastNewsSync2 = Long.parseLong(lastNewsSyncStr2);
356                 else
357                     lastNewsSync2 = 0;
358
359                 NewsManager nm2 = new NewsManager(AppContext, syncSource2);
360
361                 if (lastNewsSync2 == 0 || now - lastNewsSync2 > (86400 * 1)) { //sync every day
362                     nm2.performSynchronisation(new NewsManagerInterface() {
363                         @Override
364                         public void onNewsUpdateDone() {
365                             long now = (new Date()).getTime() / 1000;
366                             AppContext.getDatabaseManager().setRuntimeCache("LastNewsSync_" + syncSource2, Long.toString(now));
367                             onSplashTaskComplete(8, true);
368                         }
369
370                         @Override
371                         public void onNewsUpdateFail(String errorMessage) {
372                             onSplashTaskComplete(8, false);
373                         }
374                     });
375                 } else
376                     onSplashTaskComplete(8, true);
377                 break;
378             case 9:
379                 String lastStuvSyncStr = AppContext.getDatabaseManager().getRuntimeCache("LastStuvSync");
380                 long lastStuvSync;
381                 if (lastStuvSyncStr != null)
382                     lastStuvSync = Long.parseLong(lastStuvSyncStr);
383                 else
384                     lastStuvSync = 0;
385
386                 final String calendarName = "STUV";
387                 CalendarManager stuvsyncmgr = new CalendarManager(AppContext, calendarName);
388
389                 if (lastStuvSync == 0 || now - lastStuvSync > (86400 * 3)) { // full sync every 3 days
390                     stuvsyncmgr.performFullSynchronisation(new CalendarManagerInterface() {
391                         @Override
392                         public void onCalendarUpdateDone() {
393                             long now = (new Date()).getTime() / 1000;
394                             AppContext.getDatabaseManager().setRuntimeCache("LastStuvSync", Long.toString(now));
395                             onSplashTaskComplete(9, true);
396                         }
397
398                         @Override
399                         public void onCalendarUpdateFail(String errorMessage) {
400                             onSplashTaskComplete(9, false);
401                         }
402
403                         @Override
404                         public SearchIndices onGenerateCalendarSearchIndices(CourseEvent event) {
405                             CourseGroup group = event.getCourseGroup();
406                             SearchIndices indices = new SearchIndices("Vorlesungsplan#Group" + group.getGroupId(), false);
407                             indices.setUpdateTime(event.getEventFrom());
408                             indices.setTarget("#News#showevent=" + group.getGroupId() + "&course=" + calendarName);
409                             indices.setTitle(calendarName + " Event: " + event.getCourseName());
410                             indices.setDescription(event.getEventTitle());
411                             indices.addKeyWord(event.getGroupTitle());
412                             indices.addKeyWord(event.getEventLocation());
413
414                             return null;
415                         }
416                     });
417                 } else
418                     onSplashTaskComplete(9, true);
419                 break;
420
421             default:
422                 onSplashTaskComplete(taskId, true);
423                 break;
424         }
425     }
426
427 }