Najczęstsze pytania

Czy Google używało OTA A/B na jakichkolwiek urządzeniach?

Tak. Nazwa marketingowa aktualizacji A/B to automatyczne aktualizacje. Telefony Pixel i Pixel XL z października 2016 r. są dostarczane z aktualizacją A/B, a wszystkie Chromebooki korzystają z tej samej implementacji A/B.update_engine W Androidzie 7.1 i nowszych niezbędna implementacja kodu platformy jest publiczna.

Dlaczego OTA A/B jest lepszy?

Aktualizacje OTA A/B zapewniają lepsze wrażenia użytkowników podczas instalowania aktualizacji. Pomiary dotyczące comiesięcznych aktualizacji zabezpieczeń wskazują, że ta funkcja już się sprawdziła: w maju 2017 r. 95% właścicieli Pixela korzystało z najnowszej aktualizacji zabezpieczeń po miesiącu, podczas gdy w przypadku Nexusa było to 87%. Użytkownicy Pixela aktualizują urządzenia szybciej niż użytkownicy Nexusa. Niepowodzenia podczas aktualizacji bloków podczas aktualizacji OTA nie będą już powodować, że urządzenie się nie uruchomi. Dopóki nowy obraz systemu nie zostanie uruchomiony, Android będzie mógł wrócić do poprzedniego działającego obrazu systemu.

Co to jest system_other?

Aplikacje są przechowywane w plikach .apk, które są w istocie archiwami ZIP. Każdy plik .apk zawiera co najmniej 1 plik .dex z przenośnym kodem bajtowym Dalvik. Plik .odex (zoptymalizowany plik .dex) znajduje się osobno od pliku .apk i może zawierać kod maszynowy specyficzny dla urządzenia. Jeśli plik .odex jest dostępny, Android może uruchamiać aplikacje z szybkością skompilowania z wyprzedzeniem, bez konieczności czekania na skompilowanie kodu za każdym razem, gdy aplikacja jest uruchamiana. Plik .odex nie jest niezbędny: Android może uruchamiać kod .dex bezpośrednio za pomocą interpretacji lub kompilacji Just-In-Time (JIT), ale jeśli jest dostępna pamięć, plik .odex zapewnia najlepszą kombinację szybkości uruchamiania i szybkości działania.

Przykład: w przypadku pliku installed-files.txt z Nexusa 6P z Androidem 7.1 o łącznym rozmiarze obrazu systemu 2628 MiB (2755792836 bajtów) podział plików według typu, które w największym stopniu zwiększają rozmiar obrazu systemu, wygląda tak:

.odex 1391770312 bajtów 50,5%
.apk 846878259 bajtów 30,7%
.so (kod natywny C/C++) 202162479 bajtów 7,3%
pliki .oat/obrazy .art. 163892188 bajtów 5,9%
Czcionki 38952361 bajtów 1,4%
dane językowe icu 27468687 bajtów 0,9%

Te wartości są podobne w przypadku innych urządzeń, więc na urządzeniach Nexus/Pixel pliki .odex zajmują około połowę partycji systemowej. Oznacza to, że możemy nadal używać ext4, ale zapisywać pliki .odex na partycji B w fabryce, a potem kopiować je na /data podczas pierwszego uruchamiania. Rzeczywiste miejsce na dane używane przez ext4 A/B jest identyczne z miejscem na dane SquashFS A/B, ponieważ gdybyśmy użyli SquashFS, wysłalibyśmy wstępnie wybrane pliki .odex na system_a zamiast na system_b.

Czy kopiowanie plików .odex do katalogu /data nie powoduje utraty miejsca w katalogu /data?

Niezupełnie. Na Pixelu większość miejsca zajmowanego przez pliki .odex jest przeznaczona na aplikacje, które zwykle znajdują się w miejscu /data. Te aplikacje pobierają aktualizacje z Google Play, więc pliki APK i ODEX w pliku obrazu systemu przez większość czasu nie są używane. Takie pliki można całkowicie wykluczyć i zastąpić małymi plikami .odex zależnymi od profilu, gdy użytkownik faktycznie korzysta z konkretnej aplikacji (dzięki czemu nie trzeba zajmować miejsca na aplikacje, których użytkownik nie używa). Więcej informacji znajdziesz w prezentacji z Google I/O 2016 Ewolucja sztuki.

Porównanie jest trudne z kilku głównych powodów:

  • Aplikacje aktualizowane przez Google Play mają pliki .odex w wersji /data od momentu otrzymania pierwszej aktualizacji.
  • Aplikacje, których użytkownik nie uruchamia, nie wymagają pliku .odex.
  • Kompilacja na podstawie profilu generuje mniejsze pliki .odex niż kompilacja z wyprzedzeniem (ponieważ optymalizuje tylko kod o krytycznym znaczeniu dla wydajności).

Szczegółowe informacje o opcjach dostrajania dostępnych dla producentów OEM znajdziesz w artykule Konfigurowanie ART.

