Platforma testów manualnych natywnych aplikacji

Transkrypt

Platforma testów manualnych natywnych aplikacji
Platforma testów manualnych natywnych
aplikacji Android
Rafał Mańka
28 czerwca 2015
Streszczenie
System pozwalający na połączenie się z urządzeniem android przez
internet pozwoli na stworzenie usługi, która umożliwi sprzedaż czasowego dostępu do smartfona typu Android. Usługa pozwoli wykluczyć
konieczność fizycznego dostępu do telefonu w celu przeprowadzania testów manualnych. Interakcja z urządzeniem odbywa się w czasie rzeczywistym, przy pośrednictwie przeglądarki internetowej. centralny
element interfejsu użytkownika stanowi podgląd kamery wideo skierowanej na ekran telefonu. Kliknięcia w oknie przeglądarki na elemencie podglądu przekazywane są do serwera przy wykorzystaniu technologi AJAX. Serwer po otrzymaniu żądania z interfejsu użytkownika
przeprowadza symulacje gestów na urządzeniu wykorzystując program
ADB.
Spis treści
1 Wstęp
3
2 Analiza zagadnienia
7
2.1 Historia systemu operacyjnego Android . . . . . . . . . . . . . 9
2.2 Analiza podobnych rozwiązań dostępnych na rynku . . . . . . 14
3 Projekt Systemu
3.1 Dziedzina problemowa . . . . . .
3.2 Cel systemu . . . . . . . . . . . .
3.3 Zakres odpowiedzialności systemu
3.4 Użytkownicy systemu . . . . . . .
3.5 Wymagania wobec systemu . . .
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15
15
16
16
17
18
3.6
3.7
3.8
3.9
3.5.1 Wymagania funkcjonalne . . . . . . . . . . . . . . . .
3.5.2 Wymagania niefunkcjonalne . . . . . . . . . . . . . .
Klasa "Biznesowa"Telefon . . . . . . . . . . . . . . . . . . .
Diagram przypadków użycia . . . . . . . . . . . . . . . . . .
Decyzje projektowe . . . . . . . . . . . . . . . . . . . . . . .
3.8.1 Wybór technologii w której stworzony będzie interfejs
użytkownika . . . . . . . . . . . . . . . . . . . . . . .
Wybór protokołu za pomocą którego interfejs użytkownika komunikować się będzie z serwerem. . . . . . . . . . . . . . . .
3.9.1 Wybór technologii do stworzenia części aplikacji działającej po stronie serwera. . . . . . . . . . . . . . . .
3.9.2 Wybór narzędzia za pomocą którego przekazywany będzie obraz aktualnie wyświetlany na urządzeniu z systemem Android. . . . . . . . . . . . . . . . . . . . . .
3.9.3 Komunikacja serwera z telefonem android . . . . . . .
.
.
.
.
.
. 20
. 22
. 25
. 27
. 28
4 Budowa systemu
4.1 Komponenty systemu . . . . . . . . . . . . . . . . . . . . . . .
4.1.1 Sprzęt . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.2 Oprogramowanie . . . . . . . . . . . . . . . . . . . . .
4.2 Schematy połączeń . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Zestawienie kamery z telefonem . . . . . . . . . . . . . . . . .
4.4 Napotkane problemy i sposoby ich rozwiązania . . . . . . . . .
4.4.1 Streaming z kamery Raspberry Pi . . . . . . . . . . . .
4.4.2 Symulowanie wciskania przycisków znajdujących się na
obudowie telefonu. . . . . . . . . . . . . . . . . . . . .
4.4.3 Komunikacja serwera z systemem operacyjnym Android.
4.4.4 Symulowanie zdarzeń poprzez interfejs programu ADB.
4.4.5 Przekazywanie współrzędnych gestu “tap” z interfejsu
użytkownika. . . . . . . . . . . . . . . . . . . . . . . .
4.4.6 Udostępnianie usługi pod niezmiennym adresem http. .
5 Testy systemu
5.1 Cel testów . . . . . . . . . . . . . . . . . . . . . .
5.2 Potencjalne zagrożenia . . . . . . . . . . . . . . .
5.3 Testy dostępności aplikacji przy zmianie adresu IP
nej serwera. . . . . . . . . . . . . . . . . . . . . .
5.4 Testy latencji . . . . . . . . . . . . . . . . . . . .
5.5 Testy dokładności mapowania gestu “tap” . . . . .
5.6 Modyfikacje systemu na podstawie testów . . . .
2
. . . . . .
. . . . . .
sieci lokal. . . . . .
. . . . . .
. . . . . .
. . . . . .
18
18
19
20
20
29
29
29
34
35
36
37
37
39
44
45
47
54
55
. 55
. 55
.
.
.
.
56
56
58
58
6 Zakończenie - plany dalszego rozwoju systemu
6.1 Dalszy rozwój serwera zarządzającego telefonem . . . . . . .
6.2 Stworzenie kolejnych jednostek serwerów Raspberry Pi . . .
6.3 Stworzenie centralnej aplikacji, która zarządzałaby dostępem
do poszczególnych serwerów . . . . . . . . . . . . . . . . . .
6.4 Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . .
1
59
. 59
. 60
. 60
. 61
Wstęp
W mojej pracy przedstawiam pokrótce historię systemu operacyjnego Android i kontekst w jakim środowisko to było rozwijane. Począwszy od powstania pierwszej jego wersji jeszcze przed wykupieniem firmy Android Inc.
przez Google aż do dnia dzisiejszego. Jako, że Android jest systemem operacyjnym z rodziny linux, jego rozwój odbywa się w specyficznym ekosystemie
open source. Konkurencyjne platformy producentów takich jak Apple, Microsoft czy Blackberry bazują na oprogramowaniu własnościowym, opieczętowanym różnego rodzaju patentami.
W kolejnych częściach pracy inżynierskiej zaprezentuję rozwiązanie, które
ma na celu ułatwienie programistom dostarczenie na rynek aplikacji lepiej
dostosowanych do dostępnych na rynku urządzeń Android. Ostatni rozdział
pracy poświęcę na opisywanie testów stworzonego systemu i potencjalnych
zagrożeniach przy dalszej jego eksploatacji. Na koniec pozwolę sobie zaproponować jak może wyglądać dalsza ewolucja układu i jego wdrożenie na rynek
komercyjny.
Projekt, który jest przedmiotem niniejszej pracy zakłada, że interfejs
przeglądarki internetowej jest wystarczająco elastyczny, aby pośredniczyć w
testowaniu oprogramowania w czasie rzeczywistym. System nie ma stanowić
alternatywy dla emulatora czy urządzenia Android podłączonego do stacji
roboczej za pomocą kabla USB tylko ma mieć charakter dodatkowej usługi.
Według założeń projektowych głównym wykorzystaniem systemu ma być pomoc w ostatniej fazie wdrożeniowej, tuż przed opublikowaniem jej na Google
Play. Twórcy oprogramowania mogą skorzystać z tego systemu w celu wykonania testów manualnych, uzyskując tym samym pewność, że wytworzone
oprogramowanie funkcjonuje prawidłowo na określonej liczbie urządzeń.
Kolejnym zastosowaniem systemu mogą być sytuacje krytyczne, kiedy
błąd pojawia się jedynie na niektórych urządzeniach. Wówczas zespół deweloperski może odtworzyć dane zdarzenie na urządzeniu testowym i wyciągnąć
na tej podstawie określone wnioski.
Tezy mojej pracy są następujące:
3
system pozwoli przetestować aplikację na urządzeniu, do którego programista nie ma fizycznego dostępu w celu upewnienia się, że aplikacja
zachowuje się zgodnie z założeniami;
system pozwoli wykryć błędy pojawiające się na konkretnym modelu telefonu, a które nie pojawiają się na innych urządzeniach;
Praca ma charakter praktyczny. Oprócz części teoretycznej praca składa
się również z prototypu systemu złożonego z następujących elementów:
Komputer Raspberry Pi B+ z zainstalowanym systemem operacyjnym
Raspbian. Raspbian jest to dystrybucja linuxa zbudowana na bazie popularnego systemu operacyjnego Debian zbudowana na potrzeby urządzenia Raspberry Pi. Komputer pełni rolę serwera, który zarówno udostępnia interfejs webowy jak również wykonuje operacje na urządzeniu
Android za pomocą programu ADB (Android Debug Bridge).
Raspberry Pi Camera Module. Kamera Dedykowana dla urządzenia Raspberry Pi, połączona z urządzeniem za pomocą interfejsu MIPI. Kamera umożliwia nagrywanie obrazu w wysokiej rozdzielczości.
Soczewka powiększająca x10 Moduł kamery Raspbery Pi pozwala na
nagrywanie obrazu w wysokiej rozdzielczości. Jednak przystosowana
jest ona do standardowych warunków, gdzie odległość od nagrywanego
obiektu jest większa niż pół metra. W moim projekcie obiekt na który
skierowany jest obiektyw kamery znajduje się na odległości około 20cm.
W takim układzie obraz kamery jest zamazany. Żeby uzyskać odpowiednią ostrość niezbędna jest soczewka powiększająca typu macro.
Od strony oprogramowania system składa się z Aplikacji webowej dostępnej pod adresem http://rafalmanka.ddns.net. Przedmiotowy układ tworzą
następujące części:
Frontendowej , działającej po stronie klienta i wykorzystującej technologie HTML5 i JavaScript. Interfejs webowy pozwala na przekazywanie eventów o kliknięciach w guziki telefonu oraz kliknięcia na ekranie
telefonu oraz gesty “swipe”. Interfejs użytkownika komunikuje się z
serwerem przy użyciu technologi AJAX. Technologia ta została również wykorzystana w celu wyświetlenia obrazu kamery. Mianowicie w
odstępach 100 milisekundowych wysyłane jest żądanie do serwera na
które ten odpowiada przekazując obrazek w formacie jpg stanowiący
aktualny podgląd. W dalszej kolejności następuje zamiana obrazka w
przeglądarce internetowej, przez co użytkownik aplikacji ma wrażenie,
że wyświetlany jest strumień video.
4
(a) Raspberry Pi model B+.
(b) Kamera dedykowana dla urządzenia
Raspberry Pi.
(c) Soczewka powiększająca umożliwiająca nagrywane obrazu macro za pomocą
(d) Telefon Samsung Galaxy Ace z systekamery Raspberry Pi.
mem operacyjnym Android 2.3.
Rysunek 1: Komponenty wykorzystane do zbudowania systemu.
Backendowej , działającej po stronie serwera i wykorzystującej technologię
PHP. Aplikacja odpowiedzialna jest za udostępnianie warstwy frontendowej klientowi, przetwarzanie zapytań AJAX oraz wysyłanie zapytań
do programu ADB. Aplikacja odpowiada również za instalowanie na
urządzeniu Android aplikacji APK przez konektor ADB.
Konektora ADB umożliwiającego komunikację serwera z telefonem Android. Program ADB wykonuje operacje na urządzeniu Android oraz
zwraca wyniki działania z powrotem do aplikacji PHP.
5
Rysunek 2: Serwer Raspberry Pi połączony z telefonem Samsung Galaxy Ace
za pomocą kable USB i kamerą umożliwiają podgląd wyświetlanego obrazu.
6
Rysunek 3: Interfejs użytkownika w oknie przeglądarki internetowej.
2
Analiza zagadnienia
W przeciągu ostatnich lat obserwujemy gwałtowny rozwój komputeryzacji
w obszarze telefonów komórkowych. Zaprezentowany w styczniu 2007 roku
przez firmę Apple iPhone1 dał początek rozwojowi rynku smartfonów. Wystarczyło zaledwie kilka lat na to, żeby telefony tego typu absolutnie zdominowały rynek i wyparły praktycznie zupełnie telefony starszej generacji,
jakimi były telefony GSM z klawiaturą sprzętową.
Przewaga smartfonów nad tradycyjnymi telefonami widoczna jest w wielu
aspektach, jednak jako najważniejsze z nich można wyróżnić2 :
1
Wikipedia. iphone — Wikipedia, wolna encyklopedia, 2004
IBTimes Staff Reporter.
Top ten reasons why people buy smartphones. http://www.ibtimes.co.uk/smartphone-features-camera-browsing-gaming-apps-gps348123, 2012
2
7
Serwisy społecznościowe takie jak Facebook, Instagram czy LinkedIn.
Telefony z ekranem dotykowym dzięki dużej przekątnej ekranu i rozdzielczości umożliwiają wysokiej jakości projekcję obrazu. Przeglądanie zdjęć i filmów jest możliwe przy uzyskaniu podobnych parametrów
rozdzielczości jak w przypadku komputera osobistego. Te cechy sprawiły, że aplikacje takie jak Facebook stanowią najchętniej instalowane
aplikacje na platformę Android3 .
Robienie zdjęć. Nowoczesne smartfony wyposażone są w jedną bądź dwie
kamery. Pierwsza ulokowana jest zawsze na tylnej ścianie obudowy
urządzenia, dzięki czemu użytkownik otrzymuje natychmiastowy podgląd fotografowanej przestrzeni. Druga kamera instalowana jest zawsze
z przodu urządzenia, co umożliwia robienie zdjęć i nagrywanie filmów
użytkownikowi. Jakość wykonywanych zdjęć jest niezwykle wysoka,
w niektórych przypadkach może wręcz konkurować z profesjonalnym
sprzętem fotograficznym. Powyższe implikuje fakt w postaci tego, że
większość użytkowników smartfonów bardzo regularnie korzysta z tej
funkcjonalności.
Słuchanie muzyki . Większość smarfonów wyposażonych jest w wyjście
słuchawkowe mini jack, analogiczne do tych które znajdziemy na przenośnych odtwarzaczach audio. Ww. urządzenia mobilne charakteryzuje wysoka wydajność przetwarzania dźwięku. Dostępna jest znaczna
ilość bibliotek wspierających wiele popularnych formatów zapewniających wysoką jakość audio. W połączeniu z odpowiednim oprogramowaniem telefon typu smartfon z powodzeniem może zastąpić przenośny
odtwarzacz mp3. W ostatnich latach pojawiło się kilka interesujących
aplikacji, takich jak Spotify czy Deezer, które to dodatkowo ułatwiają
konsumpcję muzyki na urządzeniach mobilnych.
Gry. Smartfony wyposażone są w wydajny procesor graficzny,który czyni
możliwym przetwarzanie grafiki wymagającej wykorzystanie większej
ilości zasobów obliczeniowych. Smartfon stał się więc punktem zainteresowań producentów gier, otwierając kolejny kanał dystrybucji, pozwalający dotrzeć do szerszego grona konsumentów.
Przeglądanie stron internetowych. Wyświetlacz standardowego smartfona typu android wyposażony jest w wyświetlacz o przekątnej ok. 4,5
cala. W połączeniu z szybkim procesorem ARM, który przetwarza
3
Wikipedia. List of most downloaded android applications — Wikipedia, wolna encyklopedia, 2004
8
strony internetowe w sposób wydajny. Bieżące statystyki odwiedzalności stron internetowych4 wskazują na rosnącą tendencję wykorzystywania smartfona jako medium konsumpcji stron internetowych. Twórcy
portali www co raz chętniej wspierają rozdzielczości smartfonów i tabletów. Nadto przewiduje się, że w niedalekiej przyszłości urządzenia mobilne będą wykorzystywane do przeglądania stron internetowych
zdecydowanie częściej aniżeli komputery klasy PC.
Oglądanie filmów. Wszystkie smartfony dostępne na rynku w dniu dzisiejszym wyposażone są w aplikację umożliwiającą wyświetlanie filmów z
platformy YouTube. Odtwarzanie filmów na tego typu urządzeniu nie
stanowi większego problemu ze względu na obszerną liczbę dedykowanych do tego aplikacji, wspierających szeroką gamę formatów wideo. Ze
względu na wygodę użytkowania telefony komórkowe stały się popularnym medium biorącym udział w konsumpcji materiałów filmowych.
Aplikacje. W przeciwieństwie do wcześniejszych modeli telefonów komórkowych z klawiaturą na obudowie, smartfony umożliwiają pobieranie i
instalowanie aplikacji autorstwa deweloperów nie związanych z firmami
odpowiedzialnymi za system operacyjny. Deweloperzy na całym świecie mają możliwość samodzielnego stworzenia programu i udostępnienia
go milionom użytkowników na całym świecie. Dzięki temu pojawiło się
wiele niezwykle ciekawych aplikacji, wykorzystywanych w praktycznie
każdej dziedzinie życia.
2.1
Historia systemu operacyjnego Android
Rok po premierze iPhone Open Handset Alliance5 wraz z Google zaprezentowało alternatywę dla systemu autorstwa Apple o nazwie Android6 . Był
to system otwarty i miał być niezależny od platformy sprzętowej. Oznacza
to, że każdy producent telefonów komórkowych na świecie mógł dowolnie
wykorzystywać i modyfikować to oprogramowanie.
Liczba użytkowników telefonów typu Android przewyższała konkurencyjnego Iphona praktycznie od samego początku istnienia tych dwóch systemów
operacyjnych. Tego samego jednak nie można powiedzieć o dochodach ze
sprzedaży generowanych w ramach tych ekosystemów. Użytkownicy iPhona
4
Marketing Land. Mobile devices: 30 percent of traffic, 15 percent of sales, February
28 2014
5
Wikipedia. Open handset alliance — Wikipedia, wolna encyklopedia, 2004
6
Wikipedia. Android (system operacyjny) — Wikipedia, wolna encyklopedia, 2004
9
są przeciętnie bardziej aktywni w ruchu sieciowym oraz chętniej dokonują
płatności w ramach aplikacji generując wyższe zyski twórcom aplikacji7 .
Android należy do rodziny systemów operacyjnych linux przez co obejmuje go licencja GNU8 . Jego pierwotne przeznaczenie obejmowało jedynie
telefony komórkowe wyposażone w ekran dotykowy, jednak gama urządzeń
uległa z biegiem czasu rozszerzeniu o tablety, telewizory i netbooki9 . Obecnie jest to najpopularniejszy system operacyjny na świecie. Liczba urządzeń
działających z jego wykorzystaniem przekroczyła już jakiś czas temu całkowitą ilość komputerów klasy PC.
Platforma Android przeszła długą drogę od momentu pierwszego zaprezentowania jej na rynku komercyjnym. Pierwsza jej wersja nie obsługiwała
nawet ekranu dotykowego i mogła być instalowana wyłącznie na telefonach
z klawiaturą sprzętową. Nie prezentowała się więc bardzo atrakcyjne w zestawieniu z popularnym już na rynku iPhonem. Jednak wraz w wypuszczaniem kolejnych wersji oprogramowania przedmiotowa sytuacja zaczęła się
zmieniać. Stopniowo wprowadzane udoskonalenia to między innymi: obsługa ekranu dotykowego, zaawansowana obsługa multimediów, widżety10 ,
zaawansowana obsługa kamery, narzędzia administracyjne jak i wiele innych.
Ze względu na fakt, że licencja GNU gwarantuje publiczny dostęp do
całości kodu źródłowego i nieograniczone jego wykorzystywanie wiele firm
produkujących telefony komórkowe zaczęło modyfikować go na własne potrzeby. Każdy telefon może posiadać zainstalowany system operacyjny zmodyfikowany na potrzeby dostawcy usług komórkowych czy producenta telefonu.
Jednak każda modyfikacja kodu źródłowego niesie za sobą również negatywne konsekwencje. Z myślą o zapewnieniu unikalnego doświadczenia użytkownika producenci handsetów i innego typu sprzętu wprowadzili na rynek
ogromną ilość urządzeń, które różnią się nie tylko wymiarami wyświetlacza.
Różnice dotykają takich elementów jak na przykład sterowanie kamerą czy
galerią zdjęć. Programiści aplikacji chcąc wspierać wszystkie warianty sprzętowe, zmuszeni są do pisania programów, które na różne sposoby komunikują
się z pewnymi komponentami w zależności od tego na jakim modelu telefonu
zainstalowana jest aplikacja. Niektóre urządzenia wyposażone są w pewne
7
Benjamin Travis.
Android vs. ios: User differences every developer should
know.
http://www.comscore.com/lat/Insights/Blog/Android-vs-iOS-User-DifferencesEvery-Developer-Should-Know, 2013
8
Wikipedia. Gnu general public license — Wikipedia, wolna encyklopedia, 2004
9
Ed Burnette. Hello, Android: Introducing Google’s Mobile Development Platform.
Pragmatic Bookshelf, 2nd edition, 2009, s. 14
10
10
podzespoły takie jak np. lampa błyskowa, inne zaś są ich pozbawione.
Zjawisko fragmentacji to jeden z najważniejszych problemów z jakim muszą poradzić sobie deweloperzy przy tworzeniu oprogramowania11 . Różnice w
uwarunkowaniach sprzętowych stanowią jeden problem, kolejny to różnice w
wersjach systemu operacyjnego. Jedynie niewielka liczba użytkowników korzysta z najnowszej wersji oprogramowania, co sprawia, że twórcy aplikacji
zmuszeni są do wspierania starszych wersji. To z kolei utrudnia proces tworzenia aplikacji i stawia dodatkowe ograniczenia. Większość użytkowników
telefonów z systemem operacyjnym Android nie ma dostępu do nowych funkcjonalności. Jako, że deweloperzy zmuszeni są do wspierania starszych urządzeń, zaproponowane nowe funkcjonalności nie będą wykorzystywane przez
twórców oprogramowania przez długi czas od wprowadzenia ich do narzędzi
deweloperskich. W przypadku handsetów korzystających z systemu operacyjnego IOS zjawisko segmentacji praktycznie nie istnieje. Zdecydowana
większość smartfonów typu iPhone, bo prawie 75%, korzysta z najnowszej
wersji oprogramowania.
Różnic pomiędzy poszczególnymi telefonami jest tak wiele, że temat segmentacji stał się poważnym problemem przy tworzeniu aplikacji pod system
Android. Często w procesie planowania rozwoju oprogramowania, na etapie
założeń projektowych wymienia się kilka konkretnych modeli wspieranych
telefonów. Oznacza to, że przed wprowadzeniem aplikacji na rynek, aplikacja nie będzie przetestowana na większości sprzętów, na których będzie ona
funkcjonować.
Obecnie na rynku istnieje ponad 18 tysięcy modeli telefonów z systemem
operacyjnym Android. Z dnia na dzień liczba ta staje się coraz większa.
Przetestowanie aplikacji w każdym możliwym układzie nie jest możliwe nawet w przypadku najbardziej zagorzałego testera. Ponadto należy wskazać
na fakt, w przedmiocie tego, że większość twórców oprogramowania nie ma
dostępu nawet do reprezentacyjnej gamy telefonów.
Nadto wskazać należy, że nic nie wskazuje na to, jakoby zjawisko segmentacji wśród urządzeń android miałoby się zmniejszyć. Google przyjęło
oficjalne stanowisko wobec tego problemu już przy pierwszych wersjach systemu operacyjnego Android12 . Nie istnieją plany ograniczenia platform sprzętowych na jakich miałby działać system, gdyż byłoby to sprzeczne z założonymi postulatami o otwartości i uniwersalności tego oprogramowania. Pro11
Patrick O’Rourke.
Android’s biggest problem is operating system fragmentation. http://o.canada.com/technology/personal-tech/androids-biggest-problem-isoperating-system-segmentation, 2014
12
Kit Eaton.
Google isn’t defending android from segmentation—a secret
success plan.
http://www.fastcompany.com/1745417/google-isnt-defending-androidsegmentation-secret-success-plan, 2011
11
(a) Różnice wielkości ekranów(b) Różnice wielkości ekranów
wśród urządzeń Androi.
wśród urządzeń rodziny Apple.
Rysunek 4: Różnice w wielkościach ekranów w telefonach z systemem operacyjnym Android i OSX.
blem segmentacji jest więc nieuniknionym skutkiem ubocznym przyjętej we
wczesnych fazach rozwoju strategii.
Tworzenie aplikacji przy tak ogromnej różnorodności wyświetlaczy to nie
lada wyzwanie. Nie dość, że nie istnieje ściśle sprecyzowana szerokość i wysokość wyświetlacza jaką urządzenie powinno posiadać, to każdy wyświetlacz
może obsługiwać różną rozdzielczość, przez co inaczej wyświetlać będzie obrazy i grafikę a także kolory oraz animacje.
Konkurencyjny na rynku system IOS jest pod tym względem o wiele bardziej przewidywalny. Tutaj mamy do czynienia zaledwie z pięcioma różnymi
wyświetlaczami. Nie stanowi dużego wyzwania sprawdzenie jak aplikacja zachowuje się na każdym dostępnym urządzeniu.
Narzędzia deweloperskie na platformę Android wyposażone są w całą
gamę emulatorów pozwalających deweloperowi na uruchomienie wirtualnej
maszyny w dowolnie wybranej przez siebie konfiguracji. Bardzo popularny
wśród developerów emulator o nazwie Genymotion13 pozwala na uruchomienie wielu popularnych konfiguracji systemowych przy wykorzystaniu wirtualnej maszyny bezpośrednio na komputerze. Z całą pewnością ułatwia to pracę
nad oprogramowaniem, jednak nie daje gwarancji na to, że urządzenie w
ręku użytkownika będzie zachowywało się analogicznie. Genymotion wykorzystuje wirtualne zasoby sprzętowe procesora i pamięci operacyjnej, przez
co szybciej wykonuje zasobochłonne obliczenia. Jego odpowiednik sprzętowy
w tej samej sytuacji może zgłaszać błąd z powodu całkowitego wykorzystania
pamięci operacyjnej lub zbyt dużego obciążenia procesora.
Kolejnym mankamentem dostępnych emulatorów Genymotion jest brak
zainstalowanych na nich Google Play Services. W świecie wirtualnym coraz
13
William J. Francis.
Speed up your android development cycle with genymotion.
http://www.techrepublic.com/blog/software-engineer/speed-up-your-androiddevelopment-cycle-with-genymotion/, 2013
12
rzadziej spotykamy aplikacje, które funkcjonują samodzielnie bez połączenia
z innymi usługami oraz serwisami. Normalnym jest chociażby to, że aby
zalogować się do aplikacji webowej czy mobilnej twórcy aplikacji dali nam do
wyboru możliwość utworzenia konta na podstawie naszego profilu Facebook
czy Google Plus. Google Play Services są obarczone licencjami, które obecnie
wykluczają możliwość zainstalowania ich na emulatorach. Przetestowanie
następujących usług wymaga więc fizycznego dostępu do urządzenia lub też
użycia zawodnych emulatorów dostępnych w ramach narzędzi deweloperskich
Google AVD14 .
Do głównych usług, które nie są dostępne w ramach emulatorów Genymotion należy zaliczyć:
Location APIs. Usługa pozwala na wykorzystanie informacji na temat lokalizacji użytkownika czy wykorzystania Google Maps wewnątrz aplikacji. Dzięki usłudze można modyfikować działanie aplikacji na podstawie
geograficznego położenia urządzenia.
Google Play Game Services. Twórcy aplikacji mogą wykorzystać tą usługę
do tworzenia bardziej społecznego środowiska gry przez osiągnięcia
(Achievements), tablice wyników (Social and public leaderboards), zapisywanie stanu gry w chmurze (Cloud saves) oraz bibliotekę umożliwiającą stworzenie multiplayera czasu rzeczywistego przy wykorzystaniu platformy Google+ (Real-time multiplayer)15 .
Google+. Usługa umożliwia identyfikację użytkownika bez konieczności wieloetapowego procesu rejestracji za pomocą skrzynki email. Użytkownicy automatycznie logują się do aplikacji przy wykorzystaniu danych
platformy Google+.
Mapy Google. Usługa pozwala na umieszczenie wewnątrz aplikacji map
Google oraz Google Street View. Na warstwie widoku komponentów
developerzy są w stanie nanosić dodatkowe elementy takie jak np. markery czy znaczniki obszaru.
Google Wallet. Usługa mająca na celu ułatwienie dokonywania płatności
wewnątrz aplikacji. Przy wykorzystaniu tej usługi można znacznie zredukować czas jaki użytkownik poświęca na przekazanie środków i zdecydowanie uprościć proces transferu środków.
14
Wikipedia. Google play services — Wikipedia, wolna encyklopedia, 2004
Greg
Hartrell.
Introducing
google
play
game
http://googledevelopers.blogspot.com/2013/05/introducing-google-play-gameservices.html, 2013
15
13
services.
Inne takie jak Google Drive, Google Cast i Google Ads.
Jako, że sam tworzę oprogramowanie na platformę Android, opisywane
powyżej problemy są mi doskonale znane. Wielokrotnie zdarzała się w mojej pracy sytuacja w przedmiocie tego, że aplikacja zgłaszała błąd, bądź nie
wykonywała konkretnej funkcji na pojedynczym modelu telefonu. Problem
stawał się szczególnie dotkliwy wtedy, kiedy dany model smartfona nie był
dla mnie fizycznie dostępny, wówczas naprawianie tego rodzaju błędu jest niezwykle uciążliwe. Trzeba bowiem albo zdobyć podobny telefon, co wiąże się
z kosztami, albo “po omacku”, domyślając się w którym miejscu jest problem
wprowadzać zmiany i konsultować z klientem czy problem został rozwiązany.
Pomysł na stworzenie aplikacji, która jest przedmiotem mojej pracy zrodził się już dawno temu. Chciałem mieć możliwość wypożyczenia telefonu
dosłownie na kilkadziesiąt minut, żeby zainstalować na nim moją aplikację i
sprawdzić w którym miejscu zgłaszany jest błąd i czy wprowadzone zmiany
go rozwiązują.
2.2
Analiza podobnych rozwiązań dostępnych na rynku
Na rynku istnieją już rozwiązania zaprojektowane z myślą o rozwiązaniu tego
problemu. Zazwyczaj jednak opierają się wyłącznie na przeprowadzaniu testów automatycznych16 . Rozwiązania te cieszą się dużą popularnością szczególnie wśród dużych firm zatrudniających profesjonalnych testerów, jednak
nie są one powszechnie stosowane przy małych projektach.
Przygotowanie testów automatycznych jest zajęciem czasochłonnym, wymagającym dużego nakładu pracy. Poza tym pisanie ich wymaga posiadania
określonej wiedzy ze strony testera oraz przygotowania merytorycznego. Ponadto podkreślenia wymaga fakt, że testy automatyczne często nie mogą
zastąpić testów manualnych, gdyż kompilatory bardzo często mają problemy
z interpretowaniem pewnych informacji.
Xamarin Cloud17 to rozwiązanie bazujące na testach automatycznych w
chmurze. Użytkownik wysyła na serwer aplikację, którą chce przetestować
oraz aplikację przeznaczoną do testowania tej pierwszej. W następnym kroku
testy są uruchamiane na wszystkich dostępnych urządzeniach, po wykonaniu których generowany jest raport i wysyłany z powrotem do użytkownika.
Osoba testująca nie ma więc możliwości manualnego testowania aplikacji przy
wykorzystaniu tego rozwiązania. Niedostępny jest również podgląd wykonywanych na telefonie operacji. Bowiem użytkownik otrzymuje jedynie zrzuty
16
Marek
Konera.
Wprowadzenie
do
testów
automatycznych.
http://kainos.pl/blog/wprowadzenie-do-testow-automatycznych-czesc-1/
17
Xamarin. Xamarin test cloud. http://xamarin.com/test-cloud
14
ekranu na poszczególnych etapach wykonywania testów automatycznych.
Najprawdopodobniej jedynym dostępnym w sieci rozwiązaniem oferującym możliwość wykonywania testów manualnych w chmurze jest Keynote
Mobile Testing tools18 . Rozwiązanie to pozwala na połączenie się z prawdziwym telefonem podłączonym do serwera, instalowanie na nim dowolnej aplikacji i przeprowadzanie testów manualnych. Dodatkowo posiada zestaw narzędzi pozwalających na dogłębną analizę procesów wykonywanych na urządzeniu, struktury widoków i innych aspektów urządzenia w czasie rzeczywistym.
3
Projekt Systemu
3.1
Dziedzina problemowa
Stworzony przeze mnie system może zostać zaimplementowany przy tworzeniu serwisu, który można określić jako "Platforma testów manualnych
natywnych aplikacji Android". Mam na myśli usługę www oferującą możliwość wykupienia dostępu do urządzenia przez internet. Użytkownik miałby
logować się do systemu i uzyskiwać dostęp do telefonu, którego podgląd uzyskiwałby w oknie przeglądarki. Sterowanie urządzeniem odbywałoby się przy
zastosowaniu kursora myszy, podobnie jak w przypadku emulatorów. Moja
praca ogranicza się jedynie do stworzenia interfejsu w celu komunikacji z
urządzeniem android przy użyciu przeglądarki internetowej jednakże kolejne
funkcjonalności w pełni komercyjnego systemu wykraczają poza jej zakres.
Do stworzenia aplikacji niezbędna była znajomość następujących zagadnień:
1. Programowanie w językach PHP (serwer), JavaScript (frontend) i Java
(android)
2. Programowanie urządzeń mobilnych i administracja serwera web oraz
bazy danych MySQL.
3. Tworzenie skryptów bash wykonujących polecenia na urządzeniu android przy użyciu programu adb (Android Debug Bridge).
4. Projektowanie interfejsu użytkownika przy użyciu HTML5 i CSS3
18
Keynote. Keynote mobile testing tools. http://www.keynote.com/solutions/testing/mobiletesting
15
3.2
Cel systemu
Celem systemu jest umożliwienie użytkownikowi obsługę telefonu z systemem
operacyjnym Android przy pośrednictwie przeglądarki internetowej. Użytkownik ma możliwość zainstalowania dowolnej aplikacji na urządzeniu i wykonywanie podstawowych czynności, takich jak kliknięcie w dowolne miejsce
na ekranie czy klawisz znajdujący się na obudowie telefonu. Użytkownik
dzięki systemowi będzie w stanie przetestować stworzoną przez siebie aplikację na urządzeniu bez konieczności posiadania fizycznego dostępu do niego.
System spełni swoje funkcje, jeżeli umożliwi użytkownikowi:
1. Wysłanie pliku APK na serwer i zainstalowanie aplikacji na urządzeniu
Android.
2. Kliknięcie w dowolne miejsce na ekranie i wywołanie akcji na urządzeniu."
3. Wykonanie gestu swipe w lewo, prawo, do góry i w dół. Dodatkowo
użytkownik powinien mieć możliwość przekazania współrzędnej początkowej i końcowej wykonywanego gestu.
4. Kliknięcie w dowolny guzik znajdujący się na obudowie telefonu, czyli
kolejno: Home, Back, Menu, Power, Volume Up, Volume Down.
3.3
Zakres odpowiedzialności systemu
Zadaniem systemu jest udostępnianie interfejsu do sterowania telefonem Android przez sieć internetową. Korzystanie z interfejsu odbywa się przy wykorzystaniu przeglądarki internetowej.System powinien dostarczyć użytkownikowi następujących informacji
1. Czy stworzona przez niego aplikacja uruchamia się na danym urządzeniu
2. Czy aplikacja nie zgłasza błędu podczas przechodzenia pomiędzy ekranami, przejśca do innej aplikacji czy wprowadzenie jej w stan uśpienia.
3. Jak aplikacja zachowuje się w połączeniu z innymi aplikacjami dostępnymi na danym modelu telefonu, takimi jak odtwarzacz muzyki, aplikacja do wyświetlania plików w formacie pdf, wysyłania wiadomości
email i inne.
4. Jak aplikacja wygląda na danym urządzeniu przy wykorzystaniu dostępnych komponentów systemu android, przy konkretnym modelu wyświetlacza o danej rozdzielczości i zagęszczeniu pikseli.
16
Przy wykorzystaniu kamery internetowej system ma udostępniać aktualnie wyświetlany obraz na ekranie urządzenia. System odbiera od użytkownika
żądania wykonania operacji na telefonie i symuluje ich wywołanie.
Poza zakresem Do odpowiedzialności systemu należą:
1. Udostępnianie interfejsu do debuggowania za pomocą konsoli logcat19 .
2. Umożliwianie użytkownikowi jak również administratorowi systemu na
przywrócenie ustawień początkowych telefonu za pomocą narzędzia
bmgr20 .
3. Umożliwienie robienia zrzutów ekranu oraz nagrywania filmów video
bezpośrednio z urządzenia.
4. Udostępnienie konsoli służącej do debuggowania pamięci operacyjnej
i procesów działających w zakresie danej aplikacji przy pomocy programu DDMS21 .
5. Umożliwianie zmiany orientacji telefonu z pozycji pionowej do pionowej
i odwrotnie.
3.4
Użytkownicy systemu
Użytkownik systemu to zazwyczaj programista aplikacji mobilnych na platformę Android. Do grupy odbiorców można zaliczyć również osoby zlecające
wykonanie aplikacji zewnętrznym podmiotom, których to zadaniem jest zweryfikowanie poprawnego wytworzenia oprogramowania.
Prototyp systemu nie znajdzie wykorzystania na rynku komercyjnym, ma
on jedynie służyć w celach poglądowych, które mają stanowić podstawę do
stworzenia rozbudowanego systemu z którego mogą korzystać osoby na całym
świecie.
Aplikacja dostępna jest w sieci internetowej pod adresem http://rafalmanka.ddns.net/.
Jej funkcjonalność pozwala na wykonywanie operacji na telefonie, jednak nie
jest wyposażona w takie elementy jak: zarządzanie kontem użytkownika,
przydzielanie czasu dostępu do urządzenia czy system płatności. Poza tym
użytkownik ma dostęp wyłącznie do jednego modelu telefonu.
19
Android Community. logcat. http://developer.android.com/tools/help/logcat.html
Android Community. bmgr. http://developer.android.com/tools/help/bmgr.html
21
Android Community. Using ddms. http://developer.android.com/tools/debugging/ddms.html
20
17
3.5
3.5.1
Wymagania wobec systemu
Wymagania funkcjonalne
System powinien udostępniać podgląd z kamery skierowanej na urządzenie i
wyświetlać jego stan w czasie rzeczywistym. Opóźnienie w czasie pomiędzy
wywołaniem zdarzenia a reakcją urządzenia powinno być na tyle niewielkie,
żeby możliwe było normalne użytkowanie sprzętu.
Gdy użytkownik zainstaluje na urządzeniu dowolną aplikację, ma się ona
automatycznie uruchomić i wyświetlić na ekranie wyświetlacza automatycznie.
System musi pośredniczyć w wykonywaniu operacji pomiędzy użytkownikiem a telefonem Android. Jego kluczowym zadaniem jest umożliwienie
użytkownikowi wysłanie aplikacji w formacie APK na serwer i automatyczne
zainstalowanie tej aplikacji na telefonie.
System powinien zwracać użytkownikowi informacje o wszelakich błędach, które pojawiły się podczas instalowania aplikacji jak również podczas
samego użytkowania telefonu.
Obecne ustawienie serwera umożliwia wykonywanie operacji wyłączenie
na danym urządzeniu. Jednak podłączenie innego typu telefonu do serwera
wymagałoby niewielkich modyfikacji w kodzie źródłowym. Każde urządzenie
Android przyjmuje informacje o zdarzeniach przy pomocy polecenia w pakiecie adb o nazwie sendevent. Jednak parametr, który determinuje to czy
polecenie wysłane jest do ekranu dotykowego, czy do urządzenia GPS, czy
klawiatury zewnętrznej może być inny w każdym urządzeniu . Dostosowanie
serwera pod inny telefon wymagało by więc niewielkiego nakładu pracy.
W przypadku odcięcia prądu od serwera system powinien automatycznie
powrócić do ustawień początkowych w momencie, kiedy zasilanie zostanie
przywrócone.
Administrator systemu powinien mieć możliwość przywrócenia urządzenia i ustawień serwera do wartości początkowych w przypadku włamania się
na serwer przez osoby trzecie, lub tez w przypadku fizycznego rozregulowania
zestawu np. przesunięcie kamery względem telefonu.
3.5.2
Wymagania niefunkcjonalne
System powinien wykorzystywać technologię udostępnianą przez popularne
przeglądarki internetowe. Jako, że technologia flash nie jest już wspierana,
frontendowa część systemu powinna być zbudowana w oparciu o technologię
HTML5, JavaScript i CSS3.
Serwer powinien umożliwiać komunikację http z przeglądarką internetową
po stronie klienta jak również umożliwiać komunikację przy pomocy techno18
logii AJAX. Wykonywanie poleceń w przeglądarce internetowej nie powinno
wiązać się z koniecznością przeładowania całej strony internetowej.
3.6
Klasa "Biznesowa"Telefon
jedyną klasą biznesową w systemie jest klasa "Telefon"w aplikacji "Wypożyczalnia telefonów Android". Podkreślić należy, że wszystkie pozostałe są
klasycznie związane z modelem biznesowym aplikacji, i wykorzystywane są
do obsługi systemu. Atrybuty obiektu klasy Telefon:
• id
• name
• current-installs (lista nazw pakietów obecnie zainstalowanych aplikacji)
• default-packages (lista nazw pakietów aplikacji zainstalowanych fabrycznie na urządzeniu)
• settings (pole tekstowe przechowujące obiekt JSON w formacie tekstowym. W nim przechowywane są informacja na temat parametrów
urządzenia takie jak jego rozdzielczność, wielkość ekranu itp.)
Rysunek 5: Przykładowa wartość pola settings.
Atrybuty klasowe: Wszystkie atrybuty klasowe zostały usunięte i ich funkcję
przejął atrybut śettingsą w klasie roślina. Ta decyzja projektowa ma na celu
przystosowanie systemu do tego, że w przyszłości będzie wykorzystywany w
połączeniu z wieloma różnymi telefonami z systemem Android, które posiadają inne parametry i ustawienia.
19
3.7
Diagram przypadków użycia
Rysunek 6: Diagram przypadków użycia aplikacji "Wypożyczalnia telefonów
Android".
3.8
3.8.1
Decyzje projektowe
Wybór technologii w której stworzony będzie interfejs użytkownika
Wybierając technologię która pozwoli mi na stworzenie interfejsu użytkownika miałem do wyboru wiele technologii. Pozwolę sobie opisać trzy najciekawsze, wymienić ich zalety oraz wady jak również uzasadnić dlaczego
zdecydowałem się na wykorzystanie jednej z nich.
Natywna aplikacja desktopowa. Aplikacje natywne są naturalnym
komponentem każdego systemu operacyjnego. Działają one bezpośrednio na
20
warstwie systemu i działają zgodnie z założeniami twórców systemu. Główna
korzyść takiego rozwiązania to wydajność, niezależnie od tego czy piszemy
na platformę Windows, Linux czy OSX mamy do dyspozycji natywne komponenty systemowe do wykorzystania, które pozwalają na stworzenie działającej szybko aplikacji, co pozytywnie wpływa na wrażenia użytkownika. Kolejnym ważnym aspektem jest to, że aplikacja tego typu wygląda jak część
systemu. Standardowe elementy takie jak menu, czy pasek zadań pozwalają
zachować spójność aplikacji z resztą środowiska.
Jednak niewątpliwym minusem tego rozwiązania jest konieczność stworzenia trzech niezależnych aplikacji od podstaw, żeby pokryć wszystkie platformy sprzętowe jakimi posługiwać się będzie potencjalny użytkownik. Założeniem projektu było, żeby aplikacja była dostępna dla użytkowników każdej
platformy sprzętowej niezależnie od tego czy osoba korzystająca z aplikacji
posługuje się systemem operacyjnym Windows, Linux, czy OSX. Aplikacja
na platformę Windows wymagałaby znajomości języka C-sharp i środowiska developerskiego Visual Studio, aplikacja na Linuxa wymagałaby użycia
Pythona lub QT, zaś oprogramowanie na system operacyjny OSX wymagałoby wykorzystania Objective-C. Oczywiście zawsze można byłoby stworzyć
oprogramowanie wyłącznie na platformę Windows, co zaspokoiłoby potrzeby
większości użytkowników, jednak duża ich znaczna część nie byłaby w stanie
skorzystać z naszego rozwiązania.
Uniwersjalna aplikacja desktopowa. Tworzenie uniwersalnych aplikacji w oparciu o język programowani było możliwe już od dawna. Użytkownik żeby korzystać z aplikacji desktopowej napisanej w Javie musiał jedynie
zainstalować na komputerze wirtualną maszynę i mógł korzystać z aplikacji niezależnie od platformy. W ostatnich latach na popularności zyskały
aplikacje oparte o NodeJS, który w niektórych aspektach posiada przewagę
na Javą. Napisanie mojej aplikacji w oparciu o język Java albo JavaScript
umożliwiłoby mi stworzenie uniwersalnej aplikacji do zainstalowania na dowolnym systemie operacyjnym co niewątpliwie przyspieszyłoby proces tworzenia oprogramowania.
Niestety do minusów tego rozwiązania niewątpliwie należy zaliczyć konieczność dostosowania aplikacji do wszystkich systemów operacyjnych. To
samo dotyczy debuggowania. Na każdym systemie operacyjnym aplikacja będzie działała troszeczkę inaczej i będziemy doświadczali innych problemów
co prowadzi ponownie do tego samego problemu jak w pierwszym rozwiązaniu. Kolejną kwestią negatywną, którą chciałem poruszyć, to sam proces
instalowania aplikacji na komputerze użytkownika. Ludzie bardzo niechętnie instalują na swoim sprzęcie oprogramowanie nieznanego pochodzenia w
obawia przed wirusami. Każdy użytkownik, który zrezygnuje z możliwości
skorzystania z mojego oprogramowania niewątpliwie będzie stratny.
21
Aplikacja webowa. Technologie webowe takie jak HTML5 i JavaScript
pozwalają na zastosowanie prawdziwie zaawansowanych rozwiązań, które w
niektórych aspektach mogą dorównywać lub nawet zastępować aplikacje desktopowe. Tworzona przeze mnie aplikacja nie wymaga zaawansowanych obliczeń graficznych, czy korzystania z komponentów systemowych czy z bazy
danych na komputerze użytkownika. Możliwości jakie daje JavaScript w zupełności wystarczą mi na to, żeby stworzyć wygodny interfejs użytkownika.
W tworzonej przeze mnie aplikacji wymagane jest nieustanne połączenie
z internetem bowiem Użytkownik wykonuje operacje na telefonie, który znajduje się po stronie serwera. Największym mankamentem aplikacji webowych
była do tej pory konieczność nieustannego połączenia z internetem podczas
korzystania z oprogramowania. Ze względu na coraz to większą powszechność internetu staje się to mniejszym problemem dla wielu użytkowników.
Jednakże połączenie z internetem zawsze będzie warunkowało szybkość działania aplikacji. W przypadku mojego rozwiązania aplikacja desktopowa również działałaby wyłącznie przy stałym połączeniu z serwerem, więc problem
ten dotyczy mnie równie mocno niezależnie od wybranego rozwiązania.
Kolejną zaletą interfejsu webowego była dla mnie znajomość tej technologii. W przeszłości napisałem kilka stron internetowych i przyglądałem się
różnego typu rozwiązaniom, które pojawiły się w tym obszarze w przeciągu
kilku lat. W porównaniu z innymi rozwiązaniami które opisałem wcześniej,
zdecydowanie najbardziej komfortowo czuję się pisząc interfejs webowy i jestem przekonany o tym, że jakość wyprodukowanego przeze mnie kodu będzie
o wiele lepsza niż w przypadku gdybym miał się posługiwać językiem programowania, z którym nigdy wcześniej nie miałem styczności.
Jednakże nie należy pominąć negatywnych cech przedmiotowego rozwiązania. Na rynku znajduje się całe multum przeglądarek internetowych, rozwijanych od wielu lat zupełnie od siebie niezależnie. Każda przeglądarka w
teorii interpretuje kod HTML5 i JavaScript jednakowo, jednak w praktyce
okazuje się, że aplikacja czasami zachowuje się inaczej w każdej z nich. Wybranie technologii webowej wiązać się więc będzie z koniecznością wprowadzenia poprawek w kodzie dostosowujących aplikację do konkretnej przeglądarki
internetowej żeby uzyskać jej spójność.
3.9
Wybór protokołu komunikacji serwer - klient.
Przeglądarki internetowe potrafią komunikować się z serwerem na wiele sposobów. Najbardziej popularne są żądania Http typu GET, które wywoływane są bezpośrednio z kodu HTML. Co raz bardziej jednak na popularności
zyskuje technologia AJAX,również posługujący się protokołem http. Wykorzystywana jest ona przede wszystkim przy tworzeniu coraz to bardziej
22
popularnych aplikacji typu single page. Jednak protokół Http nie jest jedynym sposobem w jaki interfejs użytkownika może komunikować się z serwerem. Przy tworzeniu mojej aplikacji zastanawiałem się nad wykorzystaniem
trzech protokołów:
UDP. W porównaniu do http jest szybszy ale za to bardziej zawodny. Wykorzystywany jedynie w niewielkim stopniu przy tworzeniu aplikacji webowych. JavaScript nie umożliwia komunikacji przy użyciu protokołu
UDP, konieczne jest w tym przypadku posłużenie się chociażby językiem Cold Fusion22 . Takie zapytanie może wyglądać jak w poniższym
przykładzie.
Listing 1: Przykład żądania UDP w języku Cold Fusion.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
< cfscript >
...
try {
packet = createObject ( " java " , " java . net .
DatagramPacket " ) . init (
charsetDecode ( message , " utf -8 " ) ,
javaCast ( " int " , len ( " Hello world ! " ) ) ,
remoteInetAddress ,
remotePort
);
socket . send ( packet ) ;
...
} catch ( any error ) {
} finally {
socket . close () ;
}
</ cfscript >
22
Ben Nadel. Sending and receiving udp (user datagram protocol) messages with coldfusion. http://www.bennadel.com/blog/2579-sending-and-receiving-udp-user-datagramprotocol-messages-with-coldfusion.htm, 2014
23
RTP. Real-time Transport Protocol wykorzystywany jest współcześnie głównie w komunikacji VoIP oraz telekonferencjach23 . Podejmowano próby
wykorzystania tego protokołu do komunikacji przy pośrednictwie przeglądarki internetowej, czego przykładem może być biblioteka Meeting.js24 .
Technologia ta jednak nie jest wykorzystywana do komunikacji innej niż
audio i wideo.
Http. Protokół ten stanowi standard w komunikowaniu się przeglądarki internetowej z serwerem25 . Obsługiwany przez każdą współczesną przeglądarkę język JavaScript wspiera wyłącznie ten protokół. Ponadto
od początku powstania technologii webowych powstało wiele bibliotek,
które dodatkowo upraszczają tworzenie zapytań tego typu.Przykładowe
zapytanie z wykorzystaniem biblioteki jQuery może wyglądać jak na
poniższym listingu.
Listing 2: Przykład żądania AJAX w języku JavaScript.
1
2
3
4
5
6
7
8
9
< script type = ’ text / javascript ’ >
$ ( " button " ) . click ( function () {
$ . ajax ({ url : " demo_test . txt " , success : function (
result ) {
$ ( " # div1 " ) . html ( result ) ;
}}) ;
}) ;
</ script >
W celu zrealizowanie mojego projektu zdecydowałem się na wykorzystanie protokołu http wspierany natywnie przez język JavaScript. Moją decyzję motywowałem faktem, że ten sposób komunikacji jest wspierany przez
wszystkie popularne przeglądarki już od wielu lat. Dzięki temu istnieje mniejsze prawdopodobieństwo wystąpienia błędu biblioteki pośredniczącej w komunikacji, jak również
3.9.1
Wybór technologii do stworzenia części aplikacji działającej
po stronie serwera.
Istnieje duża ilość technologii, które można wykorzystać w celu stworzenia
aplikacji działającej po stronie serwera. Każde rozwiązanie posiada swoje
23
Wikipedia. Real-time transport protocol — Wikipedia, wolna encyklopedia, 2004
Meeting.js. Meeting.js » a webrtc library for media streaming
25
Wikipedia. Hypertext transfer protocol — Wikipedia, wolna encyklopedia, 2004
24
24
wady i zalety. W związku z powyższym niewątpliwie podjęcie decyzji odnośnie wyboru rozwiązania, które byłoby najbardziej efektywne, nie należało
do prostych.
W tym miejscu należałoby wspomnieć, że aplikacja "Wypożyczalnia telefonów android"działa w niestandardowych jak na aplikację webową warunkach. Centralnym elementem aplikacji jest obraz z kamery który jest udostępniany do sieci. Potrzebny jest więc serwer http, który będzie pobierał
obraz z kamery i wysyłał go do sieci. Nie mogłem więc wykorzystać usługi
hostingowej zewnętrznego dostawcy takiego jak OVH, DigitalOcean, Google
App Engine czy Amazon Web Services. Serwer który mogłem wykorzystać
musiał mieć bezpośrednie połączenie z kamerą.
Jednakże pozytywnym aspektem był niewątpliwie fakt w przedmiocie
dość niedrogiego rozwiązania, które mogłem wykorzystać, a mianowicie Raspberry Pi w zestawieniu z dedykowanym do tego urządzenia modułem
kamery. Przy użyciu Raspberry Pi byłem w stanie stworzyć w pełni niezależny serwer www u siebie w domu, który zarówno udostępnia obraz kamery
jak również symuluje operacje na telefonie przy wykorzystaniu programu
ADB (Android Debug Bridge).
W następnym etapie jednak należało wybrać technologię, która posłuży
mi do napisania aplikacji po stronie serwera. Pozwolę sobie opisać trzy technologie, które wydawały mi się najciekawsze i nad którymi zastanawiałem
się najbardziej.
Java. Język ten od wielu lat używany jest powszechnie do tworzenia
profesjonalnych aplikacji webowych. Dzięki ogromnej ilości bibliotek i frameworków takich jak Spring tworzenie naprawdę zaawansowanych aplikacji
odbywa się przy stosunkowo niewielkim nakładzie pracy. Java jest językiem
kompilowanym, więc część błędów programistycznych wykrywanych jest na
poziomie kompilacji. Poza tym Java jest językiem, który dobrze się skaluje.
Jednak największym mankamentem tej technologii jest fakt, że aplikacje
zbudowane na bazie Javy działają na wirtualnej maszynie, wykorzystując
większą ilość zasobów pamięci i mocy obliczeniowej niż innego typu rozwiązania. Serwer, który miałem do dyspozycji posiada 512MB pamięci ram, dodatkowo był on obciążony przez obsługę kamery skierowanej na telefon.Przy
pewnym obciążeniu serwera mogłoby się okazać, że serwer którym dysponuję
jest zbyt słaby, żeby obsłużyć wszystkie zadania. Był to więc główny powód
dlaczego nie zdecydowałem się użyć tej technologii.
Python. Raspberry Pi zrzesza niezwykle liczną rzeszę deweloperów, którzy poświęcają swój prywatny czas budując aplikacje do wykorzystania przez
innych. Najpopularniejszym językiem programowania wykorzystywanym do
tworzenia takich aplikacji jest Python, który w środowisku linux stanowi
standard. Decydując się na to rozwiązanie mogłem liczyć na obszerne źró25
dło informacji z którego mogę korzystać jak również wsparcie społeczności,
a nawet pomoc w pewnych przypadkach.
Jednakże język Python nie jest mi znany. Nigdy nie posługiwałem się
tym językiem i przed przystąpieniem do tworzenia oprogramowania byłbym
zmuszony do zaznajomienia się z nim przynajmniej w niewielkim stopniu.
PHP. Obecnie jest to najpopularniejszy język programowania wykorzystywany do tworzenia stron internetowych. Tworzenie prostych aplikacji wykorzystując ten język odbywa się stosunkowo szybko i niewielkim kosztem.
Niestety język PHP znany jest z tego, że aplikacje napisane z jego wykorzystaniem nie skalują się zbyt dobrze. Przy pewnym stopniu skomplikowania
struktury logicznej dochodzi do znacznego obciążenia serwera. Jest to problem, który również tyczy się języka Python i innych języków skryptowych.
Jednak zdecydowałem się właśnie na wykorzystanie tego języka głownie
ze względu na to, że jestem z nim zaznajomiony. W przeszłości wykorzystywałem go już do tworzenia aplikacji i wydaje mi się, że w zestawieniu z
innymi dostępnymi rozwiązaniami jest to rozsądny wybór.
Od momentu kiedy zacząłem pracę nad prezentowanym przeze mnie projektem, pojawił się na rynku nowy model Raspberry Pi 2 o wyposażony w 4
rdzeoniowy procesor o mocy 900MHz i pamięci RAM 1GB. Takie parametry
sprzętowe pozwalają już na wykorzystanie go jako serwera aplikacji opartych
o Javę26 , więc w przyszłości planuję przepisać serwerową część aplikacji na
język Java.
Rysunek 7: Raspberry Pi 2.
26
Oracle. System requirements. http://www.oracle.com/technetwork/java/javaee/documentation/javaee7sdkreadme-1957703.html
26
3.9.2
Wybór narzędzia za pomocą którego przekazywany będzie
obraz aktualnie wyświetlany na urządzeniu z systemem Android.
Żeby spełnić założenia aplikacji musiałem znaleźć sposób na to, żeby przechwycić obecnie wyświetlany obraz na telefonie i przekazać go na użytek
aplikacji działającej po stronie serwera. Zastanawiałem się nad dwoma sposobami, jak można byłoby to zadanie zrealizować.
Przed przystąpieniem do tworzenia aplikacji jak również w czasie jego
trwania aktywnie badałem rynek w poszukiwaniu rozwiązań, które mogą stanowić alternatywę i konkurencje do mojego. Najbardziej zbliżonym rozwiązaniem do mojego jest platforma Device Everywhere stworzona przez firmę
Keynote27 . Twórcy tego rozwiązania zdecydowali się na rozwiązanie, które
opiera się o przechwytywanie obrazu płynącego do wyświetlacza i przekierowywanie go do przeglądarki internetowej użytkownika.
Pragnę wskazać na dwie wady zastosowania takiego rozwiązania. Przechwycenie obrazu jest pewnego rodzaju ingerencją w funkcjonowanie urządzenia, moim celem było dostarczenie wrażenia użytkowania telefonu możliwie
najbardziej zbliżonego do rzeczywistego doświadczenia.
Kolejnym problemem było dla mnie to, że obecnie narzędzia deweloperskie nie umożliwiają nieprzechwytywania obrazu. Wymagałoby to ode mnie
napisania własnego kontrollera, który by to umożliwiał jak również podłączenie go do modułu wyświetlacza w telefonie fizycznie, co mogłoby uszkodzić
urządzenie.
Oba wymienione przeze mnie sposoby pobierania aktualnego stanu wyświetlacza wzajemnie się nie wykluczają. System w kolejnych fazach rozwojowych nie wyklucza funkcjonalności pozwalającej użytkownikowi przemieszczać się pomiędzy dwoma widokami: kamery oraz wyświetlacza.
3.9.3
Komunikacja serwera z telefonem android
Nie miałem dużego wyboru jeżeli chodzi o komunikację serwer-telefon. ADB
(Android Debug Bridge) to uniwersalne narzędzie służące do komunikacji
z telefonem Android za pomocą linii poleceń. Znajduje się ono w pakiecie
narzędzi deweloperskich niezbędnych do tworzenia oprogramowania na platformę Android. Składa się ono z trzech głównych komponentów:
27
Gordon Makryllos.
devices everywhere – it’s time for mobile device management as a service.
http://www.orange-business.com/en/blogs/connectingtechnology/innovation/devices-devices-devices-everywhere-it-s-time-for-next-generationmobile-device-management-as-a-service, 2014
27
1. Klienta, który zainstalowany jest na komputerze i który wysyła polecenia do telefonu.
2. Serwera, który działa w tle systemu i który zarządza aktualnie podłączonymi do serwera urządzeniami.
3. Daemona, który działa na telefonie z androidem jako proces w tle.
Za pomocą programu ADB możliwe jest symulowanie różnego rodzaju zdarzeń na telefonie za pomocą polecenia bash o nazwie sendevent. W moim
systemie umożliwiłem użytkownikowi wykonywanie następujących poleceń
an telefonie:
1. Kliknięcie w guzik znajdujący się na obudowie. Na każdym telefonie
android znajdują się następujące guziki: Power, Back, Menu, Home,
Volume up i Volume down.
2. Kliknięcie w dowolne miejsce na ekranie
3. Wykonanie gestów: Swipe left, Swipe right, Swipe up, Swipe down.
Za pomocą tych gestów możliwe jest normalne użytkowanie telefonu dokładnie w taki sposób jakby użytkownik trzymał urządzenie w ręku.
4
Budowa systemu
Rysunek 8: Finalna wersja systemu.
28
4.1
4.1.1
Komponenty systemu
Sprzęt
Raspberry Pi model B+
Rysunek 9: Raspberry Pi model B+.
Komputer stworzony przez Raspberry Pi Foundation. Jest to następca
niezwykle popularnej jednostki Raspberry Pi Model B, który zadebiutował
na rynku w lipcu 2014 roku.
Komputer wyróżnia się swoim niezwykle małym rozmiarem, gdyż ma szerokość zbliżoną do dowodu osobistego czy karty płatniczej. Jego wymiary to
85,60 × 53,98 mm a waga, to 45g. Obsługuje wiele systemów operacyjnych z
rodziny linux, takie jak Debian GNU/Linux, Fedora, Arch Linux i FreeBSD,
jednak najpopularniejsza na tą platformę stała się dedykowana dystrybucja
linuxa o nazwie Raspbian.
Jego kolejnym ogromnym atutem jest cena, gdyż na allegro można go
kupić za cenę oscylującą na poziomie 100 zł. Urządzenie to zrzesza ogromną
liczbę fanatyków, którzy wykorzystują ten komputer na wiele sposobów. Jednakże głównymi sektorami użytkowania tego sprzętu są: edukacja i robotyka.
Dzięki tak ogromnej społeczności w internecie można znaleźć ogromną liczbę
materiałów i oprogramowania stworzonego pod to konkretne urządzenie28 .
28
Raspberry
Pi
Foundation.
Raspberry
29
pi
1
model
b+.
Specyfikacja:
1. Układ Scalony:Broadcom BCM2835 (CPU + GPU + DSP + SDRAM)
2. CPU: 700 MHz ARM1176JZF-S core
3. GPU: Broadcom VideoCore IV[12], OpenGL ES 2.0, 1080p30 h.264/MPEG4 AVC high-profile decode
4. SDRAM: 512 MB (współdzielona z GPU)
5. Porty USB 2.0: 4 (uzyskane za pomocą zintegrowanego koncentratora
USB)
6. Wyjścia wideo: Composite RCA (PAL i NTSC) przez 4-pinowe (TRRS)
złącze Jack, HDMI (wersja: 1.3 i 1.4)
7. Wejście wideo: 15-pinowy interfejs kamery MIPI z konnektorem (CSI),
używany w zestawieniu z kamerą Raspberry Pi lub kamerą Raspberry
Pi NoIR
8. Wyjścia dźwięku: 3.5 mm jack, HDMI
9. Nośnik danych: MicroSD
10. Połączenie sieciowe 10/100 Ethernet (RJ45)
11. Pozostałe złącza: 17 x GPIO
12. Źródło zasilania: 5 V przy pomocy złącza MicroUSB
Kamera dedykowana dla urządzenia Raspberry Pi
https://www.raspberrypi.org/products/model-b-plus/
30
Rysunek 10: Kamera dedykowana dla urządzenia Raspberry Pi.
Kamera dedykowana do urządzenia Raspberry Pi. Połączenie z jednostką
Raspberry Pi za pomocą interfejsu MIPI umożliwia nagrywanie wysokiej
jakości filmów przy minimalnym obciążeniu procesora.
Specyfikacja:
1. Wymiary: 25 x 20 x 9 mm
2. Waga: 3g
3. Rozdzielczości wideo: 1080p30, 720p60 and 640x480p 60/90
4. częstotliwość wyświetlania klatek: do 120 fps
5. format wideo: h.264
Soczewka typu macro.
31
Rysunek 11: Soczewka typu macro.
Moduł kamery raspberry pi pozwala na nagrywanie wysokiej jakości filmów. Jednak kamera nie została przystosowana do kręcenia obiektów z bliskiej odległości. W celu otrzymania ostrego obrazu niezbędne jest użycie
soczewki powiększającej typu makro.
Specyfikacja
1. Średnica: 72mm
2. Moc powiększenia: 10x
Urządzenie mobilne - smartfon z systemem operacyjnym Android w wersji
2.3
32
Rysunek 12: Samsung Galaxy Ace.
System został zaprojektowany w taki sposób, aby przy niewielkim wkładzie pracy można było go dostosować do dowolnego urządzenia z zainstalowanym systemem operacyjnym typu android. Przy projektowaniu mojego
zestawu posłużyłem się smartfonem, który posiada zainstalowaną wersję androida 2.3. Starsze wersje oprogramowania wychodzą już z użytku i coraz rzadziej tworzone są programy wspierające androida w wersji niższej niż
4.0.Jednak jednym z założeń projektu było to, aby system obsługiwał urządzenia w starszej wersji.
Specyfikacja29 :
1. Nazwa: Samsung GT-S5830 Ace
2. CPU: Qualcomm MSM7227 800 MHz
3. Wymiary: 112,40 x 59,90 x 11,50 mm
4. Waga: 113g
5. Wyświetlacz: 320 x 480 px (3.50") 165 ppi
29
Samsung gt-s5830 ace. http://www.mgsm.pl/pl/katalog/samsung/gts5830ace/
33
6. Pamięć RAM: 384MB
7. Pamięc wbudowana: 158MB
4.1.2
Oprogramowanie
Do zrealizowania projektu niezbędne było stworzenie programu działającego
po stronie serwera. Całość kodu znajduje się na dołączonym do pracy nośniku
w formie elektronicznej. Jako główne komponenty oprogramowania należy
wyróżnić:
1. Interfejs użytkownika: część oprogramowania działająca po stronie użytkownika w skład której wchodzi część interfejsu użytkownika z podpiętymi pod poszczególne elementy słuchaczami, które po aktywowaniu
komunikują się z serwerem za pomocą technologii AJAX.
2. API typu REST: część oprogramowania która służy do odbierania żądań pochodzących z interfejsu użytkownika i przekazująca je do kolejnych części programu.
3. Adapter ADB. Klasa obiektu, który odpowiada za komunikację serwera
z urządzeniem typu Android.
4. Adapter Bazy danych. Klasa obiektu, który odpowiada za komunikację
z bazą danych.
34
4.2
Schematy połączeń
Rysunek 13: Połączenie Raspberry Pi z siecią internetową za pomocą modułu
Ethernet.
Rysunek 14: Połączenie Raspberry Pi ze smartofnem typu Android za pomocą kabla USB.
35
Rysunek 15: Połączenie Raspberry Pi z kamerą za pomocą kabla MIPI.
Rysunek 16: Kamera Raspberry Pi w zestawieniu z soczewką typu macro.
4.3
Zestawienie kamery z telefonem
W celu stworzenia układu, który jest przedmiotem mojej pracy zbudowałem
metalowy wysięgnik, który umieściłem na podstawie z tworzywa sztucznego.
36
Rysunek 17: Układ pozwalający na nagrywanie obrazu wyświetlanego na
telefonie.
4.4
Napotkane problemy i sposoby ich rozwiązania
Największym wyzwaniem podczas tworzenia pracy było udostępnienie obrazu
z kamery przez sieć internetową przy możliwie najmniejszej latencji. Istnieje
wiele sposobów na jakie można pobierać obraz i go udostępniać do sieci.
Jednakże większość rozwiązań niesie za sobą duże opóźnienie od momentu
pobrania obrazu przez kamerę do wyświetlenia go w oknie przeglądarki. Jednakże dzięki wsparciu społeczności zrzeszonej wokół Raspberry Pi na formach
internetowych udało mi się znaleźć rozwiązanie, które pozwoliło mi zmniejszyć czas opóźnienia do takiego, które byłem w stanie zaakceptować.
Kolejnym dużym problemem było uruchomienie programu ADB na Raspberry Pi. Program ten jest przystosowany do działania na systemie operacyjnym linux, jednak jego twórcy nie stworzyli wersji działającej pod architekturą procesora ARM. Tutaj również nieocenioną pomocą okazała się społeczność, jednak tym razem zrzeszona wokół systemu operacyjnego Android.
Kilka modyfikacji w kodzie źródłowym pozwoliło mi na to, żeby skompilować
program ADB i uruchomić go pomyślnie na Raspberry Pi.
4.4.1
Streaming z kamery Raspberry Pi
Centralnym elementem interfejsu użytkownika jest obraz z kamery padający
na telefon typu android. Założeniem było, żeby użytkownik posługujący się
37
interfejsem mógł w czasie rzeczywistym korzystać z urządzenia, co wymuszało
konieczność uzyskania niskiej latencji na drodze kamera-użytkownik.
Najbardziej popularnym sposobem streamingu video było użycie programu VLC zarówno po stronie serwera jak i po stronie klienta. Jest to
na tyle dobre rozwiązanie, że nie wymaga dużego nakładu pracy. Wystarczy jedynie zainstalować po obu stronach komunikacji program, następnie
uruchomić go po stronie serwera za pomocą jednego polecenia. Po stronie
klienta wtedy jedynie trzeba wpisać adres z którego nadawany jest sygnał i
można wyświetlać obraz kamery.
Jednak to podejście ma dwie wady, które wykluczają użycie tego sposobu
na moje zapotrzebowanie. Po pierwsze przy wykorzystaniu tego sposobu
musimy liczyć się z dużą latencją na poziomie 2-3 sekund. Nawet przy próbie skonfigurowania lub zmniejszenia jakości wysyłanego sygnału nie udało
mi się uzyskać widocznej poprawy. Po drugie potrzebowałem, żeby obraz
kamery był wyświetlany jako element interfejsu webowego, nie jako obraz w
wyświetlany w osobnej aplikacji.
W kolejnym podejściu posłużyłem się programem raspivid, który został
stworzony specjalnie z myślą o Raspberry Pi. Program ten był na tyle efektywny z mojej perspektywy, że umożliwiał przekazywanie obrazu bezpośrednio do określonego portu. Pozwoliło mi to na umieszczenie elementu w kodzie
HTML, który na bieżąco wyświetla wysyłany obraz.
Jednak przy zastosowaniu tego sposobu również uzyskiwałem duże opóźnienie przy wyświetlaniu obrazu i próby zoptymalizowania czasu opóźnienia
za pomocą konfiguracji programu okazały się bezskuteczne.
Trzecie z kolei podejście wykorzystywało program raspimjpeg. Jak sama
nazwa wskazuje że program ten umożliwia robienie zdjęć. Jego główną zaletą jest to, że potrafi on wykonywać zdjęcia w niedużej odległości czasowej
nieustannie i zapisywać je na dysku urządzenia.To rozwiązanie wymagało napisanie skryptu JavaScript, Który pobierałby to zdjęcie i wyświetlał w oknie
przeglądarki z częstotliwością dającą wrażenie streamingu video.
Listing 3: Fragment kodu JavaScript odpowiedzialny za odświerzanie podglądu kamery w oknie przeglądarki.
1 var mjpeg_img ;
2
3 function reload_img () {
4
mjpeg_img . src = " cam_pic . php ? time = " + new Date () . getTime
() ;
5 }
6
7 function error_img () {
38
8
9
10
11
12
13
14
15
16
17
18
19
20
setTimeout ( " mjpeg_img . src = ’ cam_pic . php ? time = ’ + new
Date () . getTime () ; " , 100) ;
}
function initCameraPreview () {
mjpeg_img = document . getElementById ( " mjpeg_dest " ) ;
mjpeg_img . onload = reload_img ;
mjpeg_img . onerror = error_img ;
reload_img () ;
}
window . onload = function () {
setTimeout ( initCameraPreview () , 100) ;
(...)
};
Listing 4: Fragment kodu PHP odpowiedzialny za wysyłanie aktualnego obrazu kamery do przeglądarki.
1
2
3
4
5
6
7
<? php
/*
* cam_pic . php
*/
header ( " Content - Type : image / jpeg " ) ;
readfile ( " / dev / shm / mjpeg / cam . jpg " ) ;
?>
Listing 5: Fragment kodu HTML stanowiący element w którym wyświetlany
jest bieżący podgląd kamery.
1 <html >
2
...
3
< img id = " mjpeg_dest " draggable = " false " >
4
...
5 </ html >
Powyższe rozwiązanie okazało się spełniać założenia projektu pozwalając
uzyskać obraz kamery w przeglądarce internetowej przy opóźnieniu nieprzekraczającym jednej sekundy.
4.4.2
Symulowanie wciskania przycisków znajdujących się na obudowie telefonu.
W celu zrealizowania tej części projektu stworzyłem guziki w layoucie interfejsu użytkownika, które po kliknięciu inicjują żądanie typu AJAX. Zależało
mi na tym, że użytkownik miał pozytywne wrażenie korzystając z aplikacji
39
i żeby interfejs działał płynnie i intuicyjnie. Dzięki zastosowaniu asynchronicznych zapytań ujętych w funkcjach języka JavaScript, byłem w stanie
przekazać żądania z przeglądarki do serwera bez konieczności przeładowania
strony. Technologia AJAX w sposób zadowalający pozwala osiągnąć opisywany cel. W momencie, kiedy przeglądarka internetowa wysyła żądanie do
serwera użytkownik nadal może korzystać z aplikacji. Ponadto, kiedy odpowiedź z serwera dobiegnie z powrotem, wtedy aktywność użytkownika nie
zostanie przerwana przeładowaniem strony. Jedynie część interfejsu ulegnie
modyfikacji.
Listing 6: Fragment kodu HTML definiujący guziki interfejsu użytkownika.
1 <html >
2 ...
3
< button id = " btn - power " class = " button black right - align " >
Power </ button >
4 ...
5
< button id = " btn - volume - up " class = " button black right -
align " > Volume up </ button >
6 ...
7
< button id = " btn - volume - down " class = " button black right -
align " > Volume down </ button >
8 ...
9
< button id = " btn - calibrate " class = " button black right -
align " > Calibrate </ button >
10 ...
11
< button id = " btn - back " class = " button black full - width " >
Back </ button >
12 ...
13
< button id = " btn - home " class = " button black full - width " >
Home </ button >
14 ...
15
< button id = " btn - menu " class = " button black full - width " >
Menu </ button >
16 ...
17 </ html >
Listing 7: Fragment kodu javaScript ustawiający metody jakie zostaną wywołane po wykonaniu kliknięcia na interfejsie użytkownika.
1 function _ ( el ) {
2
return document . getElementById ( el ) ;
3 }
4
40
5 var filePicker = _ ( " file - picker " ) ;
6 filePicker . addEventListener ( " click " , filePickerClicked ,
false ) ;
7
8 var fileHolder = _ ( ’ file - holder ’) ;
9 fileHolder . addEventListener ( ’ change ’ , startUploadFile ,
false ) ;
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var removeBtn = _ ( " install_last " ) ;
removeBtn . addEventListener ( " click " , onAPKRemove , false ) ;
var source = new EventSource ( ’ ajax_read_output . php ’) ;
source . onmessage = onMessage ;
var catcher = _ ( ’ mjpeg_dest ’) ;
catcher . addEventListener ( " click " , catchMouse ) ;
var btn_home = _ ( ’btn - home ’) ;
btn_home . addEventListener ( " click " , clickHome ) ;
var btn_power = _ ( ’btn - power ’) ;
btn_power . addEventListener ( " click " , clickPower ) ;
var btn_menu = _ ( ’btn - menu ’) ;
btn_menu . addEventListener ( " click " , clickMenu ) ;
var btn_back = _ ( ’btn - back ’) ;
btn_back . addEventListener ( " click " , clickBackButton ) ;
var btn_vol_down = _ ( ’btn - volume - down ’) ;
btn_vol_down . addEventListener ( " click " , clickVolumeDown ) ;
var btn_vol_up = _ ( ’btn - volume - up ’) ;
btn_vol_up . addEventListener ( " click " , clickVolumeUp ) ;
var btn_calibrate = _ ( ’btn - calibrate ’) ;
btn_calibrate . addEventListener ( " click " , clickCalibrate ) ;
Listing 8: Fragment kodu JavaScript odpowiedzialny za interakcje z serwerem
przy pomocy zapytań AJAX.
1 function clickHardwareCompleteHandler ( event ) {
2 }
3
41
4
5
6
7
8
9
10
11
12
13
14
15
16
function clickHardwareErrorHandler ( event ) {
}
function clickHardwareAbortHandler ( event ) {
}
function sendAjaxEvent ( event_id ) {
var formdata = new FormData () ;
formdata . append ( " operation " , event_id ) ;
var ajax = new XMLHttpRequest () ;
ajax . addEventListener ( " load " ,
clickHardwareCompleteHandler , false ) ;
ajax . addEventListener ( " error " , clickHardwareErrorHandler ,
false ) ;
ajax . addEventListener ( " abort " , clickHardwareAbortHandler ,
false ) ;
ajax . open ( " POST " , " ajax_click_hardware . php " ) ;
ajax . send ( formdata ) ;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
}
function clickHome ( e ) {
sendAjaxEvent (0) ;
}
function clickPower ( e ) {
sendAjaxEvent (1) ;
}
function clickMenu ( e ) {
sendAjaxEvent (2) ;
}
function clickBackButton ( e ) {
sendAjaxEvent (3) ;
}
function clickVolumeDown ( e ) {
sendAjaxEvent (4) ;
}
42
44
45
46
47
48
49
50
function clickVolumeUp ( e ) {
sendAjaxEvent (5) ;
}
function swipe ( e ) {
sendAjaxEvent (6) ;
}
Listing 9: Fragment kodu PHP przetwarzający otrzymane zapytanie z interfejsu użytkownika.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<? php
/* *
* ajax_click_hardware . php
*/
define ( ’ BASE_DIR ’ , dirname ( __FILE__ ) ) ;
require_once ( BASE_DIR . ’/ config . php ’) ;
require_once ( CLASSES_DIR . ’/ Log . php ’) ;
require_once ( CLASSES_DIR . ’/ AdbAdapter . php ’) ;
$log = new Log ( __FILE__ ) ;
$adb = new AdbAdapter ( true ) ;
switch ( $_POST [ ’ operation ’ ]) {
case 0: // HOME
$log - > d ( " Home button clicked " ) ;
$adb - > clickHome () ;
break ;
case 1: // POWER
$log - > d ( " Power button clicked " ) ;
$adb - > clickPower () ;
break ;
case 2: // MENU
$log - > d ( " Menu button clicked " ) ;
$adb - > clickMenu () ;
break ;
case 3: // BACK
$log - > d ( " Back button clicked " ) ;
$adb - > clickBackButton () ;
break ;
case 4: // VOL DOWN
$log - > d ( " Volume down button clicked " ) ;
$adb - > clickVolumeDown () ;
43
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
break ;
case 5: // VOL UP
$log - > d ( " Volume up button clicked " ) ;
$adb - > clickVolumeUp () ;
break ;
case 6: // swipe
$log - > d ( " swipe detected " ) ;
$adb - > swipe () ;
break ;
default :
$log - > d ( " operation not supported " ) ;
break ;
}
$adb = null ;
$log = null ;
die ;
4.4.3
Komunikacja serwera z systemem operacyjnym Android.
Głównym zadaniem serwera jest przyjmowanie zapytań wysyłanych przez
przeglądarkę internetową i późniejsze symulowanie odpowiadających działań
na telefonie typu Android. Program ADB umożliwia wykonanie tych operacji, jednak jego wykorzystanie w połączeniu z serwerem wymaga pewnych
modyfikacji.
Program ADB w przy komunikacji się z telefonem wymaga uprawnień
root, jednak serwer na którym działa interpreter języka PHP w systemie
operacyjnym linux należy do grupy www-data i tym samym nie posiada wystarczających uprawnień żeby wykonywać polecenia sudo bez podawania hasła.
W celu rozwiązania tego problemu należało użyć programu visudo do
edycji pliku sudoers. Następnie należało dodać polecenie, które znosi konieczność użycia hasła podczas wykonywania operacji za pomocą programu
ADB z poziomu root. Dzięki temu zabiegowi możliwe jest zagnieżdżenie poleceń bash wewnątrz skryptu PHP odwołujących się do programu ADB za
pomocą funkcji języka PHP shell_exec().
Listing 10: Fragment ustawień pliku suoers umożliwiający wykonywanie operacji przy wykorzystaniu programu adb bez użycia hasła.
1 ...
2 # Allow apache user to execute adb cmommand without
passsword
44
3 www - data ALL = NOPASSWD : / etc / android - tools / adb
4 ...
ADB (Android Debug Bridge) jest programem stanowiącym zestaw narzędzi służących do wykonywania operacji na urządzeniu typu Android z
poziomu systemu operacyjnego za pośrednictwem kable USB. Został przystosowany do działania na platformach typu Windows, Mac i linux. Do
wykonania projektu posłużyłem się serwerem, na którym został zainstalowany system operacyjny Respbian, który jest pochodną systemu Debian należący do rodziny Linux. Jednak Raspberry Pi wyposażone jest w procesor
typu ARM, co ma znaczenie dla poprawnego działania ADB. Program ten
nie wspiera fabrycznie architektury ARM i niezbędne było zmodyfikowanie
kodu źródłowego, aby umożliwić uruchomienie na serwerze. Jednakże dzięki
wsparciu społeczności zrzeszającej developerów platformy Android udało mi
się stworzyć kopię programu działającej pod architekturą mojego serwera30 .
4.4.4
Symulowanie zdarzeń poprzez interfejs programu ADB.
ADB pozwala na symulowanie zdarzeń, które normalnie wywoływane są przez
interakcję użytkownika z urządzeniem. Do takich zdarzeń zaliczyć można
kliknięcie guzika “Power”, czy wykonanie gestu “tap” na ekranie dotykowym.
Aby dokonywać symulacji na urządzeniu, należy wysłać serię poleceń za
pomocą komendy sendevent przechodząc wcześniej do interfejsu shell programu ADB wpisując w linii poleceń “sudo adb shell”. Każde urządzenie
Android może przyjmować inne parametry reprezentujące dany gest, więc
przed przystąpieniem do wysyłania poleceń, najpierw należy dowiedzieć się
jakiej składni powinniśmy użyć. W tym celu posłużymy się poleceniem getevent z poziomu shell programu adb. Polecenie getevent bez parametru
definiującego urządzenie wejścia/wyjścia otrzymujemy następujący wynik:
Listing 11: Wynik ekranu konsoli po wydaniu polecenia getevent
1
2
3
4
5
6
7
8
9
10
$ getevent
add device
name :
add device
name :
add device
name :
add device
name :
add device
30
1: / dev / input / event4
" magnetic_sensor "
2: / dev / input / event3
" accelerometer_sensor "
3: / dev / input / event2
" sec_key "
4: / dev / input / event1
" sec_touchscreen "
5: / dev / input / event0
AdamOutler. Adb for raspberry pi, October 7 2012
45
name :
11
" sec_jack "
W celu włączenia nasłuchu na zdarzenie kliknięcie w ekran telefonu, należy użyć polecenia getevent podając jako parametr nazwę urządzenia wejścia/wyjścia. Na potrzeby przykładu przedstawię wynik konsoli po włączeniu
nasłuchu i wykonaniu gestu “tap” na ekranie telefonu w miejscu o współrzędnych x=143 y=289.
Listing 12: Wynik ekranu konsoli zwracającej informację o wykrytym geście
“tap”.
1
2
3
4
5
6
7
8
9
10
11
12
13
$ getevent / dev / input / event1
0003 0035 0000008 f
0003 0036 00000121
0003 0030 00000001
0003 0032 0000003 f
0000 0002 00000000
0000 0000 00000000
0003 0035 0000008 f
0003 0036 00000121
0003 0030 00000000
0003 0032 0000003 f
0000 0002 00000000
0000 0000 00000000
W celu wykonania symulacji powyższego zdarzenia na telefonie przez polecenie sendevent, należy sekwencję poleceń poddać pewnej modyfikacji. Polecenie getevent zwraca ciąg liczb w systemie szesnastkowym, zaś sendevent w
systemie dziesiętnym. Po przekształceniu przykładowego zdarzenia wysłana
sekwencja poleceń przybiera postać z poniższego listingu.
Listing 13: Symulacja wykonania gestu “tap” na telefonie.
1
2
3
4
5
6
7
8
9
10
11
12
$
$
$
$
$
$
$
$
$
$
$
$
sendevent
sendevent
sendevent
sendevent
sendevent
sendevent
sendevent
sendevent
sendevent
sendevent
sendevent
sendevent
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
/ dev / input / event1
3
3
3
3
0
0
3
3
3
3
0
0
46
53 143
54 289
48 1
50 63
2 0
0 0
53 143
54 289
48 0
50 63
2 0
0 0
4.4.5
Przekazywanie współrzędnych gestu “tap” z interfejsu użytkownika.
W projekcie obiektyw kamery skierowany jest na wyświetlacz telefonu. Jednak kamera obejmuje również elementy poza samym wyświetlaczem, między
innymi obudowę telefonu. W celu przekazania współrzędnych kliknięcia użytkownika w ekran telefonu niezbędna jest więc informacja o współrzędnych
ekranu telefonu w stosunku do krawędzi podglądu.
W celu zdobycia informacji o tym która część podglądu odpowiada za
ekran telefonu użyłem biblioteki języka JavaScript o nazwie tracking.js31 .
Jedna z jej funkcjonalności umożliwia określenie współrzędnych obiektu o
określonym kolorze w zlokalizowanym w elemencie drzewa html. Dzięki aplikacji, której jedynym celem jest wyświetlanie jednolitego koloru zakrywającego całość ekranu można było uruchomić skrypt i przesłać współrzędne
ekranu smartfona do serwera, a następnie zapisać te informacje do bazy danych.
Listing 14: Fragment kodu JavaScript odpowiedzialny za uzyskanie informacji o współrzędnych ekranu.
1 function calibrateCompleteHandler ( event ) {
2
var response = event . target . response ;
3
var result = JSON . parse ( response ) ;
4
5
x_coordinate = result . rect_x ;
6
y_coordinate = result . rect_y - 30;
7
8 }
9
10 function onTrack ( event ) {
11
12
if ( event . data . length !== 0) {
13
event . data . forEach ( function ( rect ) {
14
if ( rect . color == ’ yellow ’) {
15
16
var formdata = new FormData () ;
17
formdata . append ( " rect - x " , rect . x ) ;
18
formdata . append ( " rect - y " , rect . y ) ;
19
formdata . append ( " rect - width " , rect . width ) ;
20
formdata . append ( " rect - height " , rect . height ) ;
21
22
var ajax = new XMLHttpRequest () ;
31
tracking.js. http://trackingjs.com/. Accessed: 2015-04-27
47
23
24
25
ajax . addEventListener ( " load " ,
calibrateCompleteHandler , false ) ;
ajax . addEventListener ( " error " ,
calibrateErrorHandler , false ) ;
ajax . addEventListener ( " abort " ,
calibrateAbortHandler , false ) ;
ajax . open ( " POST " , " ajax_calibrate . php " ) ;
ajax . send ( formdata ) ;
26
27
28
}
29
}) ;
30
}
31
32 }
33
34 function clickCalibrate () {
35
36
var tracker = new tracking . ColorTracker ([ ’ yellow ’ ]) ;
37
38
tracker . on ( ’ track ’ , onTrack ) ;
39
tracking . track ( ’# mjpeg_dest ’ , tracker ) ;
40
41 }
Użytkownik klikając myszką na podglądzie kamery wywołuje kod JavaScript, który na podstawie współrzędnych determinujących położenie ekranu
telefonu wykonuje następujące obliczenia:
1. Sprawdzenie, czy użytkownik kliknął w ekran urządzenia, czy poza jego
granice.
2. Kiedy kliknięcie zostało wywołane na ekranie, wtedy od współrzędnej kliknięcia x odejmuje się margines pomiędzy odległością podglądu
kamery od krawędzi interfejsu dodając odległość pomiędzy lewą krawędzią podglądu a lewą krawędzią wyświetlacza. Od współrzędnej y zaś
odejmuje się margines pomiędzy odległością górnej krawędzi okna przeglądarki a krawędzią podglądu plus odległość górnej krawędzi podglądu
od górnej krawędzi wyświetlacza.
3. uzyskane w ten sposób odległości dzielone są przez wysokość i szerokość
wyświetlacza uzyskując w ten sposób procent szerokości i wysokości na
którym wykonany został gest.
4. Wysłanie uzyskanych danych do serwera w celu wykonania symulacji
na urządzeniu.
48
Otrzymując dane o zdarzeniach z interfejsu użytkownika serwer wykonuje
operacje na urządzeniu w czasie rzeczywistym przy wykorzystaniu polecenia
sendevent programu ADB. W tym celu stworzyłem klasę AdbAdapter, która
odpowiada za całość interakcji na drodze serwer - smartfon.
Listing 15: Klasa obiektu AdbAdapter odpowiadająca za interakcję z telefonem typu android za pomocą programu ADB.
1 <? php
2
3 class AdbAdapter
4 {
5
6
private $log ;
7
private $isPrivate ;
8
private $adb ;
9
10
public function __construct ( $isPrivate = false )
11
{
12
$this - > isPrivate = $isPrivate ;
13
$this - > log = new Log ( __FILE__ ) ;
14
}
15
16
public function __destruct ()
17
{
18
$this - > log = null ;
19
}
20
21
public function execute ( $command = ’ ’ , $argument = ’ ’)
22
{
23
$cmd = array (
24
’ command ’ = > $command ,
25
’ parameter ’ = > $argument
26
);
27
28
$arr = array () ;
29
$arr [0] = $cmd ;
30
31
return $this - > execute_cmd ( $arr ) ;
32
}
33
34
public function execute_cmd ( $commands = array () , $level =
’ level - verbose ’)
35
{
49
if (! is_array ( $commands ) ) {
$this - > log - > e ( ’ Not an array ! exiting . ’) ;
return ;
}
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
$to_execute = ’ sudo adb ’;
foreach ( $commands as $command ) {
if (! is_array ( $command ) ) {
continue ;
}
$to_execute
$to_execute
$to_execute
$to_execute
.=
.=
.=
.=
’ ’;
$command [ ’ command ’ ];
’ ’;
$command [ ’ parameter ’ ];
}
$this - > log - > d ( ’ executing : ’ . $to_execute ) ;
$output = shell_exec ( $to_execute ) ;
$oparray = preg_split ( ’ /\ s +/ ’ , trim ( $output ) ) ;
if (! $this - > isPrivate ) {
foreach ( $oparray as $op ) {
$m = ’ <p class =" ’ . $level . ’" > ’ . $op . ’ </p > ’;
$this - > log - > d ( ’# - - ’ . $m ) ;
file_put_contents ( " log_cat . txt " , $m , FILE_APPEND ) ;
}
}
$this - > log - > d ( ’ Size of the result array is ’ . sizeof (
$oparray ) ) ;
return $oparray ;
}
public function click ( $ratio_x , $ratio_y )
{
$this - > log - > d ( ’ ratio x = ’ . $ratio_x . ’ and ratio y = ’ .
$ratio_y ) ;
76
50
$display = $this - > getDisplay () ;
$realX = round ( $display - > DisplayWidth * $ratio_x ) ;
$realY = round ( $display - > DisplayHeight * $ratio_y ) ;
$this - > log - > d ( ’ $realX = ’ . $realX . ’ and $realY = ’ .
$realY ) ;
77
78
79
80
81
82
83
$cmd = ’ shell ’;
$cmd .= ’" sendevent / dev / input / event1 3 53 ’ . $realX .
’; ’;
$cmd .= ’ sendevent / dev / input / event1 3 54 ’ . $realY .
’; ’;
$cmd .= ’ sendevent / dev / input / event1 3 48 1; ’;
$cmd .= ’ sendevent / dev / input / event1 3 50 50; ’;
$cmd .= ’ sendevent / dev / input / event1 0 2 0; ’;
$cmd .= ’ sendevent / dev / input / event1 0 0 0; ’;
$cmd .= ’ sendevent / dev / input / event1 3 53 ’ . $realX .
’; ’;
$cmd .= ’ sendevent / dev / input / event1 3 54 ’ . $realY .
’; ’;
$cmd .= ’ sendevent / dev / input / event1 3 48 0; ’;
$cmd .= ’ sendevent / dev / input / event1 3 50 50; ’;
$cmd .= ’ sendevent / dev / input / event1 0 2 0; ’;
$cmd .= ’ sendevent / dev / input / event1 0 0 0;" ’;
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
$this - > log - > d ( $cmd ) ;
$this - > execute ( $cmd ) ;
}
public function clickHome ()
{
$cmd
$cmd
$cmd
$cmd
$cmd
= ’ shell ’;
.= ’" sendevent / dev / input / event2 1 102 1; ’;
.= ’ sendevent / dev / input / event2 1 102 0; ’;
.= ’ sendevent / dev / input / event2 1 102 1; ’;
.= ’ sendevent / dev / input / event2 1 102 0;" ’;
$this - > log - > d ( $cmd ) ;
$this - > execute ( $cmd ) ;
}
51
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
public function clickPower ()
{
$cmd = ’ shell ’;
$cmd .= ’" sendevent / dev / input / event2 1 107 1; ’;
$cmd .= ’ sendevent / dev / input / event2 1 107 0;" ’;
$this - > log - > d ( $cmd ) ;
$this - > execute ( $cmd ) ;
}
public function clickMenu ()
{
$cmd
$cmd
$cmd
$cmd
$cmd
= ’ shell ’;
.= ’" sendevent / dev / input / event1 1 139 1; ’;
.= ’ sendevent / dev / input / event1 0 0 0; ’;
.= ’ sendevent / dev / input / event1 1 139 0; ’;
.= ’ sendevent / dev / input / event1 0 0 0;" ’;
$this - > log - > d ( $cmd ) ;
$this - > execute ( $cmd ) ;
}
public function clickBackButton ()
{
$cmd
$cmd
$cmd
$cmd
$cmd
= ’ shell ’;
.= ’" sendevent / dev / input / event1 1 158 1; ’;
.= ’ sendevent / dev / input / event1 0 0 0; ’;
.= ’ sendevent / dev / input / event1 1 158 0; ’;
.= ’ sendevent / dev / input / event1 0 0 0;" ’;
$this - > log - > d ( $cmd ) ;
$this - > execute ( $cmd ) ;
}
public function clickVolumeDown ()
{
52
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
$cmd = ’ shell ’;
$cmd .= ’" sendevent / dev / input / event2 1 114 1; ’;
$cmd .= ’ sendevent / dev / input / event2 1 114 0;" ’;
$this - > log - > d ( $cmd ) ;
$this - > execute ( $cmd ) ;
}
public
{
$cmd
$cmd
$cmd
function clickVolumeUp ()
= ’ shell ’;
.= ’" sendevent / dev / input / event2 1 115 1; ’;
.= ’ sendevent / dev / input / event2 1 115 0;" ’;
$this - > log - > d ( $cmd ) ;
$this - > execute ( $cmd ) ;
}
public function swipe ()
{
// todo
}
public function getDisplay ()
{
$display = array () ;
$db = new DbAdapter ( ’ settings ’) ;
$results = $db - > fetch ( ’ key ’ , ’ display ’) ;
if ( $results - > num_rows > 0) {
while ( $row = $results - > fetch_assoc () ) {
$displayJS = $row [ ’ value ’ ];
}
$display = json_decode ( $displayJS ) ;
$this - > log - > d ( ’ DisplayWidth = ’ . $display - >
DisplayWidth . ’ DisplayHeight = ’ . $display - >
DisplayHeight ) ;
return $display ;
} else {
53
$screen_res = $this - > execute ( ’ shell dumpsys window |
grep DisplayWidth ’) ;
foreach ( $screen_res as $res ) {
$vals = explode ( " = " , $res ) ;
if ( $vals [0] == ’ DisplayWidth ’) {
$display [ ’ DisplayWidth ’] = intval ( $vals [1]) ;
} else if ( $vals [0] == ’ DisplayHeight ’) {
$display [ ’ DisplayHeight ’] = intval ( $vals [1]) ;
}
$this - > log - > d ( ’# screen res : ’ . $res ) ;
}
$displayJS = json_encode ( $display ) ;
$this - > log - > d ( $displayJS ) ;
$db - > insert (
array (
array (
’ table_name ’ = > ’ key ’ ,
’ value ’ = > ’ display ’
),
array (
’ table_name ’ = > ’ value ’ ,
’ value ’ = > $displayJS
)
)
);
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
return $this - > getDisplay () ;
225
}
226
227
}
228 }
4.4.6
Udostępnianie usługi pod niezmiennym adresem http.
Usługa powinna być dostępna dla użytkowników poprzez internet w dowolnym czasie oraz z dowolnego miejsca. Niestety sieć w której znajduje się
serwer posiada zmienny adres IP, który zostaje losowo przydzielony przez
operatora sieci w momencie zresetowania routera. Serwer DNS gromadzący
informacje o tym pod jakim adresem IP znajduje się aplikacja musiałby zostać poinformowany o każdej zmianie adresu. Wiązałoby się to z dużym
nakładem pracy administratora systemu oraz wysokim ryzykiem przerw w
dostępności usługi pomiędzy zmianą IP a ingerencją administratora do mo54
mentu propagacji adresu DNS w internecie.
W celu rozwiązania powyższego problemu użyłem usługi DDNS (Dynamic
Domanin Name System)32 . Dzięki wykorzystaniu tego mechanizmu, możliwe
jest komunikowanie w czasie rzeczywistym o zmianie adresu ip serwera aplikacji. Nie jest wymagane modyfikowanie kodu czy ręczne konfigurowanie
serwera oraz klienta, wprowadzając aktualizacje adresów IP. Dzieje się to automatycznie, dzięki zainstalowanej na serwerze aplikacji, która w odstępach
10-minutowych aktualizuje swoje położenie w sieci na serwerze DDNS.
Kiedy klient w postaci przeglądarki internetowej wysyła żądanie do serwera, otrzymuje aktualny adres IP z serwera DDNS, dzięki któremu możliwa
jest dalsza wymiana komunikatów.
5
Testy systemu
5.1
Cel testów
W celu upewnienia się, że system spełnia przyjęte wymagania, przeprowadzono szereg testów. Jako podstawowe kryteria warunkujące poprawność
napisanego kodu przyjęto:
1. Poprawność działania interfejsu użytkownika.
2. Niski poziom latencji pomiędzy wywołaniem zdarzenia a odpowiedzią
serwera.
3. Uniwersalność i łatwość wykorzystania napisanego kodu w połączeniu
z innym urządzeniem typu Android.
5.2
Potencjalne zagrożenia
Większość zagrożeń, które mogłyby zakłócić poprawne działanie oprogramowania zostało zidentyfikowanych jeszcze przed przystąpieniem do testowania.
Posłużyły one do stworzenia scenariuszy testowych prowadzących do iteracyjnego udoskonalania wytworzonego oprogramowania. Największy priorytet
został przypisany tym aspektom, które odpowiadają za pozytywne wrażenia
użytkownika. Należą do nich między innymi:
1. Dostępność systemu przy wykorzystaniu przeglądarki internetowej.
2. Szybkość z jaką system reaguje na polecenia docierające z interfejsu
użytkownika
32
Wikipedia. Ddns — Wikipedia, wolna encyklopedia, 2004
55
3. Dokładność z jaką system przenosi kliknięcia wykonane w przeglądarce
internetowej i symuluje je na urządzeniu.
4. Komunikacja systemu z użytkownikiem, dzięki czemu osoba korzystająca z oprogramowana na każdym kroku otrzymuje informacje o tym
jaki proces aktualnie jest wykonywany przez system.
5.3
Testy dostępności aplikacji przy zmianie adresu IP
sieci lokalnej serwera.
Jako, że serwer znajduje się w sieci, która korzysta z dostępu do internetu
przy braku stałego adresu IP, istotne było, żeby system był dostępny również
kiedy zmieniony zostanie adres IP sieci lokalnej w której się znajduje.
Scenariusz:
1. Połącz się z serwerem wpisując w przeglądarce internetowej adres http
na jakim znajduje się aplikacja
2. Wyłącz z prądu router do którego podłączony jest serwer i odczekaj
kilka minut
3. Włącz z powrotem router i poczekaj aż połączy się on z internetem
4. Opcjonalnie sprawdź, czy zmienił się adres ip sieci lokalnej (na przykład
na stronie whatismyipaddress.com)
5. Ponownie wpisz adres http aplikacji w przeglądarce internetowej i sprawdź
czy aplikacja wyświetla się poprawnie.
Wnioski:
1. Dzięki usłudze DDNS możliwe było stworzenie systemu w sieci o zmiennym adresie ip posiadającego stały adres internetowy
2. Skorzystanie z DDNS poprzez usługę no-ip (www.noip.com) wymaga
niewielkiej wiedzy i jest proste w konfiguracji.
5.4
Testy latencji
Jako podstawowe kryterium odpowiadające za pozytywne wrażenia użytkownika podczas korzystania z systemu określona została szybkość z jaką
system reaguje na bodźce pochodzące z interfejsu użytkownika. Test należy
przeprowadzić wykorzystując usługę umożliwiającą komunikację z serwerem
56
przy pośrednictwie VPN, sprawdzając jak zmienia się czas reakcji systemu
przy zmianie fizycznej odległości pomiędzy serwerem a klientem.
Scenariusz:
1. Zainstaluj program umożliwiający tunelowanie połączenia za pomocą
VPN oraz zmianę położenia klienta końcowego pod kontem odległości
geograficznej od serwera.
2. Połącz się z serwerem za pomocą przeglądarki internetowej.
3. Za pomocą interfejsu przeglądarki zainstaluj aplikację na telefonie przesyłając plik APK na serwer.
4. Kliknij kolejno we wszystkie guziki odpowiadające za symulowanie kliknięcia w guziki znajdujące się na obudowie urządzenia.
5. Wykonaj gest "tapńa podglądzie kamery
6. Wykonaj gest świpeńa podglądzie kamery
7. Zaobserwuj czas jaki upłynął od momentu wysłania żądania przez przeglądarkę internetową do uzyskania odpowiedzi.
Wnioski:
1. Już w pierwszych fazach tworzenia systemu latencja była najbardziej
odczuwalnym problemem, który uniemożliwiał płynne korzystanie z
układu.
2. Odległość serwera od klienta końcowego miała marginalne znaczenie w
kontekście doświadczanego w początkowych fazach tworzenia oprogramowania opóźnienia.
3. Czas jaki serwer potrzebował na pobranie obrazu kamery i późniejsze
wysłanie go do klienta końcowego determinował jakiej latencji będzie
doświadczał użytkownik.
4. Udoskonalenie sposobu udostępniania obrazu pozwoliło znacznie obniżyć opóźnienie.
57
5.5
Testy dokładności mapowania gestu “tap”
Użytkownik powinien być w stanie korzystać z systemu w podobny sposób jak
to wygląda w przypadku różnego rodzaju emulatorów. Do spełnienia tego założenia niezbędne jest precyzyjne przekazywanie współrzędnych o kliknięciu
do serwera i późniejsze mapowanie gestów na urządzeniu. Testy poprawnego
mapowania mają na celu sprawdzenie, czy po kliknięciu zostanie wywołana
akcja, której użytkownik oczekuje.
Scenariusz:
1. Połącz się z serwerem za pomocą przeglądarki internetowej i wykonaj
dowolne działanie klikając w podgląd kamery. Otwórz aplikację "Kamera", wyjdź z niej klikając w guzik "Home", następnie wykonaj gest
świpe"przechodząc do kolejnej strony pulpitu.
2. Zmniejsz okno przeglądarki i wykonaj te same operacje ponownie.
3. Zmień rozdzielczość ekranu i ponownie przejdź przez cały scenariusz.
4. Połącz się z aplikacją używając nas†ępujących przeglądarek: Chrome,
Firefox, Opera oraz Internet Explorer i ponownie wykonaj te same kroki
jak w poprzednich podpunktach
Wnioski:
1. Dzięki uniwersalności kodu udało się poprawnie mapować kliknięcia w
każdej wspieranej przeglądarce.
2. Mapowanie działa poprawnie nawet wtedy kiedy podgląd kamery nie
mieści się na wyświetlaczu i w celu kliknięcia w dolną część wyświetlacza należy przewinąć stronę w dół.
5.6
Modyfikacje systemu na podstawie testów
Wykonując kolejne iteracje scenariuszy testowych i analizując założenia postawione w fazie planowania wprowadzono szereg ulepszeń dzięki którym
korzystanie z aplikacji stało się przyjemniejsze i płynniejsze. Jednak istnieje
jeszcze szereg aspektów aplikacji, które można byłoby ulepszyć. Jako najważniejsze z nich należy wymienić:
1. Ostrość kamery i jakość obrazu. Sprzęt, z którego obecnie system jest
zbudowany nie pozwala na uzyskanie wyższej ostrości obrazu.
58
2. Soczewka powiększająca typu macro została stworzona z myślą o innym
zastosowaniu, więc w celu wyeliminowania zakrzywień obrazu należałoby w przyszłości zastąpić ją czymś bardziej odpowiednim.
3. Ulepszony interfejs użytkownika zaprojektowany przez profesjonalnego
grafika.
4. Zabezpieczenie przed niepożądanym dostępem osób nieautoryzowanych
z zamiarem uszkodzenia systemu. W tym kierunku nie zostały przeprowadzone żadne testy, przez co system jest narażony na uszkodzenia
ze strony osób trzecich.
Jednak te modyfikacje wymagają kolejnych testów i badań jak również
nakładów finansowych i czasowych, tak więc zostaną one wprowadzone w
kolejnych wersjach systemu.
6
Zakończenie - plany dalszego rozwoju systemu
System przeszedłszy wszystkie testy może służyć jako podstawa do tworzenia
usługi wypożyczania telefonów komórkowych przez internet.
Niestety obecna wersja systemu nie jest wystarczająco rozbudowana, żeby
wykorzystać ją komercyjnie. W celu wprowadzenia produktu na rynek niezbędne byłoby stworzenie następujących funkcjonalności:
6.1
Dalszy rozwój serwera zarządzającego telefonem
Na obecnym etapie rozwoju aplikacji użytkownik ma kontrolę nad wieloma
aspektami urządzenia. Jednak system nie pozwala między innymi na komunikację audio. Należałoby więc w kolejnej fazie połączyć telefon komórkowy
z serwerem za pomocą kabla mini-jack i streaming audio do interfejsu użytkownika. Dodatkowo, system powinien umożliwiać komunikację dźwiękową
na drodze użytkownik-telefon z przeglądarki internetowej do smartfona.
Obecny stan serwera nie umożliwia również wykorzystywania akcelerometru. Użytkownik ma możliwość korzystania z aplikacji wyłącznie w orientacji pionowej. Finalna wersja systemu powinna mieć możliwość zmieniania
orientacji ekranu w czasie rzeczywistym. W tym celu należałoby zbudować
mechanizm, który obracałby telefonem zmieniając jego orientację na żądanie
użytkownika.
59
6.2
Stworzenie kolejnych jednostek serwerów Raspberry
Pi
Docelowo usługa ma stanowić wypożyczalnię telefonów komórkowych. Użytkownicy będą odwiedzali portal w celu wybrania konkretnego modelu urządzenia typu Android spośród obecnie dostępnych, wykupując czasowy do
niego dostęp. Twórca systemu jest więc zobligowany do tego, żeby zakupić
takie modele smartfonów, które potencjalnie będą klientów interesowały i
udostępnić je im za pomocą stworzonego systemu.
W początkowej fazie działania usługi, serwer nie będzie obciążony dużym
ruchem sieciowym. Wraz z biegiem czasu system będzie zyskiwał nowych
użytkowników, którzy będą odwiedzali stronę w celu testowania swoich aplikacji. Żeby uruchomić pierwszą wersję aplikacji, potrzebna jest więc reprezentacyjna liczba różnych modeli telefonów, aby użytkownik mógł wybrać
ten najbardziej go interesujący. Można więc obrać jako cel publikację pierwszej wersji systemu, która będzie wyposażona w 10 najbardziej popularnych
modeli smartfonów na rynku.
Z biegiem czasu, kiedy zauważalne będzie, że dany telefon komórkowy jest
wykorzystywany w takim stopniu, że inni użytkownicy wykazują ogromne zainteresowanie chęcią skorzystania z niego, wówczas można na bieżąco dokupować dodatkowe modele telefonów i dodawać je do puli dostępnych urządzeń.
6.3
Stworzenie centralnej aplikacji, która zarządzałaby
dostępem do poszczególnych serwerów
Do poprawnego działania całej usługi niezbędne jest stworzenie dodatkowej
aplikacji, której celem będzie zarządzanie dostępem do pozostałych serwerów
Raspberry Pi.
Użytkownik, który będzie odwiedzał portal internetowy wypożyczalni telefonów będzie mógł założyć konto użytkownika, przelać środki, wybrać interesujący go model telefonu i połączyć się z nim wykorzystując fundusze
zgromadzone na jego koncie.
Niezbędną funkcjonalnością opisywanej aplikacji jest więc zarządzanie
kontem użytkownika. Osoba odwiedzająca portal musi mieć możliwość założenia konta wraz z zalogowania się do niego. Dodatkowo użytkownik musi
mieć możliwość edytowanie swoich ustawień przez panel użytkownika, a także
mieć wgląd we wprowadzone do niego informacje.
System powinien również komunikować się z użytkownikiem na podstawie wiadomości w skrzynce odbiorczej. Chodzi tutaj o takie informacje jak
niski poziom zgromadzonych środków, dodanie nowego urządzenia do puli
60
dostępnych telefonów w serwisie, czy aktualizacja warunków korzystania z
portalu.
Jako, że dostęp do telefonów będzie przydzielany odpłatnie, niezbędna
jest integracja z systemem płatności. Użytkownik musi mieć możliwość przelewania środków pieniężnych na swoje konto do wykorzystania podczas korzystania z serwisu. Na rynku istnieje wiele systemów płatności, które udostępniają interfejs pozwalający na integrację z innymi serwisami za pomocą
uniwersalnego API. W początkowej fazie działania serwisu można więc wykorzystać jeden z nich a później stopniowo dodawać kolejne.
W ostatnim czasie na popularności zyskuje system płatności Bitcoin,
który daje możliwość użytkownikowi przelewania pieniędzy bez udziału podmiotów trzecich. Stanowi to atrakcyjną alternatywę dla standardowych systemów i można wykorzystać go zamiast ww. wskazanych usług.
Aplikacja centralnego serwera powinna posiadać również galerię dostępnych telefonów wraz z opisami urządzeń. Użytkownik poza dostępem do
swojego konta powinien mieć możliwość wyświetlenia interfejsu przedstawiającego dostępne modele smartfonów, podglądu szczegółów danego modelu
oraz cennika dostępu do niego. Użytkownik przeglądający kolejne modele telefonów powinien mieć również możliwość natychmiastowego wypożyczenia
smartfona i połączenie się z perspektywy podglądu szczegółów telefonu.
6.4
Podsumowanie
Zaprezentowana powyżej wersja systemu stanowi więc jedynie pierwszą część
planowanego przedsięwzięcia. Bowiem wprowadzenie produktu na rynek komercyjny z całą pewnością będzie wymagało jeszcze dużego nakładu pracy.
Biorąc jednak pod uwagę zapotrzebowanie i potencjał dzisiejszego rynku
smartfonów wydaje mi się, w pełnie zasadne, zrealizowanie przedmiotowego
projektu do fazy pozwoli wdrożyć produkt na rynek komercyjny. Ponadto,
obserwując duży sukces firm takich jak Device Everywhere i Xamarin Cloud
można wyciągnąć wnioski, że z całą pewnością na rynku istnieje zapotrzebowanie na analogiczne rozwiązania. Niewykluczone, że spotka się ono z wystarczającym zainteresowaniem użytkowników i w konsekwencji spowoduje,
że dalszy rozwój przedsięwzięcia będzie możliwy.
Spis rysunków
1
Komponenty wykorzystane do zbudowania systemu. . . . . . .
61
5
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Serwer Raspberry Pi połączony z telefonem Samsung Galaxy
Ace za pomocą kable USB i kamerą umożliwiają podgląd wyświetlanego obrazu. . . . . . . . . . . . . . . . . . . . . . . .
Interfejs użytkownika w oknie przeglądarki internetowej. . .
Różnice w wielkościach ekranów w telefonach z systemem operacyjnym Android i OSX. . . . . . . . . . . . . . . . . . . .
Przykładowa wartość pola settings. . . . . . . . . . . . . . .
Diagram przypadków użycia aplikacji "Wypożyczalnia telefonów Android". . . . . . . . . . . . . . . . . . . . . . . . . . .
Raspberry Pi 2. . . . . . . . . . . . . . . . . . . . . . . . . .
Finalna wersja systemu. . . . . . . . . . . . . . . . . . . . .
Raspberry Pi model B+. . . . . . . . . . . . . . . . . . . . .
Kamera dedykowana dla urządzenia Raspberry Pi. . . . . . .
Soczewka typu macro. . . . . . . . . . . . . . . . . . . . . .
Samsung Galaxy Ace. . . . . . . . . . . . . . . . . . . . . . .
Połączenie Raspberry Pi z siecią internetową za pomocą modułu Ethernet. . . . . . . . . . . . . . . . . . . . . . . . . .
Połączenie Raspberry Pi ze smartofnem typu Android za pomocą kabla USB. . . . . . . . . . . . . . . . . . . . . . . . .
Połączenie Raspberry Pi z kamerą za pomocą kabla MIPI. .
Kamera Raspberry Pi w zestawieniu z soczewką typu macro.
Układ pozwalający na nagrywanie obrazu wyświetlanego na
telefonie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
6
7
. 12
. 19
.
.
.
.
.
.
.
20
27
29
30
31
32
33
. 35
. 35
. 36
. 36
. 37
Spis kodów źródłowych
1
2
3
4
5
6
7
8
Przykład żądania UDP w języku Cold Fusion. . . . . . . . . .
Przykład żądania AJAX w języku JavaScript. . . . . . . . . .
Fragment kodu JavaScript odpowiedzialny za odświerzanie podglądu kamery w oknie przeglądarki. . . . . . . . . . . . . . . .
Fragment kodu PHP odpowiedzialny za wysyłanie aktualnego
obrazu kamery do przeglądarki. . . . . . . . . . . . . . . . . .
Fragment kodu HTML stanowiący element w którym wyświetlany jest bieżący podgląd kamery. . . . . . . . . . . . . . . .
Fragment kodu HTML definiujący guziki interfejsu użytkownika.
Fragment kodu javaScript ustawiający metody jakie zostaną
wywołane po wykonaniu kliknięcia na interfejsie użytkownika.
Fragment kodu JavaScript odpowiedzialny za interakcje z serwerem przy pomocy zapytań AJAX. . . . . . . . . . . . . . .
62
23
24
38
39
39
40
40
41
9
10
11
12
13
14
15
Fragment kodu PHP przetwarzający otrzymane zapytanie z
interfejsu użytkownika. . . . . . . . . . . . . . . . . . . . . .
Fragment ustawień pliku suoers umożliwiający wykonywanie
operacji przy wykorzystaniu programu adb bez użycia hasła.
Wynik ekranu konsoli po wydaniu polecenia getevent . . . .
Wynik ekranu konsoli zwracającej informację o wykrytym geście “tap”. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Symulacja wykonania gestu “tap” na telefonie. . . . . . . . .
Fragment kodu JavaScript odpowiedzialny za uzyskanie informacji o współrzędnych ekranu. . . . . . . . . . . . . . . . . .
Klasa obiektu AdbAdapter odpowiadająca za interakcję z telefonem typu android za pomocą programu ADB. . . . . . .
. 43
. 44
. 45
. 46
. 46
. 47
. 49
Literatura
[1] Samsung gt-s5830 ace. http://www.mgsm.pl/pl/katalog/samsung/gts5830ace/.
[2] tracking.js. http://trackingjs.com/. Accessed: 2015-04-27.
[3] AdamOutler. Adb for raspberry pi, October 7 2012.
[4] Ed Burnette. Hello, Android: Introducing Google’s Mobile Development
Platform. Pragmatic Bookshelf, 2nd edition, 2009.
[5] Android Community. bmgr. http://developer.android.com/tools/help/bmgr.html.
[6] Android Community. logcat. http://developer.android.com/tools/help/logcat.html.
[7] Android
Community.
Using
http://developer.android.com/tools/debugging/ddms.html.
ddms.
[8] Kit Eaton. Google isn’t defending android from segmentation—a secret success plan. http://www.fastcompany.com/1745417/google-isntdefending-android-segmentation-secret-success-plan, 2011.
[9] Raspberry Pi Foundation.
Raspberry pi 1
https://www.raspberrypi.org/products/model-b-plus/.
model
b+.
[10] William J. Francis. Speed up your android development cycle with genymotion. http://www.techrepublic.com/blog/software-engineer/speedup-your-android-development-cycle-with-genymotion/, 2013.
63
[11] Greg Hartrell.
Introducing google play game services.
http://googledevelopers.blogspot.com/2013/05/introducing-googleplay-game-services.html, 2013.
[12] Keynote.
Keynote
mobile
testing
http://www.keynote.com/solutions/testing/mobile-testing.
tools.
[13] Marek Konera.
Wprowadzenie do testów automatycznych.
http://kainos.pl/blog/wprowadzenie-do-testow-automatycznych-czesc1/.
[14] Marketing Land. Mobile devices: 30 percent of traffic, 15 percent of
sales, February 28 2014.
[15] Gordon Makryllos.
devices everywhere – it’s time for mobile device management as a service.
http://www.orangebusiness.com/en/blogs/connecting-technology/innovation/devicesdevices-devices-everywhere-it-s-time-for-next-generation-mobile-devicemanagement-as-a-service, 2014.
[16] Meeting.js. Meeting.js » a webrtc library for media streaming.
[17] Ben Nadel. Sending and receiving udp (user datagram protocol) messages with coldfusion. http://www.bennadel.com/blog/2579-sending-andreceiving-udp-user-datagram-protocol-messages-with-coldfusion.htm,
2014.
[18] Oracle. System requirements. http://www.oracle.com/technetwork/java/javaee/documentati
readme-1957703.html.
[19] Patrick O’Rourke. Android’s biggest problem is operating system fragmentation. http://o.canada.com/technology/personal-tech/androidsbiggest-problem-is-operating-system-segmentation, 2014.
[20] IBTimes Staff Reporter. Top ten reasons why people buy smartphones. http://www.ibtimes.co.uk/smartphone-features-camera-browsinggaming-apps-gps-348123, 2012.
[21] Benjamin Travis. Android vs. ios: User differences every developer
should know. http://www.comscore.com/lat/Insights/Blog/Androidvs-iOS-User-Differences-Every-Developer-Should-Know, 2013.
[22] Wikipedia. Android (system operacyjny) — Wikipedia, wolna encyklopedia, 2004.
64
[23] Wikipedia. Ddns — Wikipedia, wolna encyklopedia, 2004.
[24] Wikipedia. Gnu general public license — Wikipedia, wolna encyklopedia, 2004.
[25] Wikipedia. Google play services — Wikipedia, wolna encyklopedia,
2004.
[26] Wikipedia. Hypertext transfer protocol — Wikipedia, wolna encyklopedia, 2004.
[27] Wikipedia. iphone — Wikipedia, wolna encyklopedia, 2004.
[28] Wikipedia. List of most downloaded android applications — Wikipedia,
wolna encyklopedia, 2004.
[29] Wikipedia. Open handset alliance — Wikipedia, wolna encyklopedia,
2004.
[30] Wikipedia. Real-time transport protocol — Wikipedia, wolna encyklopedia, 2004.
[31] Xamarin. Xamarin test cloud. http://xamarin.com/test-cloud.
65

Podobne dokumenty