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