Czy w katalogu /data nie ma 2 kopii plików .odex?

Jest to nieco bardziej skomplikowane... Po zapisaniu nowego obrazu systemu nowa wersja dex2oat jest uruchamiana na nowych plikach DEX, aby wygenerować nowe pliki ODEX. Dzieje się tak, gdy stary system nadal działa, więc stare i nowe pliki .odex są jednocześnie dostępne na/data.

Kod w OtaDexoptService (frameworks/base/+/main/services/core/java/com/android/server/pm/OtaDexoptService.java) wywołuje funkcję getAvailableSpace przed zoptymalizowaniem każdego pakietu, aby uniknąć przepełnienia./data Pamiętaj, że dostępne to nadal konserwatywne określenie: to ilość miejsca przed osiągnięciem zwykłego progu niskiego miejsca w systemie (mierzonego jako odsetek i liczba bajtów). Jeśli /data jest pełna, nie będzie dwóch kopii każdego pliku .odex. Ten sam kod zawiera też BULK_DELETE_THRESHOLD: jeśli urządzenie zbliża się do zapełnienia dostępnej przestrzeni (jak opisano powyżej), pliki .odex należące do aplikacji, których nie używasz, są usuwane. To kolejny przypadek bez dwóch kopii każdego pliku .odex.

