Insights: kpToggle

Bevor Sie anfangen, dieses Dokument zu lesen, muss ich zugeben, dass Deutsch nicht meine Muttersprache ist, deshalb sind Fehler zu erwarten. Falls sie Sie sehr stören und Sie Englisch können, könnten Sie auch die Sprache des Dokuments wechseln.

kpToggle ist eine kleine App für Android zusammen mit einem Cloud-Server, die beide von CaSensitive, einer Einmann-Firma, entwickelt wurden. Dieses Projekt wurde entwickelt, um zukunftige Kunden eine Idee zu geben, was eine einzige Person mit sehr vielfältige Fähigkeiten schaffen kann, und um Erkenntnisse über die Entwicklung zuverlässiger Software vorzustellen. Man soll bemerken, dass dieses kein Vollzeitprojekt war, sondern in der Freizeit gemacht wurde, deshalb sollte es nicht mit Projekten verglichen werden, die mit einem erheblichen Budget entwickelt wurden.

Das Spiel selbst ist sehr einfach und wurde ursprünglich für Desktop und Browser mit Java Swing vor mehreren Jahren an einem regnerischen Wochenende entwickelt. Weil es gut zu Touchscreens passt, wurde es entschieden, das Spiel für Android zu entwickeln. Wenn man nicht besser wusste, könnte man denken, dass der Javaquelltext des ursprünglichen Spieles wieder benutzt werden könnte, aber die Arkitektur von Anwendung auf Android ist ganz anderes.

Wenn Sie ein Android-Gerät besitzen, können Sie kpToggle von Google Play Store installieren, sonst können Sie die Screenshots da anschauen. Wenn Java-Applets in Ihrem Webbrowser gestattet sind, kann sogar das ursprüngliche Spiel gespielt werden, aber die App für Android macht mehr Spas und enthielt mehr Funktionalität z.B. Tutorials.

Anforderungen und Analysis

Die Basis des Spieles wurde schon definiert, aber weil es möglich ist, Daten auf dem Gerät zu speichern, macht es auch Sinn Top-Scores zu unterstützen.

Android-Geräte ermöglichen, viel Information über Benutzer/-innen auf Servers zu sammeln, aber dieses Spiel hat keine Anforderung persönliche Daten über Benutzer zu sammeln. Tatsächlich sollte es vermieden werden, um Sicherheitsprobleme zu vermindern, wie solche, die oft heutzutage in den Medien berichtet werden. Trotzdem wurde es erwünscht zu erfassen, wie oft das Spiel installiert wurde und wie oft es gespielt wurde, deshalb müssen ein bisschen Information von einem Server gesammelt werden.

Bisher sehen die beschriebene Anforderungen nich komplex aus, aber mehere Details fehlen noch, z.B.

Ausser des letzten Punktes, wurden diese Punkte auf 2 Themen abstrahiert:

  1. Authentifizierung einer Instanz der Applikation
  2. Erholung von Fehler

Bezüglich des ersten Punktes, obwohl kpToggle keine kritischen Daten handelt, wurde es trotzdem vorgezogen zu wissen, ob empfangenen Daten, vertraut werden könnten. Eine einzigartige Bezeichnung zu generieren, ist einfach, aber Meldungen mit so einer Bezeichnung zu bestätigen, ist ein bisschen komplexer. Natürlich soll die Kommunikationsverbindung verschlüsselt werden, aber das bedeutet nicht, dass das System sicher wäre. Leider ist es einem Benutzer relativ einfach, die Sicherheit eines Android-Geräts zu beeinträchtigen und dann Sicherheitslöche in Anwendungen zu entdecken. Wegen eines Mangels kritischer Daten wurde es entschieden, nur zu erkennen, welche Geräte beeinträchtigt wurden, damit Speilresultate von solchen Geräten ausgeschlossen werden könnten z.B. bei einem zukunftigen Wettbewerb. Trotzdem musste die Quelle der Bestätigung vertraut werden. Die Lösung musste im Server implementiert werden, anhand zusätzlicher Daten von einem Google-Dienst.

Die folgende Grafik des Systemüberblicks zeigt einfach die Interaktionen zwischen der Android-App, dem Server und dem Dienst von Google.

Client-App

Die App wurde auf Java implementiert, mit 4 Android-Aktivitäten:

  1. Tutorials
  2. Spieloptionen
  3. Das Spiel
  4. Resultate