W najgorszym przypadku, gdy /data jest całkowicie pełny, aktualizacja czeka, aż urządzenie uruchomi się ponownie z nowym systemem i nie będzie już potrzebować plików .odex ze starego systemu. Zarządzanie tym procesem zapewnia PackageManager (frameworks/base/+/main/services/core/java/com/android/server/pm/PackageManagerService.java#7215). Po uruchomieniu nowego systemu installd (frameworks/native/+/main/cmds/installd/dexopt.cpp#2422) może usunąć pliki .odex używane przez stary system, przywracając urządzenie do stanu stabilnego, w którym jest tylko jedna kopia.

Chociaż /data może zawierać 2 kopie wszystkich plików .odex, (a) jest to tymczasowe i (b) występuje tylko wtedy, gdy na /data jest dużo wolnego miejsca. Z wyjątkiem aktualizacji jest tylko jedna kopia. W ramach ogólnych funkcji odporności ART nigdy nie wypełni /data plikami .odex (ponieważ byłoby to problemem również w systemie innym niż A/B).

Czy pisanie i kopiowanie nie zwiększa zużycia pamięci flash?

Przepisana zostaje tylko niewielka część pamięci flash: pełna aktualizacja systemu Pixela zapisuje około 2,3 GB. (aplikacje są też ponownie kompilowane, ale dotyczy to również testów niebędących testami A/B). Tradycyjnie pełne OTA na podstawie bloków zapisywały podobną ilość danych, więc stopnie zużycia pamięci flash powinny być podobne.

Czy przeflashowanie dwóch partycji systemu wydłuża czas flashowania fabrycznego?

Nie. Rozmiar obrazu systemu w Pixelu nie wzrósł (został podzielony na 2 partycje).

Czy przechowywanie plików .odex na dysku B nie powoduje spowolnienia ponownego uruchamiania po przywróceniu danych fabrycznych?

Tak. Jeśli urządzenie było używane, zostało zaktualizowane przez OTA i przywrócono na nim ustawienia fabryczne, pierwszy rozruch będzie wolniejszy niż zwykle (1 minuta i 40 sekund w przypadku Pixela XL w porównaniu z 40 sekundami), ponieważ po pierwszej aktualizacji OTA pliki .odex zostaną utracone na urządzeniu B, przez co nie będzie można ich skopiować na /data. To jest kompromis.

Przywracanie ustawień fabrycznych powinno być rzadką operacją w porównaniu z normalnym uruchamianiem, więc czas potrzebny na jej wykonanie jest mniej istotny. (Nie dotyczy to użytkowników ani recenzentów, którzy otrzymali urządzenie bezpośrednio od producenta, ponieważ w takim przypadku dostępna jest partycja B). Korzystanie z kompilatora JIT oznacza, że nie musimy ponownie kompilować wszystkiego, więc nie jest to aż tak źle, jak mogłoby się wydawać. Można też oznaczyć aplikacje jako wymagające wstępnej kompilacji, używając w pliku manifestu elementu coreApp="true": (frameworks/base/+/main/packages/SystemUI/AndroidManifest.xml#23). Obecnie używa tego system_server, ponieważ ze względów bezpieczeństwa nie może korzystać z kompilacji na żądanie.

Czy przechowywanie plików .odex w folderze /data zamiast w folderze /system nie powoduje spowolnienia ponownego uruchamiania po aktualizacji OTA?

Nie. Jak już wspomniano powyżej, nowy dex2oat jest uruchamiany, gdy nadal działa stary obraz systemu, aby wygenerować pliki potrzebne nowemu systemowi. Aktualizacja jest uważana za dostępną dopiero po wykonaniu tych czynności.

Czy możemy (powinniśmy) wysłać urządzenie A/B o pojemności 32 GB? 16 GiB? 8 GiB?

32 GB działa dobrze, co zostało potwierdzone na Pixelu, a 320 MiB z 16 GB oznacza redukcję o 2%. Podobnie 320 MiB z 8 GiB to redukcja o 4%. Oczywiście na urządzeniach z 4 GB pamięci nie zalecamy korzystania z testów A/B, ponieważ obciążenie 320 MB to prawie 10% całkowitej dostępnej przestrzeni.

Czy AVB 2.0 wymaga OTA A/B?

Nie. Sprawdzanie poprawności uruchamiania w Androidzie zawsze wymagało aktualizacji na podstawie bloków, ale niekoniecznie aktualizacji A/B.

Czy OTA A/B wymaga AVB 2.0?

Nie.

Czy OTA A/B narusza ochronę przed cofnięciem w Androidzie AVB2.0?

Nie. Jest tu pewne zamieszanie, ponieważ jeśli system A/B nie uda się uruchomić z nowego obrazu systemu, automatycznie (po kilku próbach określonych przez bootloader) wróci do „poprzedniego” obrazu systemu. Najważniejsze jest jednak to, że „poprzedni” w ujęciu A/B oznacza nadal „aktualny” obraz systemu. Gdy tylko urządzenie uruchomi nowy obraz, ochrona przed cofnięciem wprowadzi zabezpieczenie, które uniemożliwi Ci cofnięcie. Dopóki jednak nie uruchomisz nowego obrazu, ochrona przed cofnięciem nie uzna go za bieżący obraz systemu.

Czy instalowanie aktualizacji przy włączonym systemie nie jest powolne?

W przypadku aktualizacji innych niż A/B celem jest jak najszybsze zainstalowanie aktualizacji, ponieważ użytkownik musi czekać i nie może korzystać z urządzenia, gdy jest ono aktualizowane. W przypadku aktualizacji A/B jest odwrotnie: użytkownik nadal używa urządzenia, więc celem jest jak najmniejszy wpływ aktualizacji, dlatego jest ona celowo powolna. Dzięki logice w kliencie aktualizacji systemu Java (w przypadku Google jest to GmsCore, czyli podstawowy pakiet dostarczany przez GMS) Android próbuje też wybrać czas, gdy użytkownicy w ogóle nie korzystają z urządzeń. Platforma obsługuje wstrzymywanie i wznawianie aktualizacji, a klient może skorzystać z tej funkcji, aby wstrzymać aktualizację, gdy użytkownik zacznie korzystać z urządzenia, i wznowić ją, gdy urządzenie znowu będzie nieaktywne.

W ramach aktualizacji OTA występują 2 fazy, wyraźnie widoczne w interfejsie jako Krok 1 z 2Krok 2 z 2 pod paskiem postępu. Krok 1 odpowiada zapisywaniu bloków danych, a krok 2 to wstępna kompilacja plików .dex. Te 2 fazy mają odmienny wpływ na wydajność. Pierwsza faza to proste operacje wejścia/wyjścia. Nie wymaga to wielu zasobów (pamięci RAM, procesora, operacji wejścia/wyjścia), ponieważ polega tylko na powolnym kopiowaniu bloków.

Druga faza uruchamia dex2oat, aby wstępnie skompilować nowy obraz systemu. W tym przypadku wymagania są oczywiście mniej wyraźnie określone, ponieważ kompilator kompiluje rzeczywiste aplikacje. Kompilacja dużej i złożonej aplikacji wymaga oczywiście znacznie więcej pracy niż w przypadku małej i prostej aplikacji. W etapie 1 nie ma bloków dyskowych, które byłyby większe lub bardziej złożone niż inne.

Proces jest podobny do tego, gdy Google Play instaluje aktualizację aplikacji w tle, zanim wyświetli powiadomienie 5 aplikacji zostało zaktualizowanych. Robi tak od lat.

Co zrobić, jeśli użytkownik faktycznie czeka na aktualizację?

Obecna implementacja w GmsCore nie rozróżnia aktualizacji w tle i aktualizacji inicjowanych przez użytkownika, ale może to zrobić w przyszłości. Jeśli użytkownik wyraźnie poprosi o zainstalowanie aktualizacji lub będzie obserwować ekran z postępem aktualizacji, damy priorytet pracy nad aktualizacją, zakładając, że użytkownik aktywnie czeka na jej zakończenie.

Co się stanie, jeśli nie uda się zastosować aktualizacji?

W przypadku aktualizacji innych niż A/B, jeśli aktualizacja nie została zastosowana, użytkownik zwykle nie mógł korzystać z urządzenia. Jedynym wyjątkiem jest sytuacja, gdy błąd wystąpił jeszcze przed uruchomieniem aplikacji (np. z powodu nieudanej weryfikacji pakietu). W przypadku aktualizacji A/B nieudane zastosowanie aktualizacji nie wpływa na obecnie działający system. Aktualizację można po prostu powtórzyć później.