Die Aktivität für Tutorials wurder hinzugefügt, nach ein bisschen Testen mit Leuten. Einige Leute hatten alles im Griff nach nur ein paar Klicken, aber einige hatten Schwierigkeiten, Konzepte zu verstehen, deshalb dachte ich, dass einige Tutorials helfen könnten. Um die Aufwand zu reduzieren, wurde die Lösung auf Text mit vorkonfigurierten Spielen basiert. Der Hauptvorteil dieser Lösung war, dass normale Spielen und Spielen in Tutorials den gleichen Code benutzen - wegen des Unterschieds der Grosse sehen sie nur ein bisschen anderes aus. Noch ein Vorteil ist, dass Benutzer auch frei sind, mehrere Lösungen für ein Tutorial zu entdecken.

Es gibt auch ein Paar Services, die im Hintergrund laufen, um die Interaktion mit der localen Datenbank sowie dem Server zu handeln, nämlich:

Wie schon gesagt, es gibt noch ein bisschen Komplexität, von Netzfehler usw. zu erholen. Weil die Registrierung einer App-Instanz abstrahiert wurde, damit sie auch wie die Synchronisierung von Daten mit dem Server behandelt werden konnte, war es möglich eine einzige, wiederverwendbare Lösung zu finden. Um Resourcen auf dem Gerät zu sparen, wird die Kombination von Netzmonitor und Timers aktiviert, nur wenn nötig. Am Ende konnte alle solche Fehler mit dieser Lösung behandlet werden. Solche Zuverlässigkeit in der App bedeutet, dass der Server auch ohne Risiko von verlorenen Daten irgendwann kurzfristig gestoppt werden kann.

Der Server

Der Server wurde auf C++ geschrieben und läuft auf Linux, momentan in einem Docker-Container. C++ wurde benutzt, damit der Server auf sehr gunstige Hardware laufen kann. Ursprünglich sollte er auf einem Raspberry Pi laufen, aber am Ende wurden der Server und die Datenbank zu einem Cloud-Server eingesetzt, mit jährlichen Kosten von ungefähr 60 Schweizer Franken.

Es ist vielleicht ein bisschen aussergewöhnlich, aber alle Infrastruktur-Bibliotheken sind auch von CaSensitive, ausser OpenSSL für Kommunikationsverschlüsseln, eine Bibliothek für PostgreSQL und natürlich "standard" C/C++ Bibliotheken. Solche Infrastruktur wurde entwickelt, um zu zeigen, wie gutes Design zur Entwicklung von wiederverwendbarem Code führen kann und zu demonstrieren, was ein Entwickler mit sehr vielfältige Fähigkeiten schaffen kann. Natürlich wäre es schneller ein schon existierendes Framework zu benutzen, aber dann gäbe es oft auch mehrere Nachteilen z.B.

Die Details der Infrastruktur-Bibliotheken in ein paar Sätzen zu beschreiben, ist unmöglich, aber die folgende Grafik zeigt einen Überblick der wiederverwendbaren Funktionalität. C++ infrastructure libraries

Der Funktionalität des Servers ist nicht complex, wenn man zuerst betrachtet, wie viel Funktionalität von den Infrastruktur-Bibliotheken behandelt wird. Etwas ein bisschen merkwürdig ist, dass der Server nicht nur einen HTTPS-Server enthielt, sondern auch ein HTTPS-Client. Um eine App-Instanz zu verifizieren, wird eine Abfrage nach einem Dienst von Google geschickt, um herauszufinden, ob eine Bezeichnung gültig ist, und wenn so, ob die Sicherheit des Geräts kompromittiert (oder "rooted") wurde. Weitere Abfragen könnten geschickt werden, um zu bestätigen, dass die Anwendung immer noch auf einem Gerät existiert.

Cloud Deployment

Statt ein proprietär Cloud-Dienst zu benutzen, wurden der Server sowie die Datenbank anhand Docker und verwandten Werkzeuge zu einem Cloud-Dienst installiert, damit die Auswahl von Linux-Distribution, Version und Datenbank deutlich grösser war. Die Docker-Images wurder lokal erstellt, vor sie zu Docker-Hub heraufgeladen wurden, aber ohne geschützten Daten (z.B. Zugriff-Codes für Google Dienste, DB Passwörter und Zertifikäten für Kommunikationsverschlüsselung). Die modularen Konfiguration in den Infrastruktur-Bibliotheken ermöglicht, dass solche Information sich auf einem separaten Laufwerk befinden konnten.

Abschluss

Das ist alles für die Erkenntnisse über die Entwicklung von kpToggle, einem einfachen Spiel, aber dafür war die Andwendung mehrerer Fähigkeiten nötig z.B.: