From c382adc88285c8b889335707c5ea1d8acad7a03c Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Fri, 26 Apr 2019 11:45:31 -0700 Subject: Wallpaper picker fixes Do not keep display size cached, if we keep the size cached in a singleton then config changes won't be reflected and WPP will crash. Also default to minZoom in PreviewFragment. Fixes: 117099627 Fixes: 117559479 Change-Id: I4da7f8df130cc093883c18ae329d9677c6b2d05a --- src/com/android/wallpaper/picker/PreviewFragment.java | 2 +- src/com/android/wallpaper/util/ScreenSizeCalculator.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/android/wallpaper/picker/PreviewFragment.java b/src/com/android/wallpaper/picker/PreviewFragment.java index 33767ee..1c3c56b 100755 --- a/src/com/android/wallpaper/picker/PreviewFragment.java +++ b/src/com/android/wallpaper/picker/PreviewFragment.java @@ -794,7 +794,7 @@ public class PreviewFragment extends Fragment implements centerPosition.offset( - (screenToCropSurfacePosition.x + cropSurfaceToWallpaperPosition.x), - (screenToCropSurfacePosition.y + cropSurfaceToWallpaperPosition.y)); - mFullResImageView.setScaleAndCenter(defaultWallpaperZoom, centerPosition); + mFullResImageView.setScaleAndCenter(minWallpaperZoom, centerPosition); } protected Rect calculateCropRect() { diff --git a/src/com/android/wallpaper/util/ScreenSizeCalculator.java b/src/com/android/wallpaper/util/ScreenSizeCalculator.java index 49148c3..d55cf99 100755 --- a/src/com/android/wallpaper/util/ScreenSizeCalculator.java +++ b/src/com/android/wallpaper/util/ScreenSizeCalculator.java @@ -73,16 +73,16 @@ public class ScreenSizeCalculator { private Point getPortraitScreenSize(Display display) { if (mPortraitScreenSize == null) { mPortraitScreenSize = new Point(); - writeDisplaySizeToPoint(display, mPortraitScreenSize); } + writeDisplaySizeToPoint(display, mPortraitScreenSize); return mPortraitScreenSize; } private Point getLandscapeScreenSize(Display display) { if (mLandscapeScreenSize == null) { mLandscapeScreenSize = new Point(); - writeDisplaySizeToPoint(display, mLandscapeScreenSize); } + writeDisplaySizeToPoint(display, mLandscapeScreenSize); return mLandscapeScreenSize; } -- cgit v1.2.3 From 2156b3a0a1753a67025250fdcaaead7f233a9f87 Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Tue, 30 Apr 2019 17:24:15 -0700 Subject: [DO NOT MERGE] Update target SDK Bug: 115925295 Change-Id: I53b344b771e5ad7bcb9c77b15de68e3e59fbb092 --- AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 690afd1..af8b4db 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -5,7 +5,7 @@ + android:targetSdkVersion="28"/> -- cgit v1.2.3 From f8129bc20a61808fb3969cd335465f6cbd146c33 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 25 May 2019 18:23:59 -0700 Subject: Import translations. DO NOT MERGE Change-Id: Iae2825675a50be58f3b95363d4898138eb826c68 Auto-generated-cl: translation import --- res/values-af/strings.xml | 4 +++- res/values-am/strings.xml | 4 +++- res/values-ar/strings.xml | 6 ++++-- res/values-as/strings.xml | 4 +++- res/values-az/strings.xml | 4 +++- res/values-b+sr+Latn/strings.xml | 8 +++++--- res/values-be/strings.xml | 4 +++- res/values-bg/strings.xml | 4 +++- res/values-bn/strings.xml | 4 +++- res/values-bs/strings.xml | 4 +++- res/values-ca/strings.xml | 4 +++- res/values-cs/strings.xml | 4 +++- res/values-da/strings.xml | 4 +++- res/values-de/strings.xml | 6 ++++-- res/values-el/strings.xml | 4 +++- res/values-en-rAU/strings.xml | 4 +++- res/values-en-rGB/strings.xml | 4 +++- res/values-en-rIN/strings.xml | 4 +++- res/values-es-rUS/strings.xml | 4 +++- res/values-es/strings.xml | 4 +++- res/values-et/strings.xml | 4 +++- res/values-eu/strings.xml | 6 ++++-- res/values-fa/strings.xml | 4 +++- res/values-fi/strings.xml | 4 +++- res/values-fr-rCA/strings.xml | 4 +++- res/values-fr/strings.xml | 4 +++- res/values-gl/strings.xml | 4 +++- res/values-gu/strings.xml | 4 +++- res/values-hi/strings.xml | 4 +++- res/values-hr/strings.xml | 4 +++- res/values-hu/strings.xml | 4 +++- res/values-hy/strings.xml | 4 +++- res/values-in/strings.xml | 6 ++++-- res/values-is/strings.xml | 4 +++- res/values-it/strings.xml | 4 +++- res/values-iw/strings.xml | 4 +++- res/values-ja/strings.xml | 4 +++- res/values-ka/strings.xml | 4 +++- res/values-kk/strings.xml | 6 ++++-- res/values-km/strings.xml | 4 +++- res/values-kn/strings.xml | 4 +++- res/values-ko/strings.xml | 4 +++- res/values-ky/strings.xml | 4 +++- res/values-lo/strings.xml | 4 +++- res/values-lt/strings.xml | 4 +++- res/values-lv/strings.xml | 4 +++- res/values-mk/strings.xml | 4 +++- res/values-ml/strings.xml | 6 ++++-- res/values-mn/strings.xml | 4 +++- res/values-mr/strings.xml | 4 +++- res/values-ms/strings.xml | 4 +++- res/values-my/strings.xml | 4 +++- res/values-nb/strings.xml | 4 +++- res/values-ne/strings.xml | 4 +++- res/values-nl/strings.xml | 6 ++++-- res/values-or/strings.xml | 4 +++- res/values-pa/strings.xml | 4 +++- res/values-pl/strings.xml | 4 +++- res/values-pt-rPT/strings.xml | 4 +++- res/values-pt/strings.xml | 4 +++- res/values-ro/strings.xml | 4 +++- res/values-ru/strings.xml | 4 +++- res/values-si/strings.xml | 6 ++++-- res/values-sk/strings.xml | 4 +++- res/values-sl/strings.xml | 4 +++- res/values-sq/strings.xml | 4 +++- res/values-sr/strings.xml | 8 +++++--- res/values-sv/strings.xml | 4 +++- res/values-sw/strings.xml | 4 +++- res/values-ta/strings.xml | 8 +++++--- res/values-te/strings.xml | 4 +++- res/values-th/strings.xml | 4 +++- res/values-tl/strings.xml | 4 +++- res/values-tr/strings.xml | 4 +++- res/values-uk/strings.xml | 6 ++++-- res/values-ur/strings.xml | 4 +++- res/values-uz/strings.xml | 4 +++- res/values-vi/strings.xml | 8 +++++--- res/values-zh-rCN/strings.xml | 4 +++- res/values-zh-rHK/strings.xml | 6 ++++-- res/values-zh-rTW/strings.xml | 4 +++- res/values-zu/strings.xml | 4 +++- 82 files changed, 264 insertions(+), 100 deletions(-) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 550ee32..ea86de2 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -20,7 +20,7 @@ "Muurpapiere" - "Kies muurpapier" + "Muurpapierkategorieë" "Stel muurpapier" "Stel tans muurpapier …" "Probeer weer" @@ -28,6 +28,7 @@ "Kan nie muurpapier laai nie. Die prent is óf korrup óf onbeskikbaar." "Tans gestel" "Daaglikse muurpapier" + "Tuis- en sluitskerm" "Tuisskerm" "Sluitskerm" "Tuis- en sluitskerm" @@ -78,4 +79,5 @@ "Middel" "Gesentreerde snoei" "Rek" + "Voorskou" diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index ab05383..bca3e97 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -20,7 +20,7 @@ "ልጣፎች" - "ልጣፍ ይምረጡ" + "የልጣፍ ምድቦች" "ልጣፍ ያዘጋጁ" "ልጣፍን በማዘጋጀት ላይ…" "እንደገና ሞክር" @@ -28,6 +28,7 @@ "ወደ ልጣፍ መጫን አልተቻለም። ምስሉ የተበላሸ ወይም የማይገኝ ነው።" "በአሁኑ ጊዜ የተዘጋጀ" "ዕለታዊ ልጣፍ" + "መነሻ ገጽ እና የማያ ገጽ ቁልፍ" "መነሻ ገጽ" "ማያ ገጽ ቁልፍ" "መነሻ እና ቁልፍ" @@ -78,4 +79,5 @@ "መሃል" "መሃል ላይ ከርክም" "ወጥር" + "ቅድመ-እይታ" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 8a91483..2a6c183 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -20,14 +20,15 @@ "الخلفيات" - "اختيار خلفية" + "فئات الخلفيات" "تعيين كخلفية" "جارٍ تعيين الخلفية…" "إعادة المحاولة" "يتعذّر تعيين الخلفية." "يتعذّر تحميل الخلفية. قد تكون الصورة تالفة أو غير متاحة." - "خلفية معيَّنة حاليًا" + "الخلفية المختارة حاليًا" "خلفية يومية" + "الشاشة الرئيسية وشاشة التأمين" "الشاشة الرئيسية" "شاشة التأمين" "الشاشة الرئيسية وشاشة التأمين" @@ -78,4 +79,5 @@ "توسيط" "توسيط مع اقتصاص المساحة الزائدة" "توسيع للعرض بملء الشاشة" + "معاينة" diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index fe25627..95a66fd 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -20,7 +20,7 @@ "ৱালপেপাৰ" - "ৱালপেপাৰ বাছনি কৰক" + "ৱালপেপাৰৰ শিতানসমূহ" "ৱালপেপাৰ ছেট কৰক" "ৱালপেপাৰ ছেট কৰি থকা হৈছে…" "আকৌ চেষ্টা কৰক" @@ -28,6 +28,7 @@ "ৱালপেপাৰ ল\'ড কৰিব পৰা নগ\'ল। প্ৰতিচ্ছবিখন ব্যৱহাৰযোগ্য নহয় বা উপলব্ধ নহয়।" "বর্তমান ছেট কৰি থোৱা ৱালপেপাৰ" "দৈনিক ৱালপেপাৰ" + "গৃহ আৰু লক স্ক্ৰীণ" "গৃহ স্ক্ৰীণ" "লক স্ক্ৰীণ" "গৃহ স্ক্ৰীণ আৰু লক স্ক্ৰীণ" @@ -78,4 +79,5 @@ "সোঁমাজত" "মধ্য অংশৰ পৰা কৰা ক্ৰপ" "প্ৰসাৰিত" + "পূৰ্বদৰ্শন" diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 9df06f6..162d0c9 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -20,7 +20,7 @@ "Divar kağızları" - "Divar kağızı seçin" + "Divar kağızı kateqoriyaları" "Divar kağızı ayarlayın" "Divar kağızı ayarlanır..." "Yenidən sınayın" @@ -28,6 +28,7 @@ "Divar kağızını yükləmək olmadı. Şəkil ya zədələnib, ya da əlçatan deyil." "Hazırda ayarlanıb" "Günlük divar kağızları" + "Əsas səhifə & Ekran kilidi" "Əsas ekran" "Ekran kilidi" "Əsas səhifə və Kilid" @@ -78,4 +79,5 @@ "Mərkəz" "Mərkəzi kəsim" "Dartın" + "Önizləmə" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 35462dd..b005851 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -20,7 +20,7 @@ "Pozadine" - "Izaberite pozadinu" + "Kategorije pozadina" "Podesi pozadinu" "Podešava se pozadina…" "Probajte ponovo" @@ -28,12 +28,13 @@ "Učitavanje pozadine nije uspelo. Slika je oštećena ili nije dostupna." "Trenutno podešena" "Dnevna pozadina" + "Početni i zaključani ekran" "Početni ekran" - "Zaključani ekran" + "Zaključan ekran" "Početni i zaključani ekran" "Podesite pozadinu" "Početni ekran" - "Zaključani ekran" + "Zaključan ekran" "Početni ekran i zaključani ekran" "Rotirajuća pozadina sa slikom" "Da bi se aktuelna pozadina prikazivala ovde, aplikacija %1$s treba da ima pristup memorijskom prostoru na uređaju." @@ -78,4 +79,5 @@ "Centar" "Opseci u centru" "Razvuci" + "Pregled" diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 7907583..bfb434f 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -20,7 +20,7 @@ "Шпалеры" - "Выберыце шпалеры" + "Катэгорыі шпалер" "Усталяваць як шпалеры" "Усталяванне шпалер…" "Паўтарыць спробу" @@ -28,6 +28,7 @@ "Немагчыма загрузіць шпалеры. Відарыс пашкоджаны або недаступны." "Усталяванае як шпалеры" "Шпалеры на кожны дзень" + "Галоўная старонка і экран блакіроўкі" "Галоўны экран" "Экран блакіроўкі" "Стандартна" @@ -78,4 +79,5 @@ "Размясціць па цэнтры" "Запоўніць" "Расцягнуць" + "Перадпрагляд" diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 4f93889..4953524 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -20,7 +20,7 @@ "Тапети" - "Изберете тапет" + "Категории на тапетите" "Задаване на тапета" "Тапетът се задава…" "Нов опит" @@ -28,6 +28,7 @@ "Тапетът не може да се зареди. Изображението е повредено или не е налично." "Зададено понастоящем" "Тапет за деня" + "Начален и заключен екран" "Начален екран" "Заключен екран" "Начален и заключен екран" @@ -78,4 +79,5 @@ "Центриране" "Центриране с подрязване" "Разтегляне" + "Визуализация" diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 98528d2..d51734f 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -20,7 +20,7 @@ "ওয়ালপেপার" - "ওয়ালপেপার বেছে নিন" + "ওয়ালপেপারের বিভাগ" "ওয়ালপেপার সেট করুন" "ওয়ালপেপার সেট করা হচ্ছে…" "আবার চেষ্টা করুন" @@ -28,6 +28,7 @@ "ওয়ালপেপার লোড করা গেল না। ছবিটি হয়ত খারাপ হয়ে গেছে বা সেটি উপলভ্য নয়।" "বর্তমানে সেট করা রয়েছে" "প্রতিদিনের ওয়ালপেপার" + "হোম ও লক স্ক্রিন" "হোম স্ক্রিন" "লক স্ক্রিন" "হোম ও লক" @@ -78,4 +79,5 @@ "মাঝখানে" "সীমানার দিকে কাটছাঁট করা" "প্রসারিত" + "প্রিভিউ" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index cf64412..167b77f 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -20,7 +20,7 @@ "Pozadinske slike" - "Odaberite pozadinsku sliku" + "Kategorije pozadinskih slika" "Postavi pozadinsku sliku" "Postavljanje pozadinske slike…" "Pokušaj ponovo" @@ -28,6 +28,7 @@ "Nije moguće učitati pozadinsku sliku. Slika je oštećena ili nije dostupna." "Trenutno se koristi" "Dnevna pozadinska slika" + "Početni ekran i zaključani ekran" "Početni ekran" "Zaključavanje ekrana" "Početni i zaključani ekran" @@ -78,4 +79,5 @@ "Sredina" "Sredina s odrezanim rubovima" "Razvučeno" + "Pregled" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 1759a67..b2fd98d 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -20,7 +20,7 @@ "Fons de pantalla" - "Selecciona un fons de pantalla" + "Categories de fons de pantalla" "Estableix el fons de pantalla" "S\'està establint el fons de pantalla…" "Torna-ho a provar" @@ -28,6 +28,7 @@ "No es pot carregar el fons de pantalla. La imatge està malmesa o bé no està disponible." "Establert actualment" "Fons de pantalla diari" + "Pantalla d\'inici i de bloqueig" "Pantalla d\'inici" "Pantalla de bloqueig" "Pantalla d\'inici i de bloqueig" @@ -78,4 +79,5 @@ "Centra" "Centra i retalla" "Amplia" + "Previsualitza" diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index fd57881..cebf392 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -20,7 +20,7 @@ "Tapety" - "Výběr tapety" + "Kategorie tapet" "Nastavit jako tapetu" "Nastavování tapety…" "Zkusit znovu" @@ -28,6 +28,7 @@ "Tapetu se nepodařilo načíst. Obrázek je poškozený nebo není k dispozici." "Aktuálně nastaveno" "Denní tapeta" + "Plocha a obrazovka uzamčení" "Plocha" "Obrazovka uzamčení" "Plocha a uzamknutí" @@ -78,4 +79,5 @@ "Vycentrovat" "Vycentrovat a oříznout" "Roztáhnout" + "Náhled" diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 5add57c..049affe 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -20,7 +20,7 @@ "Baggrunde" - "Vælg baggrund" + "Kategorier for baggrunde" "Angiv baggrund" "Angiver baggrund…" "Prøv igen" @@ -28,6 +28,7 @@ "Baggrunden kan ikke indlæses. Billedet er enten beskadiget eller ikke tilgængeligt." "Nuværende" "Daglig baggrund" + "Start- og låseskærm" "Startskærm" "Låseskærm" "Start- og låseskærm" @@ -78,4 +79,5 @@ "Centrer" "Centrer og beskær" "Stræk" + "Forhåndsvisning" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index d88eece..48bb948 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -20,7 +20,7 @@ "Hintergründe" - "Hintergrund auswählen" + "Hintergrundkategorien" "Als Hintergrund festlegen" "Hintergrund wird festgelegt…" "Noch einmal versuchen" @@ -28,6 +28,7 @@ "Der Hintergrund konnte nicht geladen werden. Das Bild ist entweder beschädigt oder nicht verfügbar." "Derzeit festgelegt" "Täglicher Hintergrund" + "Startbildschirm & Sperrbildschirm" "Startbildschirm" "Sperrbildschirm" "Startbildschirm & Sperrbildschirm" @@ -42,7 +43,7 @@ "Live-Hintergrunddienst mit rotierenden Bildern" "Täglicher Hintergrund" "Zum Aktivieren tippen" - "Hintergrund ändert sich automatisch jeden Tag. Um die Einrichtung abzuschließen, tippen Sie auf dem nächsten Bildschirm auf <strong>Als Hintergrund festlegen</strong>." + "Hintergrund ändert sich automatisch jeden Tag. Um die Einrichtung abzuschließen, tippe auf dem nächsten Bildschirm auf <strong>Als Hintergrund festlegen</strong>." "Neue Hintergründe nur über WLAN herunterladen" "Weiter" "Erster Hintergrund wird heruntergeladen…" @@ -78,4 +79,5 @@ "Zentriert" "Zentriert anpassen" "Strecken" + "Vorschau" diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 30807f5..d14cc2b 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -20,7 +20,7 @@ "Ταπετσαρίες" - "Επιλογή ταπετσαρίας" + "Κατηγορίες ταπετσαρίας" "Ορισμός ταπετσαρίας" "Ορισμός ταπετσαρίας…" "Δοκιμάστε ξανά" @@ -28,6 +28,7 @@ "Δεν είναι δυνατή η φόρτωση της ταπετσαρίας. Η εικόνα είναι κατεστραμμένη ή δεν είναι διαθέσιμη." "Έχει οριστεί" "Ημερήσια ταπετσαρία" + "Αρχική οθόνη και οθόνη κλειδώματος" "Αρχική οθόνη" "Οθόνη κλειδώματος" "Αρχική και κλειδώματος" @@ -78,4 +79,5 @@ "Κέντρο" "Περικοπή στο κέντρο" "Τέντωμα" + "Προεπισκόπηση" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 01cd559..158ce10 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -20,7 +20,7 @@ "Wallpapers" - "Select wallpaper" + "Wallpaper categories" "Set Wallpaper" "Setting wallpaper…" "Try again" @@ -28,6 +28,7 @@ "Unable to load wallpaper. The image is either corrupted or unavailable." "Currently set" "Daily wallpaper" + "Home & Lock screen" "Home screen" "Lock screen" "Home & Lock" @@ -78,4 +79,5 @@ "Centre" "Centre crop" "Stretch" + "Preview" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 01cd559..158ce10 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -20,7 +20,7 @@ "Wallpapers" - "Select wallpaper" + "Wallpaper categories" "Set Wallpaper" "Setting wallpaper…" "Try again" @@ -28,6 +28,7 @@ "Unable to load wallpaper. The image is either corrupted or unavailable." "Currently set" "Daily wallpaper" + "Home & Lock screen" "Home screen" "Lock screen" "Home & Lock" @@ -78,4 +79,5 @@ "Centre" "Centre crop" "Stretch" + "Preview" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 01cd559..158ce10 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -20,7 +20,7 @@ "Wallpapers" - "Select wallpaper" + "Wallpaper categories" "Set Wallpaper" "Setting wallpaper…" "Try again" @@ -28,6 +28,7 @@ "Unable to load wallpaper. The image is either corrupted or unavailable." "Currently set" "Daily wallpaper" + "Home & Lock screen" "Home screen" "Lock screen" "Home & Lock" @@ -78,4 +79,5 @@ "Centre" "Centre crop" "Stretch" + "Preview" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index d565340..a95e589 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -20,7 +20,7 @@ "Fondos de pantalla" - "Seleccionar el fondo de pantalla" + "Categorías de fondos de pantalla" "Definir como fondo de pantalla" "Estableciendo como fondo de pantalla…" "Reintentar" @@ -28,6 +28,7 @@ "No se puede cargar el fondo de pantalla. La imagen está dañada o no está disponible." "Establecido actualmente" "Fondo de pantalla diario" + "Pantalla principal y bloqueada" "Pantalla principal" "Pantalla bloqueada" "Pantalla principal y bloqueada" @@ -78,4 +79,5 @@ "Centrar" "Recortar y centrar" "Estirar" + "Vista previa" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 4368d30..f28956d 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -20,7 +20,7 @@ "Fondos de pantalla" - "Selecciona un fondo de pantalla" + "Categorías de fondos de pantalla" "Establecer fondo de pantalla" "Estableciendo fondo de pantalla…" "Reintentar" @@ -28,6 +28,7 @@ "No se puede cargar el fondo de pantalla. La imagen no está disponible o está dañada." "Configurado actualmente" "Fondo de pantalla diario" + "Pantalla de inicio y bloqueo" "Pantalla de inicio" "Pantalla de bloqueo" "Inicio y bloqueo" @@ -78,4 +79,5 @@ "Centrar" "Recortar el centro" "Expandir" + "Vista previa" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index a8fb28f..8216c44 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -20,7 +20,7 @@ "Taustapildid" - "Taustapildi valimine" + "Taustapiltide kategooriad" "Määra taustapilt" "Taustapildi määramine …" "Proovi uuesti" @@ -28,6 +28,7 @@ "Taustapilti ei saa laadida. Pilt on rikutud või pole saadaval." "Praegu määratud" "Päeva taustapilt" + "Ava- ja lukustuskuva" "Avaekraan" "Lukustuskuva" "Avaekraan ja lukustuskuva" @@ -78,4 +79,5 @@ "Keskele" "Keskele kärpimine" "Venitamine" + "Eelvaade" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index c1e1587..ef4d945 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -20,14 +20,15 @@ "Horma-paperak" - "Hautatu horma-papera" + "Horma-paperen kategoriak" "Ezarri horma-papera" "Horma-papera ezartzen…" "Saiatu berriro" "Ezin da ezarri horma-papera." "Ezin da kargatu horma-papera. Irudia hondatuta dago edo ezin da eskuratu." - "Ezarrita dago" + "Hau dago ezarrita:" "Eguneko horma-papera" + "Hasieran eta pantaila blokeatuan" "Hasierako pantaila" "Pantaila blokeatua" "Hasieran + pantaila blokeatuan" @@ -78,4 +79,5 @@ "Erdian" "Erdian, moztuta" "Pantailara egokituta" + "Aurreikusi" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 0ac08b5..898c514 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -20,7 +20,7 @@ "کاغذدیواری" - "انتخاب کاغذ‌دیواری" + "دسته‌های کاغذدیواری" "تنظیم کاغذ‌دیواری" "در حال تنظیم کاغذدیواری..." "امتحان مجدد" @@ -28,6 +28,7 @@ "کاغذدیواری باز نشد. تصویر خراب است یا دردسترس نیست." "درحال حاضر تنظیم‌ شده است" "کاغذ‌دیواری روزانه" + "صفحه اصلی و صفحه قفل" "صفحه اصلی" "صفحه در حالت قفل" "صفحه اصلی و صفحه در حالت قفل" @@ -78,4 +79,5 @@ "وسط" "برش از مرکز برای پر کردن صفحه." "کشیدن برای پر کردن صفحه" + "پیش‌نمایش" diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 105064f..2a5d754 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -20,7 +20,7 @@ "Taustakuvat" - "Valitse taustakuva" + "Taustakuvaluokat" "Aseta taustakuva" "Asetetaan taustakuvaa…" "Yritä uudelleen" @@ -28,6 +28,7 @@ "Taustakuvan lataaminen epäonnistui. Kuva on joko vioittunut tai se ei ole käytettävissä." "Nykyinen taustakuva" "Päivän taustakuva" + "Aloitus- ja lukitusnäyttö" "Aloitusnäyttö" "Lukitusnäyttö" "Aloitus- ja lukitusnäyttö" @@ -78,4 +79,5 @@ "Keskusta" "Keskirajaus" "Venytä" + "Esikatselu" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index ed9d5a1..539256a 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -20,7 +20,7 @@ "Fonds d\'écran" - "Sélectionnez un fond d\'écran" + "Catégories de fond d\'écran" "Définir le fond d\'écran" "Définition du fond d\'écran en cours…" "Réessayer" @@ -28,6 +28,7 @@ "Impossible de charger le fond d\'écran. L\'image est corrompue ou n\'est pas accessible." "Fond d\'écran actuel" "Fond d\'écran quotidien" + "Écrans d\'accueil et de verrouillage" "Écran d\'accueil" "Écran de verrouillage" "Écr. d\'accueil et de verrouill." @@ -78,4 +79,5 @@ "Centrer" "Rogné au centre" "Étiré" + "Aperçu" diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index ea64132..f075e19 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -20,7 +20,7 @@ "Fonds d\'écran" - "Sélectionner un fond d\'écran" + "Catégories de fonds d\'écran" "Définir comme fond d\'écran" "Définition du fond d\'écran…" "Réessayer" @@ -28,6 +28,7 @@ "Impossible de charger le fond d\'écran. L\'image est corrompue ou indisponible." "Actuellement défini" "Fond d\'écran quotidien" + "Écran d\'accueil et écran de verrouillage" "Écran d\'accueil" "Écran de verrouillage" "Accueil et verrouillage" @@ -78,4 +79,5 @@ "Centrer" "Recadrer et centrer" "Étirer" + "Prévisualiser" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 2d0cf91..fc49812 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -20,7 +20,7 @@ "Fondos de pantalla" - "Selecciona un fondo de pantalla" + "Categorías de fondos de pantalla" "Establecer fondo de pantalla" "Establecendo fondo de pantalla…" "Tentar de novo" @@ -28,6 +28,7 @@ "Non se puido cargar o fondo de pantalla. A imaxe está danada ou non está dispoñible." "Establecido actualmente" "Fondo de pantalla diario" + "Pantallas de inicio e bloqueo" "Pantalla de inicio" "Pantalla de bloqueo" "Pantallas de inicio e bloqueo" @@ -78,4 +79,5 @@ "Centro" "Recortar no centro" "Estirar" + "Mostrar vista previa" diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index e5928a0..e9fcf97 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -20,7 +20,7 @@ "વૉલપેપર" - "વૉલપેપર પસંદ કરો" + "વૉલપેપરની કૅટેગરી" "વૉલપેપર સેટ કરો" "વૉલપેપર સેટ કરી રહ્યાં છીએ…" "ફરી પ્રયાસ કરો" @@ -28,6 +28,7 @@ "વૉલપેપર લોડ કરવામાં અસમર્થ છીએ. છબી કાં તો દૂષિત છે અથવા તો અનુપલબ્ધ છે." "સેટ કરેલું વૉલપેપર" "દૈનિક વૉલપેપર" + "હોમ અને લૉક સ્ક્રીન" "હોમ સ્ક્રીન" "લૉક સ્ક્રીન" "હોમ અને લૉક" @@ -78,4 +79,5 @@ "મધ્ય" "મધ્યમાંથી કાપેલ" "ખેંચેલ" + "પ્રીવ્યૂ કરો" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index ab00456..269f05d 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -20,7 +20,7 @@ "वॉलपेपर" - "वॉलपेपर चुनें" + "वॉलपेपर की श्रेणियां" "वॉलपेपर सेट करें" "वॉलपेपर सेट किया जा रहा है…" "फिर से कोशिश करें" @@ -28,6 +28,7 @@ "वॉलपेपर लोड नहीं हो पा रहा है. इमेज उपलब्ध नहीं है या उसमें खराबी है." "फ़िलहाल यह वॉलपेपर सेट किया गया है" "रोज़ वॉलपेपर बदलने की सुविधा" + "होम स्क्रीन और लॉक स्क्रीन पर" "होम स्क्रीन" "लॉक स्‍क्रीन" "होम स्क्रीन और लॉक स्क्रीन पर" @@ -78,4 +79,5 @@ "बीचों-बीच" "बीच का हिस्सा रखें" "स्क्रीन के हिसाब से खींचें" + "झलक" diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 006cd9f..baa985b 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -20,7 +20,7 @@ "Pozadine" - "Odaberite pozadinu" + "Kategorije pozadina" "Postavi pozadinu" "Postavljanje pozadine…" "Pokušaj ponovo" @@ -28,6 +28,7 @@ "Učitavanje pozadine nije uspjelo. Slika je oštećena ili nije dostupna." "Trenutačno postavljeno" "Dnevna pozadina" + "Početni i zaključan zaslon" "Početni zaslon" "Zaključan zaslon" "Početni i zaključan zaslon" @@ -78,4 +79,5 @@ "Centriranje" "Centriranje s obrezivanjem" "Rastezanje" + "Pregled" diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 23094f5..de05be5 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -20,7 +20,7 @@ "Háttérképek" - "Háttérkép kiválasztása" + "Háttérkép-kategóriák" "Háttérkép beállítása" "Háttérkép beállítása…" "Újra" @@ -28,6 +28,7 @@ "A háttérkép betöltése sikertelen. A kép sérült vagy nem áll rendelkezésre." "Jelenleg beállított" "Napi háttérkép" + "Kezdő- és lezárási képernyő" "Kezdőképernyő" "Lezárási képernyő" "Kezdő- és lezárási képernyő" @@ -78,4 +79,5 @@ "Középre igazítás" "Középre igazítás körülvágással" "Nyújtás" + "Előnézet" diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 541ab53..9ea0696 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -20,7 +20,7 @@ "Պաստառներ" - "Ընտրեք պաստառը" + "Պաստառների կատեգորիաներ" "Օգտագործել որպես պաստառ" "Պաստառը տեղադրվում է…" "Նորից փորձել" @@ -28,6 +28,7 @@ "Չհաջողվեց բեռնել պաստառը: Պատկերը կամ վնասված է, կամ հասանելի չէ:" "Ընթացիկ պաստառ" "Օրվա պաստառ" + "Հիմնական էկրան և կողպէկրան" "Հիմնական էկրան" "Կողպէկրան" "Հիմնական էկրան և կողպէկրան" @@ -78,4 +79,5 @@ "Կենտրոնում" "Կենտրոնում, կտրած" "Ձգել" + "Նախադիտել" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 11082ae..565f9c4 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -20,7 +20,7 @@ "Wallpaper" - "Pilih wallpaper" + "Kategori wallpaper" "Setel Wallpaper" "Menyetel wallpaper…" "Coba lagi" @@ -28,6 +28,7 @@ "Tidak dapat memuat wallpaper. Gambar sudah rusak atau tidak tersedia." "Yang disetel saat ini" "Wallpaper harian" + "Layar utama & layar kunci" "Layar utama" "Layar kunci" "Beranda & Layar Kunci" @@ -49,7 +50,7 @@ "Tidak dapat mendownload wallpaper pertama. Harap periksa setelan jaringan dan coba lagi." "Wallpaper akan otomatis berubah setiap hari" "Setelan" - "Jelajahi" + "Pelajari" "Wallpaper berikutnya" "Fitur menyetel wallpaper dinonaktifkan di perangkat ini" "Fitur menyetel wallpaper dinonaktifkan oleh administrator perangkat" @@ -78,4 +79,5 @@ "Tengah" "Crop tengah" "Regang" + "Pratinjau" diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index f34ab80..7a1d53f 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -20,7 +20,7 @@ "Veggfóður" - "Veldu veggfóður" + "Veggfóðursflokkar" "Velja veggfóður" "Vistar sem veggfóður…" "Reyna aftur" @@ -28,6 +28,7 @@ "Ekki tókst að hlaða veggfóður. Myndin er annaðhvort skemmd eða ekki tiltæk." "Valið núna" "Daglegt veggfóður" + "Heima- og lásskjár" "Heimaskjár" "Lásskjár" "Heima- og lásskjár" @@ -78,4 +79,5 @@ "Miðja" "Miðjuskurður" "Teygja" + "Forskoða" diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 3ef3e42..2d8cc15 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -20,7 +20,7 @@ "Sfondi" - "Seleziona sfondo" + "Categorie di sfondi" "Imposta sfondo" "Impostazione dello sfondo…" "Riprova" @@ -28,6 +28,7 @@ "Impossibile caricare lo sfondo. L\'immagine è danneggiata o non disponibile." "Attualmente impostato" "Sfondo giornaliero" + "Schermate Home e di blocco" "Schermata Home" "Schermata di blocco" "Schermate Home e di blocco" @@ -78,4 +79,5 @@ "Al centro" "Ritaglia al centro" "Allunga" + "Anteprima" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 876c3e1..d8a697f 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -20,7 +20,7 @@ "טפטים" - "בחירת טפט" + "קטגוריות של טפטים" "הגדרת טפט" "מגדיר טפט…" "ניסיון חוזר" @@ -28,6 +28,7 @@ "לא ניתן לטעון את הטפט. התמונה פגומה או לא זמינה." "מוגדר עכשיו" "טפט יומי" + "מסך הבית ומסך הנעילה" "מסך הבית" "מסך נעילה" "מסך הבית ונעילה" @@ -78,4 +79,5 @@ "ממורכז" "ממורכז וחתוך" "מתוח" + "תצוגה מקדימה" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 1ab89d2..bc84a91 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -20,7 +20,7 @@ "壁紙" - "壁紙の選択" + "壁紙のカテゴリ" "壁紙を設定" "壁紙を設定しています…" "再試行" @@ -28,6 +28,7 @@ "壁紙を読み込めません。画像が破損しているか、使用できません。" "現在の設定" "毎日の壁紙" + "ホーム画面とロック画面" "ホーム画面" "ロック画面" "ホーム画面とロック画面" @@ -78,4 +79,5 @@ "中央" "中央で切り抜き" "拡大" + "プレビュー" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index d8f1ede..9a41fc9 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -20,7 +20,7 @@ "ფონები" - "აირჩიეთ ფონი" + "ფონის კატეგორიები" "ფონის დაყენება" "მიმდინარეობს ფონის დაყენება…" "ხელახლა ცდა" @@ -28,6 +28,7 @@ "ფონი ვერ ჩაიტვირთა. სურათი დაზიანებული ან მიუწვდომელია." "ამჟამად დაყენებული" "ყოველდღიური ფონი" + "მთავარი და ჩაკეტილი ეკრანები" "მთავარი ეკრანი" "ჩაკეტილი ეკრანი" "მთავარი და ჩაკეტილი ეკრანები" @@ -78,4 +79,5 @@ "ცენტრირება" "ცენტრში ჩამოჭრა" "გადაჭიმვა" + "გადახედვა" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 554510a..03094c0 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -20,14 +20,15 @@ "Тұсқағаздар" - "Тұсқағазды таңдаңыз" + "Тұсқағаз санаттары" "Тұсқағаз орнату" "Тұсқағаз орнатылуда…" "Қайталау" "Тұсқағаз орнатылмады." "Тұсқағаз жүктелмеді. Кескін бүлінген не қолжетімді емес." - "Ағымдағы орнатылған" + "Қазір орнатылған" "Күнделікті тұсқағаз" + "Негізгі экран және құлып экраны" "Негізгі экран" "Құлыпталған экран" "Негізгі және құлыпталған экран" @@ -78,4 +79,5 @@ "Ортасы" "Ортасынан қию" "Созу" + "Алдын ала қарау" diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 353e631..dba3d35 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -20,7 +20,7 @@ "ផ្ទាំង​រូបភាព" - "ជ្រើសរើសផ្ទាំងរូបភាព" + "ប្រភេទផ្ទាំងរូបភាព" "កំណត់ផ្ទាំងរូបភាព" "កំពុង​កំណត់​ផ្ទាំង​រូបភាព..." "ព្យាយាមម្ដងទៀត" @@ -28,6 +28,7 @@ "មិនអាចផ្ទុកផ្ទាំងរូបភាពបានទេ។ រូបភាពអាចខូច ឬមិនអាចប្រើបាន។" "ឥឡូវនេះបានកំណត់" "ផ្ទាំងរូបភាពប្រចាំថ្ងៃ" + "អេក្រង់ដើម និង​អេក្រង់ចាក់សោ" "អេក្រង់ដើម" "អេក្រង់​ចាក់សោ" "ដើម និង​ចាក់សោ" @@ -78,4 +79,5 @@ "កណ្តាល" "ច្រឹប​កណ្តាល" "ទាញ" + "មើលសាកល្បង" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 5a25608..c6cf1d4 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -20,7 +20,7 @@ "ವಾಲ್‌ಪೇಪರ್‌ಗಳು" - "ವಾಲ್‌ಪೇಪರ್ ಆಯ್ಕೆಮಾಡಿ" + "ವಾಲ್‌ಪೇಪರ್‌ ವರ್ಗಗಳು" "ವಾಲ್‌ಪೇಪರ್ ಹೊಂದಿಸಿ" "ವಾಲ್‌ಪೇಪರ್ ಹೊಂದಿಸಲಾಗುತ್ತಿದೆ..." "ಪುನಃ ಪ್ರಯತ್ನಿಸಿ" @@ -28,6 +28,7 @@ "ವಾಲ್‌ಪೇಪರ್ ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಚಿತ್ರವು ದೋಷಪೂರಿತವಾಗಿರಬಹುದು ಅಥವಾ ಲಭ್ಯವಿಲ್ಲದಿರಬಹುದು." "ಪ್ರಸ್ತುತವಾಗಿ ಹೊಂದಿಸಿ" "ದಿನನಿತ್ಯದ ವಾಲ್‌ಪೇಪರ್" + "ಹೋಮ್ ಮತ್ತು ಲಾಕ್‌ ಸ್ಕ್ರೀನ್" "ಮುಖಪುಟದ ಪರದೆ" "ಲಾಕ್ ಪರದೆ" "ಮುಖಪುಟ ಮತ್ತು ಲಾಕ್‌" @@ -78,4 +79,5 @@ "ಮಧ್ಯ" "ಮಧ್ಯಕ್ಕೆ ಕ್ರಾಪ್ ಮಾಡಿ" "ವಿಸ್ತರಿಸಿ" + "ಪೂರ್ವವೀಕ್ಷಣೆ" diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 8ef1e57..6f10f4f 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -20,7 +20,7 @@ "배경화면" - "배경화면 선택" + "배경화면 카테고리" "배경화면 설정" "배경화면을 설정하는 중..." "다시 시도" @@ -28,6 +28,7 @@ "배경화면을 로드할 수 없습니다. 이미지가 손상되었거나 사용할 수 없습니다." "현재 설정" "일일 배경화면" + "홈 및 잠금 화면" "홈 화면" "잠금 화면" "홈 및 잠금" @@ -78,4 +79,5 @@ "중앙" "중앙 자르기" "확대" + "미리보기" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 1aaea2a..b56b372 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -20,7 +20,7 @@ "Тушкагаздар" - "Тушкагаз тандоо" + "Тушкагаз категориялары" "Тушкагаз орнотуу" "Тушкагаз орнотулууда…" "Кайталоо" @@ -28,6 +28,7 @@ "Тушкагаз жүктөлбөй жатат. Сүрөт бузулган же жеткиликтүү эмес." "Учурда тушкагаз катары орнотулган" "Күнүмдүк тушкагаз" + "Башкы жана кулпуланган экран" "Башкы экран" "Кулпуланган экран" "Башкы жана кулпуланган экран" @@ -78,4 +79,5 @@ "Ортосунда" "Ортосуна тууралап кесүү" "Чоюу" + "Алдын ала көрүү" diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 353dab2..1f5bc34 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -20,7 +20,7 @@ "ຮູບພື້ນຫຼັງ" - "ເລືອກຮູບພື້ນຫຼັງ" + "ໝວດໝູ່ຮູບພື້ນຫຼັງ" "ຕັ້ງເປັນຮູບພື້ນຫຼັງ" "ກຳລັງຕັ້ງຮູບພື້ນຫຼັງ..." "ລອງໃໝ່" @@ -28,6 +28,7 @@ "ບໍ່ສາມາດໂຫຼດພາບພື້ນຫຼັງໄດ້" "ຕັ້ງຕອນນີ້" "ຮູບພື້ນຫຼັງປະຈຳວັນ" + "ໜ້າຫຼັກ ແລະ ໜ້າຈໍລັອກ" "ໜ້າຈໍຫຼັກ" "ໜ້າຈໍລັອກ" "ໜ້າຈໍຫຼັກ ແລະ ການລັອກ" @@ -78,4 +79,5 @@ "ກາງ" "ຕັດເຄິ່ງກາງ" "ຍືດ" + "ຕົວຢ່າງ" diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 829760e..80fa37e 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -20,7 +20,7 @@ "Ekrano fonai" - "Pasirinkite ekrano foną" + "Ekrano fonų kategorijos" "Nustatyti ekrano foną" "Nustatomas fonas…" "Bandyti dar kartą" @@ -28,6 +28,7 @@ "Nepavyko įkelti ekrano fono. Šis vaizdas sugadintas arba nepasiekiamas." "Šiuo metu nustatytas" "Dienos ekrano fonas" + "Pagrindinis ir užrakinimo ekranai" "Pagrindinis ekranas" "Užrakinimo ekranas" "Pagrindinis ir užrakinimo ekr." @@ -78,4 +79,5 @@ "Centre" "Apkirpti centre" "Ištempti" + "Peržiūra" diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 03f5838..318c0f8 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -20,7 +20,7 @@ "Fona tapetes" - "Atlasiet fona tapeti" + "Fona tapešu kategorijas" "Iestatīt fona tapeti" "Notiek fona tapetes iestatīšana..." "Mēģināt vēlreiz" @@ -28,6 +28,7 @@ "Nevar ielādēt fona tapeti. Attēls vai nu ir bojāts, vai arī nav pieejams." "Pašlaik iestatīta" "Dienas fona tapete" + "Sākuma un bloķēšanas ekrāns" "Sākuma ekrāns" "Bloķēšanas ekrāns" "Sākuma un bloķēšanas ekrāns" @@ -78,4 +79,5 @@ "Centrēt" "Apgriezt centrā" "Pielāgot" + "Priekšskatīt" diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 8014ce1..9f2901f 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -20,7 +20,7 @@ "Тапети" - "Изберете тапет" + "Категории на тапети" "Постави го тапетот" "Тапетот се поставува…" "Обиди се пак" @@ -28,6 +28,7 @@ "Тапетот не може да се вчита. Сликата е оштетена или недостапна." "Моментално поставен" "Дневен тапет" + "Почетен и заклучен екран" "Почетен екран" "Заклучен екран" "Почетен и заклучен екран" @@ -78,4 +79,5 @@ "Во средина" "Исечи централно" "Растегни" + "Преглед" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 3f52526..f70fbf0 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -20,14 +20,15 @@ "വാൾപേപ്പറുകൾ" - "വാൾപേപ്പർ തിരഞ്ഞെടുക്കുക" + "വാൾപേപ്പർ വിഭാഗങ്ങൾ" "വാൾപേപ്പർ സജ്ജമാക്കുക" "വാൾപേപ്പർ സജ്ജമാക്കുന്നു…" "വീണ്ടും ശ്രമിക്കുക" "വാൾപേപ്പർ സജ്ജമാക്കാനാവുന്നില്ല." "വാൾപേപ്പർ ലോഡുചെയ്യാനാവുന്നില്ല. ചിത്രം കേടായിരിക്കുന്നു അല്ലെങ്കിൽ ലഭ്യമല്ല." - "നിലവിൽ സജ്ജമാക്കി" + "നിലവിൽ സജ്ജമാക്കിയിരിക്കുന്നത്" "പ്രതിദിന വാൾപേപ്പർ" + "ഹോമും ലോക്ക് സ്‌ക്രീനും" "ഹോം സ്‌ക്രീൻ" "ലോക്ക് സ്‌ക്രീൻ" "ഹോമും ലോക്ക് സ്‌ക്രീനും" @@ -78,4 +79,5 @@ "മധ്യം" "നടുവിൽ വലുപ്പം മാറ്റുക" "വലിച്ചുനീട്ടുക" + "പ്രിവ്യൂ" diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index c771220..7352b7c 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -20,7 +20,7 @@ "Ханын зураг" - "Ханын зураг сонгох" + "Ханийн зургийн ангилал" "Ханын зураг тохируулах" "Ханын зургийг тохируулж байна…" "Дахин оролдох" @@ -28,6 +28,7 @@ "Дэлгэцийн зургийг ачаалах боломжгүй байна. Зураг нь гэмтэлтэй буюу эсвэл ашиглах боломжгүй байна." "Одоогоор тохируулсан ханын зураг" "Өдөр тутмын ханын зураг" + "Нүүр болон түгжигдсэн дэлгэц" "Үндсэн нүүр" "Түгжигдсэн дэлгэц" "Нүүр хуудас болон түгжээ" @@ -78,4 +79,5 @@ "Гол хэсэг" "Голлуулж тайрах" "Сунгах" + "Урьдчилан үзэх" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index d244573..bc7de36 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -20,7 +20,7 @@ "वॉलपेपर" - "वॉलपेपर निवडा" + "वॉलपेपर वर्गवाऱ्या" "वॉलपेपर सेट करा" "वॉलपेपर सेट करत आहे…" "पुन्हा प्रयत्न करा" @@ -28,6 +28,7 @@ "वॉलपेपर लोड करता आला नाही. इमेज करप्ट झालेली किंवा अनुपलब्ध आहे." "सध्या सेट केलेला" "दैनिक वॉलपेपर" + "होम आणि लॉक स्‍क्रीन" "होम स्क्रीन" "लॉक स्क्रीन" "होम आणि लॉक" @@ -78,4 +79,5 @@ "मध्यभागी" "मध्यभागी क्रॉप केलेले" "ताणा" + "पूर्वावलोकन करा" diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index e1ba745..d10b20d 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -20,7 +20,7 @@ "Kertas dinding" - "Pilih kertas dinding" + "Kategori kertas dinding" "Tetapkan Kertas Dinding" "Menetapkan kertas dinding…" "Cuba lagi" @@ -28,6 +28,7 @@ "Tidak dapat memuatkan kertas dinding. Imej rosak atau tidak tersedia." "Ditetapkan pada masa ini" "Kertas dinding harian" + "Skrin utama & Skrin kunci" "Skrin utama" "Kunci skrin" "Skrin Utama & Kunci" @@ -78,4 +79,5 @@ "Tengah" "Pangkas ke tengah" "Regang" + "Pratonton" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index e4bbdd2..b5d4855 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -20,7 +20,7 @@ "နောက်ခံပုံများ" - "နောက်ခံကို ရွေးပါ" + "နောက်ခံပုံ အမျိုးအစားများ" "နောက်ခံ သတ်မှတ်ပါ" "နောက်ခံ သတ်မှတ်နေသည်…" "ထပ်စမ်းကြည့်ရန်" @@ -28,6 +28,7 @@ "နောက်ခံကို ဖွင့်၍မရပါ။ ဤပုံသည် ပျက်နေပါသည် သို့မဟုတ် မရနိင်ပါ။" "လက်ရှိတွင် သတ်မှတ်ထားသည်" "နေ့စဉ် နောက်ခံ" + "ပင်မစာမျက်နှာနှင့် လော့ခ်ချထားချိန် မျက်နှာပြင်" "ပင်မစာမျက်နှာ" "လော့ခ်ချထားချိန် မျက်နှာပြင်" "ပင်မနှင့် လော့ခ်မျက်နှာပြင်" @@ -78,4 +79,5 @@ "အလယ်" "အလယ်တွင် ဖြတ်ညှိရန်" "ဆွဲဆန့်ရန်" + "အစမ်းကြည့်ရန်" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 3b8e234..2028c9d 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -20,7 +20,7 @@ "Bakgrunner" - "Velg bakgrunn" + "Bakgrunnskategorier" "Angi bakgrunn" "Angir bakgrunn …" "Prøv igjen" @@ -28,6 +28,7 @@ "Kan ikke laste inn bakgrunnen. Bildet er enten skadet eller utilgjengelig." "Nåværende bakgrunn" "Daglig bakgrunn" + "Startskjermen og låseskjermen" "Startskjerm" "Låseskjermen" "Startskjermen og låseskjermen" @@ -78,4 +79,5 @@ "Midtstilt" "Midtstilt beskjæring" "Strekk" + "Ta en forhåndskikk" diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index d755731..28a1052 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -20,7 +20,7 @@ "वालपेपरहरू" - "वालपेपर चयन गर्नुहोस्" + "वालपेपरका कोटीहरू" "वालपेपर सेट गर्नुहोस्" "वालपेपर सेट गर्दै…" "फेरि प्रयास गर्नुहोस्‌" @@ -28,6 +28,7 @@ "वालपेपर लोड गर्न सकिएन। छवि या त त्रुटिपूर्ण छ वा उपलब्ध छैन।" "हाल सेट गरिएको" "दैनिक वालपेपर" + "गृह तथा लक स्क्रिन" "गृह स्क्रिन" "लक स्क्रिन" "गृह स्क्रिन & लक स्क्रिन" @@ -78,4 +79,5 @@ "मध्यभाग" "मध्यभागमा क्रप गरिएको" "तन्काइएको" + "पूर्वावलोकन" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index b53fda8..543e654 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -20,7 +20,7 @@ "Achtergronden" - "Achtergrond selecteren" + "Achtergrondcategorieën" "Achtergrond instellen" "Achtergrond instellen…" "Opnieuw" @@ -28,6 +28,7 @@ "Kan achtergrond niet laden. De afbeelding is beschadigd of is niet beschikbaar." "Momenteel ingesteld" "Dagelijkse achtergrond" + "Start- en vergrendelingsscherm" "Startscherm" "Scherm vergrendelen" "Home- en vergrendelingsscherm" @@ -37,7 +38,7 @@ "Startscherm en vergrendelingsscherm" "Achtergrond met roulerende afbeelding" "%1$s heeft toegang nodig tot de opslag van je apparaat om de huidige achtergrond hier weer te geven." - "Achtergronden heeft toegang nodig tot de opslag van je apparaat om de huidige achtergrond hier weer te geven.\n\nAls je deze instelling wilt wijzigen, ga je naar het gedeelte Machtigingen in de app-informatie van Achtergronden." + "Achtergronden heeft toegang nodig tot de opslag van je apparaat om de huidige achtergrond hier weer te geven.\n\nAls je deze instelling wilt wijzigen, ga je naar het gedeelte Rechten in de app-informatie van Achtergronden." "Toegang toestaan" "Service voor interactieve achtergrond met roulerende achtergronden" "Dagelijkse achtergrond" @@ -78,4 +79,5 @@ "Midden" "Gecentreerd bijsnijden" "Uitrekken" + "Voorbeeld" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index caa61dc..32e791e 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -20,7 +20,7 @@ "ୱାଲ୍‌ପେପର୍‌" - "ୱାଲପେପର୍‌ ଚୟନ କରନ୍ତୁ" + "ୱାଲ୍‌ପେପର୍ ବର୍ଗଗୁଡ଼ିକ" "ୱାଲପେପର୍‍ ସେଟ୍ କରନ୍ତୁ" "ୱାଲପେପର୍‌ ସେଟ୍ ହେଉଛି…" "ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ" @@ -28,6 +28,7 @@ "ୱାଲପେପର୍ ଲୋଡ୍ କରିବାରେ ଅସମର୍ଥ। ଇମେଜ୍‌ଟି ନଷ୍ଟ ହୋଇଯାଇଛି କିମ୍ବା ଉପଲବ୍ଧ ନାହିଁ।" "ଏହିକ୍ଷଣି ସେଟ୍ ହୋଇଛି" "ଦୈନିକ ୱାଲପେପର୍" + "ହୋମ୍ ଓ ଲକ୍ ସ୍କ୍ରିନ୍" "ହୋମ୍‍ ସ୍କ୍ରୀନ୍‍" "ଲକ୍‌ ସ୍କ୍ରୀନ୍‌" "ହୋମ୍ ଓ ଲକ୍" @@ -78,4 +79,5 @@ "କେନ୍ଦ୍ର" "ସେଣ୍ଟର୍ କ୍ରପ୍" "ପ୍ରସାରିତ କରନ୍ତୁ" + "ପ୍ରିଭ୍ୟୁ" diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index 5b00fcf..9d8f5f7 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -20,7 +20,7 @@ "ਵਾਲਪੇਪਰ" - "ਵਾਲਪੇਪਰ ਚੁਣੋ" + "ਵਾਲਪੇਪਰ ਸ਼੍ਰੇਣੀਆਂ" "ਵਾਲਪੇਪਰ ਸੈੱਟ ਕਰੋ" "ਵਾਲਪੇਪਰ ਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…" "ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ" @@ -28,6 +28,7 @@ "ਵਾਲਪੇਪਰ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਚਿੱਤਰ ਖਰਾਬ ਜਾਂ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।" "ਇਸ ਵੇਲੇ ਸੈੱਟ ਹੈ" "ਰੋਜ਼ਾਨਾ ਵਾਲਪੇਪਰ" + "ਹੋਮ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ" "ਹੋਮ ਸਕ੍ਰੀਨ" "ਲਾਕ ਸਕ੍ਰੀਨ" "ਹੋਮ ਸਕ੍ਰੀਨ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ" @@ -78,4 +79,5 @@ "ਵਿਚਕਾਰ" "ਵਿਚਕਾਰੋਂ ਕਾਂਟ-ਛਾਂਟ ਕਰੋ" "ਫੈਲਾਓ" + "ਪੂਰਵ-ਝਲਕ" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index c930640..82d7408 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -20,7 +20,7 @@ "Tapety" - "Wybierz tapetę" + "Kategorie tapet" "Ustaw tapetę" "Ustawiam tapetę…" "Spróbuj ponownie" @@ -28,6 +28,7 @@ "Nie można załadować tapety. Obraz jest uszkodzony lub niedostępny." "Obecnie ustawiona" "Codzienna tapeta" + "Ekran główny i ekran blokady" "Ekran główny" "Ekran blokady" "Ekran główny i ekran blokady" @@ -78,4 +79,5 @@ "Na środku" "Przycięta na środku" "Rozciągnięcie" + "Podgląd" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 36d0ac4..3ba961d 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -20,7 +20,7 @@ "Imagens de fundo" - "Selecionar imagem de fundo" + "Categorias de imagens de fundo" "Definir imagem de fundo" "A definir a imagem de fundo…" "Tentar novamente" @@ -28,6 +28,7 @@ "Não foi possível carregar a imagem de fundo. A imagem está danificada ou indisponível." "Definida atualmente" "Imagem de fundo diária" + "Ecrã principal e de bloqueio" "Ecrã principal" "Ecrã de bloqueio" "Ecrã principal e de bloqueio" @@ -78,4 +79,5 @@ "Centrar" "Recortar e centrar" "Esticar" + "Pré-visualizar" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 81b894f..f26164b 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -20,7 +20,7 @@ "Planos de fundo" - "Selecione um plano de fundo" + "Categorias de plano de fundo" "Definir plano de fundo" "Definindo plano de fundo…" "Tentar novamente" @@ -28,6 +28,7 @@ "Não foi possível carregar o plano de fundo. A imagem está corrompida ou indisponível." "Definido no momento" "Plano de fundo diário" + "Tela inicial e de bloqueio" "Tela inicial" "Tela de bloqueio" "Tela inicial e de bloqueio" @@ -78,4 +79,5 @@ "Centralizar" "Corte central" "Expandir" + "Visualizar" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 870fec8..0766d1a 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -20,7 +20,7 @@ "Imagini de fundal" - "Selectați o imagine de fundal" + "Categorii de imagini de fundal" "Setați imaginea de fundal" "Se setează imaginea de fundal…" "Încercați din nou" @@ -28,6 +28,7 @@ "Imaginea de fundal nu a putut fi încărcată. Imaginea este deteriorată sau nu este disponibilă." "Setată în prezent" "Imaginea de fundal zilnică" + "Ecran de pornire și de blocare" "Ecran de pornire" "Ecran de blocare" "De pornire și de blocare" @@ -78,4 +79,5 @@ "Centru" "Decupare în centru" "Extindeți" + "Previzualizați" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index f0ebd8c..1421a1b 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -20,7 +20,7 @@ "Обои" - "Выберите обои" + "Категории обоев" "Установить как обои" "Установка обоев…" "Повторить" @@ -28,6 +28,7 @@ "Не удалось загрузить обои. Изображение повреждено или недоступно." "Установлено как обои" "Обои на каждый день" + "Главный и заблокированный экраны" "Главный экран" "Заблокированный экран" "Оба экрана" @@ -78,4 +79,5 @@ "Разместить по центру" "Заполнить" "Растянуть" + "Предварительный просмотр" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 9e6241a..8022ce9 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -17,10 +17,10 @@ - "බිතුපත්" + "වෝල්පේපර" - "වෝල්පේපරයක් තෝරන්න" + "බිතුපත් ප්‍රවර්ග" "වෝල්පේපරය සකසන්න" "වෝල්පේපරය සකසමින්…" "නැවත උත්සාහ කර." @@ -28,6 +28,7 @@ "වෝල්පේපරය පූරණය කිරීමට නොහැකිය. මෙම රූපය හානි වී හෝ ලබා ගත නොහැකිව ඇත." "දැනට සකසා ඇත" "දෛනික වෝල්පේපරය" + "මුල් පිටුව සහ අගුළු තිරය" "මුල් පිටු තිරය" "අගුලු තිරය" "මුල් පිටුව සහ අගුල" @@ -78,4 +79,5 @@ "මැද" "මැද කප්පාදු කිරීම" "අදින්න" + "පෙරදසුන" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 7f06740..d12ddd0 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -20,7 +20,7 @@ "Tapety" - "Vyberte tapetu" + "Kategórie tapiet" "Nastaviť tapetu" "Nastavuje sa tapeta…" "Skúsiť znova" @@ -28,6 +28,7 @@ "Tapetu sa nepodarilo načítať. Obrázok je poškodený alebo nie je k dispozícii." "Práve nastavená" "Denná tapeta" + "Plocha a uzamknutá obrazovka" "Plocha" "Uzamknutá obrazovka" "Plocha a uzamknutá obrazovka" @@ -78,4 +79,5 @@ "Vycentrovať" "Vycentrovať a orezať" "Roztiahnuť" + "Zobraziť ukážku" diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 380e090..dae44d7 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -20,7 +20,7 @@ "Ozadja" - "Izberite ozadje" + "Kategorije ozadij" "Nastavi ozadje" "Nastavljanje ozadja …" "Poskusi znova" @@ -28,6 +28,7 @@ "Ozadja ni mogoče naložiti. Slika je poškodovana ali ni na voljo." "Trenutno nastavljeno" "Dnevno ozadje" + "Začetni in zaklenjeni zaslon" "Začetni zaslon" "Zaklenjen zaslon" "Začetni in zaklenjeni zaslon" @@ -78,4 +79,5 @@ "Na sredini" "Na sredini obrezano" "Raztegnjeno" + "Predogled" diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index b301e84..e35ad48 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -20,7 +20,7 @@ "Imazhet e sfondit" - "Zgjidh imazhin e sfondit" + "Kategoritë e imazheve të sfondit" "Cakto imazhin e sfondit" "Po cakton imazhin e sfondit..." "Provo sërish" @@ -28,6 +28,7 @@ "Sfondi nuk mund të ngarkohet. Imazhi është i dëmtuar ose i padisponueshëm." "E caktuar aktualisht" "Imazh sfondi i përditshëm" + "\"Ekrani bazë\" dhe \"Ekrani i kyçjes\"" "Ekrani bazë" "Ekrani i kyçjes" "\"Ekrani bazë\" dhe \"Kyçja\"" @@ -78,4 +79,5 @@ "Qendror" "Prerje qendrore" "E tendosur" + "Shiko paraprakisht" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index f4132a6..6c26b0a 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -20,7 +20,7 @@ "Позадине" - "Изаберите позадину" + "Категорије позадина" "Подеси позадину" "Подешава се позадина…" "Пробајте поново" @@ -28,12 +28,13 @@ "Учитавање позадине није успело. Слика је оштећена или није доступна." "Тренутно подешена" "Дневна позадина" + "Почетни и закључани екран" "Почетни екран" - "Закључани екран" + "Закључан екран" "Почетни и закључани екран" "Подесите позадину" "Почетни екран" - "Закључани екран" + "Закључан екран" "Почетни екран и закључани екран" "Ротирајућа позадина са сликом" "Да би се актуелна позадина приказивала овде, апликација %1$s треба да има приступ меморијском простору на уређају." @@ -78,4 +79,5 @@ "Центар" "Опсеци у центру" "Развуци" + "Преглед" diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 10379ad..54bc2cb 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -20,7 +20,7 @@ "Bakgrunder" - "Välj bakgrund" + "Bakgrundskategorier" "Använd som bakgrund" "Ställer in bakgrund …" "Försök igen" @@ -28,6 +28,7 @@ "Det gick inte att läsa in bakgrunden. Bilden är skadad eller inte tillgänglig." "Nuvarande bakgrund" "Dagens bakgrund" + "Start- och låsskärm" "Startskärm" "Låsskärm" "Start- och låsskärm" @@ -78,4 +79,5 @@ "Centrera" "Centrera och beskär" "Dra ut" + "Förhandsgranska" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 8b83051..17734e1 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -20,7 +20,7 @@ "Mandhari" - "Chagua mandhari" + "Aina za mandhari" "Weka Mandhari" "Inaweka mandhari..." "Jaribu tena" @@ -28,6 +28,7 @@ "Imeshindwa kupakia mandhari. Picha imeharibika au haipatikani." "Mandhari yaliyopo" "Mandhari ya kila siku" + "Skrini ya Kwanza na Iliyofungwa" "Skrini ya kwanza" "Skrini iliyofungwa" "Skrini ya Kwanza na Iliyofungwa" @@ -78,4 +79,5 @@ "Katikati" "Punguza katikati" "Panua" + "Kagua kwanza" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 3152b87..5be8064 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -20,7 +20,7 @@ "Wallpapers" - "வால்பேப்பரைத் தேர்ந்தெடுக்கவும்" + "வால்பேப்பர் வகைகள்" "வால்பேப்பரை அமை" "வால்பேப்பரை அமைக்கிறது…" "மீண்டும் முயல்க" @@ -28,6 +28,7 @@ "வால்பேப்பரை ஏற்ற முடியவில்லை. படம் சிதைந்துவிட்டது அல்லது இல்லை." "தற்போது அமைத்துள்ள வால்பேப்பர்" "தினசரி வால்பேப்பர்" + "முகப்பு & பூட்டுத் திரை" "முகப்புத் திரை" "பூட்டுத் திரை" "முகப்பு & பூட்டு" @@ -37,7 +38,7 @@ "முகப்புத் திரையும் பூட்டுத் திரையும்" "சுழலும் பட வால்பேப்பர்" "இந்த வால்பேப்பரை இங்கே காட்ட, %1$s பயன்பாட்டிற்கு உங்கள் சாதனத்தின் சேமிப்பகத்திற்கான அணுகல் தேவை." - "இந்த வால்பேப்பரை இங்கே காட்ட, வால்பேப்பர்களுக்கு உங்கள் சாதனத்தின் சேமிப்பகத்திற்கான அணுகல் தேவை.\n\nஇந்த அமைப்பை மாற்ற, வால்பேப்பர்களின் பயன்பாட்டுத் தகவல் பக்கத்தில் உள்ள அனுமதிகள் பகுதிக்குச் செல்லவும்." + "இந்த வால்பேப்பரை இங்கே காட்ட, வால்பேப்பர்களுக்கு உங்கள் சாதனத்தின் சேமிப்பகத்திற்கான அணுகல் தேவை.\n\nஇந்த அமைப்பை மாற்ற, வால்பேப்பர்களின் ஆப்ஸ் தகவல் பக்கத்தில் உள்ள அனுமதிகள் பகுதிக்குச் செல்லவும்." "அணுகலை அனுமதி" "சுழலும் வால்பேப்பர்களுக்கான லைவ் வால்பேப்பர் சேவை" "தினசரி வால்பேப்பர்" @@ -74,8 +75,9 @@ "எனது படங்கள்" "எனது படம்" "வால்பேப்பர்" - "பயன்பாடு நிறுவப்படவில்லை." + "ஆப்ஸ் நிறுவப்படவில்லை." "மையம்" "மையமாகச் செதுக்கு" "திரையில் பொருந்தும்படி விரி" + "மாதிரிக்காட்சி" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 6101ab2..3db68b3 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -20,7 +20,7 @@ "వాల్‌పేపర్‌లు" - "వాల్‌పేపర్‌ను ఎంచుకోండి" + "వాల్‌పేపర్ రకాలు" "వాల్‌పేపర్‌ను సెట్ చేయి" "వాల్‌పేపర్‌ను సెట్ చేస్తోంది…" "మళ్లీ ప్రయత్నించు" @@ -28,6 +28,7 @@ "వాల్‌పేపర్‌ను లోడ్ చేయలేకపోయాము. చిత్రం పాడై ఉండవచ్చు లేదా అందుబాటులో లేకపోవచ్చు." "ప్రస్తుతం సెట్ చేసినది" "రోజువారీ వాల్‌పేపర్" + "హోమ్ & లాక్ స్క్రీన్" "హోమ్ స్క్రీన్" "లాక్ స్క్రీన్" "హోమ్ & లాక్" @@ -78,4 +79,5 @@ "మధ్య" "మధ్యన కత్తిరించు" "విస్తరించు" + "ప్రివ్యూ చూపు" diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 8f4e001..0aaa891 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -20,7 +20,7 @@ "วอลเปเปอร์" - "เลือกวอลเปเปอร์" + "หมวดหมู่วอลเปเปอร์" "ตั้งค่าวอลเปเปอร์" "กำลังตั้งค่าวอลเปเปอร์…" "ลองอีกครั้ง" @@ -28,6 +28,7 @@ "โหลดวอลเปเปอร์ไม่ได้ รูปภาพเสียหายหรือใช้งานไม่ได้" "วอลเปเปอร์ปัจจุบัน" "วอลเปเปอร์รายวัน" + "หน้าจอหลักและหน้าจอล็อก" "หน้าจอหลัก" "หน้าจอล็อก" "หน้าแรกและหน้าจอล็อก" @@ -78,4 +79,5 @@ "กลาง" "ครอบตัดกึ่งกลาง" "ยืด" + "แสดงพรีวิว" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index e1348fb..7232a7e 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -20,7 +20,7 @@ "Mga Wallpaper" - "Pumili ng wallpaper" + "Mga kategorya ng wallpaper" "Itakda na Wallpaper" "Itinatakda ang wallpaper…" "Subukang muli" @@ -28,6 +28,7 @@ "Hindi ma-load ang wallpaper. Sira o hindi available ang larawan." "Kasalukuyang nakatakda" "Pang-araw-araw na wallpaper" + "Home & Lock screen" "Home screen" "Lock screen" "Home at Lock" @@ -78,4 +79,5 @@ "Center" "I-crop sa gitna" "I-stretch" + "I-preview" diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index bbbe10b..1600f69 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -20,7 +20,7 @@ "Duvar kağıtları" - "Duvar kağıdı seçin" + "Duvar kağıdı kategorileri" "Duvar Kağıdını Ayarla" "Duvar kağıdı ayarlanıyor…" "Tekrar dene" @@ -28,6 +28,7 @@ "Duvar kağıdı yüklenemedi. Resim bozuk veya kullanılamıyor." "Şu anda ayarlı" "Günlük duvar kağıdı" + "Ana Sayfa ve Kilit ekranı" "Ana ekran" "Kilit ekranı" "Ana Ekran ve Kilit Ekranı" @@ -78,4 +79,5 @@ "Orta" "Ortalayarak kırp" "Genişlet" + "Önizle" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 4abd4cc..0d4fd12 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -20,14 +20,15 @@ "Фонові малюнки" - "Виберіть фоновий малюнок" + "Категорії фонових малюнків" "Зробити фоновим малюнком" "Налаштування фонового малюнка…" "Повторити" "Не вдалося налаштувати фоновий малюнок." "Не вдалося завантажити фоновий малюнок. Зображення пошкоджене або недоступне." - "Налаштовано зараз" + "Вибрано зараз" "Щоденний фоновий малюнок" + "Головний і заблокований екрани" "Головний екран" "Заблокований екран" "Головний і заблокований екрани" @@ -78,4 +79,5 @@ "Центр" "Обрізати відносно центру" "Розтягнути" + "Переглянути" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index c496290..b4a5043 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -20,7 +20,7 @@ "وال پیپرز" - "وال پیپر منتخب کریں" + "وال پیپر کے زمرے" "وال پیپر سیٹ کریں" "وال پیپر سیٹ ہو رہا ہے…" "دوبارہ کوشش کریں" @@ -28,6 +28,7 @@ "وال پیپر لوڈ کرنے سے قاصر۔ تصویر یا تو خراب ہو گئی ہے یا دستیاب نہیں ہے۔" "فی الحال سیٹ کردہ" "روزانہ وال پیپر" + "ہوم اور مقفل اسکرین" "ہوم اسکرین" "مقفل اسکرین" "ہوم اور لاک" @@ -78,4 +79,5 @@ "مرکز" "مرکزی تراش" "پھیلائیں" + "پیش منظر" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 9daafea..ede76e6 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -20,7 +20,7 @@ "Fon rasmlari" - "Fon rasmini tanlang" + "Fon rasmi turkumlari" "Fonga rasm o‘rnatish" "Fonga rasm o‘rnatilmoqda…" "Qaytadan" @@ -28,6 +28,7 @@ "Fon rasmi yuklanmadi. Rasm buzilgan yoki mavjud emas." "Hozirda o‘rnatilgan" "Kunlik fon rasmi" + "Bosh ekran va ekran qulfi" "Bosh ekran" "Ekran qulfi" "Bosh ekran va ekran qulfi" @@ -78,4 +79,5 @@ "Markazlash" "Markazlab qirqish" "Yoyish" + "Razm solish" diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 49274df..f0c0176 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -20,14 +20,15 @@ "Hình nền" - "Chọn hình nền" + "Danh mục hình nền" "Đặt hình nền" "Đang đặt hình nền..." "Thử lại" "Không thể đặt hình nền." "Không thể tải hình nền. Hình ảnh bị hỏng hoặc không có sẵn." - "Hiện được đặt" + "Hình nền hiện tại" "Hình nền hàng ngày" + "Màn hình chính và màn hình khóa" "Màn hình chính" "Màn hình khóa" "Màn hình chính và khóa" @@ -71,11 +72,12 @@ "Trên thiết bị" "Hình nền Android" "Hình nền động" - "Các ảnh của tôi" + "Ảnh của tôi" "Ảnh của tôi" "Hình nền" "Ứng dụng chưa được cài đặt." "Giữa" "Cắt giữa" "Kéo dài" + "Xem trước" diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 18270df..3795c39 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -20,7 +20,7 @@ "壁纸" - "选择壁纸" + "壁纸类别" "设置壁纸" "正在设置壁纸…" "重试" @@ -28,6 +28,7 @@ "无法加载壁纸。图片已损坏或不可用。" "当前设置的壁纸" "每日壁纸" + "主屏幕和锁定屏幕" "主屏幕" "锁定屏幕" "主屏幕和锁定屏幕" @@ -78,4 +79,5 @@ "居中" "居中裁剪" "拉伸" + "预览" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 19fa6f8..f9ecc62 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -20,14 +20,15 @@ "桌布" - "選擇桌布" + "桌布類別" "設定「桌布」" "正在設定桌布…" "再試一次" "無法設定桌布。" "無法載入桌布。圖片已損壞或無法使用。" - "目前已設定" + "目前設定" "每日桌布" + "主畫面及上鎖畫面" "主畫面" "上鎖畫面" "主畫面及上鎖畫面" @@ -78,4 +79,5 @@ "置中" "裁剪中間部分" "延展" + "預覽" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 47636e5..f6e67cf 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -20,7 +20,7 @@ "桌布" - "選取桌布" + "桌布類別" "設定桌布" "正在設定桌布…" "再試一次" @@ -28,6 +28,7 @@ "無法載入桌布。圖片已毀損或無法使用。" "目前設定的桌布" "每日桌布" + "主螢幕和螢幕鎖定" "主螢幕" "螢幕鎖定" "主螢幕和螢幕鎖定" @@ -78,4 +79,5 @@ "置中" "置中裁剪" "延伸" + "預覽" diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index ff0290b..2db2a33 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -20,7 +20,7 @@ "Izithombe zangemuva" - "Khetha isithombe sangemuva" + "Izigaba zesithombe sangemuva" "Setha isithombe sangemuva" "Isetha isithombe sangemuva..." "Zama futhi" @@ -28,6 +28,7 @@ "Ayikwazi ukulayisha isithombe sangemuva. Isithombe kungenzeka sonakele noma asitholakali." "Manje isethiwe" "Isithombe sangemuva sansuku zonke" + "Ikhaya nesikrini sokukhiya" "Isikrini sasekhaya" "Khiya isikrini" "Ikhaya nokukhiya" @@ -78,4 +79,5 @@ "Phakathi kwendawo" "Nqampuna phakathi kwendawo" "Nweba" + "Buka kuqala" -- cgit v1.2.3 From aac8e7b6e2d21bd26651e49a49c649c14798106b Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 15 Jul 2019 16:41:35 -0700 Subject: Import translations. DO NOT MERGE Change-Id: I00946015c8ebc760b259de331128cb8e2ad1115e Auto-generated-cl: translation import --- res/values-es-rUS/strings.xml | 2 +- res/values-in/strings.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index a95e589..d96971c 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -28,7 +28,7 @@ "No se puede cargar el fondo de pantalla. La imagen está dañada o no está disponible." "Establecido actualmente" "Fondo de pantalla diario" - "Pantalla principal y bloqueada" + "Pantalla principal y de bloqueo" "Pantalla principal" "Pantalla bloqueada" "Pantalla principal y bloqueada" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 565f9c4..afe8069 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -42,8 +42,8 @@ "Izinkan akses" "Layanan wallpaper animasi untuk memutar wallpaper" "Wallpaper harian" - "Tap untuk mengaktifkan" - "Wallpaper akan otomatis berubah setiap hari. Untuk menyelesaikan penyiapan, tap <strong>Setel wallpaper</strong> di layar selanjutnya." + "Ketuk untuk mengaktifkan" + "Wallpaper akan otomatis berubah setiap hari. Untuk menyelesaikan penyiapan, ketuk <strong>Setel wallpaper</strong> di layar selanjutnya." "Download wallpaper mendatang hanya melalui Wi-Fi" "Lanjutkan" "Mendownload wallpaper pertama…" -- cgit v1.2.3 From 4ccd603670b1b2616da62845c6bbb71472328d74 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 25 Jul 2019 10:08:12 -0700 Subject: Import translations. DO NOT MERGE Change-Id: Iea8597a192e5e13e08acd04ca3b32040e09d08c1 Auto-generated-cl: translation import --- res/values-hi/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 269f05d..453ecb0 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -37,9 +37,9 @@ "लॉक स्‍क्रीन" "होम स्क्रीन और लॉक स्क्रीन" "तय समय के बाद बदलने वाला इमेज वॉलपेपर" - "यहां पर मौजूदा वॉलपेपर दिखाने के लिए, %1$s को आपके डिवाइस की मेमोरी का एक्सेस चाहिए." - "यहां पर मौजूदा वॉलपेपर दिखाने के लिए, वॉलपेपर को आपके डिवाइस की मेमोरी का एक्सेस चाहिए. \n\nवॉलपेपर ऐप्लिकेशन की जानकारी के मंज़ूरी वाले विकल्प पर जाकर आप यह सेटिंग बदल सकते हैं." - "एक्सेस दें" + "यहां पर मौजूदा वॉलपेपर दिखाने के लिए, %1$s को आपके डिवाइस की मेमोरी का ऐक्सेस चाहिए." + "यहां पर मौजूदा वॉलपेपर दिखाने के लिए, वॉलपेपर को आपके डिवाइस की मेमोरी का ऐक्सेस चाहिए. \n\nवॉलपेपर ऐप्लिकेशन की जानकारी के मंज़ूरी वाले विकल्प पर जाकर आप यह सेटिंग बदल सकते हैं." + "ऐक्सेस दें" "तय समय के बाद बदलने वाले वॉलपेपर के लिए लाइव वॉलपेपर सेवा" "रोज़ वॉलपेपर बदलने की सुविधा" "चालू करने के लिए टैप करें" -- cgit v1.2.3 From 8dbefef3c15db982043a8bd5060b5012b06fefda Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Thu, 1 Aug 2019 17:32:19 -0700 Subject: Refactor shared preferences Group non-backup-able preferences separately so we can easily backup only the backup-able ones. Bug: 124394484 Change-Id: Ib0687c88eb74fbbd0133ed822f9e6c02aff1a5fc --- Android.mk | 1 + AndroidManifest.xml | 2 +- .../module/DefaultWallpaperPreferences.java | 340 ++++++++++++++------- .../wallpaper/module/WallpaperPreferenceKeys.java | 54 ++-- 4 files changed, 268 insertions(+), 129 deletions(-) diff --git a/Android.mk b/Android.mk index e7e051e..adf7fea 100755 --- a/Android.mk +++ b/Android.mk @@ -34,6 +34,7 @@ LOCAL_MODULE := wallpaper2-glide-target LOCAL_SDK_VERSION := current LOCAL_SRC_FILES := ../../../prebuilts/maven_repo/bumptech/com/github/bumptech/glide/glide/SNAPSHOT/glide-SNAPSHOT$(COMMON_JAVA_PACKAGE_SUFFIX) LOCAL_UNINSTALLABLE_MODULE := true +LOCAL_JETIFIER_ENABLED := true include $(BUILD_PREBUILT) include $(CLEAR_VARS) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0192398..1415226 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -20,7 +20,7 @@ android:name="com.android.wallpaper.NOTIFY_ROTATING_WALLPAPER_CHANGED" /> backupManager.dataChanged(); mSharedPrefs.registerOnSharedPreferenceChangeListener(mSharedPrefsChangedListener); } + /** + * Move {@link NoBackupKeys} preferences that might have been in mSharedPrefs from previous + * versions of the app into mNoBackupPrefs. + */ + private void upgradePrefs() { + SharedPreferences.Editor editor = mNoBackupPrefs.edit(); + if (mSharedPrefs.contains( + NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL)) { + editor.putString(NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, + mSharedPrefs.getString(NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, null)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID)) { + editor.putInt(NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID, + mSharedPrefs.getInt(NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID)) { + editor.putString(NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID, + mSharedPrefs.getString(NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID, null)); + } + if (mSharedPrefs.contains( + NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE)) { + editor.putString(NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE, + mSharedPrefs.getString(NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE, null)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID)) { + editor.putInt(NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, + mSharedPrefs.getInt(NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, 0)); + } + if (mSharedPrefs.contains( + NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE)) { + editor.putString(NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, + mSharedPrefs.getString(NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, null)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS)) { + editor.putString(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, + mSharedPrefs.getString(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, null)); + } + if (mSharedPrefs.contains( + NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, -1)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_ROTATION_STATUS)) { + editor.putInt(NoBackupKeys.KEY_LAST_ROTATION_STATUS, + mSharedPrefs.getInt(NoBackupKeys.KEY_LAST_ROTATION_STATUS, -1)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS)) { + editor.putInt(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + mSharedPrefs.getInt(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + WALLPAPER_SET_NOT_PENDING)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS)) { + editor.putInt(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + mSharedPrefs.getInt(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + DAILY_WALLPAPER_UPDATE_NOT_PENDING)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED)) { + editor.putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, + mSharedPrefs.getInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED)) { + editor.putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, + mSharedPrefs.getInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME)) { + editor.putString(NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, + mSharedPrefs.getString(NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, null)); + } + + editor.apply(); + } + private int getResIdPersistedByName(String key, String type) { String resName = mSharedPrefs.getString(key, null); if (resName == null) { @@ -106,13 +197,16 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { public void setHomeWallpaperAttributions(List attributions) { SharedPreferences.Editor editor = mSharedPrefs.edit(); if (attributions.size() > 0) { - editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_1, attributions.get(0)); + editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_1, + attributions.get(0)); } if (attributions.size() > 1) { - editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_2, attributions.get(1)); + editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_2, + attributions.get(1)); } if (attributions.size() > 2) { - editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_3, attributions.get(2)); + editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_3, + attributions.get(2)); } editor.apply(); } @@ -155,19 +249,22 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override public String getHomeWallpaperBaseImageUrl() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, null); } @Override public void setHomeWallpaperBaseImageUrl(String baseImageUrl) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, baseImageUrl).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, baseImageUrl) + .apply(); } @Override @Nullable public String getHomeWallpaperCollectionId() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_COLLECTION_ID, null); + return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_COLLECTION_ID, + null); } @Override @@ -179,14 +276,14 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override @Nullable public String getHomeWallpaperBackingFileName() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BACKING_FILE, - null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE, null); } @Override public void setHomeWallpaperBackingFileName(String fileName) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BACKING_FILE, fileName).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE, fileName).apply(); } @Override @@ -213,47 +310,56 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ACTION_URL) .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ACTION_LABEL_RES) .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ACTION_ICON_RES) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL) .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_HASH_CODE) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_MANAGER_ID) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_REMOTE_ID) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BACKING_FILE) + .apply(); + + mNoBackupPrefs.edit() + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME) + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID) + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID) + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL) + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE) .apply(); } @Override public String getHomeWallpaperPackageName() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, null); } @Override public void setHomeWallpaperPackageName(String packageName) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, packageName).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, packageName) + .apply(); } @Override public int getHomeWallpaperManagerId() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_MANAGER_ID, 0); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID, 0); } @Override public void setHomeWallpaperManagerId(int homeWallpaperId) { - mSharedPrefs.edit().putInt( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_MANAGER_ID, homeWallpaperId).apply(); + mNoBackupPrefs.edit().putInt( + NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID, homeWallpaperId) + .apply(); } @Nullable @Override public String getHomeWallpaperRemoteId() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_REMOTE_ID, null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID, null); } @Override public void setHomeWallpaperRemoteId(@Nullable String wallpaperRemoteId) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_REMOTE_ID, wallpaperRemoteId).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID, wallpaperRemoteId) + .apply(); } @Override @@ -269,13 +375,16 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { public void setLockWallpaperAttributions(List attributions) { SharedPreferences.Editor editor = mSharedPrefs.edit(); if (attributions.size() > 0) { - editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_1, attributions.get(0)); + editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_1, + attributions.get(0)); } if (attributions.size() > 1) { - editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_2, attributions.get(1)); + editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_2, + attributions.get(1)); } if (attributions.size() > 2) { - editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_3, attributions.get(2)); + editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_3, + attributions.get(2)); } editor.apply(); } @@ -319,7 +428,8 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override @Nullable public String getLockWallpaperCollectionId() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_COLLECTION_ID, null); + return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_COLLECTION_ID, + null); } @Override @@ -331,25 +441,27 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override @Nullable public String getLockWallpaperBackingFileName() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, - null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, null); } @Override public void setLockWallpaperBackingFileName(String fileName) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, fileName).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, fileName).apply(); } @Override public int getLockWallpaperId() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, 0); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, 0); } @Override public void setLockWallpaperId(int lockWallpaperId) { - mSharedPrefs.edit().putInt( - WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, lockWallpaperId).apply(); + mNoBackupPrefs.edit().putInt( + NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, lockWallpaperId) + .apply(); } @Override @@ -378,21 +490,25 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ACTION_LABEL_RES) .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ACTION_ICON_RES) .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_HASH_CODE) - .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_MANAGER_ID) - .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_BACKING_FILE) + .apply(); + + mNoBackupPrefs.edit() + .remove(NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID) + .remove(NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE) .apply(); } @Override public void addDailyRotation(long timestamp) { - String jsonString = mSharedPrefs.getString( - WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); + String jsonString = mNoBackupPrefs.getString( + NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); try { JSONArray jsonArray = new JSONArray(jsonString); jsonArray.put(timestamp); - mSharedPrefs.edit() - .putString(WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, jsonArray.toString()) + mNoBackupPrefs.edit() + .putString(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, + jsonArray.toString()) .apply(); } catch (JSONException e) { Log.e(TAG, "Failed to add a daily rotation timestamp due to a JSON parse exception"); @@ -401,8 +517,8 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override public long getLastDailyRotationTimestamp() { - String jsonString = mSharedPrefs.getString( - WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); + String jsonString = mNoBackupPrefs.getString( + NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); try { JSONArray jsonArray = new JSONArray(jsonString); @@ -428,15 +544,15 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { oneWeekAgo.add(Calendar.WEEK_OF_YEAR, -1); long oneWeekAgoTimestamp = oneWeekAgo.getTimeInMillis(); - // Return null if daily rotation wasn't enabled (timestamp value of -1) or was enabled earlier - // than one week ago. + // Return null if daily rotation wasn't enabled (timestamp value of -1) or was enabled + // less than one week ago. if (enabledTimestamp == -1 || enabledTimestamp > oneWeekAgoTimestamp) { return null; } List timestamps = new ArrayList<>(); - String jsonString = mSharedPrefs.getString( - WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); + String jsonString = mNoBackupPrefs.getString( + NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); try { JSONArray jsonArray = new JSONArray(jsonString); @@ -451,8 +567,9 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { } jsonArray = new JSONArray(timestamps); - mSharedPrefs.edit() - .putString(WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, jsonArray.toString()) + mNoBackupPrefs.edit() + .putString(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, + jsonArray.toString()) .apply(); } catch (JSONException e) { Log.e(TAG, "Failed to get daily rotation timestamps due to a JSON parse exception"); @@ -479,21 +596,21 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { midnightToday.set(Calendar.MINUTE, 0); long midnightTodayTimestamp = midnightToday.getTimeInMillis(); - // Return null if daily rotation wasn't enabled (timestamp value of -1) or was enabled earlier - // than midnight yesterday. + // Return null if daily rotation wasn't enabled (timestamp value of -1) or was enabled + // less than midnight yesterday. if (enabledTimestamp == -1 || enabledTimestamp > midnightYesterdayTimestamp) { return null; } List timestamps = new ArrayList<>(); - String jsonString = mSharedPrefs.getString( - WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); + String jsonString = mNoBackupPrefs.getString( + NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); try { JSONArray jsonArray = new JSONArray(jsonString); - // Filter the timestamps (which cover up to one week of data) to only include those between - // midnight yesterday and midnight today. + // Filter the timestamps (which cover up to one week of data) to only include those + // between midnight yesterday and midnight today. for (int i = 0; i < jsonArray.length(); i++) { long timestamp = jsonArray.getLong(i); if (timestamp >= midnightYesterdayTimestamp && timestamp < midnightTodayTimestamp) { @@ -510,160 +627,175 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override public long getDailyWallpaperEnabledTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, -1); + return mNoBackupPrefs.getLong( + NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, -1); } @Override public void setDailyWallpaperEnabledTimestamp(long timestamp) { - mSharedPrefs.edit() - .putLong(WallpaperPreferenceKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, timestamp) + mNoBackupPrefs.edit() + .putLong(NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, + timestamp) .apply(); } @Override public void clearDailyRotations() { - mSharedPrefs.edit() - .remove(WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS) - .remove(WallpaperPreferenceKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP) + mNoBackupPrefs.edit() + .remove(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS) + .remove(NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP) .apply(); } @Override public long getLastDailyLogTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, 0); + return mNoBackupPrefs.getLong( + NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, 0); } @Override public void setLastDailyLogTimestamp(long timestamp) { - mSharedPrefs.edit() - .putLong(WallpaperPreferenceKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, timestamp) + mNoBackupPrefs.edit() + .putLong(NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, timestamp) .apply(); } @Override public long getLastAppActiveTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, 0); + return mNoBackupPrefs.getLong( + NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, 0); } @Override public void setLastAppActiveTimestamp(long timestamp) { - mSharedPrefs.edit() - .putLong(WallpaperPreferenceKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, timestamp) + mNoBackupPrefs.edit() + .putLong(NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, timestamp) .apply(); } @Override public void setDailyWallpaperRotationStatus(int status, long timestamp) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_LAST_ROTATION_STATUS, status) - .putLong(WallpaperPreferenceKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, timestamp) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_LAST_ROTATION_STATUS, status) + .putLong(NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, + timestamp) .apply(); } @Override public int getDailyWallpaperLastRotationStatus() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_LAST_ROTATION_STATUS, -1); + return mNoBackupPrefs.getInt(NoBackupKeys.KEY_LAST_ROTATION_STATUS, -1); } @Override public long getDailyWallpaperLastRotationStatusTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, 0); + return mNoBackupPrefs.getLong( + NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, 0); } @Override public long getLastSyncTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_LAST_SYNC_TIMESTAMP, 0); + return mNoBackupPrefs.getLong(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP, 0); } @Override public void setLastSyncTimestamp(long timestamp) { - // Write synchronously via commit() to ensure this timetsamp gets written to disk immediately. - mSharedPrefs.edit() - .putLong(WallpaperPreferenceKeys.KEY_LAST_SYNC_TIMESTAMP, timestamp) + // Write synchronously via commit() to ensure this timetsamp gets written to disk + // immediately. + mNoBackupPrefs.edit() + .putLong(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP, timestamp) .commit(); } @Override public void setPendingWallpaperSetStatusSync(@PendingWallpaperSetStatus int setStatus) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_PENDING_WALLPAPER_SET_STATUS, setStatus) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + setStatus) .commit(); } @Override public int getPendingWallpaperSetStatus() { //noinspection ResourceType - return mSharedPrefs.getInt( - WallpaperPreferenceKeys.KEY_PENDING_WALLPAPER_SET_STATUS, WALLPAPER_SET_NOT_PENDING); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + WALLPAPER_SET_NOT_PENDING); } @Override public void setPendingWallpaperSetStatus(@PendingWallpaperSetStatus int setStatus) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_PENDING_WALLPAPER_SET_STATUS, setStatus) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + setStatus) .apply(); } @Override public void setPendingDailyWallpaperUpdateStatusSync( @PendingDailyWallpaperUpdateStatus int updateStatus) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, updateStatus) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + updateStatus) .commit(); } @Override public int getPendingDailyWallpaperUpdateStatus() { //noinspection ResourceType - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, DAILY_WALLPAPER_UPDATE_NOT_PENDING); } @Override public void setPendingDailyWallpaperUpdateStatus( @PendingDailyWallpaperUpdateStatus int updateStatus) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, updateStatus) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + updateStatus) .apply(); } @Override public void incrementNumDaysDailyRotationFailed() { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, getNumDaysDailyRotationFailed() + 1) .apply(); } @Override public int getNumDaysDailyRotationFailed() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0); } @Override public void resetNumDaysDailyRotationFailed() { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0) .apply(); } @Override public void incrementNumDaysDailyRotationNotAttempted() { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, getNumDaysDailyRotationNotAttempted() + 1) .apply(); } @Override public int getNumDaysDailyRotationNotAttempted() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0); } @Override public void resetNumDaysDailyRotationNotAttempted() { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0) .apply(); } } diff --git a/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java b/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java index f63506f..e4c6588 100755 --- a/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java +++ b/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java @@ -28,12 +28,7 @@ public class WallpaperPreferenceKeys { public static final String KEY_HOME_WALLPAPER_ACTION_LABEL_RES = "home_wallpaper_action_label"; public static final String KEY_HOME_WALLPAPER_ACTION_ICON_RES = "home_wallpaper_action_icon"; public static final String KEY_HOME_WALLPAPER_COLLECTION_ID = "home_wallpaper_collection_id"; - public static final String KEY_HOME_WALLPAPER_BASE_IMAGE_URL = "home_wallpaper_base_image_url"; public static final String KEY_HOME_WALLPAPER_HASH_CODE = "home_wallpaper_hash_code"; - public static final String KEY_HOME_WALLPAPER_MANAGER_ID = "home_wallpaper_id"; - public static final String KEY_HOME_WALLPAPER_PACKAGE_NAME = "home_wallpaper_package_name"; - public static final String KEY_HOME_WALLPAPER_REMOTE_ID = "home_wallpaper_remote_id"; - public static final String KEY_HOME_WALLPAPER_BACKING_FILE = "home_wallpaper_backing_file"; public static final String KEY_LOCK_WALLPAPER_ATTRIB_1 = "lock_wallpaper_attribution_line_1"; public static final String KEY_LOCK_WALLPAPER_ATTRIB_2 = "lock_wallpaper_attribution_line_2"; @@ -43,24 +38,35 @@ public class WallpaperPreferenceKeys { public static final String KEY_LOCK_WALLPAPER_ACTION_ICON_RES = "lock_wallpaper_action_icon"; public static final String KEY_LOCK_WALLPAPER_HASH_CODE = "lock_wallpaper_hash_code"; public static final String KEY_LOCK_WALLPAPER_COLLECTION_ID = "lock_wallpaper_collection_id"; - public static final String KEY_LOCK_WALLPAPER_MANAGER_ID = "lock_wallpaper_id"; - public static final String KEY_LOCK_WALLPAPER_BACKING_FILE = "lock_wallpaper_backing_file"; - public static final String KEY_DAILY_ROTATION_TIMESTAMPS = "daily_rotation_timestamps"; - public static final String KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP = - "daily_wallpaper_enabled_timestamp"; - - public static final String KEY_LAST_DAILY_LOG_TIMESTAMP = "last_daily_log_timestamp"; - public static final String KEY_LAST_APP_ACTIVE_TIMESTAMP = "last_app_active_timestamp"; - public static final String KEY_LAST_ROTATION_STATUS = "last_rotation_status"; - public static final String KEY_LAST_ROTATION_STATUS_TIMESTAMP = "last_rotation_status_timestamp"; - public static final String KEY_LAST_SYNC_TIMESTAMP = "last_sync_timestamp"; - - public static final String KEY_PENDING_WALLPAPER_SET_STATUS = "pending_wallpaper_set_status"; - public static final String KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS = - "pending_daily_wallpaper_update_status"; - - public static final String KEY_NUM_DAYS_DAILY_ROTATION_FAILED = "num_days_daily_rotation_failed"; - public static final String KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED = - "num_days_daily_rotation_not_attempted"; + /** + * Preferences with these keys should not be backed up + */ + public interface NoBackupKeys { + public static final String KEY_HOME_WALLPAPER_BASE_IMAGE_URL = + "home_wallpaper_base_image_url"; + public static final String KEY_HOME_WALLPAPER_MANAGER_ID = "home_wallpaper_id"; + public static final String KEY_HOME_WALLPAPER_REMOTE_ID = "home_wallpaper_remote_id"; + public static final String KEY_HOME_WALLPAPER_BACKING_FILE = "home_wallpaper_backing_file"; + public static final String KEY_LOCK_WALLPAPER_MANAGER_ID = "lock_wallpaper_id"; + public static final String KEY_LOCK_WALLPAPER_BACKING_FILE = "lock_wallpaper_backing_file"; + public static final String KEY_DAILY_ROTATION_TIMESTAMPS = "daily_rotation_timestamps"; + public static final String KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP = + "daily_wallpaper_enabled_timestamp"; + public static final String KEY_LAST_DAILY_LOG_TIMESTAMP = "last_daily_log_timestamp"; + public static final String KEY_LAST_APP_ACTIVE_TIMESTAMP = "last_app_active_timestamp"; + public static final String KEY_LAST_ROTATION_STATUS = "last_rotation_status"; + public static final String KEY_LAST_ROTATION_STATUS_TIMESTAMP = + "last_rotation_status_timestamp"; + public static final String KEY_LAST_SYNC_TIMESTAMP = "last_sync_timestamp"; + public static final String KEY_PENDING_WALLPAPER_SET_STATUS = + "pending_wallpaper_set_status"; + public static final String KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS = + "pending_daily_wallpaper_update_status"; + public static final String KEY_NUM_DAYS_DAILY_ROTATION_FAILED = + "num_days_daily_rotation_failed"; + public static final String KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED = + "num_days_daily_rotation_not_attempted"; + public static final String KEY_HOME_WALLPAPER_PACKAGE_NAME = "home_wallpaper_package_name"; + } } -- cgit v1.2.3 From cdefc50b55e63a1656ce56da95098a78cde630b3 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 6 Aug 2019 19:35:49 -0700 Subject: Add PREUPLOAD.cfg file to enable repo checkstyle hooks fixes: 65162750 Change-Id: I9215f1872b397f558a3a6672b6f4930ccd412aaf --- PREUPLOAD.cfg | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 PREUPLOAD.cfg diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg new file mode 100644 index 0000000..f3db20e --- /dev/null +++ b/PREUPLOAD.cfg @@ -0,0 +1,2 @@ +[Hook Scripts] +checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT} -- cgit v1.2.3 From 7f88915dc52e6db118a3536a0f00e0f59b3e4e3f Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Thu, 8 Aug 2019 01:33:48 -0700 Subject: Make WallpaperPicker2 unbundled Bug: 136199516 Change-Id: I3a900426cbbdb7b33b610f738b26a5bdaf831b35 --- Android.mk | 27 ++------------------------- libs/style_protos.jar | Bin 53134 -> 0 bytes 2 files changed, 2 insertions(+), 25 deletions(-) delete mode 100644 libs/style_protos.jar diff --git a/Android.mk b/Android.mk index adf7fea..fec9941 100755 --- a/Android.mk +++ b/Android.mk @@ -16,18 +16,6 @@ LOCAL_PATH := $(call my-dir) -# -# Prebuilt Java Libraries -# -include $(CLEAR_VARS) -LOCAL_MODULE := libStyleProtos -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_CLASS := JAVA_LIBRARIES -LOCAL_SRC_FILES := libs/style_protos.jar -LOCAL_UNINSTALLABLE_MODULE := true -LOCAL_SDK_VERSION := current -include $(BUILD_PREBUILT) - include $(CLEAR_VARS) LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_MODULE := wallpaper2-glide-target @@ -100,14 +88,7 @@ LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res LOCAL_PROGUARD_ENABLED := disabled LOCAL_MANIFEST_FILE := AndroidManifest.xml -ifneq (,$(wildcard frameworks/base)) - LOCAL_STATIC_JAVA_LIBRARIES += SystemUISharedLib styleprotosnano - LOCAL_PRIVATE_PLATFORM_APIS := true -else - LOCAL_STATIC_JAVA_LIBRARIES += libSharedSystemUI libStyleProtos - LOCAL_SDK_VERSION := current -endif - +LOCAL_SDK_VERSION := current LOCAL_MODULE := WallpaperPicker2CommonDepsLib LOCAL_PRIVILEGED_MODULE := true @@ -132,11 +113,7 @@ LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res LOCAL_PROGUARD_FLAG_FILES := proguard.flags LOCAL_PROGUARD_ENABLED := disabled -ifneq (,$(wildcard frameworks/base)) - LOCAL_PRIVATE_PLATFORM_APIS := true -else - LOCAL_SDK_VERSION := system_current -endif +LOCAL_SDK_VERSION := system_current LOCAL_PACKAGE_NAME := WallpaperPicker2 LOCAL_JETIFIER_ENABLED := true diff --git a/libs/style_protos.jar b/libs/style_protos.jar deleted file mode 100644 index 8708555..0000000 Binary files a/libs/style_protos.jar and /dev/null differ -- cgit v1.2.3 From 03bc6ac9003c392e11c955cac2c80244d9af14e1 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Thu, 19 Sep 2019 12:01:50 -0700 Subject: Remove support for rotating live wallpaper Bug:112267966 Change-Id: I3b75dcb462ca648d2a2dc7d7fe04d878cb8de4a6 --- .../model/WallpaperRotationInitializer.java | 7 - .../wallpaper/module/BaseWallpaperInjector.java | 9 - .../DefaultRotatingWallpaperComponentChecker.java | 77 ---- .../module/DefaultWallpaperPersister.java | 449 +++++---------------- src/com/android/wallpaper/module/Injector.java | 2 - .../module/RotatingWallpaperComponentChecker.java | 69 ---- .../picker/StartRotationDialogFragment.java | 25 +- .../individual/IndividualPickerFragment.java | 66 ++- 8 files changed, 136 insertions(+), 568 deletions(-) delete mode 100755 src/com/android/wallpaper/module/DefaultRotatingWallpaperComponentChecker.java delete mode 100755 src/com/android/wallpaper/module/RotatingWallpaperComponentChecker.java diff --git a/src/com/android/wallpaper/model/WallpaperRotationInitializer.java b/src/com/android/wallpaper/model/WallpaperRotationInitializer.java index ad9eef9..5797650 100755 --- a/src/com/android/wallpaper/model/WallpaperRotationInitializer.java +++ b/src/com/android/wallpaper/model/WallpaperRotationInitializer.java @@ -57,13 +57,6 @@ public interface WallpaperRotationInitializer extends Parcelable { void setFirstWallpaperInRotation(Context appContext, @NetworkPreference int networkPreference, Listener listener); - /** - * Returns whether the live wallpaper needs to be set to the device in order to be able to start - * rotation or is already set but on home-only on N-MR2 or later, which means the user has the - * option to pick a new destination preference. - */ - boolean isNoBackupImageWallpaperPreviewNeeded(Context appContext); - /** * Gets the current state of the possible wallpaper rotation represented by this object. */ diff --git a/src/com/android/wallpaper/module/BaseWallpaperInjector.java b/src/com/android/wallpaper/module/BaseWallpaperInjector.java index f8191fc..7f52823 100755 --- a/src/com/android/wallpaper/module/BaseWallpaperInjector.java +++ b/src/com/android/wallpaper/module/BaseWallpaperInjector.java @@ -39,7 +39,6 @@ public abstract class BaseWallpaperInjector implements Injector { private AlarmManagerWrapper mAlarmManagerWrapper; private ExploreIntentChecker mExploreIntentChecker; private SystemFeatureChecker mSystemFeatureChecker; - private RotatingWallpaperComponentChecker mRotatingWallpaperComponentChecker; private FormFactorChecker mFormFactorChecker; private PackageStatusNotifier mPackageStatusNotifier; private LiveWallpaperInfoFactory mLiveWallpaperInfoFactory; @@ -160,14 +159,6 @@ public abstract class BaseWallpaperInjector implements Injector { return mSystemFeatureChecker; } - @Override - public synchronized RotatingWallpaperComponentChecker getRotatingWallpaperComponentChecker() { - if (mRotatingWallpaperComponentChecker == null) { - mRotatingWallpaperComponentChecker = new DefaultRotatingWallpaperComponentChecker(); - } - return mRotatingWallpaperComponentChecker; - } - @Override public synchronized FormFactorChecker getFormFactorChecker(Context context) { if (mFormFactorChecker == null) { diff --git a/src/com/android/wallpaper/module/DefaultRotatingWallpaperComponentChecker.java b/src/com/android/wallpaper/module/DefaultRotatingWallpaperComponentChecker.java deleted file mode 100755 index eddb6bf..0000000 --- a/src/com/android/wallpaper/module/DefaultRotatingWallpaperComponentChecker.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.wallpaper.module; - -import android.content.Context; -import android.content.pm.PackageManager; - -/** - * Default implementation of {@link RotatingWallpaperComponentChecker}. - */ -public class DefaultRotatingWallpaperComponentChecker implements RotatingWallpaperComponentChecker { - - private static boolean isLiveWallpaperSupported(Context context) { - return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LIVE_WALLPAPER); - } - - @Override - @RotatingWallpaperComponent - public int getCurrentRotatingWallpaperComponent(Context context) { - if (!isLiveWallpaperSupported(context)) { - return ROTATING_WALLPAPER_COMPONENT_STATIC; - } - - // If presentation mode is ROTATING but the live wallpaper is not set, then "legacy" rotation - // from older APKs is in effect and the current rotating wallpaper component is a static WP. - Injector injector = InjectorProvider.getInjector(); - WallpaperPreferences preferences = injector.getPreferences(context); - LiveWallpaperStatusChecker liveWallpaperStatusChecker = injector - .getLiveWallpaperStatusChecker(context); - if (preferences.getWallpaperPresentationMode() - == WallpaperPreferences.PRESENTATION_MODE_ROTATING - && !liveWallpaperStatusChecker.isNoBackupImageWallpaperSet()) { - return ROTATING_WALLPAPER_COMPONENT_STATIC; - } - - return ROTATING_WALLPAPER_COMPONENT_LIVE; - } - - @Override - @RotatingWallpaperComponent - public int getNextRotatingWallpaperComponent(Context context) { - if (!isLiveWallpaperSupported(context)) { - return ROTATING_WALLPAPER_COMPONENT_STATIC; - } - - return ROTATING_WALLPAPER_COMPONENT_LIVE; - } - - @Override - @RotatingWallpaperSupport - public int getRotatingWallpaperSupport(Context context) { - FormFactorChecker formFactorChecker = - InjectorProvider.getInjector().getFormFactorChecker(context); - - if (formFactorChecker.getFormFactor() == FormFactorChecker.FORM_FACTOR_DESKTOP) { - return ROTATING_WALLPAPER_SUPPORT_SUPPORTED; - } - - // While static daily rotation is supported on desktops, it isn't (yet?) supported on phones. - // For phones which don't support live wallpapers thus we disallow daily rotation altogether. - return isLiveWallpaperSupported(context) ? ROTATING_WALLPAPER_SUPPORT_SUPPORTED - : ROTATING_WALLPAPER_SUPPORT_NOT_SUPPORTED; - } -} diff --git a/src/com/android/wallpaper/module/DefaultWallpaperPersister.java b/src/com/android/wallpaper/module/DefaultWallpaperPersister.java index e2c968c..27e4491 100755 --- a/src/com/android/wallpaper/module/DefaultWallpaperPersister.java +++ b/src/com/android/wallpaper/module/DefaultWallpaperPersister.java @@ -19,7 +19,6 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.WallpaperManager; import android.content.Context; -import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; @@ -32,6 +31,8 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; +import androidx.annotation.Nullable; + import com.android.wallpaper.asset.Asset; import com.android.wallpaper.asset.Asset.BitmapReceiver; import com.android.wallpaper.asset.Asset.DimensionsReceiver; @@ -42,24 +43,16 @@ import com.android.wallpaper.compat.BuildCompat; import com.android.wallpaper.compat.WallpaperManagerCompat; import com.android.wallpaper.model.WallpaperInfo; import com.android.wallpaper.module.BitmapCropper.Callback; -import com.android.wallpaper.module.RotatingWallpaperComponentChecker.RotatingWallpaperComponent; import com.android.wallpaper.util.BitmapTransformer; -import com.android.wallpaper.util.DiskBasedLogger; -import com.android.wallpaper.util.FileMover; import com.android.wallpaper.util.ScreenSizeCalculator; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; -import androidx.annotation.Nullable; - /** * Concrete implementation of WallpaperPersister which actually sets wallpapers to the system via * the WallpaperManager. @@ -71,11 +64,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { private final Context mAppContext; // The application's context. // Context that accesses files in device protected storage - private final Context mDeviceProtectedContext; private final WallpaperManager mWallpaperManager; private final WallpaperManagerCompat mWallpaperManagerCompat; private final WallpaperPreferences mWallpaperPreferences; - private final RotatingWallpaperComponentChecker mRotatingWallpaperComponentChecker; private final WallpaperChangedNotifier mWallpaperChangedNotifier; private WallpaperInfo mWallpaperInfoInPreview; @@ -83,21 +74,19 @@ public class DefaultWallpaperPersister implements WallpaperPersister { @SuppressLint("ServiceCast") public DefaultWallpaperPersister(Context context) { mAppContext = context.getApplicationContext(); - mDeviceProtectedContext = mAppContext.createDeviceProtectedStorageContext(); // Retrieve WallpaperManager using Context#getSystemService instead of // WallpaperManager#getInstance so it can be mocked out in test. Injector injector = InjectorProvider.getInjector(); mWallpaperManager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE); mWallpaperManagerCompat = injector.getWallpaperManagerCompat(context); mWallpaperPreferences = injector.getPreferences(context); - mRotatingWallpaperComponentChecker = injector.getRotatingWallpaperComponentChecker(); mWallpaperChangedNotifier = WallpaperChangedNotifier.getInstance(); } @Override public void setIndividualWallpaper(final WallpaperInfo wallpaper, Asset asset, - @Nullable Rect cropRect, float scale, @Destination final int destination, - final SetWallpaperCallback callback) { + @Nullable Rect cropRect, float scale, @Destination final int destination, + final SetWallpaperCallback callback) { // Set wallpaper without downscaling directly from an input stream if there's no crop rect // specified by the caller and the asset is streamable. if (cropRect == null && asset instanceof StreamableAsset) { @@ -149,7 +138,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { @Override public void setIndividualWallpaperWithPosition(Activity activity, WallpaperInfo wallpaper, - @WallpaperPosition int wallpaperPosition, SetWallpaperCallback callback) { + @WallpaperPosition int wallpaperPosition, SetWallpaperCallback callback) { Display display = ((WindowManager) mAppContext.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display); @@ -164,9 +153,10 @@ public class DefaultWallpaperPersister implements WallpaperPersister { } switch (wallpaperPosition) { - // Crop out screen-sized center portion of the source image if it's larger than the screen - // in both dimensions. Otherwise, decode the entire bitmap and fill the space around it to - // fill a new screen-sized bitmap with plain black pixels. + // Crop out screen-sized center portion of the source image if it's larger + // than the screen + // in both dimensions. Otherwise, decode the entire bitmap and fill the space + // around it to fill a new screen-sized bitmap with plain black pixels. case WALLPAPER_POSITION_CENTER: setIndividualWallpaperWithCenterPosition( wallpaper, asset, dimensions, screenSize, callback); @@ -178,19 +168,22 @@ public class DefaultWallpaperPersister implements WallpaperPersister { wallpaper, asset, dimensions, screenSize, callback); break; - // Decode full bitmap sized for screen and stretch it to fill the screen dimensions. + // Decode full bitmap sized for screen and stretch it to fill the screen + // dimensions. case WALLPAPER_POSITION_STRETCH: asset.decodeBitmap(screenSize.x, screenSize.y, new BitmapReceiver() { @Override public void onBitmapDecoded(@Nullable Bitmap bitmap) { - setIndividualWallpaperStretch(wallpaper, bitmap, screenSize /* stretchSize */, + setIndividualWallpaperStretch(wallpaper, bitmap, + screenSize /* stretchSize */, WallpaperPersister.DEST_BOTH, callback); } }); break; default: - Log.e(TAG, "Unsupported wallpaper position option specified: " + wallpaperPosition); + Log.e(TAG, "Unsupported wallpaper position option specified: " + + wallpaperPosition); callback.onError(null); } } @@ -208,7 +201,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * @param callback Callback used to notify original caller of wallpaper set operation result. */ private void setIndividualWallpaperWithCenterPosition(WallpaperInfo wallpaper, Asset asset, - Point dimensions, Point screenSize, SetWallpaperCallback callback) { + Point dimensions, Point screenSize, SetWallpaperCallback callback) { if (dimensions.x >= screenSize.x && dimensions.y >= screenSize.y) { Rect cropRect = new Rect( (dimensions.x - screenSize.x) / 2, @@ -218,7 +211,8 @@ public class DefaultWallpaperPersister implements WallpaperPersister { asset.decodeBitmapRegion(cropRect, screenSize.x, screenSize.y, new BitmapReceiver() { @Override public void onBitmapDecoded(@Nullable Bitmap bitmap) { - setIndividualWallpaper(wallpaper, bitmap, WallpaperPersister.DEST_BOTH, callback); + setIndividualWallpaper(wallpaper, bitmap, WallpaperPersister.DEST_BOTH, + callback); } }); } else { @@ -249,7 +243,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * @param callback Callback used to notify original caller of wallpaper set operation result. */ private void setIndividualWallpaperWithCenterCropPosition(WallpaperInfo wallpaper, Asset asset, - Point dimensions, Point screenSize, SetWallpaperCallback callback) { + Point dimensions, Point screenSize, SetWallpaperCallback callback) { float scale = Math.max((float) screenSize.x / dimensions.x, (float) screenSize.y / dimensions.y); @@ -276,7 +270,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * @param callback Called once the wallpaper was set or if an error occurred. */ private void setIndividualWallpaper(WallpaperInfo wallpaper, Bitmap croppedBitmap, - @Destination int destination, SetWallpaperCallback callback) { + @Destination int destination, SetWallpaperCallback callback) { SetWallpaperTask setWallpaperTask = new SetWallpaperTask(wallpaper, croppedBitmap, destination, callback); setWallpaperTask.execute(); @@ -287,15 +281,16 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * * @param wallpaper Wallpaper model object. * @param croppedBitmap Bitmap representing the individual wallpaper image. - * @param fillSize Specifies the final bitmap size that should be set to WallpaperManager. This - * final bitmap will show the visible area of the provided bitmap after applying a mask with - * black background the source bitmap and centering. There may be black borders around the - * original bitmap if it's smaller than the fillSize in one or both dimensions. + * @param fillSize Specifies the final bitmap size that should be set to WallpaperManager. + * This final bitmap will show the visible area of the provided bitmap + * after applying a mask with black background the source bitmap and + * centering. There may be black borders around the original bitmap if + * it's smaller than the fillSize in one or both dimensions. * @param destination The destination - where to set the wallpaper to. * @param callback Called once the wallpaper was set or if an error occurred. */ private void setIndividualWallpaperFill(WallpaperInfo wallpaper, Bitmap croppedBitmap, - Point fillSize, @Destination int destination, SetWallpaperCallback callback) { + Point fillSize, @Destination int destination, SetWallpaperCallback callback) { SetWallpaperTask setWallpaperTask = new SetWallpaperTask(wallpaper, croppedBitmap, destination, callback); setWallpaperTask.setFillSize(fillSize); @@ -308,13 +303,14 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * * @param wallpaper Wallpaper model object. * @param croppedBitmap Bitmap representing the individual wallpaper image. - * @param stretchSize Specifies the final size to which the the bitmap should be stretched prior + * @param stretchSize Specifies the final size to which the bitmap should be stretched + * prior * to being set to the device. * @param destination The destination - where to set the wallpaper to. * @param callback Called once the wallpaper was set or if an error occurred. */ private void setIndividualWallpaperStretch(WallpaperInfo wallpaper, Bitmap croppedBitmap, - Point stretchSize, @Destination int destination, SetWallpaperCallback callback) { + Point stretchSize, @Destination int destination, SetWallpaperCallback callback) { SetWallpaperTask setWallpaperTask = new SetWallpaperTask(wallpaper, croppedBitmap, destination, callback); setWallpaperTask.setStretchSize(stretchSize); @@ -330,7 +326,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * @param callback Called once the wallpaper was set or if an error occurred. */ private void setIndividualWallpaper(WallpaperInfo wallpaper, InputStream inputStream, - @Destination int destination, SetWallpaperCallback callback) { + @Destination int destination, SetWallpaperCallback callback) { SetWallpaperTask setWallpaperTask = new SetWallpaperTask(wallpaper, inputStream, destination, callback); setWallpaperTask.execute(); @@ -338,58 +334,31 @@ public class DefaultWallpaperPersister implements WallpaperPersister { @Override public boolean setWallpaperInRotation(Bitmap wallpaperBitmap, List attributions, - int actionLabelRes, int actionIconRes, - String actionUrl, String collectionId) { - @RotatingWallpaperComponent int rotatingWallpaperComponent = mRotatingWallpaperComponentChecker - .getCurrentRotatingWallpaperComponent(mAppContext); - - switch (rotatingWallpaperComponent) { - case RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC: - return setWallpaperInRotationStatic(wallpaperBitmap, attributions, actionUrl, - actionLabelRes, actionIconRes, collectionId); - case RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_LIVE: - return setWallpaperInRotationLive(wallpaperBitmap, attributions, actionUrl, - actionLabelRes, actionIconRes, collectionId); - default: - Log.e(TAG, "Unknown rotating wallpaper component: " + rotatingWallpaperComponent); - return false; - } + int actionLabelRes, int actionIconRes, String actionUrl, String collectionId) { + + return setWallpaperInRotationStatic(wallpaperBitmap, attributions, actionUrl, + actionLabelRes, actionIconRes, collectionId); } @Override public int setWallpaperBitmapInNextRotation(Bitmap wallpaperBitmap) { - @RotatingWallpaperComponent int rotatingWallpaperComponent = mRotatingWallpaperComponentChecker - .getNextRotatingWallpaperComponent(mAppContext); - - switch (rotatingWallpaperComponent) { - case RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC: - return setWallpaperBitmapInRotationStatic(wallpaperBitmap); - case RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_LIVE: - boolean isSuccess = setWallpaperBitmapInRotationLive(wallpaperBitmap, true /* isPreview */); - return isSuccess ? 1 : 0; - default: - Log.e(TAG, "Unknown rotating wallpaper component: " + rotatingWallpaperComponent); - return 0; - } + return setWallpaperBitmapInRotationStatic(wallpaperBitmap); } @Override public boolean finalizeWallpaperForNextRotation(List attributions, String actionUrl, - int actionLabelRes, int actionIconRes, - String collectionId, int wallpaperId) { - @RotatingWallpaperComponent int rotatingWallpaperComponent = - mRotatingWallpaperComponentChecker.getNextRotatingWallpaperComponent(mAppContext); + int actionLabelRes, int actionIconRes, String collectionId, int wallpaperId) { return finalizeWallpaperForRotatingComponent(attributions, actionUrl, actionLabelRes, - actionIconRes, collectionId, wallpaperId, rotatingWallpaperComponent); + actionIconRes, collectionId, wallpaperId); } /** - * Sets wallpaper image and attributions when a static wallpaper is responsible for presenting the + * Sets wallpaper image and attributions when a static wallpaper is responsible for presenting + * the * current "daily wallpaper". */ private boolean setWallpaperInRotationStatic(Bitmap wallpaperBitmap, List attributions, - String actionUrl, int actionLabelRes, - int actionIconRes, String collectionId) { + String actionUrl, int actionLabelRes, int actionIconRes, String collectionId) { final int wallpaperId = setWallpaperBitmapInRotationStatic(wallpaperBitmap); if (wallpaperId == 0) { @@ -397,8 +366,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { } return finalizeWallpaperForRotatingComponent(attributions, actionUrl, actionLabelRes, - actionIconRes, collectionId, wallpaperId, - RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC); + actionIconRes, collectionId, wallpaperId); } /** @@ -413,83 +381,21 @@ public class DefaultWallpaperPersister implements WallpaperPersister { int actionLabelRes, int actionIconRes, String collectionId, - int wallpaperId, - @RotatingWallpaperComponent int rotatingWallpaperComponent) { + int wallpaperId) { mWallpaperPreferences.clearHomeWallpaperMetadata(); boolean isLockWallpaperSet = isSeparateLockScreenWallpaperSet(); - // Persist wallpaper IDs if the rotating wallpaper component is static and this device is - // running Android N or later. - if (rotatingWallpaperComponent - == RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC) { - if (BuildCompat.isAtLeastN()) { - mWallpaperPreferences.setHomeWallpaperManagerId(wallpaperId); + // Persist wallpaper IDs if the rotating wallpaper component + mWallpaperPreferences.setHomeWallpaperManagerId(wallpaperId); - // Only copy over wallpaper ID to lock wallpaper if no explicit lock wallpaper is set (so - // metadata isn't lost if a user explicitly sets a home-only wallpaper). - if (!isLockWallpaperSet) { - mWallpaperPreferences.setLockWallpaperId(wallpaperId); - } - } else { // Pre-N but using static component - // Compute bitmap hash code after setting the wallpaper because JPEG compression has likely - // changed many pixels' color values. Forget the previously loaded wallpaper bitmap so that - // WallpaperManager doesn't return the old wallpaper drawable. - mWallpaperManager.forgetLoadedWallpaper(); - Bitmap bitmap = ((BitmapDrawable) mWallpaperManagerCompat.getDrawable()).getBitmap(); - long bitmapHash = BitmapUtils.generateHashCode(bitmap); - - mWallpaperPreferences.setHomeWallpaperHashCode(bitmapHash); - } - } else { // Live wallpaper rotating component. - - // Copy "preview" JPEG to "rotating" JPEG if the preview file exists. - File rotatingWallpaper; - try { - rotatingWallpaper = moveToDeviceProtectedStorage( - NoBackupImageWallpaper.PREVIEW_WALLPAPER_FILE_PATH, - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - } catch (Exception e) { - DiskBasedLogger.e( - TAG, - "Unable to move preview to final file for rotating wallpaper " + - "file (exception)" + e.toString(), - mAppContext); - return false; - } - if (rotatingWallpaper == null) { - rotatingWallpaper = mDeviceProtectedContext.getFileStreamPath( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - } - try { - FileInputStream fis = new FileInputStream(rotatingWallpaper.getAbsolutePath()); - Bitmap bitmap = BitmapFactory.decodeStream(fis); - fis.close(); - - if (bitmap != null) { - long bitmapHash = BitmapUtils.generateHashCode(bitmap); - mWallpaperPreferences.setHomeWallpaperHashCode(bitmapHash); - } else { - Log.e(TAG, "Unable to decode rotating wallpaper file"); - return false; - } - } catch (FileNotFoundException e) { - Log.e(TAG, "Rotating wallpaper file not found at path: " - + rotatingWallpaper.getAbsolutePath()); - e.printStackTrace(); - return false; - } catch (IOException e) { - Log.e(TAG, "IOException when closing FileInputStream " + e); - return false; - } - - mWallpaperChangedNotifier.notifyWallpaperChanged(); - - // Send a broadcast to {@link RotatingWallpaperChangedReceiver} in the :live_wallpaper - // process so the currently displayed wallpaper updates. - notifyLiveWallpaperBitmapChanged(); + // Only copy over wallpaper ID to lock wallpaper if no explicit lock wallpaper is set + // (so metadata isn't lost if a user explicitly sets a home-only wallpaper). + if (!isLockWallpaperSet) { + mWallpaperPreferences.setLockWallpaperId(wallpaperId); } + mWallpaperPreferences.setHomeWallpaperAttributions(attributions); mWallpaperPreferences.setHomeWallpaperActionUrl(actionUrl); mWallpaperPreferences.setHomeWallpaperActionLabelRes(actionLabelRes); @@ -498,11 +404,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperPreferences.setHomeWallpaperBaseImageUrl(null); mWallpaperPreferences.setHomeWallpaperCollectionId(collectionId); - // Set metadata to lock screen also when the rotating wallpaper is a static one so if user sets - // a home screen-only wallpaper later, these attributions will still be available. - if (rotatingWallpaperComponent - == RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC - && !isLockWallpaperSet) { + // Set metadata to lock screen also when the rotating wallpaper so if user sets a home + // screen-only wallpaper later, these attributions will still be available. + if (!isLockWallpaperSet) { mWallpaperPreferences.setLockWallpaperAttributions(attributions); mWallpaperPreferences.setLockWallpaperActionUrl(actionUrl); mWallpaperPreferences.setLockWallpaperActionLabelRes(actionLabelRes); @@ -513,26 +417,6 @@ public class DefaultWallpaperPersister implements WallpaperPersister { return true; } - /** - * Sets wallpaper image and attributions when a live wallpaper is responsible for presenting the - * current "daily wallpaper". - */ - private boolean setWallpaperInRotationLive(Bitmap wallpaperBitmap, List attributions, - String actionUrl, int actionLabelRes, - int actionIconRes, String collectionId) { - - synchronized (RotatingWallpaperLockProvider.getInstance()) { - if (!setWallpaperBitmapInRotationLive(wallpaperBitmap, false /* isPreview */)) { - return false; - } - - return finalizeWallpaperForRotatingComponent(attributions, actionUrl, actionLabelRes, - actionIconRes, collectionId, - 0 /* wallpaperId */, - RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_LIVE); - } - } - /** * Sets a wallpaper in rotation as a static wallpaper to the {@link WallpaperManager} with the * option allowBackup=false to save user data. @@ -552,84 +436,6 @@ public class DefaultWallpaperPersister implements WallpaperPersister { whichWallpaper); } - /** - * Sets a wallpaper in rotation as a live wallpaper. Writes wallpaper bitmap to a file in internal - * storage and sends a broadcast to the live wallpaper notifying it that rotating wallpaper image - * data changed. - * - * @return whether the set wallpaper operation was successful. - */ - private boolean setWallpaperBitmapInRotationLive(Bitmap wallpaperBitmap, boolean isPreview) { - File pendingFile; - try { - pendingFile = File.createTempFile("rotating_pending", ".jpg", mAppContext.getFilesDir()); - } catch (IOException e) { - Log.e(TAG, "Unable to create temp file for rotating wallpaper"); - return false; - } - - FileOutputStream fos; - try { - fos = mAppContext.openFileOutput(pendingFile.getName(), Context.MODE_PRIVATE); - } catch (FileNotFoundException e) { - Log.e(TAG, "Unable to open file output stream for pending rotating wallpaper file"); - return false; - } - - boolean compressedSuccessfully = - wallpaperBitmap.compress(CompressFormat.JPEG, DEFAULT_COMPRESS_QUALITY, fos); - - // Close the file stream. - try { - fos.flush(); - fos.close(); - } catch (IOException e) { - Log.e(TAG, "Unable to close FileOutputStream for pending rotating wallpaper file" - + " (compress succeeded"); - return false; - } - - if (compressedSuccessfully) { - // Compressing/writing to disk succeeded, so move the pending file to the final location. - try { - if (isPreview) { - if (!pendingFile.renameTo(mAppContext.getFileStreamPath( - NoBackupImageWallpaper.PREVIEW_WALLPAPER_FILE_PATH))) { - return false; - } - } else { - moveToDeviceProtectedStorage(pendingFile.getName(), - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - } - } catch (Exception e) { - Log.e(TAG, "Unable to rename pending to final file for rotating wallpaper file" - + " (exception)" + e.toString()); - return false; - } - } else { - Log.e(TAG, "Unable to compress the wallpaper bitmap"); - - // Delete the pending file since compressing/writing the image to disk failed. - try { - pendingFile.delete(); - } catch (SecurityException e) { - Log.e(TAG, "Unable to delete pending rotating wallpaper file"); - return false; - } - - return false; - } - - mWallpaperChangedNotifier.notifyWallpaperChanged(); - - // Send a broadcast to {@link RotatingWallpaperChangedReceiver} in the :live_wallpaper - // process so the currently displayed wallpaper updates if the live wallpaper is set to the - // device. - notifyLiveWallpaperBitmapChanged(); - - return true; - } - /** * Sets a wallpaper bitmap to the {@link WallpaperManagerCompat}. * @@ -638,7 +444,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * operation was successful and zero if the operation encountered an error. */ private int setBitmapToWallpaperManagerCompat(Bitmap wallpaperBitmap, boolean allowBackup, - int whichWallpaper) { + int whichWallpaper) { ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(); if (wallpaperBitmap.compress(CompressFormat.JPEG, DEFAULT_COMPRESS_QUALITY, tmpOut)) { try { @@ -668,9 +474,10 @@ public class DefaultWallpaperPersister implements WallpaperPersister { } private int setStreamToWallpaperManagerCompat(InputStream inputStream, boolean allowBackup, - int whichWallpaper) { + int whichWallpaper) { try { - return mWallpaperManagerCompat.setStream(inputStream, null, allowBackup, whichWallpaper); + return mWallpaperManagerCompat.setStream(inputStream, null, allowBackup, + whichWallpaper); } catch (IOException e) { return 0; } @@ -688,7 +495,8 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperInfoInPreview.getWallpaperComponent(); // If there is no live wallpaper set on the WallpaperManager or it doesn't match the - // WallpaperInfo which was last previewed, then do nothing and nullify last previewed wallpaper. + // WallpaperInfo which was last previewed, then do nothing and nullify last previewed + // wallpaper. if (currentWallpaperComponent == null || previewedWallpaperComponent == null || !currentWallpaperComponent.getPackageName() .equals(previewedWallpaperComponent.getPackageName())) { @@ -729,9 +537,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperInfoInPreview.getWallpaperComponent(); mWallpaperPreferences.clearHomeWallpaperMetadata(); - // NOTE: We explicitly do not also clear the lock wallpaper metadata. Since the user may have - // set the live wallpaper on the home screen only, we leave the lock wallpaper metadata intact. - // If the user has set the live wallpaper for both home and lock screens, then the + // NOTE: We explicitly do not also clear the lock wallpaper metadata. Since the user may + // have set the live wallpaper on the home screen only, we leave the lock wallpaper metadata + // intact. If the user has set the live wallpaper for both home and lock screens, then the // WallpaperRefresher will pick up on that and update the preferences later. mWallpaperPreferences .setHomeWallpaperAttributions(mWallpaperInfoInPreview.getAttributions(mAppContext)); @@ -744,36 +552,6 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperPreferences.clearDailyRotations(); } - /** - * Notifies the :live_wallpaper process that the contents of the rotating live wallpaper bitmap - * changed. - */ - private void notifyLiveWallpaperBitmapChanged() { - Intent intent = new Intent(mAppContext.getPackageName() - + NoBackupImageWallpaper.ACTION_ROTATING_WALLPAPER_CHANGED); - // Handled by a runtime-registered receiver in NoBackupImageWallpaper. - intent.setPackage(mAppContext.getPackageName()); - mAppContext.sendBroadcast(intent); - } - - /** - * Moves a file from the app's files directory to the device content protected storage - * directory. - * @param srcFileName Name of the source file (just the name, no path). It's expected to be - * located in {@link Context#getFilesDir()} for {@link #mAppContext} - * @param dstFileName Name of the destination file (just the name, no path), which will be - * located in {@link Context#getFilesDir()} - * for {@link #mDeviceProtectedContext} - * @return a {@link File} corresponding to the moved file in its new location, or null if - * nothing was moved (because srcFileName didn't exist). - */ - @Nullable - private File moveToDeviceProtectedStorage(String srcFileName, String dstFileName) - throws IOException { - return FileMover.moveFileBetweenContexts(mAppContext, srcFileName, mDeviceProtectedContext, - dstFileName); - } - private class SetWallpaperTask extends AsyncTask { private final WallpaperInfo mWallpaper; @@ -793,7 +571,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { private Point mStretchSize; SetWallpaperTask(WallpaperInfo wallpaper, Bitmap bitmap, @Destination int destination, - WallpaperPersister.SetWallpaperCallback callback) { + WallpaperPersister.SetWallpaperCallback callback) { super(); mWallpaper = wallpaper; mBitmap = bitmap; @@ -806,7 +584,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * will close the InputStream once it is done with it. */ SetWallpaperTask(WallpaperInfo wallpaper, InputStream stream, - @Destination int destination, WallpaperPersister.SetWallpaperCallback callback) { + @Destination int destination, WallpaperPersister.SetWallpaperCallback callback) { mWallpaper = wallpaper; mInputStream = stream; mDestination = destination; @@ -815,16 +593,18 @@ public class DefaultWallpaperPersister implements WallpaperPersister { void setFillSize(Point fillSize) { if (mStretchSize != null) { - throw new IllegalArgumentException("Can't pass a fill size option if a stretch size is " - + "already set."); + throw new IllegalArgumentException( + "Can't pass a fill size option if a stretch size is " + + "already set."); } mFillSize = fillSize; } void setStretchSize(Point stretchSize) { if (mFillSize != null) { - throw new IllegalArgumentException("Can't pass a stretch size option if a fill size is " - + "already set."); + throw new IllegalArgumentException( + "Can't pass a stretch size option if a fill size is " + + "already set."); } mStretchSize = stretchSize; } @@ -841,16 +621,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { | WallpaperManagerCompat.FLAG_LOCK; } - // NOTE: The rotating wallpaper component must be determined here, _before_ actually setting - // the bitmap/stream on WallpaperManagerCompat, to ensure that the - // RotatingWallpaperComponentChecker is doing its check while rotation is still enabled. - // E.g., if "live wallpaper" is the component, then it needs to check while live wallpaper is - // still set as the active wallpaper on the device. Otherwise, the checker would see a static - // wallpaper is currently set and it would return the wrong value. - @RotatingWallpaperComponent int currentRotatingWallpaperComponent = - mRotatingWallpaperComponentChecker.getCurrentRotatingWallpaperComponent(mAppContext); - boolean wasLockWallpaperSet = LockWallpaperStatusChecker.isLockWallpaperSet(mAppContext); + boolean wasLockWallpaperSet = LockWallpaperStatusChecker.isLockWallpaperSet( + mAppContext); boolean allowBackup = mWallpaper.getBackupPermission() == WallpaperInfo.BACKUP_ALLOWED; final int wallpaperId; @@ -860,15 +633,20 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mBitmap = BitmapTransformer.applyFillTransformation(mBitmap, mFillSize); } if (mStretchSize != null) { - mBitmap = Bitmap.createScaledBitmap(mBitmap, mStretchSize.x, mStretchSize.y, true); + mBitmap = Bitmap.createScaledBitmap(mBitmap, mStretchSize.x, mStretchSize.y, + true); } - wallpaperId = setBitmapToWallpaperManagerCompat(mBitmap, allowBackup, whichWallpaper); + wallpaperId = setBitmapToWallpaperManagerCompat(mBitmap, allowBackup, + whichWallpaper); } else if (mInputStream != null) { - wallpaperId = setStreamToWallpaperManagerCompat(mInputStream, allowBackup, whichWallpaper); + wallpaperId = setStreamToWallpaperManagerCompat(mInputStream, allowBackup, + whichWallpaper); } else { - Log.e(TAG, "Both the wallpaper bitmap and input stream are null so we're unable to set any " - + "kind of wallpaper here."); + Log.e(TAG, + "Both the wallpaper bitmap and input stream are null so we're unable to " + + "set any " + + "kind of wallpaper here."); wallpaperId = 0; } @@ -878,7 +656,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { == WallpaperPreferences.PRESENTATION_MODE_ROTATING && !wasLockWallpaperSet && BuildCompat.isAtLeastN()) { - copyRotatingWallpaperToLock(currentRotatingWallpaperComponent); + copyRotatingWallpaperToLock(); } setImageWallpaperMetadata(mDestination, wallpaperId); return true; @@ -914,12 +692,8 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * Used to accommodate the case where a user had gone from a home+lock daily rotation to * selecting a static wallpaper on home-only. The image and metadata that was previously * rotating is now copied to the lock screen. - * - * @param currentRotatingWallpaperComponent The component in which rotating wallpapers were - * presented. */ - private void copyRotatingWallpaperToLock( - @RotatingWallpaperComponent int currentRotatingWallpaperComponent) { + private void copyRotatingWallpaperToLock() { mWallpaperPreferences.setLockWallpaperAttributions( mWallpaperPreferences.getHomeWallpaperAttributions()); @@ -935,41 +709,28 @@ public class DefaultWallpaperPersister implements WallpaperPersister { // Set the lock wallpaper ID to what Android set it to, following its having // copied the system wallpaper over to the lock screen when we changed from // "both" to distinct system and lock screen wallpapers. - if (currentRotatingWallpaperComponent - == RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC) { - mWallpaperPreferences.setLockWallpaperId( - mWallpaperManagerCompat.getWallpaperId(WallpaperManagerCompat.FLAG_LOCK)); - } else { - try { - FileInputStream fileInputStream = mDeviceProtectedContext.openFileInput( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - int lockWallpaperId = setStreamToWallpaperManagerCompat( - fileInputStream, false /* allowBackup */, WallpaperManagerCompat.FLAG_LOCK); - fileInputStream.close(); - mWallpaperPreferences.setLockWallpaperId(lockWallpaperId); - } catch (FileNotFoundException e) { - Log.e(TAG, "Couldn't copy over previously rotating wallpaper to lock screen."); - } catch (IOException e) { - Log.e(TAG, "IOException when closing the file input stream " + e); - } - } + mWallpaperPreferences.setLockWallpaperId( + mWallpaperManagerCompat.getWallpaperId(WallpaperManagerCompat.FLAG_LOCK)); + } /** - * Sets the image wallpaper's metadata on SharedPreferences. This method is called after the set - * wallpaper operation is successful. + * Sets the image wallpaper's metadata on SharedPreferences. This method is called after the + * set wallpaper operation is successful. * - * @param destination Which destination of wallpaper the metadata corresponds to (home screen, - * lock screen, or both). - * @param wallpaperId The ID of the static wallpaper returned by WallpaperManager, which on N - * and later versions of Android uniquely identifies a wallpaper image. + * @param destination Which destination of wallpaper the metadata corresponds to (home + * screen, lock screen, or both). + * @param wallpaperId The ID of the static wallpaper returned by WallpaperManager, which + * on N and later versions of Android uniquely identifies a wallpaper + * image. */ private void setImageWallpaperMetadata(@Destination int destination, int wallpaperId) { if (destination == DEST_HOME_SCREEN || destination == DEST_BOTH) { mWallpaperPreferences.clearHomeWallpaperMetadata(); setImageWallpaperHomeMetadata(wallpaperId); - // Reset presentation mode to STATIC if an individual wallpaper is set to the home screen + // Reset presentation mode to STATIC if an individual wallpaper is set to the + // home screen // because rotation always affects at least the home screen. mWallpaperPreferences.setWallpaperPresentationMode( WallpaperPreferences.PRESENTATION_MODE_STATIC); @@ -988,10 +749,11 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperPreferences.setHomeWallpaperManagerId(homeWallpaperId); } - // Compute bitmap hash code after setting the wallpaper because JPEG compression has likely - // changed many pixels' color values. Forget the previously loaded wallpaper bitmap so that - // WallpaperManager doesn't return the old wallpaper drawable. Do this on N+ devices in - // addition to saving the wallpaper ID for the purpose of backup & restore. + // Compute bitmap hash code after setting the wallpaper because JPEG compression has + // likely changed many pixels' color values. Forget the previously loaded wallpaper + // bitmap so that WallpaperManager doesn't return the old wallpaper drawable. Do this + // on N+ devices in addition to saving the wallpaper ID for the purpose of backup & + // restore. mWallpaperManager.forgetLoadedWallpaper(); mBitmap = ((BitmapDrawable) mWallpaperManagerCompat.getDrawable()).getBitmap(); long bitmapHash = BitmapUtils.generateHashCode(mBitmap); @@ -1023,9 +785,10 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperPreferences.setLockWallpaperCollectionId( mWallpaper.getCollectionId(mAppContext)); - // Save the lock wallpaper image's hash code as well for the sake of backup & restore because - // WallpaperManager-generated IDs are specific to a physical device and cannot be used to - // identify a wallpaper image on another device after restore is complete. + // Save the lock wallpaper image's hash code as well for the sake of backup & restore + // because WallpaperManager-generated IDs are specific to a physical device and + // cannot be used to identify a wallpaper image on another device after restore is + // complete. saveLockWallpaperHashCode(); } @@ -1051,7 +814,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { try { fileStream.close(); } catch (IOException e) { - Log.e(TAG, "IO exception when closing the input stream for the lock screen WP."); + Log.e(TAG, + "IO exception when closing the input stream for the lock screen " + + "WP."); } } } diff --git a/src/com/android/wallpaper/module/Injector.java b/src/com/android/wallpaper/module/Injector.java index 3afaeb4..1f59951 100755 --- a/src/com/android/wallpaper/module/Injector.java +++ b/src/com/android/wallpaper/module/Injector.java @@ -56,8 +56,6 @@ public interface Injector { Requester getRequester(Context context); - RotatingWallpaperComponentChecker getRotatingWallpaperComponentChecker(); - SystemFeatureChecker getSystemFeatureChecker(); UserEventLogger getUserEventLogger(Context context); diff --git a/src/com/android/wallpaper/module/RotatingWallpaperComponentChecker.java b/src/com/android/wallpaper/module/RotatingWallpaperComponentChecker.java deleted file mode 100755 index 8a2908a..0000000 --- a/src/com/android/wallpaper/module/RotatingWallpaperComponentChecker.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.wallpaper.module; - -import android.content.Context; - -import androidx.annotation.IntDef; - -/** - * Checks what component is responsible for presenting the rotating wallpaper image under the - * device's launcher or keyguard for current and future rotations. - */ -public interface RotatingWallpaperComponentChecker { - - int ROTATING_WALLPAPER_COMPONENT_LIVE = 1; - int ROTATING_WALLPAPER_COMPONENT_STATIC = 2; - - int ROTATING_WALLPAPER_SUPPORT_NOT_SUPPORTED = 0; - int ROTATING_WALLPAPER_SUPPORT_SUPPORTED = 1; - - /** - * Returns the rotating wallpaper component for the current wallpaper rotation. - */ - @RotatingWallpaperComponent - int getCurrentRotatingWallpaperComponent(Context context); - - /** - * Returns the rotating wallpaper component for future wallpaper rotations. - */ - @RotatingWallpaperComponent - int getNextRotatingWallpaperComponent(Context context); - - /** - * Returns the support level for rotating wallpaper. - */ - @RotatingWallpaperSupport - int getRotatingWallpaperSupport(Context context); - - /** - * Possible components for presenting the rotating wallpaper image. - */ - @IntDef({ - ROTATING_WALLPAPER_COMPONENT_LIVE, - ROTATING_WALLPAPER_COMPONENT_STATIC}) - @interface RotatingWallpaperComponent { - } - - /** - * Possible support levels for rotating wallpaper. - */ - @IntDef({ - ROTATING_WALLPAPER_SUPPORT_NOT_SUPPORTED, - ROTATING_WALLPAPER_SUPPORT_SUPPORTED}) - @interface RotatingWallpaperSupport { - } -} diff --git a/src/com/android/wallpaper/picker/StartRotationDialogFragment.java b/src/com/android/wallpaper/picker/StartRotationDialogFragment.java index d5fd017..f0e4dcd 100755 --- a/src/com/android/wallpaper/picker/StartRotationDialogFragment.java +++ b/src/com/android/wallpaper/picker/StartRotationDialogFragment.java @@ -29,8 +29,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import androidx.appcompat.view.ContextThemeWrapper; import androidx.fragment.app.DialogFragment; import com.android.wallpaper.R; @@ -42,29 +40,14 @@ import com.android.wallpaper.module.InjectorProvider; */ public class StartRotationDialogFragment extends DialogFragment { private static final String KEY_IS_WIFI_ONLY_CHECKED = "key_is_wifi_only_checked"; - private static final String KEY_IS_LIVE_WALLPAPER_PREVIEW_NEEDED = "key_is_live_wallpaper_needed"; private static final boolean DEFAULT_IS_WIFI_ONLY = true; private boolean mIsWifiOnlyChecked; - private boolean mIsLiveWallpaperPreviewNeeded; - - public static StartRotationDialogFragment newInstance(boolean isLiveWallpaperPreviewNeeded) { - StartRotationDialogFragment dialogFragment = new StartRotationDialogFragment(); - Bundle args = new Bundle(); - args.putBoolean(KEY_IS_LIVE_WALLPAPER_PREVIEW_NEEDED, isLiveWallpaperPreviewNeeded); - dialogFragment.setArguments(args); - return dialogFragment; - } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Bundle args = getArguments(); - if (args != null) { - mIsLiveWallpaperPreviewNeeded = args.getBoolean(KEY_IS_LIVE_WALLPAPER_PREVIEW_NEEDED); - } - if (savedInstanceState == null) { mIsWifiOnlyChecked = DEFAULT_IS_WIFI_ONLY; } else { @@ -117,14 +100,10 @@ public class StartRotationDialogFragment extends DialogFragment { } private int getBodyTextResourceId() { - return mIsLiveWallpaperPreviewNeeded - ? R.string.start_rotation_dialog_body_live_wallpaper_needed - : R.string.start_rotation_dialog_body; + return R.string.start_rotation_dialog_body; } private int getPositiveButtonTextResourceId() { - return mIsLiveWallpaperPreviewNeeded - ? R.string.start_rotation_dialog_continue - : android.R.string.ok; + return android.R.string.ok; } } diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java index db21da3..401634d 100755 --- a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java +++ b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java @@ -64,7 +64,6 @@ import com.android.wallpaper.module.FormFactorChecker.FormFactor; import com.android.wallpaper.module.Injector; import com.android.wallpaper.module.InjectorProvider; import com.android.wallpaper.module.PackageStatusNotifier; -import com.android.wallpaper.module.RotatingWallpaperComponentChecker; import com.android.wallpaper.module.WallpaperChangedNotifier; import com.android.wallpaper.module.WallpaperPersister; import com.android.wallpaper.module.WallpaperPersister.Destination; @@ -116,7 +115,6 @@ public class IndividualPickerFragment extends Fragment WallpaperPreferences mWallpaperPreferences; WallpaperChangedNotifier mWallpaperChangedNotifier; - RotatingWallpaperComponentChecker mRotatingWallpaperComponentChecker; RecyclerView mImageGrid; IndividualAdapter mAdapter; WallpaperCategory mCategory; @@ -250,8 +248,6 @@ public class IndividualPickerFragment extends Fragment mWallpaperChangedNotifier = WallpaperChangedNotifier.getInstance(); mWallpaperChangedNotifier.registerListener(mWallpaperChangedListener); - mRotatingWallpaperComponentChecker = injector.getRotatingWallpaperComponentChecker(); - mFormFactor = injector.getFormFactorChecker(appContext).getFormFactor(); mPackageStatusNotifier = injector.getPackageStatusNotifier(appContext); @@ -614,34 +610,33 @@ public class IndividualPickerFragment extends Fragment // app before the first wallpaper image in rotation finishes downloading. Activity activity = getActivity(); - if (activity != null - && mWallpaperRotationInitializer - .isNoBackupImageWallpaperPreviewNeeded(appContext)) { - ((IndividualPickerActivity) activity).showNoBackupImageWallpaperPreview(); - } else { - if (mWallpaperRotationInitializer.startRotation(appContext)) { - if (activity != null && mFormFactor == FormFactorChecker.FORM_FACTOR_MOBILE) { - try { - Toast.makeText(getActivity(), R.string.wallpaper_set_successfully_message, - Toast.LENGTH_SHORT).show(); - } catch (NotFoundException e) { - Log.e(TAG, "Could not show toast " + e); - } - activity.setResult(Activity.RESULT_OK); - activity.finish(); - } else if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) { - mAdapter.updateSelectedTile(SPECIAL_FIXED_TILE_ADAPTER_POSITION); - } - } else { // Failed to start rotation. - showStartRotationErrorDialog(networkPreference); - - if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) { - DesktopRotationHolder rotationViewHolder = - (DesktopRotationHolder) mImageGrid.findViewHolderForAdapterPosition( - SPECIAL_FIXED_TILE_ADAPTER_POSITION); - rotationViewHolder.setSelectionState(SelectableHolder.SELECTION_STATE_DESELECTED); + if (mWallpaperRotationInitializer.startRotation(appContext)) { + if (activity != null + && mFormFactor == FormFactorChecker.FORM_FACTOR_MOBILE) { + try { + Toast.makeText(getActivity(), + R.string.wallpaper_set_successfully_message, + Toast.LENGTH_SHORT).show(); + } catch (NotFoundException e) { + Log.e(TAG, "Could not show toast " + e); } + + activity.setResult(Activity.RESULT_OK); + activity.finish(); + } else if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) { + mAdapter.updateSelectedTile(SPECIAL_FIXED_TILE_ADAPTER_POSITION); + } + } else { // Failed to start rotation. + showStartRotationErrorDialog(networkPreference); + + if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) { + DesktopRotationHolder rotationViewHolder = + (DesktopRotationHolder) + mImageGrid.findViewHolderForAdapterPosition( + SPECIAL_FIXED_TILE_ADAPTER_POSITION); + rotationViewHolder.setSelectionState( + SelectableHolder.SELECTION_STATE_DESELECTED); } } } @@ -690,11 +685,7 @@ public class IndividualPickerFragment extends Fragment * Returns whether rotation is enabled for this category. */ boolean isRotationEnabled() { - boolean isRotationSupported = - mRotatingWallpaperComponentChecker.getRotatingWallpaperSupport(getContext()) - == RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_SUPPORT_SUPPORTED; - - return isRotationSupported && mWallpaperRotationInitializer != null; + return mWallpaperRotationInitializer != null; } @Override @@ -765,10 +756,7 @@ public class IndividualPickerFragment extends Fragment @Override public void onClick(View v) { - boolean isLiveWallpaperNeeded = mWallpaperRotationInitializer - .isNoBackupImageWallpaperPreviewNeeded(getActivity().getApplicationContext()); - DialogFragment startRotationDialogFragment = StartRotationDialogFragment - .newInstance(isLiveWallpaperNeeded); + DialogFragment startRotationDialogFragment = new StartRotationDialogFragment(); startRotationDialogFragment.setTargetFragment( IndividualPickerFragment.this, UNUSED_REQUEST_CODE); startRotationDialogFragment.show(getFragmentManager(), TAG_START_ROTATION_DIALOG); -- cgit v1.2.3 From 6d3d1e6068073fd26fcdd9fd37272777b3cd78d7 Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Thu, 26 Sep 2019 11:11:11 -0700 Subject: [LivePicker 1/n] Extract common PreviewFragment Before incorporating LivePicker preview in WPP, create a new ImagePreviewFragment and keep PreviewFragment as a base class with the common code. Also clean up a bit the existing logic. Bug: 141391722 Change-Id: Ifbe0ec5f982e56a4b30ec67a851094eddba35bde --- .../android/wallpaper/module/WallpaperSetter.java | 5 +- .../wallpaper/picker/ImagePreviewFragment.java | 502 ++++++++++++++++ .../android/wallpaper/picker/PreviewFragment.java | 663 ++++----------------- .../wallpaper/module/WallpapersInjector.java | 8 +- 4 files changed, 628 insertions(+), 550 deletions(-) create mode 100755 src/com/android/wallpaper/picker/ImagePreviewFragment.java diff --git a/src/com/android/wallpaper/module/WallpaperSetter.java b/src/com/android/wallpaper/module/WallpaperSetter.java index 830d914..a33a5f1 100644 --- a/src/com/android/wallpaper/module/WallpaperSetter.java +++ b/src/com/android/wallpaper/module/WallpaperSetter.java @@ -72,8 +72,9 @@ public class WallpaperSetter { * @param callback optional callback to be notified when the wallpaper is set. */ public void setCurrentWallpaper(Activity containerActivity, WallpaperInfo wallpaper, - Asset wallpaperAsset, @Destination final int destination, float wallpaperScale, - @Nullable Rect cropRect, @Nullable SetWallpaperCallback callback) { + @Nullable Asset wallpaperAsset, @Destination final int destination, + float wallpaperScale, @Nullable Rect cropRect, + @Nullable SetWallpaperCallback callback) { if (wallpaper instanceof LiveWallpaperInfo) { setCurrentLiveWallpaper(containerActivity, (LiveWallpaperInfo) wallpaper, destination, callback); diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java new file mode 100755 index 0000000..d0b0fa5 --- /dev/null +++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java @@ -0,0 +1,502 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.picker; + +import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.app.Activity; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.Color; +import android.graphics.Point; +import android.graphics.PointF; +import android.graphics.Rect; +import android.os.Bundle; +import android.view.ContextThemeWrapper; +import android.view.Display; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import com.android.wallpaper.R; +import com.android.wallpaper.asset.Asset; +import com.android.wallpaper.model.WallpaperInfo; +import com.android.wallpaper.module.WallpaperPersister.Destination; +import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback; +import com.android.wallpaper.util.ScreenSizeCalculator; +import com.android.wallpaper.util.WallpaperCropUtils; +import com.android.wallpaper.widget.MaterialProgressDrawable; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.MemoryCategory; +import com.davemorrissey.labs.subscaleview.ImageSource; +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; +import com.google.android.material.bottomsheet.BottomSheetBehavior; + +import java.util.List; + +/** + * Fragment which displays the UI for previewing an individual wallpaper and its attribution + * information. + */ +public class ImagePreviewFragment extends PreviewFragment { + + private static final float DEFAULT_WALLPAPER_MAX_ZOOM = 8f; + + private SubsamplingScaleImageView mFullResImageView; + private Asset mWallpaperAsset; + private TextView mAttributionTitle; + private TextView mAttributionSubtitle1; + private TextView mAttributionSubtitle2; + private Point mDefaultCropSurfaceSize; + private Point mScreenSize; + private Point mRawWallpaperSize; // Native size of wallpaper image. + private ImageView mLoadingIndicator; + private MaterialProgressDrawable mProgressDrawable; + private ImageView mLowResImageView; + private View mSpacer; + + /** + * Creates and returns new instance of {@link ImagePreviewFragment} with the provided wallpaper + * set as an argument. + */ + public static ImagePreviewFragment newInstance( + WallpaperInfo wallpaperInfo, @PreviewMode int mode, boolean testingModeEnabled) { + Bundle args = new Bundle(); + args.putParcelable(ARG_WALLPAPER, wallpaperInfo); + args.putInt(ARG_PREVIEW_MODE, mode); + args.putBoolean(ARG_TESTING_MODE_ENABLED, testingModeEnabled); + + ImagePreviewFragment fragment = new ImagePreviewFragment(); + fragment.setArguments(args); + return fragment; + } + + private static int getAttrColor(Context context, int attr) { + TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); + int colorAccent = ta.getColor(0, 0); + ta.recycle(); + return colorAccent; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mWallpaperAsset = mWallpaper.getAsset(requireContext().getApplicationContext()); + } + + @Override + protected int getLayoutResId() { + return R.layout.fragment_preview; + } + + @Override + protected int getBottomSheetResId() { + return R.id.bottom_sheet; + } + + @Override + protected int getSetWallpaperButtonResId() { + return R.id.preview_attribution_pane_set_wallpaper_button; + } + + @Override + protected int getExploreButtonResId() { + return R.id.preview_attribution_pane_explore_button; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + + Activity activity = requireActivity(); + // Set toolbar as the action bar. + + mFullResImageView = view.findViewById(R.id.full_res_image); + mLoadingIndicator = view.findViewById(R.id.loading_indicator); + + mAttributionTitle = view.findViewById(R.id.preview_attribution_pane_title); + mAttributionSubtitle1 = view.findViewById(R.id.preview_attribution_pane_subtitle1); + mAttributionSubtitle2 = view.findViewById(R.id.preview_attribution_pane_subtitle2); + + mLowResImageView = view.findViewById(R.id.low_res_image); + mSpacer = view.findViewById(R.id.spacer); + + // Trim some memory from Glide to make room for the full-size image in this fragment. + Glide.get(activity).setMemoryCategory(MemoryCategory.LOW); + + mDefaultCropSurfaceSize = WallpaperCropUtils.getDefaultCropSurfaceSize( + getResources(), activity.getWindowManager().getDefaultDisplay()); + mScreenSize = ScreenSizeCalculator.getInstance().getScreenSize( + activity.getWindowManager().getDefaultDisplay()); + + // Load a low-res placeholder image if there's a thumbnail available from the asset that can + // be shown to the user more quickly than the full-sized image. + if (mWallpaperAsset.hasLowResDataSource()) { + mWallpaperAsset.loadLowResDrawable(activity, mLowResImageView, Color.BLACK, + new WallpaperPreviewBitmapTransformation(activity.getApplicationContext(), + isRtl())); + } + + mWallpaperAsset.decodeRawDimensions(getActivity(), dimensions -> { + // Don't continue loading the wallpaper if the Fragment is detached. + if (getActivity() == null) { + return; + } + + // Return early and show a dialog if dimensions are null (signaling a decoding error). + if (dimensions == null) { + showLoadWallpaperErrorDialog(); + return; + } + + mRawWallpaperSize = dimensions; + setUpExploreIntent(ImagePreviewFragment.this::initFullResView); + }); + + // Configure loading indicator with a MaterialProgressDrawable. + setUpLoadingIndicator(); + + return view; + } + + protected void setUpLoadingIndicator() { + Context context = requireContext(); + mProgressDrawable = new MaterialProgressDrawable(context.getApplicationContext(), + mLoadingIndicator); + mProgressDrawable.setAlpha(255); + mProgressDrawable.setBackgroundColor(getResources().getColor(R.color.material_white_100, + context.getTheme())); + mProgressDrawable.setColorSchemeColors(getAttrColor( + new ContextThemeWrapper(context, getDeviceDefaultTheme()), + android.R.attr.colorAccent)); + mProgressDrawable.updateSizes(MaterialProgressDrawable.LARGE); + mLoadingIndicator.setImageDrawable(mProgressDrawable); + + // We don't want to show the spinner every time we load an image if it loads quickly; + // instead, only start showing the spinner if loading the image has taken longer than half + // of a second. + mLoadingIndicator.postDelayed(() -> { + if (mFullResImageView != null && !mFullResImageView.hasImage() + && !mTestingModeEnabled) { + mLoadingIndicator.setVisibility(View.VISIBLE); + mLoadingIndicator.setAlpha(1f); + if (mProgressDrawable != null) { + mProgressDrawable.start(); + } + } + }, 500); + } + + protected int getDeviceDefaultTheme() { + return android.R.style.Theme_DeviceDefault; + } + + @Override + public void onSet(int destination) { + setCurrentWallpaper(destination); + } + + @Override + public void onClickTryAgain(@Destination int wallpaperDestination) { + setCurrentWallpaper(wallpaperDestination); + } + + @Override + public void onClickOk() { + FragmentActivity activity = getActivity(); + if (activity != null) { + activity.finish(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mProgressDrawable != null) { + mProgressDrawable.stop(); + } + mFullResImageView.recycle(); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet); + outState.putInt(KEY_BOTTOM_SHEET_STATE, bottomSheetBehavior.getState()); + } + + @Override + protected void setBottomSheetContentAlpha(float alpha) { + super.setBottomSheetContentAlpha(alpha); + mAttributionTitle.setAlpha(alpha); + mAttributionSubtitle1.setAlpha(alpha); + mAttributionSubtitle2.setAlpha(alpha); + } + + private void populateAttributionPane() { + final Context context = getContext(); + + final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet); + + List attributions = mWallpaper.getAttributions(context); + if (attributions.size() > 0 && attributions.get(0) != null) { + mAttributionTitle.setText(attributions.get(0)); + } + + if (attributions.size() > 1 && attributions.get(1) != null) { + mAttributionSubtitle1.setVisibility(View.VISIBLE); + mAttributionSubtitle1.setText(attributions.get(1)); + } + + if (attributions.size() > 2 && attributions.get(2) != null) { + mAttributionSubtitle2.setVisibility(View.VISIBLE); + mAttributionSubtitle2.setText(attributions.get(2)); + } + + setUpSetWallpaperButton(); + + setUpExploreButton(); + + if (mExploreButton.getVisibility() == View.VISIBLE + && mSetWallpaperButton.getVisibility() == View.VISIBLE) { + mSpacer.setVisibility(View.VISIBLE); + } else { + mSpacer.setVisibility(View.GONE); + } + + mBottomSheet.setVisibility(View.VISIBLE); + + // Initialize the state of the BottomSheet based on the current state because if the initial + // and current state are the same, the state change listener won't fire and set the correct + // arrow asset and text alpha. + if (bottomSheetBehavior.getState() == STATE_EXPANDED) { + setPreviewChecked(false); + mAttributionTitle.setAlpha(1f); + mAttributionSubtitle1.setAlpha(1f); + mAttributionSubtitle2.setAlpha(1f); + } else { + setPreviewChecked(true); + mAttributionTitle.setAlpha(0f); + mAttributionSubtitle1.setAlpha(0f); + mAttributionSubtitle2.setAlpha(0f); + } + + // Let the state change listener take care of animating a state change to the initial state + // if there's a state change. + bottomSheetBehavior.setState(mBottomSheetInitialState); + } + + /** + * Initializes MosaicView by initializing tiling, setting a fallback page bitmap, and + * initializing a zoom-scroll observer and click listener. + */ + private void initFullResView() { + mFullResImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP); + + // Set a solid black "page bitmap" so MosaicView draws a black background while waiting + // for the image to load or a transparent one if a thumbnail already loaded. + Bitmap blackBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888); + int color = (mLowResImageView.getDrawable() == null) ? Color.BLACK : Color.TRANSPARENT; + blackBitmap.setPixel(0, 0, color); + mFullResImageView.setImage(ImageSource.bitmap(blackBitmap)); + + // Then set a fallback "page bitmap" to cover the whole MosaicView, which is an actual + // (lower res) version of the image to be displayed. + Point targetPageBitmapSize = new Point(mRawWallpaperSize); + mWallpaperAsset.decodeBitmap(targetPageBitmapSize.x, targetPageBitmapSize.y, + pageBitmap -> { + // Check that the activity is still around since the decoding task started. + if (getActivity() == null) { + return; + } + + // Some of these may be null depending on if the Fragment is paused, stopped, + // or destroyed. + if (mLoadingIndicator != null) { + mLoadingIndicator.setVisibility(View.GONE); + } + // The page bitmap may be null if there was a decoding error, so show an + // error dialog. + if (pageBitmap == null) { + showLoadWallpaperErrorDialog(); + return; + } + if (mFullResImageView != null) { + // Set page bitmap. + mFullResImageView.setImage(ImageSource.bitmap(pageBitmap)); + + setDefaultWallpaperZoomAndScroll(); + crossFadeInMosaicView(); + } + if (mProgressDrawable != null) { + mProgressDrawable.stop(); + } + getActivity().invalidateOptionsMenu(); + + populateAttributionPane(); + }); + } + + /** + * Makes the MosaicView visible with an alpha fade-in animation while fading out the loading + * indicator. + */ + private void crossFadeInMosaicView() { + long shortAnimationDuration = getResources().getInteger( + android.R.integer.config_shortAnimTime); + + mFullResImageView.setAlpha(0f); + mFullResImageView.animate() + .alpha(1f) + .setDuration(shortAnimationDuration) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + // Clear the thumbnail bitmap reference to save memory since it's no longer + // visible. + if (mLowResImageView != null) { + mLowResImageView.setImageBitmap(null); + } + } + }); + + mLoadingIndicator.animate() + .alpha(0f) + .setDuration(shortAnimationDuration) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (mLoadingIndicator != null) { + mLoadingIndicator.setVisibility(View.GONE); + } + } + }); + } + + /** + * Sets the default wallpaper zoom and scroll position based on a "crop surface" + * (with extra width to account for parallax) superimposed on the screen. Shows as much of the + * wallpaper as possible on the crop surface and align screen to crop surface such that the + * default preview matches what would be seen by the user in the left-most home screen. + * + *

This method is called once in the Fragment lifecycle after the wallpaper asset has loaded + * and rendered to the layout. + */ + private void setDefaultWallpaperZoomAndScroll() { + // Determine minimum zoom to fit maximum visible area of wallpaper on crop surface. + float defaultWallpaperZoom = + WallpaperCropUtils.calculateMinZoom(mRawWallpaperSize, mDefaultCropSurfaceSize); + float minWallpaperZoom = + WallpaperCropUtils.calculateMinZoom(mRawWallpaperSize, mScreenSize); + + Point screenToCropSurfacePosition = WallpaperCropUtils.calculateCenterPosition( + mDefaultCropSurfaceSize, mScreenSize, true /* alignStart */, isRtl()); + Point zoomedWallpaperSize = new Point( + Math.round(mRawWallpaperSize.x * defaultWallpaperZoom), + Math.round(mRawWallpaperSize.y * defaultWallpaperZoom)); + Point cropSurfaceToWallpaperPosition = WallpaperCropUtils.calculateCenterPosition( + zoomedWallpaperSize, mDefaultCropSurfaceSize, false /* alignStart */, isRtl()); + + // Set min wallpaper zoom and max zoom on MosaicView widget. + mFullResImageView.setMaxScale(Math.max(DEFAULT_WALLPAPER_MAX_ZOOM, defaultWallpaperZoom)); + mFullResImageView.setMinScale(minWallpaperZoom); + + // Set center to composite positioning between scaled wallpaper and screen. + PointF centerPosition = new PointF( + mRawWallpaperSize.x / 2f, + mRawWallpaperSize.y / 2f); + centerPosition.offset(-(screenToCropSurfacePosition.x + cropSurfaceToWallpaperPosition.x), + -(screenToCropSurfacePosition.y + cropSurfaceToWallpaperPosition.y)); + + mFullResImageView.setScaleAndCenter(minWallpaperZoom, centerPosition); + } + + private Rect calculateCropRect() { + // Calculate Rect of wallpaper in physical pixel terms (i.e., scaled to current zoom). + float wallpaperZoom = mFullResImageView.getScale(); + int scaledWallpaperWidth = (int) (mRawWallpaperSize.x * wallpaperZoom); + int scaledWallpaperHeight = (int) (mRawWallpaperSize.y * wallpaperZoom); + Rect rect = new Rect(); + mFullResImageView.visibleFileRect(rect); + int scrollX = (int) (rect.left * wallpaperZoom); + int scrollY = (int) (rect.top * wallpaperZoom); + + rect.set(0, 0, scaledWallpaperWidth, scaledWallpaperHeight); + + Display defaultDisplay = requireActivity().getWindowManager().getDefaultDisplay(); + Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize(defaultDisplay); + // Crop rect should start off as the visible screen and then include extra width and height + // if available within wallpaper at the current zoom. + Rect cropRect = new Rect(scrollX, scrollY, scrollX + screenSize.x, scrollY + screenSize.y); + + Point defaultCropSurfaceSize = WallpaperCropUtils.getDefaultCropSurfaceSize( + getResources(), defaultDisplay); + int extraWidth = defaultCropSurfaceSize.x - screenSize.x; + int extraHeightTopAndBottom = (int) ((defaultCropSurfaceSize.y - screenSize.y) / 2f); + + // Try to increase size of screenRect to include extra width depending on the layout + // direction. + if (isRtl()) { + cropRect.left = Math.max(cropRect.left - extraWidth, rect.left); + } else { + cropRect.right = Math.min(cropRect.right + extraWidth, rect.right); + } + + // Try to increase the size of the cropRect to to include extra height. + int availableExtraHeightTop = cropRect.top - Math.max( + rect.top, + cropRect.top - extraHeightTopAndBottom); + int availableExtraHeightBottom = Math.min( + rect.bottom, + cropRect.bottom + extraHeightTopAndBottom) - cropRect.bottom; + + int availableExtraHeightTopAndBottom = + Math.min(availableExtraHeightTop, availableExtraHeightBottom); + cropRect.top -= availableExtraHeightTopAndBottom; + cropRect.bottom += availableExtraHeightTopAndBottom; + + return cropRect; + } + + @Override + protected void setCurrentWallpaper(@Destination int destination) { + mWallpaperSetter.setCurrentWallpaper(getActivity(), mWallpaper, mWallpaperAsset, + destination, mFullResImageView.getScale(), calculateCropRect(), + new SetWallpaperCallback() { + @Override + public void onSuccess() { + finishActivityWithResultOk(); + } + + @Override + public void onError(@Nullable Throwable throwable) { + showSetWallpaperErrorDialog(destination); + } + }); + } +} diff --git a/src/com/android/wallpaper/picker/PreviewFragment.java b/src/com/android/wallpaper/picker/PreviewFragment.java index c698c8c..7310318 100755 --- a/src/com/android/wallpaper/picker/PreviewFragment.java +++ b/src/com/android/wallpaper/picker/PreviewFragment.java @@ -18,46 +18,33 @@ package com.android.wallpaper.picker; import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED; import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; -import android.content.res.Configuration; import android.content.res.Resources.NotFoundException; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Color; -import android.graphics.Point; -import android.graphics.PointF; import android.graphics.PorterDuff.Mode; -import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.net.Uri; import android.os.Bundle; import android.util.Log; -import android.view.ContextThemeWrapper; -import android.view.Display; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.Button; import android.widget.CheckBox; -import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.CallSuper; +import androidx.annotation.IdRes; import androidx.annotation.IntDef; +import androidx.annotation.LayoutRes; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; @@ -66,9 +53,6 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import com.android.wallpaper.R; -import com.android.wallpaper.asset.Asset; -import com.android.wallpaper.asset.Asset.BitmapReceiver; -import com.android.wallpaper.asset.Asset.DimensionsReceiver; import com.android.wallpaper.compat.BuildCompat; import com.android.wallpaper.model.LiveWallpaperInfo; import com.android.wallpaper.model.WallpaperInfo; @@ -78,17 +62,9 @@ import com.android.wallpaper.module.InjectorProvider; import com.android.wallpaper.module.UserEventLogger; import com.android.wallpaper.module.WallpaperPersister; import com.android.wallpaper.module.WallpaperPersister.Destination; -import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback; import com.android.wallpaper.module.WallpaperPreferences; import com.android.wallpaper.module.WallpaperSetter; -import com.android.wallpaper.util.ScreenSizeCalculator; -import com.android.wallpaper.util.WallpaperCropUtils; -import com.android.wallpaper.widget.MaterialProgressDrawable; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.MemoryCategory; -import com.davemorrissey.labs.subscaleview.ImageSource; -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; + import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetBehavior.State; @@ -99,20 +75,20 @@ import java.util.List; * Fragment which displays the UI for previewing an individual wallpaper and its attribution * information. */ -public class PreviewFragment extends Fragment implements +public abstract class PreviewFragment extends Fragment implements SetWallpaperDialogFragment.Listener, SetWallpaperErrorDialogFragment.Listener, LoadWallpaperErrorDialogFragment.Listener { /** * User can view wallpaper and attributions in full screen, but "Set wallpaper" button is hidden. */ - public static final int MODE_VIEW_ONLY = 0; + static final int MODE_VIEW_ONLY = 0; /** * User can view wallpaper and attributions in full screen and click "Set wallpaper" to set the * wallpaper with pan and crop position to the device. */ - public static final int MODE_CROP_AND_SET_WALLPAPER = 1; + static final int MODE_CROP_AND_SET_WALLPAPER = 1; /** * Possible preview modes for the fragment. @@ -131,47 +107,33 @@ public class PreviewFragment extends Fragment implements private static final String TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT = "set_wallpaper_error_dialog"; private static final int UNUSED_REQUEST_CODE = 1; - private static final float DEFAULT_WALLPAPER_MAX_ZOOM = 8f; private static final String TAG = "PreviewFragment"; - private static final float PAGE_BITMAP_MAX_HEAP_RATIO = 0.25f; - private static final String KEY_BOTTOM_SHEET_STATE = "key_bottom_sheet_state"; + static final String KEY_BOTTOM_SHEET_STATE = "key_bottom_sheet_state"; @PreviewMode - private int mPreviewMode; + protected int mPreviewMode; /** * When true, enables a test mode of operation -- in which certain UI features are disabled to * allow for UI tests to run correctly. Works around issue in ProgressDialog currently where the * dialog constantly keeps the UI thread alive and blocks a test forever. */ - private boolean mTestingModeEnabled; + protected boolean mTestingModeEnabled; - protected SubsamplingScaleImageView mFullResImageView; protected WallpaperInfo mWallpaper; - private Asset mWallpaperAsset; - private WallpaperSetter mWallpaperSetter; - private UserEventLogger mUserEventLogger; - private LinearLayout mBottomSheet; - private TextView mAttributionTitle; - private TextView mAttributionSubtitle1; - private TextView mAttributionSubtitle2; - private Button mAttributionExploreButton; - private int mCurrentScreenOrientation; - private Point mDefaultCropSurfaceSize; - private Point mScreenSize; - private Point mRawWallpaperSize; // Native size of wallpaper image. - private ImageView mLoadingIndicator; - private MaterialProgressDrawable mProgressDrawable; - private ImageView mLowResImageView; - private Button mSetWallpaperButton; - private View mSpacer; - private CheckBox mPreview; + protected WallpaperSetter mWallpaperSetter; + protected UserEventLogger mUserEventLogger; + protected LinearLayout mBottomSheet; + protected Button mExploreButton; + protected Button mSetWallpaperButton; + + protected CheckBox mPreview; @SuppressWarnings("RestrictTo") @State - private int mBottomSheetInitialState; + protected int mBottomSheetInitialState; - private Intent mExploreIntent; + protected Intent mExploreIntent; /** * Staged error dialog fragments that were unable to be shown when the hosting activity didn't @@ -180,40 +142,17 @@ public class PreviewFragment extends Fragment implements private SetWallpaperErrorDialogFragment mStagedSetWallpaperErrorDialogFragment; private LoadWallpaperErrorDialogFragment mStagedLoadWallpaperErrorDialogFragment; - /** - * Creates and returns new instance of {@link PreviewFragment} with the provided wallpaper set as - * an argument. - */ - public static PreviewFragment newInstance( - WallpaperInfo wallpaperInfo, @PreviewMode int mode, boolean testingModeEnabled) { - Bundle args = new Bundle(); - args.putParcelable(ARG_WALLPAPER, wallpaperInfo); - args.putInt(ARG_PREVIEW_MODE, mode); - args.putBoolean(ARG_TESTING_MODE_ENABLED, testingModeEnabled); - - PreviewFragment fragment = new PreviewFragment(); - fragment.setArguments(args); - return fragment; - } - - private static int getAttrColor(Context context, int attr) { - TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); - int colorAccent = ta.getColor(0, 0); - ta.recycle(); - return colorAccent; - } - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Activity activity = getActivity(); - Context appContext = activity.getApplicationContext(); + Context appContext = getContext().getApplicationContext(); Injector injector = InjectorProvider.getInjector(); mUserEventLogger = injector.getUserEventLogger(appContext); mWallpaper = getArguments().getParcelable(ARG_WALLPAPER); - mWallpaperAsset = mWallpaper.getAsset(appContext); + //noinspection ResourceType mPreviewMode = getArguments().getInt(ARG_PREVIEW_MODE); mTestingModeEnabled = getArguments().getBoolean(ARG_TESTING_MODE_ENABLED); @@ -236,14 +175,18 @@ public class PreviewFragment extends Fragment implements } } + @LayoutRes + protected abstract int getLayoutResId(); + @Override + @CallSuper public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_preview, container, false); + View view = inflater.inflate(getLayoutResId(), container, false); // Set toolbar as the action bar. Toolbar toolbar = view.findViewById(R.id.toolbar); - AppCompatActivity activity = (AppCompatActivity) getActivity(); + AppCompatActivity activity = (AppCompatActivity) requireActivity(); activity.setSupportActionBar(toolbar); activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); activity.getSupportActionBar().setDisplayShowTitleEnabled(false); @@ -270,18 +213,9 @@ public class PreviewFragment extends Fragment implements R.dimen.preview_toolbar_set_wallpaper_button_end_padding), /* bottom */ 0); - mFullResImageView = view.findViewById(R.id.full_res_image); - mLoadingIndicator = view.findViewById(R.id.loading_indicator); - - mBottomSheet = view.findViewById(R.id.bottom_sheet); - mAttributionTitle = view.findViewById(R.id.preview_attribution_pane_title); - mAttributionSubtitle1 = view.findViewById(R.id.preview_attribution_pane_subtitle1); - mAttributionSubtitle2 = view.findViewById(R.id.preview_attribution_pane_subtitle2); - mAttributionExploreButton = view.findViewById( - R.id.preview_attribution_pane_explore_button); - mLowResImageView = view.findViewById(R.id.low_res_image); - mSetWallpaperButton = view.findViewById(R.id.preview_attribution_pane_set_wallpaper_button); - mSpacer = view.findViewById(R.id.spacer); + mBottomSheet = view.findViewById(getBottomSheetResId()); + mExploreButton = view.findViewById(getExploreButtonResId()); + mSetWallpaperButton = view.findViewById(getSetWallpaperButtonResId()); // Workaround as we don't have access to bottomDialogCornerRadius, mBottomSheet radii are // set to dialogCornerRadius by default. @@ -294,84 +228,6 @@ public class PreviewFragment extends Fragment implements bottomSheetBackground.setCornerRadii(radii); mBottomSheet.setBackground(bottomSheetBackground); - // Trim some memory from Glide to make room for the full-size image in this fragment. - Glide.get(getActivity()).setMemoryCategory(MemoryCategory.LOW); - - mDefaultCropSurfaceSize = WallpaperCropUtils.getDefaultCropSurfaceSize( - getResources(), getActivity().getWindowManager().getDefaultDisplay()); - mScreenSize = ScreenSizeCalculator.getInstance().getScreenSize( - getActivity().getWindowManager().getDefaultDisplay()); - - // Load a low-res placeholder image if there's a thumbnail available from the asset that can be - // shown to the user more quickly than the full-sized image. - if (mWallpaperAsset.hasLowResDataSource()) { - mWallpaperAsset.loadLowResDrawable(getActivity(), mLowResImageView, Color.BLACK, - new WallpaperPreviewBitmapTransformation(getActivity().getApplicationContext(), - isRtl())); - } - - mWallpaperAsset.decodeRawDimensions(getActivity(), new DimensionsReceiver() { - @Override - public void onDimensionsDecoded(Point dimensions) { - // Don't continue loading the wallpaper if the Fragment is detached. - Activity activity = getActivity(); - if (activity == null) { - return; - } - - // Return early and show a dialog if dimensions are null (signaling a decoding error). - if (dimensions == null) { - showLoadWallpaperErrorDialog(); - return; - } - - mRawWallpaperSize = dimensions; - ExploreIntentChecker intentChecker = - InjectorProvider.getInjector().getExploreIntentChecker(activity); - String actionUrl = mWallpaper.getActionUrl(activity); - if (actionUrl != null && !actionUrl.isEmpty()) { - Uri exploreUri = Uri.parse(mWallpaper.getActionUrl(activity)); - - intentChecker.fetchValidActionViewIntent(exploreUri, exploreIntent -> { - if (getActivity() == null) { - return; - } - - mExploreIntent = exploreIntent; - initFullResView(); - }); - } else { - initFullResView(); - } - } - }); - - // Configure loading indicator with a MaterialProgressDrawable. - mProgressDrawable = new MaterialProgressDrawable(getActivity().getApplicationContext(), - mLoadingIndicator); - mProgressDrawable.setAlpha(255); - mProgressDrawable.setBackgroundColor(getResources().getColor(R.color.material_white_100, - getContext().getTheme())); - mProgressDrawable.setColorSchemeColors(getAttrColor( - new ContextThemeWrapper(getContext(), getDeviceDefaultTheme()), - android.R.attr.colorAccent)); - mProgressDrawable.updateSizes(MaterialProgressDrawable.LARGE); - mLoadingIndicator.setImageDrawable(mProgressDrawable); - - // We don't want to show the spinner every time we load an image if it loads quickly; instead, - // only start showing the spinner if loading the image has taken longer than half of a second. - mLoadingIndicator.postDelayed(() -> { - if (mFullResImageView != null && !mFullResImageView.hasImage() - && !mTestingModeEnabled) { - mLoadingIndicator.setVisibility(View.VISIBLE); - mLoadingIndicator.setAlpha(1f); - if (mProgressDrawable != null) { - mProgressDrawable.start(); - } - } - }, 500); - - mBottomSheetInitialState = (savedInstanceState == null) ? STATE_EXPANDED : savedInstanceState.getInt(KEY_BOTTOM_SHEET_STATE, @@ -381,6 +237,15 @@ public class PreviewFragment extends Fragment implements return view; } + @IdRes + protected abstract int getSetWallpaperButtonResId(); + + @IdRes + protected abstract int getBottomSheetResId(); + + @IdRes + protected abstract int getExploreButtonResId(); + protected int getDeviceDefaultTheme() { return android.R.style.Theme_DeviceDefault; } @@ -398,12 +263,12 @@ public class PreviewFragment extends Fragment implements // allow committing fragment transactions. if (mStagedLoadWallpaperErrorDialogFragment != null) { mStagedLoadWallpaperErrorDialogFragment.show( - getFragmentManager(), TAG_LOAD_WALLPAPER_ERROR_DIALOG_FRAGMENT); + requireFragmentManager(), TAG_LOAD_WALLPAPER_ERROR_DIALOG_FRAGMENT); mStagedLoadWallpaperErrorDialogFragment = null; } if (mStagedSetWallpaperErrorDialogFragment != null) { mStagedSetWallpaperErrorDialogFragment.show( - getFragmentManager(), TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT); + requireFragmentManager(), TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT); mStagedSetWallpaperErrorDialogFragment = null; } } @@ -428,20 +293,20 @@ public class PreviewFragment extends Fragment implements // the IndividualPreviewActivity, the "My photos" selection (by way of // TopLevelPickerActivity), or from a system "crop and set wallpaper" intent. // Therefore, handle the Up button as a global Back. - getActivity().onBackPressed(); + requireActivity().onBackPressed(); return true; } return false; } - protected void setupPreviewMenu(Menu menu) { + private void setupPreviewMenu(Menu menu) { mPreview = (CheckBox) menu.findItem(R.id.preview).getActionView(); mPreview.setChecked(mBottomSheetInitialState == STATE_COLLAPSED); mPreview.setOnClickListener(this::setPreviewBehavior); } - private void setPreviewChecked(boolean checked) { + protected void setPreviewChecked(boolean checked) { if (mPreview != null) { mPreview.setChecked(checked); int resId = checked ? R.string.expand_attribution_panel @@ -461,6 +326,61 @@ public class PreviewFragment extends Fragment implements } } + protected void setUpSetWallpaperButton() { + if (mPreviewMode == MODE_VIEW_ONLY) { + mSetWallpaperButton.setVisibility(View.GONE); + } else { + mSetWallpaperButton.setVisibility(View.VISIBLE); + mSetWallpaperButton.setOnClickListener(this::onSetWallpaperClicked); + } + } + + protected void setUpExploreButton() { + mExploreButton.setVisibility(View.GONE); + if (mExploreIntent == null) { + return; + } + Context context = requireContext(); + mExploreButton.setVisibility(View.VISIBLE); + mExploreButton.setText(context.getString( + mWallpaper.getActionLabelRes(context))); + + mExploreButton.setOnClickListener(view -> { + mUserEventLogger.logActionClicked(mWallpaper.getCollectionId(context), + mWallpaper.getActionLabelRes(context)); + + startActivity(mExploreIntent); + }); + } + + protected void setUpExploreIntent(@Nullable Runnable callback) { + Context context = getContext(); + if (context == null) { + return; + } + ExploreIntentChecker intentChecker = + InjectorProvider.getInjector().getExploreIntentChecker(context); + String actionUrl = mWallpaper.getActionUrl(context); + if (actionUrl != null && !actionUrl.isEmpty()) { + Uri exploreUri = Uri.parse(mWallpaper.getActionUrl(context)); + + intentChecker.fetchValidActionViewIntent(exploreUri, exploreIntent -> { + if (getActivity() == null) { + return; + } + + mExploreIntent = exploreIntent; + if (callback != null) { + callback.run(); + } + }); + } else { + if (callback != null) { + callback.run(); + } + } + } + @Override public void onSet(int destination) { setCurrentWallpaper(destination); @@ -483,10 +403,6 @@ public class PreviewFragment extends Fragment implements public void onDestroy() { super.onDestroy(); mWallpaperSetter.cleanUp(); - if (mProgressDrawable != null) { - mProgressDrawable.stop(); - } - mFullResImageView.recycle(); } @Override @@ -506,35 +422,6 @@ public class PreviewFragment extends Fragment implements } } - /** - * Returns a zoom level that is similar to the actual zoom, but that is exactly 0.5 ** n for some - * integer n. This is useful for downsampling a bitmap--we want to see the bitmap at full detail, - * or downsampled to 1 in every 2 pixels, or 1 in 4, and so on, depending on the zoom. - */ - private static float getDownsampleZoom(float actualZoom) { - if (actualZoom > 1) { - // Very zoomed in, but we can't sample more than 1 pixel per pixel. - return 1.0f; - } - float lower = 1.0f / roundUpToPower2((int) Math.ceil(1 / actualZoom)); - float upper = lower * 2; - return nearestValue(actualZoom, lower, upper); - } - - /** - * Returns the integer rounded up to the next power of 2. - */ - private static int roundUpToPower2(int value) { - return 1 << (32 - Integer.numberOfLeadingZeros(value - 1)); - } - - /** - * Returns the closer of two values a and b to the given value. - */ - private static float nearestValue(float value, float a, float b) { - return Math.abs(a - value) < Math.abs(b - value) ? a : b; - } - private void setUpBottomSheetListeners() { final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet); @@ -554,6 +441,8 @@ public class PreviewFragment extends Fragment implements case STATE_EXPANDED: setPreviewChecked(false /* checked */); break; + default: + Log.v(TAG, "Ignoring BottomSheet state: " + newState); } } @@ -565,264 +454,13 @@ public class PreviewFragment extends Fragment implements } else { alpha = 1f - slideOffset; } - mAttributionTitle.setAlpha(alpha); - mAttributionSubtitle1.setAlpha(alpha); - mAttributionSubtitle2.setAlpha(alpha); - mAttributionExploreButton.setAlpha(alpha); + setBottomSheetContentAlpha(alpha); } }); } - private boolean isWallpaperLoaded() { - return mFullResImageView.hasImage(); - } - - private void populateAttributionPane() { - final Context context = getContext(); - - final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet); - - List attributions = mWallpaper.getAttributions(context); - if (attributions.size() > 0 && attributions.get(0) != null) { - mAttributionTitle.setText(attributions.get(0)); - } - - if (attributions.size() > 1 && attributions.get(1) != null) { - mAttributionSubtitle1.setVisibility(View.VISIBLE); - mAttributionSubtitle1.setText(attributions.get(1)); - } - - if (attributions.size() > 2 && attributions.get(2) != null) { - mAttributionSubtitle2.setVisibility(View.VISIBLE); - mAttributionSubtitle2.setText(attributions.get(2)); - } - - if (mPreviewMode == MODE_CROP_AND_SET_WALLPAPER) { - mSetWallpaperButton.setVisibility(View.VISIBLE); - mSetWallpaperButton.setOnClickListener(this::onSetWallpaperClicked); - } else { - mSetWallpaperButton.setVisibility(View.GONE); - } - - String actionUrl = mWallpaper.getActionUrl(context); - - mAttributionExploreButton.setVisibility(View.GONE); - if (actionUrl != null && !actionUrl.isEmpty()) { - if (mExploreIntent != null) { - mAttributionExploreButton.setVisibility(View.VISIBLE); - mAttributionExploreButton.setText(context.getString( - mWallpaper.getActionLabelRes(context))); - - mAttributionExploreButton.setOnClickListener(view -> { - mUserEventLogger.logActionClicked(mWallpaper.getCollectionId(context), - mWallpaper.getActionLabelRes(context)); - - startActivity(mExploreIntent); - }); - } - } - - if (mAttributionExploreButton.getVisibility() == View.VISIBLE - && mSetWallpaperButton.getVisibility() == View.VISIBLE) { - mSpacer.setVisibility(View.VISIBLE); - } else { - mSpacer.setVisibility(View.GONE); - } - - mBottomSheet.setVisibility(View.VISIBLE); - - // Initialize the state of the BottomSheet based on the current state because if the initial - // and current state are the same, the state change listener won't fire and set the correct - // arrow asset and text alpha. - if (bottomSheetBehavior.getState() == STATE_EXPANDED) { - setPreviewChecked(false); - mAttributionTitle.setAlpha(1f); - mAttributionSubtitle1.setAlpha(1f); - mAttributionSubtitle2.setAlpha(1f); - } else { - setPreviewChecked(true); - mAttributionTitle.setAlpha(0f); - mAttributionSubtitle1.setAlpha(0f); - mAttributionSubtitle2.setAlpha(0f); - } - - // Let the state change listener take care of animating a state change to the initial state - // if there's a state change. - bottomSheetBehavior.setState(mBottomSheetInitialState); - } - - /** - * Initializes MosaicView by initializing tiling, setting a fallback page bitmap, and - * initializing a zoom-scroll observer and click listener. - */ - private void initFullResView() { - mFullResImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP); - - // Set a solid black "page bitmap" so MosaicView draws a black background while waiting - // for the image to load or a transparent one if a thumbnail already loaded. - Bitmap blackBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888); - int color = (mLowResImageView.getDrawable() == null) ? Color.BLACK : Color.TRANSPARENT; - blackBitmap.setPixel(0, 0, color); - mFullResImageView.setImage(ImageSource.bitmap(blackBitmap)); - - // Then set a fallback "page bitmap" to cover the whole MosaicView, which is an actual - // (lower res) version of the image to be displayed. - Point targetPageBitmapSize = new Point(mRawWallpaperSize); - mWallpaperAsset.decodeBitmap(targetPageBitmapSize.x, targetPageBitmapSize.y, - new BitmapReceiver() { - @Override - public void onBitmapDecoded(Bitmap pageBitmap) { - // Check that the activity is still around since the decoding task started. - if (getActivity() == null) { - return; - } - - // Some of these may be null depending on if the Fragment is paused, stopped, - // or destroyed. - if (mLoadingIndicator != null) { - mLoadingIndicator.setVisibility(View.GONE); - } - // The page bitmap may be null if there was a decoding error, so show an - // error dialog. - if (pageBitmap == null) { - showLoadWallpaperErrorDialog(); - return; - } - if (mFullResImageView != null) { - // Set page bitmap. - mFullResImageView.setImage(ImageSource.bitmap(pageBitmap)); - - setDefaultWallpaperZoomAndScroll(); - crossFadeInMosaicView(); - } - if (mProgressDrawable != null) { - mProgressDrawable.stop(); - } - getActivity().invalidateOptionsMenu(); - - populateAttributionPane(); - } - }); - } - - /** - * Makes the MosaicView visible with an alpha fade-in animation while fading out the loading - * indicator. - */ - private void crossFadeInMosaicView() { - long shortAnimationDuration = getResources().getInteger( - android.R.integer.config_shortAnimTime); - - mFullResImageView.setAlpha(0f); - mFullResImageView.animate() - .alpha(1f) - .setDuration(shortAnimationDuration) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - // Clear the thumbnail bitmap reference to save memory since it's no longer - // visible. - if (mLowResImageView != null) { - mLowResImageView.setImageBitmap(null); - } - } - }); - - mLoadingIndicator.animate() - .alpha(0f) - .setDuration(shortAnimationDuration) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (mLoadingIndicator != null) { - mLoadingIndicator.setVisibility(View.GONE); - } - } - }); - } - - /** - * Sets the default wallpaper zoom and scroll position based on a "crop surface" - * (with extra width to account for parallax) superimposed on the screen. Shows as much of the - * wallpaper as possible on the crop surface and align screen to crop surface such that the - * default preview matches what would be seen by the user in the left-most home screen. - * - *

This method is called once in the Fragment lifecycle after the wallpaper asset has loaded - * and rendered to the layout. - */ - private void setDefaultWallpaperZoomAndScroll() { - // Determine minimum zoom to fit maximum visible area of wallpaper on crop surface. - float defaultWallpaperZoom = - WallpaperCropUtils.calculateMinZoom(mRawWallpaperSize, mDefaultCropSurfaceSize); - float minWallpaperZoom = - WallpaperCropUtils.calculateMinZoom(mRawWallpaperSize, mScreenSize); - - Point screenToCropSurfacePosition = WallpaperCropUtils.calculateCenterPosition( - mDefaultCropSurfaceSize, mScreenSize, true /* alignStart */, isRtl()); - Point zoomedWallpaperSize = new Point( - Math.round(mRawWallpaperSize.x * defaultWallpaperZoom), - Math.round(mRawWallpaperSize.y * defaultWallpaperZoom)); - Point cropSurfaceToWallpaperPosition = WallpaperCropUtils.calculateCenterPosition( - zoomedWallpaperSize, mDefaultCropSurfaceSize, false /* alignStart */, isRtl()); - - // Set min wallpaper zoom and max zoom on MosaicView widget. - mFullResImageView.setMaxScale(Math.max(DEFAULT_WALLPAPER_MAX_ZOOM, defaultWallpaperZoom)); - mFullResImageView.setMinScale(minWallpaperZoom); - - // Set center to composite positioning between scaled wallpaper and screen. - PointF centerPosition = new PointF( - mRawWallpaperSize.x / 2f, - mRawWallpaperSize.y / 2f); - centerPosition.offset( - (screenToCropSurfacePosition.x + cropSurfaceToWallpaperPosition.x), - - (screenToCropSurfacePosition.y + cropSurfaceToWallpaperPosition.y)); - - mFullResImageView.setScaleAndCenter(minWallpaperZoom, centerPosition); - } - - protected Rect calculateCropRect() { - // Calculate Rect of wallpaper in physical pixel terms (i.e., scaled to current zoom). - float wallpaperZoom = mFullResImageView.getScale(); - int scaledWallpaperWidth = (int) (mRawWallpaperSize.x * wallpaperZoom); - int scaledWallpaperHeight = (int) (mRawWallpaperSize.y * wallpaperZoom); - Rect rect = new Rect(); - mFullResImageView.visibleFileRect(rect); - int scrollX = (int) (rect.left * wallpaperZoom); - int scrollY = (int) (rect.top * wallpaperZoom); - - rect.set(0, 0, scaledWallpaperWidth, scaledWallpaperHeight); - Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize( - getActivity().getWindowManager().getDefaultDisplay()); - // Crop rect should start off as the visible screen and then include extra width and height - // if available within wallpaper at the current zoom. - Rect cropRect = new Rect(scrollX, scrollY, scrollX + screenSize.x, scrollY + screenSize.y); - - Point defaultCropSurfaceSize = WallpaperCropUtils.getDefaultCropSurfaceSize( - getResources(), getActivity().getWindowManager().getDefaultDisplay()); - int extraWidth = defaultCropSurfaceSize.x - screenSize.x; - int extraHeightTopAndBottom = (int) ((defaultCropSurfaceSize.y - screenSize.y) / 2f); - - // Try to increase size of screenRect to include extra width depending on the layout - // direction. - if (isRtl()) { - cropRect.left = Math.max(cropRect.left - extraWidth, rect.left); - } else { - cropRect.right = Math.min(cropRect.right + extraWidth, rect.right); - } - - // Try to increase the size of the cropRect to to include extra height. - int availableExtraHeightTop = cropRect.top - Math.max( - rect.top, - cropRect.top - extraHeightTopAndBottom); - int availableExtraHeightBottom = Math.min( - rect.bottom, - cropRect.bottom + extraHeightTopAndBottom) - cropRect.bottom; - - int availableExtraHeightTopAndBottom = - Math.min(availableExtraHeightTop, availableExtraHeightBottom); - cropRect.top -= availableExtraHeightTopAndBottom; - cropRect.bottom += availableExtraHeightTopAndBottom; - - return cropRect; + protected void setBottomSheetContentAlpha(float alpha) { + mExploreButton.setAlpha(alpha); } /** @@ -830,35 +468,22 @@ public class PreviewFragment extends Fragment implements * * @param destination The wallpaper destination i.e. home vs. lockscreen vs. both. */ - private void setCurrentWallpaper(@Destination final int destination) { - mWallpaperSetter.setCurrentWallpaper(getActivity(), mWallpaper, mWallpaperAsset, - destination, mFullResImageView.getScale(), calculateCropRect(), - new SetWallpaperCallback() { - @Override - public void onSuccess() { - finishActivityWithResultOk(); - } - - @Override - public void onError(@Nullable Throwable throwable) { - showSetWallpaperErrorDialog(destination); - } - }); - } + protected abstract void setCurrentWallpaper(@Destination int destination); - private void finishActivityWithResultOk() { + protected void finishActivityWithResultOk() { + Activity activity = requireActivity(); try { - Toast.makeText( - getActivity(), R.string.wallpaper_set_successfully_message, Toast.LENGTH_SHORT).show(); + Toast.makeText(activity, + R.string.wallpaper_set_successfully_message, Toast.LENGTH_SHORT).show(); } catch (NotFoundException e) { Log.e(TAG, "Could not show toast " + e); } - getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out); - getActivity().setResult(Activity.RESULT_OK); - getActivity().finish(); + activity.overridePendingTransition(R.anim.fade_in, R.anim.fade_out); + activity.setResult(Activity.RESULT_OK); + activity.finish(); } - private void showSetWallpaperErrorDialog(@Destination int wallpaperDestination) { + protected void showSetWallpaperErrorDialog(@Destination int wallpaperDestination) { SetWallpaperErrorDialogFragment newFragment = SetWallpaperErrorDialogFragment.newInstance( R.string.set_wallpaper_error_message, wallpaperDestination); newFragment.setTargetFragment(this, UNUSED_REQUEST_CODE); @@ -866,9 +491,9 @@ public class PreviewFragment extends Fragment implements // Show 'set wallpaper' error dialog now if it's safe to commit fragment transactions, // otherwise stage it for later when the hosting activity is in a state to commit fragment // transactions. - BasePreviewActivity activity = (BasePreviewActivity) getActivity(); + BasePreviewActivity activity = (BasePreviewActivity) requireActivity(); if (activity.isSafeToCommitFragmentTransaction()) { - newFragment.show(getFragmentManager(), TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT); + newFragment.show(requireFragmentManager(), TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT); } else { mStagedSetWallpaperErrorDialogFragment = newFragment; } @@ -878,17 +503,16 @@ public class PreviewFragment extends Fragment implements * Shows 'load wallpaper' error dialog now or stage it to be shown when the hosting activity is * in a state that allows committing fragment transactions. */ - private void showLoadWallpaperErrorDialog() { + protected void showLoadWallpaperErrorDialog() { LoadWallpaperErrorDialogFragment dialogFragment = LoadWallpaperErrorDialogFragment.newInstance(); - dialogFragment.setTargetFragment(PreviewFragment.this, UNUSED_REQUEST_CODE); + dialogFragment.setTargetFragment(this, UNUSED_REQUEST_CODE); // Show 'load wallpaper' error dialog now or stage it to be shown when the hosting // activity is in a state that allows committing fragment transactions. BasePreviewActivity activity = (BasePreviewActivity) getActivity(); if (activity != null && activity.isSafeToCommitFragmentTransaction()) { - dialogFragment.show(PreviewFragment.this.getFragmentManager(), - TAG_LOAD_WALLPAPER_ERROR_DIALOG_FRAGMENT); + dialogFragment.show(requireFragmentManager(), TAG_LOAD_WALLPAPER_ERROR_DIALOG_FRAGMENT); } else { mStagedLoadWallpaperErrorDialogFragment = dialogFragment; } @@ -902,60 +526,11 @@ public class PreviewFragment extends Fragment implements private @interface ActivityInfoScreenOrientation { } - /** - * Gets the appropriate ActivityInfo orientation for the current configuration orientation to - * enable locking screen rotation at API levels lower than 18. - */ - @ActivityInfoScreenOrientation - private int getCompatActivityInfoOrientation() { - int configOrientation = getResources().getConfiguration().orientation; - final Display display = getActivity().getWindowManager().getDefaultDisplay(); - int naturalOrientation = Configuration.ORIENTATION_LANDSCAPE; - switch (display.getRotation()) { - case Surface.ROTATION_0: - case Surface.ROTATION_180: - // We are currently in the same basic orientation as the natural orientation. - naturalOrientation = configOrientation; - break; - case Surface.ROTATION_90: - case Surface.ROTATION_270: - // We are currently in the other basic orientation to the natural orientation. - naturalOrientation = (configOrientation == Configuration.ORIENTATION_LANDSCAPE) - ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; - break; - default: - // continue below - } - - // Since the map starts at portrait, we need to offset if this device's natural orientation - // is landscape. - int indexOffset = 0; - if (naturalOrientation == Configuration.ORIENTATION_LANDSCAPE) { - indexOffset = 1; - } - - switch ((display.getRotation() + indexOffset) % 4) { - case 0: - return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; - case 1: - return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; - case 2: - return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; - case 3: - return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; - default: - Log.e(TAG, "Display rotation did not correspond to a valid ActivityInfo orientation" - + "with display rotation: " + display.getRotation() + " and index offset: " - + indexOffset + "."); - return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; - } - } - /** * Returns whether layout direction is RTL (or false for LTR). Since native RTL layout support * was added in API 17, returns false for versions lower than 17. */ - private boolean isRtl() { + protected boolean isRtl() { return getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; } diff --git a/src_override/com/android/wallpaper/module/WallpapersInjector.java b/src_override/com/android/wallpaper/module/WallpapersInjector.java index 8e3b3e9..5a39524 100755 --- a/src_override/com/android/wallpaper/module/WallpapersInjector.java +++ b/src_override/com/android/wallpaper/module/WallpapersInjector.java @@ -17,12 +17,12 @@ package com.android.wallpaper.module; import android.content.Context; +import androidx.fragment.app.Fragment; + import com.android.wallpaper.model.CategoryProvider; import com.android.wallpaper.model.WallpaperInfo; import com.android.wallpaper.monitor.PerformanceMonitor; -import com.android.wallpaper.picker.PreviewFragment; - -import androidx.fragment.app.Fragment; +import com.android.wallpaper.picker.ImagePreviewFragment; /** * A concrete, real implementation of the dependency provider. @@ -69,7 +69,7 @@ public class WallpapersInjector extends BaseWallpaperInjector { WallpaperInfo wallpaperInfo, int mode, boolean testingModeEnabled) { - return PreviewFragment.newInstance(wallpaperInfo, mode, testingModeEnabled); + return ImagePreviewFragment.newInstance(wallpaperInfo, mode, testingModeEnabled); } @Override -- cgit v1.2.3 From c30376cc10ea9c6ea7ce172f4e889f6823668a24 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Tue, 8 Oct 2019 12:53:43 -0700 Subject: Switch to static wallpaper when update from rotating live wallpaper Test: Manual Bug:142082227 Change-Id: Ib68dff296232b757c2eaf7c8b73f915235aa6bab --- .../module/RotationWallpaperMoveReceiver.java | 77 -------------- .../module/RotationWallpaperUpdateReceiver.java | 111 +++++++++++++++++++++ 2 files changed, 111 insertions(+), 77 deletions(-) delete mode 100644 src/com/android/wallpaper/module/RotationWallpaperMoveReceiver.java create mode 100644 src/com/android/wallpaper/module/RotationWallpaperUpdateReceiver.java diff --git a/src/com/android/wallpaper/module/RotationWallpaperMoveReceiver.java b/src/com/android/wallpaper/module/RotationWallpaperMoveReceiver.java deleted file mode 100644 index 975b0db..0000000 --- a/src/com/android/wallpaper/module/RotationWallpaperMoveReceiver.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.android.wallpaper.module; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.android.wallpaper.compat.BuildCompat; -import com.android.wallpaper.util.DiskBasedLogger; -import com.android.wallpaper.util.FileMover; - -import java.io.File; -import java.io.IOException; - -/** - * Receiver to run when the app was updated or on first boot to migrate previously existing rotating - * wallpaper file to device protected storage so it can be read in direct-boot. - * This is basically a no-op if there's no file in - * {@link NoBackupImageWallpaper#ROTATING_WALLPAPER_FILE_PATH}. - */ -public class RotationWallpaperMoveReceiver extends BroadcastReceiver { - - private static final String TAG = "RotationWallpaperMoveReceiver"; - - @Override - public void onReceive(Context context, Intent intent) { - // This receiver is a no-op on pre-N Android and should only respond to a - // MY_PACKAGE_REPLACED intent. - if (intent.getAction() == null - || !(intent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED) - || intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) - || !BuildCompat.isAtLeastN()) { - DiskBasedLogger.e( - TAG, - "Unexpected action or Android version!", - context); - throw new IllegalStateException( - "Unexpected broadcast action or unsupported Android version"); - } - - // This is a no-op if there is no rotating wallpaper file in the files directory. - if (!context.getFileStreamPath( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH).exists()) { - return; - } - - PendingResult broadcastResult = goAsync(); - new Thread(() -> { - Context appContext = context.getApplicationContext(); - Context deviceProtectedContext = appContext.createDeviceProtectedStorageContext(); - try { - File movedFile = FileMover.moveFileBetweenContexts(appContext, - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH, - deviceProtectedContext, - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - - if (movedFile != null) { - // Notify NoBackupImageWallpaper of the change in case that's the currently - // set wallpaper - Intent intent1 = new Intent(appContext.getPackageName() - + NoBackupImageWallpaper.ACTION_ROTATING_WALLPAPER_CHANGED); - // Handled by a runtime-registered receiver in NoBackupImageWallpaper. - intent1.setPackage(appContext.getPackageName()); - appContext.sendBroadcast(intent1); - } - } catch (IOException e) { - DiskBasedLogger.e( - TAG, - "Failed to move rotating wallpaper file to device protected storage: " - + e.getMessage(), - appContext); - } finally { - broadcastResult.finish(); - } - }).start(); - - } -} diff --git a/src/com/android/wallpaper/module/RotationWallpaperUpdateReceiver.java b/src/com/android/wallpaper/module/RotationWallpaperUpdateReceiver.java new file mode 100644 index 0000000..4fbc20d --- /dev/null +++ b/src/com/android/wallpaper/module/RotationWallpaperUpdateReceiver.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.module; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import com.android.wallpaper.compat.BuildCompat; +import com.android.wallpaper.util.DiskBasedLogger; +import com.android.wallpaper.util.FileMover; + +import java.io.File; + +/** + * Receiver to run when the app was updated or on first boot to switch from live rotating wallpaper + * to static rotating wallpaper. + */ +public class RotationWallpaperUpdateReceiver extends BroadcastReceiver { + + + // Earlier versions of rotating wallpaper save the current rotation image as a file. + // We can infer from the extistance of this file whether or not user had rotating live wallpaper + private static final String ROTATING_WALLPAPER_FILE_PATH = "rotating_wallpaper.jpg"; + private static final String TAG = "RotationWallpaperUpdateReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + // This receiver is a no-op on pre-N Android and should only respond to a + // MY_PACKAGE_REPLACED intent. + if (intent.getAction() == null + || !(intent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED) + || intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) + || !BuildCompat.isAtLeastN()) { + DiskBasedLogger.e( + TAG, + "Unexpected action or Android version!", + context); + throw new IllegalStateException( + "Unexpected broadcast action or unsupported Android version"); + } + + PendingResult broadcastResult = goAsync(); + new Thread(() -> { + Context appContext = context.getApplicationContext(); + Context deviceProtectedContext = appContext.createDeviceProtectedStorageContext(); + + if (context.getFileStreamPath(ROTATING_WALLPAPER_FILE_PATH).exists()) { + moveFileToProtectedStorage(appContext, deviceProtectedContext); + } + + File wallpaperFile = deviceProtectedContext.getFileStreamPath( + ROTATING_WALLPAPER_FILE_PATH); + if (wallpaperFile.exists()) { + switchToStaticWallpaper(appContext, wallpaperFile); + } + broadcastResult.finish(); + }).start(); + } + + private void moveFileToProtectedStorage(Context context, Context deviceProtectedContext) { + try { + FileMover.moveFileBetweenContexts(context, ROTATING_WALLPAPER_FILE_PATH, + deviceProtectedContext, ROTATING_WALLPAPER_FILE_PATH); + } catch (Exception ex) { + DiskBasedLogger.e( + TAG, + "Failed to move rotating wallpaper file to device protected storage: " + + ex.getMessage(), + context); + } + } + + private void switchToStaticWallpaper(Context appContext, File wallpaperFile) { + try { + Injector injector = InjectorProvider.getInjector(); + WallpaperPreferences wallpaperPreferences = injector.getPreferences(appContext); + if (wallpaperPreferences.getWallpaperPresentationMode() + != WallpaperPreferences.PRESENTATION_MODE_ROTATING) { + return; + } + Bitmap bitmap = BitmapFactory.decodeFile(wallpaperFile.getAbsolutePath()); + + injector.getWallpaperPersister(appContext).setWallpaperInRotation(bitmap, + wallpaperPreferences.getHomeWallpaperAttributions(), + wallpaperPreferences.getHomeWallpaperActionLabelRes(), + wallpaperPreferences.getHomeWallpaperActionIconRes(), + wallpaperPreferences.getHomeWallpaperActionUrl(), + wallpaperPreferences.getHomeWallpaperCollectionId()); + wallpaperFile.delete(); + + } catch (Exception ex) { + DiskBasedLogger.e(TAG, "Unable to set static wallpaper", appContext); + } + } +} -- cgit v1.2.3 From e78fce9ff37b2656b941b2975a0a8a591557357d Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Wed, 9 Oct 2019 15:22:56 -0700 Subject: Remove NoBackupImageWallpaper Test: Manual Bug:142008417 Change-Id: I9a1879f137a242d9c453af502503401e2a16e554 --- .../wallpaper/model/CurrentWallpaperInfoV16.java | 139 --- .../wallpaper/model/CurrentWallpaperInfoVN.java | 14 - .../wallpaper/module/BaseWallpaperInjector.java | 10 - .../module/DefaultCurrentWallpaperInfoFactory.java | 41 +- .../module/DefaultLiveWallpaperStatusChecker.java | 42 - .../module/DefaultWallpaperRefresher.java | 41 +- src/com/android/wallpaper/module/Injector.java | 2 - .../module/LiveWallpaperStatusChecker.java | 27 - .../wallpaper/module/NoBackupImageWallpaper.java | 1018 -------------------- .../individual/IndividualPickerActivity.java | 32 - 10 files changed, 12 insertions(+), 1354 deletions(-) delete mode 100755 src/com/android/wallpaper/model/CurrentWallpaperInfoV16.java delete mode 100755 src/com/android/wallpaper/module/DefaultLiveWallpaperStatusChecker.java delete mode 100755 src/com/android/wallpaper/module/LiveWallpaperStatusChecker.java delete mode 100755 src/com/android/wallpaper/module/NoBackupImageWallpaper.java diff --git a/src/com/android/wallpaper/model/CurrentWallpaperInfoV16.java b/src/com/android/wallpaper/model/CurrentWallpaperInfoV16.java deleted file mode 100755 index 3db46e7..0000000 --- a/src/com/android/wallpaper/model/CurrentWallpaperInfoV16.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.wallpaper.model; - -import android.app.Activity; -import android.content.Context; -import android.os.Parcel; - -import com.android.wallpaper.asset.Asset; -import com.android.wallpaper.asset.CurrentWallpaperAssetV16; -import com.android.wallpaper.asset.FileAsset; -import com.android.wallpaper.module.InjectorProvider; -import com.android.wallpaper.module.NoBackupImageWallpaper; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import androidx.annotation.DrawableRes; -import androidx.annotation.StringRes; - -/** - * Represents the wallpaper currently set to the device for API 16 through 23. Should not be used - * to set a new wallpaper. - */ -public class CurrentWallpaperInfoV16 extends WallpaperInfo { - - public static final Creator CREATOR = - new Creator() { - @Override - public CurrentWallpaperInfoV16 createFromParcel(Parcel source) { - return new CurrentWallpaperInfoV16(source); - } - - @Override - public CurrentWallpaperInfoV16[] newArray(int size) { - return new CurrentWallpaperInfoV16[size]; - } - }; - private List mAttributions; - private Asset mAsset; - private String mActionUrl; - @StringRes - private int mActionLabelRes; - @DrawableRes - private int mActionIconRes; - private String mCollectionId; - - public CurrentWallpaperInfoV16(List attributions, String actionUrl, - @StringRes int actionLabelRes, @DrawableRes int actionIconRes, - String collectionId) { - mAttributions = attributions; - mActionUrl = actionUrl; - mActionLabelRes = actionLabelRes; - mActionIconRes = actionIconRes; - mCollectionId = collectionId; - } - - private CurrentWallpaperInfoV16(Parcel in) { - mAttributions = new ArrayList<>(); - in.readStringList(mAttributions); - mActionUrl = in.readString(); - mCollectionId = in.readString(); - mActionLabelRes = in.readInt(); - mActionIconRes = in.readInt(); - } - - @Override - public List getAttributions(Context context) { - return mAttributions; - } - - @Override - public Asset getAsset(Context context) { - if (mAsset == null) { - boolean isNoBackupImageWallpaperSet = InjectorProvider.getInjector() - .getLiveWallpaperStatusChecker(context).isNoBackupImageWallpaperSet(); - - mAsset = isNoBackupImageWallpaperSet - ? new FileAsset(new File(context.getApplicationContext().getFilesDir(), - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH)) - : new CurrentWallpaperAssetV16(context); - } - return mAsset; - } - - @Override - public Asset getThumbAsset(Context context) { - return getAsset(context); - } - - @Override - public String getActionUrl(Context unused) { - return mActionUrl; - } - - @Override - public int getActionIconRes(Context unused) { - return mActionIconRes != 0 ? mActionIconRes : WallpaperInfo.getDefaultActionIcon(); - } - - @Override - public int getActionLabelRes(Context unused) { - return mActionLabelRes != 0 ? mActionLabelRes : WallpaperInfo.getDefaultActionLabel(); - } - - @Override - public String getCollectionId(Context unused) { - return mCollectionId; - } - - @Override - public void writeToParcel(Parcel parcel, int flags) { - parcel.writeStringList(mAttributions); - parcel.writeString(mActionUrl); - parcel.writeString(mCollectionId); - parcel.writeInt(mActionLabelRes); - parcel.writeInt(mActionIconRes); - } - - @Override - public void showPreview(Activity srcActivity, InlinePreviewIntentFactory factory, - int requestCode) { - srcActivity.startActivityForResult(factory.newIntent(srcActivity, this), requestCode); - } -} diff --git a/src/com/android/wallpaper/model/CurrentWallpaperInfoVN.java b/src/com/android/wallpaper/model/CurrentWallpaperInfoVN.java index e44e717..bf54bfd 100755 --- a/src/com/android/wallpaper/model/CurrentWallpaperInfoVN.java +++ b/src/com/android/wallpaper/model/CurrentWallpaperInfoVN.java @@ -27,13 +27,10 @@ import androidx.annotation.StringRes; import com.android.wallpaper.asset.Asset; import com.android.wallpaper.asset.BuiltInWallpaperAsset; import com.android.wallpaper.asset.CurrentWallpaperAssetVN; -import com.android.wallpaper.asset.FileAsset; import com.android.wallpaper.compat.WallpaperManagerCompat; import com.android.wallpaper.compat.WallpaperManagerCompat.WallpaperLocation; import com.android.wallpaper.module.InjectorProvider; -import com.android.wallpaper.module.NoBackupImageWallpaper; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -142,17 +139,6 @@ public class CurrentWallpaperInfoVN extends WallpaperInfo { * Constructs and returns an Asset instance representing the currently-set wallpaper asset. */ private Asset createCurrentWallpaperAssetVN(Context context) { - // If the live wallpaper for rotating wallpapers is set, then provide a file asset - // representing that wallpaper. - boolean isNoBackupImageWallpaperSet = InjectorProvider.getInjector() - .getLiveWallpaperStatusChecker(context).isNoBackupImageWallpaperSet(); - if (mWallpaperManagerFlag == WallpaperManagerCompat.FLAG_SYSTEM - && isNoBackupImageWallpaperSet) { - Context deviceProtectedContext = context.createDeviceProtectedStorageContext(); - return new FileAsset(new File(deviceProtectedContext.getFilesDir(), - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH)); - } - WallpaperManagerCompat wallpaperManagerCompat = InjectorProvider.getInjector() .getWallpaperManagerCompat(context); diff --git a/src/com/android/wallpaper/module/BaseWallpaperInjector.java b/src/com/android/wallpaper/module/BaseWallpaperInjector.java index 7f52823..de9ddb1 100755 --- a/src/com/android/wallpaper/module/BaseWallpaperInjector.java +++ b/src/com/android/wallpaper/module/BaseWallpaperInjector.java @@ -34,7 +34,6 @@ public abstract class BaseWallpaperInjector implements Injector { private Requester mRequester; private WallpaperManagerCompat mWallpaperManagerCompat; private CurrentWallpaperInfoFactory mCurrentWallpaperFactory; - private LiveWallpaperStatusChecker mLiveWallpaperStatusChecker; private NetworkStatusNotifier mNetworkStatusNotifier; private AlarmManagerWrapper mAlarmManagerWrapper; private ExploreIntentChecker mExploreIntentChecker; @@ -109,15 +108,6 @@ public abstract class BaseWallpaperInjector implements Injector { return mCurrentWallpaperFactory; } - @Override - public synchronized LiveWallpaperStatusChecker getLiveWallpaperStatusChecker(Context context) { - if (mLiveWallpaperStatusChecker == null) { - mLiveWallpaperStatusChecker = - new DefaultLiveWallpaperStatusChecker(context.getApplicationContext()); - } - return mLiveWallpaperStatusChecker; - } - @Override public synchronized NetworkStatusNotifier getNetworkStatusNotifier(Context context) { if (mNetworkStatusNotifier == null) { diff --git a/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java b/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java index c74f9b2..dbe3722 100755 --- a/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java +++ b/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java @@ -17,16 +17,13 @@ package com.android.wallpaper.module; import android.content.Context; -import com.android.wallpaper.compat.BuildCompat; +import androidx.annotation.Nullable; + import com.android.wallpaper.compat.WallpaperManagerCompat; -import com.android.wallpaper.model.CurrentWallpaperInfoV16; import com.android.wallpaper.model.CurrentWallpaperInfoVN; -import com.android.wallpaper.model.LiveWallpaperInfo; import com.android.wallpaper.model.WallpaperInfo; import com.android.wallpaper.module.WallpaperPreferences.PresentationMode; -import androidx.annotation.Nullable; - /** * Default implementation of {@link CurrentWallpaperInfoFactory} which actually constructs * {@link WallpaperInfo} instances representing the wallpapers currently set to the device. @@ -35,7 +32,6 @@ public class DefaultCurrentWallpaperInfoFactory implements CurrentWallpaperInfoF private final Context mAppContext; private final WallpaperRefresher mWallpaperRefresher; - private final LiveWallpaperStatusChecker mLiveWallpaperStatusChecker; private final LiveWallpaperInfoFactory mLiveWallpaperInfoFactory; // Cached copies of the currently-set WallpaperInfo(s) and presentation mode. @@ -49,8 +45,6 @@ public class DefaultCurrentWallpaperInfoFactory implements CurrentWallpaperInfoF mAppContext = context.getApplicationContext(); Injector injector = InjectorProvider.getInjector(); mWallpaperRefresher = injector.getWallpaperRefresher(mAppContext); - mLiveWallpaperStatusChecker = - injector.getLiveWallpaperStatusChecker(mAppContext); mLiveWallpaperInfoFactory = injector.getLiveWallpaperInfoFactory(mAppContext); } @@ -72,29 +66,16 @@ public class DefaultCurrentWallpaperInfoFactory implements CurrentWallpaperInfoF mWallpaperRefresher.refresh( (homeWallpaperMetadata, lockWallpaperMetadata, presentationMode) -> { - WallpaperInfo homeWallpaper; - - if (homeWallpaperMetadata.getWallpaperComponent() == null - || mLiveWallpaperStatusChecker.isNoBackupImageWallpaperSet()) { - // Image wallpaper - if (BuildCompat.isAtLeastN()) { - homeWallpaper = new CurrentWallpaperInfoVN( - homeWallpaperMetadata.getAttributions(), - homeWallpaperMetadata.getActionUrl(), - homeWallpaperMetadata.getActionLabelRes(), - homeWallpaperMetadata.getActionIconRes(), - homeWallpaperMetadata.getCollectionId(), - WallpaperManagerCompat.FLAG_SYSTEM); - } else { - homeWallpaper = new CurrentWallpaperInfoV16( - homeWallpaperMetadata.getAttributions(), - homeWallpaperMetadata.getActionUrl(), - homeWallpaperMetadata.getActionLabelRes(), - homeWallpaperMetadata.getActionIconRes(), - homeWallpaperMetadata.getCollectionId()); - } - } else { // Live wallpaper + if (homeWallpaperMetadata.getWallpaperComponent() == null) { + homeWallpaper = new CurrentWallpaperInfoVN( + homeWallpaperMetadata.getAttributions(), + homeWallpaperMetadata.getActionUrl(), + homeWallpaperMetadata.getActionLabelRes(), + homeWallpaperMetadata.getActionIconRes(), + homeWallpaperMetadata.getCollectionId(), + WallpaperManagerCompat.FLAG_SYSTEM); + } else { homeWallpaper = mLiveWallpaperInfoFactory.getLiveWallpaperInfo( homeWallpaperMetadata.getWallpaperComponent()); } diff --git a/src/com/android/wallpaper/module/DefaultLiveWallpaperStatusChecker.java b/src/com/android/wallpaper/module/DefaultLiveWallpaperStatusChecker.java deleted file mode 100755 index 003a06b..0000000 --- a/src/com/android/wallpaper/module/DefaultLiveWallpaperStatusChecker.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.wallpaper.module; - -import android.annotation.SuppressLint; -import android.app.WallpaperManager; -import android.content.Context; - -/** - * Default implementation of {@link LiveWallpaperStatusChecker}. - */ -@SuppressLint("ServiceCast") -public class DefaultLiveWallpaperStatusChecker implements LiveWallpaperStatusChecker { - - private WallpaperManager mWallpaperManager; - - public DefaultLiveWallpaperStatusChecker(Context context) { - // Retrieve WallpaperManager using Context#getSystemService instead of - // WallpaperManager#getInstance so it can be mocked out in test. - mWallpaperManager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE); - } - - @Override - public boolean isNoBackupImageWallpaperSet() { - android.app.WallpaperInfo liveWallpaper = mWallpaperManager.getWallpaperInfo(); - return liveWallpaper != null - && liveWallpaper.getServiceName().equals(NoBackupImageWallpaper.class.getName()); - } -} diff --git a/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java b/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java index c97d2b9..d85e04e 100755 --- a/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java +++ b/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java @@ -32,7 +32,6 @@ import com.android.wallpaper.compat.WallpaperManagerCompat; import com.android.wallpaper.model.WallpaperMetadata; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -50,9 +49,6 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { private final Context mAppContext; private final WallpaperPreferences mWallpaperPreferences; private final WallpaperManager mWallpaperManager; - private final LiveWallpaperStatusChecker mLiveWallpaperStatusChecker; - private final UserEventLogger mUserEventLogger; - private final Context mDeviceProtectedContext; /** * @param context The application's context. @@ -62,13 +58,10 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { Injector injector = InjectorProvider.getInjector(); mWallpaperPreferences = injector.getPreferences(mAppContext); - mLiveWallpaperStatusChecker = injector.getLiveWallpaperStatusChecker(mAppContext); - mUserEventLogger = injector.getUserEventLogger(mAppContext); // Retrieve WallpaperManager using Context#getSystemService instead of // WallpaperManager#getInstance so it can be mocked out in test. mWallpaperManager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE); - mDeviceProtectedContext = mAppContext.createDeviceProtectedStorageContext(); } @Override @@ -203,8 +196,7 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { * current system wallpaper. */ private boolean isHomeScreenMetadataCurrent() { - return (mWallpaperManager.getWallpaperInfo() == null - || mLiveWallpaperStatusChecker.isNoBackupImageWallpaperSet()) + return (mWallpaperManager.getWallpaperInfo() == null) ? isHomeScreenImageWallpaperCurrent() : isHomeScreenLiveWallpaperCurrent(); } @@ -221,36 +213,6 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { private long getCurrentHomeWallpaperHashCode() { if (mCurrentHomeWallpaperHashCode == 0) { - if (mLiveWallpaperStatusChecker.isNoBackupImageWallpaperSet()) { - - synchronized (RotatingWallpaperLockProvider.getInstance()) { - Bitmap bitmap = null; - try { - FileInputStream fis = - mDeviceProtectedContext.openFileInput( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - bitmap = BitmapFactory.decodeStream(fis); - fis.close(); - } catch (FileNotFoundException e) { - Log.e(TAG, "Rotating wallpaper file not found at path: " - + mDeviceProtectedContext.getFileStreamPath( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH), - e); - } catch (IOException e) { - Log.e(TAG, "IOException when closing FileInputStream " + e); - } - - if (bitmap != null) { - mCurrentHomeWallpaperHashCode = BitmapUtils.generateHashCode(bitmap); - mUserEventLogger.logDailyWallpaperDecodes(true); - } else { - // If an error occurred decoding the stream then we should just assume the current - // home wallpaper remained intact. - mCurrentHomeWallpaperHashCode = mWallpaperPreferences.getHomeWallpaperHashCode(); - mUserEventLogger.logDailyWallpaperDecodes(false); - } - } - } else { BitmapDrawable wallpaperDrawable = (BitmapDrawable) mWallpaperManagerCompat.getDrawable(); Bitmap wallpaperBitmap = wallpaperDrawable.getBitmap(); mCurrentHomeWallpaperHashCode = BitmapUtils.generateHashCode(wallpaperBitmap); @@ -258,7 +220,6 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { // Manually request that WallpaperManager loses its reference to the current wallpaper // bitmap, which can occupy a large memory allocation for the lifetime of the app. mWallpaperManager.forgetLoadedWallpaper(); - } } return mCurrentHomeWallpaperHashCode; } diff --git a/src/com/android/wallpaper/module/Injector.java b/src/com/android/wallpaper/module/Injector.java index 1f59951..ca64b9d 100755 --- a/src/com/android/wallpaper/module/Injector.java +++ b/src/com/android/wallpaper/module/Injector.java @@ -44,8 +44,6 @@ public interface Injector { FormFactorChecker getFormFactorChecker(Context context); - LiveWallpaperStatusChecker getLiveWallpaperStatusChecker(Context context); - LoggingOptInStatusProvider getLoggingOptInStatusProvider(Context context); NetworkStatusNotifier getNetworkStatusNotifier(Context context); diff --git a/src/com/android/wallpaper/module/LiveWallpaperStatusChecker.java b/src/com/android/wallpaper/module/LiveWallpaperStatusChecker.java deleted file mode 100755 index 67d87f8..0000000 --- a/src/com/android/wallpaper/module/LiveWallpaperStatusChecker.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.wallpaper.module; - -/** - * Reads whether the application's live wallpaper service is set to the device. - */ -public interface LiveWallpaperStatusChecker { - - /** - * Returns whether the live wallpaper for daily wallpapers is set to the device. - */ - boolean isNoBackupImageWallpaperSet(); -} diff --git a/src/com/android/wallpaper/module/NoBackupImageWallpaper.java b/src/com/android/wallpaper/module/NoBackupImageWallpaper.java deleted file mode 100755 index a76d881..0000000 --- a/src/com/android/wallpaper/module/NoBackupImageWallpaper.java +++ /dev/null @@ -1,1018 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.wallpaper.module; - -import static javax.microedition.khronos.egl.EGL10.EGL_NO_CONTEXT; -import static javax.microedition.khronos.egl.EGL10.EGL_NO_SURFACE; - -import android.annotation.SuppressLint; -import android.app.WallpaperColors; -import android.app.WallpaperManager; -import android.content.BroadcastReceiver; -import android.content.ComponentCallbacks2; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.opengl.GLES20; -import android.opengl.GLUtils; -import android.os.AsyncTask; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.os.Handler; -import android.renderscript.Matrix4f; -import android.service.wallpaper.WallpaperService; -import android.util.Log; -import android.view.Display; -import android.view.MotionEvent; -import android.view.SurfaceHolder; -import android.view.WindowManager; - -import com.android.wallpaper.util.ScreenSizeCalculator; - -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; - -import androidx.annotation.RequiresApi; - -/** - * Live wallpaper service which simply renders a wallpaper from internal storage. Designed as a - * workaround to WallpaperManager not having an allowBackup=false option on pre-N builds of Android. - *

- * Adapted from {@code com.android.systemui.ImageWallpaper}. - */ -@SuppressLint("ServiceCast") -public class NoBackupImageWallpaper extends WallpaperService { - - public static final String ACTION_ROTATING_WALLPAPER_CHANGED = - ".ACTION_ROTATING_WALLPAPER_CHANGED"; - public static final String PERMISSION_NOTIFY_ROTATING_WALLPAPER_CHANGED = - ".NOTIFY_ROTATING_WALLPAPER_CHANGED"; - public static final String PREVIEW_WALLPAPER_FILE_PATH = "preview_wallpaper.jpg"; - public static final String ROTATING_WALLPAPER_FILE_PATH = "rotating_wallpaper.jpg"; - - private static final String TAG = "NoBackupImageWallpaper"; - private static final String GL_LOG_TAG = "ImageWallpaperGL"; - private static final boolean DEBUG = false; - private static final boolean FIXED_SIZED_SURFACE = false; - - private final Handler mHandler = new Handler(); - - private int mOpenGlContextCounter; - private WallpaperManager mWallpaperManager; - private DrawableEngine mEngine; - private boolean mIsHardwareAccelerated; - - @Override - public void onCreate() { - super.onCreate(); - - mOpenGlContextCounter = 0; - mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE); - - // By default, use OpenGL for drawing the static wallpaper image. - mIsHardwareAccelerated = true; - } - - @Override - public void onTrimMemory(int level) { - if (mEngine != null) { - mEngine.trimMemory(level); - } - } - - @Override - public Engine onCreateEngine() { - mEngine = new DrawableEngine(); - return mEngine; - } - - private class DrawableEngine extends Engine { - static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; - static final int EGL_OPENGL_ES2_BIT = 4; - private static final String S_SIMPLE_VS = - "attribute vec4 position;\n" - + "attribute vec2 texCoords;\n" - + "varying vec2 outTexCoords;\n" - + "uniform mat4 projection;\n" - + "\nvoid main(void) {\n" - + " outTexCoords = texCoords;\n" - + " gl_Position = projection * position;\n" - + "}\n\n"; - private static final String S_SIMPLE_FS = - "precision mediump float;\n\n" - + "varying vec2 outTexCoords;\n" - + "uniform sampler2D texture;\n" - + "\nvoid main(void) {\n" - + " gl_FragColor = texture2D(texture, outTexCoords);\n" - + "}\n\n"; - private static final int FLOAT_SIZE_BYTES = 4; - private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; - private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; - private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; - Bitmap mBackground; - WallpaperColors mCachedWallpaperColors; - int mBackgroundWidth = -1, mBackgroundHeight = -1; - int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; - int mLastRotation = -1; - float mXOffset = 0.5f; - float mYOffset = 0.5f; - float mScale = 1f; - boolean mVisible = true; - boolean mOffsetsChanged; - int mLastXTranslation; - int mLastYTranslation; - private Display mDefaultDisplay; - private EGL10 mEgl; - private EGLDisplay mEglDisplay; - private EGLConfig mEglConfig; - private EGLContext mEglContext; - private EGLSurface mEglSurface; - private int mTexture; - private int mProgram; - private boolean mIsOpenGlTextureLoaded; - private int mRotationAtLastSurfaceSizeUpdate = -1; - private int mDisplayWidthAtLastSurfaceSizeUpdate = -1; - private int mDisplayHeightAtLastSurfaceSizeUpdate = -1; - - private int mLastRequestedWidth = -1; - private int mLastRequestedHeight = -1; - private AsyncTask mLoader; - private boolean mNeedsDrawAfterLoadingWallpaper; - private boolean mSurfaceValid; - - private BroadcastReceiver mReceiver; - - public DrawableEngine() { - super(); - } - - public void trimMemory(int level) { - if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW - && mBackground != null) { - if (DEBUG) { - Log.d(TAG, "trimMemory"); - } - mBackground.recycle(); - mBackground = null; - mBackgroundWidth = -1; - mBackgroundHeight = -1; - } - } - - @Override - public void onCreate(SurfaceHolder surfaceHolder) { - if (DEBUG) { - Log.d(TAG, "onCreate"); - } - - super.onCreate(surfaceHolder); - - mIsOpenGlTextureLoaded = false; - - mDefaultDisplay = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay(); - - updateSurfaceSize(surfaceHolder, mDefaultDisplay, false /* forDraw */); - - // Enable offset notifications to pan wallpaper for parallax effect. - setOffsetNotificationsEnabled(true); - - // If not a preview, then register a local broadcast receiver for listening to changes in the - // rotating wallpaper file. - if (!isPreview()) { - IntentFilter filter = new IntentFilter(); - filter.addAction(getPackageName() + ACTION_ROTATING_WALLPAPER_CHANGED); - - mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (DEBUG) { - Log.i(TAG, "Broadcast received with intent: " + intent); - } - - String action = intent.getAction(); - if (action.equals(getPackageName() + ACTION_ROTATING_WALLPAPER_CHANGED)) { - DrawableEngine.this.invalidateAndRedrawWallpaper(); - } - } - }; - - registerReceiver(mReceiver, filter, getPackageName() - + PERMISSION_NOTIFY_ROTATING_WALLPAPER_CHANGED, null /* handler */); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - mBackground = null; - mWallpaperManager.forgetLoadedWallpaper(); - - if (!isPreview() && mReceiver != null) { - unregisterReceiver(mReceiver); - } - } - - boolean updateSurfaceSize(SurfaceHolder surfaceHolder, Display display, boolean forDraw) { - boolean hasWallpaper = true; - Point displaySize = ScreenSizeCalculator.getInstance().getScreenSize(display); - - // Load background image dimensions, if we haven't saved them yet - if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) { - // Need to load the image to get dimensions - loadWallpaper(forDraw); - if (DEBUG) { - Log.d(TAG, "Reloading, redoing updateSurfaceSize later."); - } - hasWallpaper = false; - } - - // Force the wallpaper to cover the screen in both dimensions - int surfaceWidth = Math.max(displaySize.x, mBackgroundWidth); - int surfaceHeight = Math.max(displaySize.y, mBackgroundHeight); - - if (FIXED_SIZED_SURFACE) { - // Used a fixed size surface, because we are special. We can do - // this because we know the current design of window animations doesn't - // cause this to break. - surfaceHolder.setFixedSize(surfaceWidth, surfaceHeight); - mLastRequestedWidth = surfaceWidth; - mLastRequestedHeight = surfaceHeight; - } else { - surfaceHolder.setSizeFromLayout(); - } - return hasWallpaper; - } - - @Override - public void onVisibilityChanged(boolean visible) { - if (DEBUG) { - Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible); - } - - if (mVisible != visible) { - if (DEBUG) { - Log.d(TAG, "Visibility changed to visible=" + visible); - } - mVisible = visible; - drawFrame(false /* forceRedraw */); - } - } - - @Override - public void onTouchEvent(MotionEvent event) { - super.onTouchEvent(event); - } - - @Override - public void onOffsetsChanged(float xOffset, float yOffset, - float xOffsetStep, float yOffsetStep, - int xPixels, int yPixels) { - if (DEBUG) { - Log.d(TAG, "onOffsetsChanged: xOffset=" + xOffset + ", yOffset=" + yOffset - + ", xOffsetStep=" + xOffsetStep + ", yOffsetStep=" + yOffsetStep - + ", xPixels=" + xPixels + ", yPixels=" + yPixels); - } - - if (mXOffset != xOffset || mYOffset != yOffset) { - if (DEBUG) { - Log.d(TAG, "Offsets changed to (" + xOffset + "," + yOffset + ")."); - } - mXOffset = xOffset; - mYOffset = yOffset; - mOffsetsChanged = true; - } - mHandler.post(new Runnable() { - @Override - public void run() { - drawFrame(false /* forceRedraw */); - } - }); - } - - @Override - public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { - if (DEBUG) { - Log.d(TAG, "onSurfaceChanged: width=" + width + ", height=" + height); - } - - super.onSurfaceChanged(holder, format, width, height); - - // Retrieve buffer in new size. - if (mEgl != null) { - mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); - } - drawFrame(false /* forceRedraw */); - } - - @Override - public void onSurfaceDestroyed(SurfaceHolder holder) { - super.onSurfaceDestroyed(holder); - if (DEBUG) { - Log.d(TAG, "onSurfaceDestroyed"); - } - mLastSurfaceWidth = mLastSurfaceHeight = -1; - mSurfaceValid = false; - - if (mIsHardwareAccelerated) { - finishGL(mTexture, mProgram); - } - } - - @Override - public void onSurfaceCreated(SurfaceHolder holder) { - super.onSurfaceCreated(holder); - if (DEBUG) { - Log.d(TAG, "onSurfaceCreated"); - } - mLastSurfaceWidth = mLastSurfaceHeight = -1; - mSurfaceValid = true; - - if (mIsHardwareAccelerated) { - if (!initGL(holder)) { - // Fall back to canvas drawing if initializing OpenGL failed. - mIsHardwareAccelerated = false; - mEgl = null; - } - } - } - - @Override - public void onSurfaceRedrawNeeded(SurfaceHolder holder) { - if (DEBUG) { - Log.d(TAG, "onSurfaceRedrawNeeded"); - } - super.onSurfaceRedrawNeeded(holder); - - drawFrame(true /* forceRedraw */); - } - - @RequiresApi(VERSION_CODES.O_MR1) - @Override - public WallpaperColors onComputeColors() { - // It's OK to return null here. - return mCachedWallpaperColors; - } - - /** - * Invalidates the currently-drawn wallpaper image, causing the engine to reload the image from - * disk and draw the new wallpaper image. - */ - public void invalidateAndRedrawWallpaper() { - // If a wallpaper load was already in flight, cancel it and restart a load in order to decode - // the new image. - if (mLoader != null) { - mLoader.cancel(true /* mayInterruptIfRunning */); - mLoader = null; - } - - loadWallpaper(true /* needsDraw */); - } - - void drawFrame(boolean forceRedraw) { - if (!mSurfaceValid) { - return; - } - - Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize(mDefaultDisplay); - int newRotation = mDefaultDisplay.getRotation(); - - // Sometimes a wallpaper is not large enough to cover the screen in one dimension. - // Call updateSurfaceSize -- it will only actually do the update if the dimensions - // should change - if (newRotation != mLastRotation) { - // Update surface size (if necessary) - if (!updateSurfaceSize(getSurfaceHolder(), mDefaultDisplay, true /* forDraw */)) { - return; - } - mRotationAtLastSurfaceSizeUpdate = newRotation; - mDisplayWidthAtLastSurfaceSizeUpdate = screenSize.x; - mDisplayHeightAtLastSurfaceSizeUpdate = screenSize.y; - } - SurfaceHolder sh = getSurfaceHolder(); - final Rect frame = sh.getSurfaceFrame(); - final int dw = frame.width(); - final int dh = frame.height(); - boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth - || dh != mLastSurfaceHeight; - - boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation - || forceRedraw; - if (!redrawNeeded && !mOffsetsChanged) { - if (DEBUG) { - Log.d(TAG, "Suppressed drawFrame since redraw is not needed " - + "and offsets have not changed."); - } - return; - } - mLastRotation = newRotation; - - // Load bitmap if its null and we're not using hardware acceleration. - if ((mIsHardwareAccelerated && !mIsOpenGlTextureLoaded) // Using OpenGL but texture not loaded - || (!mIsHardwareAccelerated && mBackground == null)) { // Draw with Canvas but no bitmap - if (DEBUG) { - Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " - + mBackground + ", " + ((mBackground == null) ? 0 : mBackground.getWidth()) + ", " - + ((mBackground == null) ? 0 : mBackground.getHeight()) + ", " + dw + ", " + dh); - } - loadWallpaper(true /* needDraw */); - if (DEBUG) { - Log.d(TAG, "Reloading, resuming draw later"); - } - return; - } - - // Center the scaled image - mScale = Math.max(1f, Math.max(dw / (float) mBackgroundWidth, - dh / (float) mBackgroundHeight)); - final int availw = dw - (int) (mBackgroundWidth * mScale); - final int availh = dh - (int) (mBackgroundHeight * mScale); - int xPixels = availw / 2; - int yPixels = availh / 2; - - // Adjust the image for xOffset/yOffset values. If window manager is handling offsets, - // mXOffset and mYOffset are set to 0.5f by default and therefore xPixels and yPixels - // will remain unchanged - final int availwUnscaled = dw - mBackgroundWidth; - final int availhUnscaled = dh - mBackgroundHeight; - if (availwUnscaled < 0) { - xPixels += (int) (availwUnscaled * (mXOffset - .5f) + .5f); - } - if (availhUnscaled < 0) { - yPixels += (int) (availhUnscaled * (mYOffset - .5f) + .5f); - } - - mOffsetsChanged = false; - if (surfaceDimensionsChanged) { - mLastSurfaceWidth = dw; - mLastSurfaceHeight = dh; - } - if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) { - if (DEBUG) { - Log.d(TAG, "Suppressed drawFrame since the image has not " - + "actually moved an integral number of pixels."); - } - return; - } - mLastXTranslation = xPixels; - mLastYTranslation = yPixels; - - if (DEBUG) { - Log.d(TAG, "Redrawing wallpaper"); - } - - if (mIsHardwareAccelerated) { - if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) { - drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); - } else { - // If OpenGL drawing was successful, then we can safely discard a reference to the - // wallpaper bitmap to save memory (since a copy has already been loaded into an OpenGL - // texture). - mBackground = null; - } - } else { - drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); - } - } - - /** - * Loads the wallpaper on background thread and schedules updating the surface frame, - * and if {@param needsDraw} is set also draws a frame. - *

- * If loading is already in-flight, subsequent loads are ignored (but needDraw is or-ed to - * the active request). - *

- * If {@param needsReset} is set also clears the cache in WallpaperManager first. - */ - private void loadWallpaper(boolean needsDraw) { - mNeedsDrawAfterLoadingWallpaper |= needsDraw; - if (mLoader != null) { - if (DEBUG) { - Log.d(TAG, "Skipping loadWallpaper, already in flight "); - } - return; - } - mLoader = new AsyncTask() { - @Override - protected Bitmap doInBackground(Void... params) { - Throwable exception = null; - try { - // Decode bitmap of rotating image wallpaper. - String wallpaperFilePath = isPreview() - ? PREVIEW_WALLPAPER_FILE_PATH : ROTATING_WALLPAPER_FILE_PATH; - Context context = isPreview() ? getApplicationContext() - : getApplicationContext().createDeviceProtectedStorageContext(); - FileInputStream fileInputStream = context.openFileInput(wallpaperFilePath); - Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream); - fileInputStream.close(); - return bitmap; - } catch (RuntimeException | FileNotFoundException | OutOfMemoryError e) { - Log.i(TAG, "couldn't decode stream: ", e); - exception = e; - } catch (IOException e) { - Log.i(TAG, "couldn't close stream: ", e); - exception = e; - } - - if (isCancelled()) { - return null; - } - - if (exception != null) { - // Note that if we do fail at this, and the default wallpaper can't - // be loaded, we will go into a cycle. Don't do a build where the - // default wallpaper can't be loaded. - Log.w(TAG, "Unable to load wallpaper!", exception); - try { - return ((BitmapDrawable) getFallbackDrawable()).getBitmap(); - } catch (OutOfMemoryError ex) { - // now we're really screwed. - Log.w(TAG, "Unable reset to default wallpaper!", ex); - } - - if (isCancelled()) { - return null; - } - } - return null; - } - - @Override - protected void onPostExecute(Bitmap b) { - mBackground = null; - mBackgroundWidth = -1; - mBackgroundHeight = -1; - - if (b != null) { - mBackground = b; - mBackgroundWidth = mBackground.getWidth(); - mBackgroundHeight = mBackground.getHeight(); - - if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) { - mCachedWallpaperColors = WallpaperColors.fromBitmap(mBackground); - notifyColorsChanged(); - } - } - - if (DEBUG) { - Log.d(TAG, "Wallpaper loaded: " + mBackground); - } - updateSurfaceSize(getSurfaceHolder(), mDefaultDisplay, - false /* forDraw */); - if (mTexture != 0 && mEgl != null) { - deleteTexture(mTexture); - } - // If background is absent (due to an error decoding the bitmap) then don't try to load - // a texture. - if (mEgl != null && mBackground != null) { - mTexture = loadTexture(mBackground); - } - if (mNeedsDrawAfterLoadingWallpaper) { - drawFrame(true /* forceRedraw */); - } - - mLoader = null; - mNeedsDrawAfterLoadingWallpaper = false; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - private Drawable getFallbackDrawable() { - Drawable drawable; - try { - drawable = mWallpaperManager.getDrawable(); - } catch (java.lang.Exception e) { - // Work around Samsung bug where SecurityException is thrown if device is still using its - // default wallpaper, and around Android 7.0 bug where SELinux issues can cause a perfectly - // valid access of the current wallpaper to cause a failed Binder transaction manifest here - // as a RuntimeException. - drawable = mWallpaperManager.getBuiltInDrawable(); - } - return drawable; - } - - @Override - protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) { - super.dump(prefix, fd, out, args); - - out.print(prefix); - out.println("ImageWallpaper.DrawableEngine:"); - out.print(prefix); - out.print(" mBackground="); - out.print(mBackground); - out.print(" mBackgroundWidth="); - out.print(mBackgroundWidth); - out.print(" mBackgroundHeight="); - out.println(mBackgroundHeight); - - out.print(prefix); - out.print(" mLastRotation="); - out.print(mLastRotation); - out.print(" mLastSurfaceWidth="); - out.print(mLastSurfaceWidth); - out.print(" mLastSurfaceHeight="); - out.println(mLastSurfaceHeight); - - out.print(prefix); - out.print(" mXOffset="); - out.print(mXOffset); - out.print(" mYOffset="); - out.println(mYOffset); - - out.print(prefix); - out.print(" mVisible="); - out.print(mVisible); - out.print(" mOffsetsChanged="); - out.println(mOffsetsChanged); - - out.print(prefix); - out.print(" mLastXTranslation="); - out.print(mLastXTranslation); - out.print(" mLastYTranslation="); - out.print(mLastYTranslation); - out.print(" mScale="); - out.println(mScale); - - out.print(prefix); - out.print(" mLastRequestedWidth="); - out.print(mLastRequestedWidth); - out.print(" mLastRequestedHeight="); - out.println(mLastRequestedHeight); - - out.print(prefix); - out.println(" DisplayInfo at last updateSurfaceSize:"); - out.print(prefix); - out.print(" rotation="); - out.print(mRotationAtLastSurfaceSizeUpdate); - out.print(" width="); - out.print(mDisplayWidthAtLastSurfaceSizeUpdate); - out.print(" height="); - out.println(mDisplayHeightAtLastSurfaceSizeUpdate); - } - - private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int left, int top) { - Canvas c = sh.lockCanvas(); - if (c != null) { - try { - if (DEBUG) { - Log.d(TAG, "Redrawing: left=" + left + ", top=" + top); - } - - final float right = left + mBackgroundWidth * mScale; - final float bottom = top + mBackgroundHeight * mScale; - if (w < 0 || h < 0) { - c.save(); - c.clipOutRect(left, top, right, bottom); - c.drawColor(0xff000000); - c.restore(); - } - if (mBackground != null) { - RectF dest = new RectF(left, top, right, bottom); - // add a filter bitmap? - c.drawBitmap(mBackground, null, dest, null); - } - } finally { - sh.unlockCanvasAndPost(c); - } - } - } - - private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) { - - mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - - final float right = left + mBackgroundWidth * mScale; - final float bottom = top + mBackgroundHeight * mScale; - - final Rect frame = sh.getSurfaceFrame(); - final Matrix4f ortho = new Matrix4f(); - ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f); - - final FloatBuffer triangleVertices = createMesh(left, top, right, bottom); - - final int attribPosition = GLES20.glGetAttribLocation(mProgram, "position"); - final int attribTexCoords = GLES20.glGetAttribLocation(mProgram, "texCoords"); - final int uniformTexture = GLES20.glGetUniformLocation(mProgram, "texture"); - final int uniformProjection = GLES20.glGetUniformLocation(mProgram, "projection"); - - checkGlError(); - - GLES20.glViewport(0, 0, frame.width(), frame.height()); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture); - - GLES20.glUseProgram(mProgram); - GLES20.glEnableVertexAttribArray(attribPosition); - GLES20.glEnableVertexAttribArray(attribTexCoords); - GLES20.glUniform1i(uniformTexture, 0); - GLES20.glUniformMatrix4fv(uniformProjection, 1, false, ortho.getArray(), 0); - - checkGlError(); - - if (w > 0 || h > 0) { - GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); - } - - // drawQuad - triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); - GLES20.glVertexAttribPointer(attribPosition, 3, GLES20.GL_FLOAT, false, - TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); - - triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); - GLES20.glVertexAttribPointer(attribTexCoords, 3, GLES20.GL_FLOAT, false, - TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - boolean status = mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); - checkEglError(); - - return status; - } - - private FloatBuffer createMesh(int left, int top, float right, float bottom) { - final float[] verticesData = { - // X, Y, Z, U, V - left, bottom, 0.0f, 0.0f, 1.0f, - right, bottom, 0.0f, 1.0f, 1.0f, - left, top, 0.0f, 0.0f, 0.0f, - right, top, 0.0f, 1.0f, 0.0f, - }; - - final int bytes = verticesData.length * FLOAT_SIZE_BYTES; - final FloatBuffer triangleVertices = ByteBuffer.allocateDirect(bytes).order( - ByteOrder.nativeOrder()).asFloatBuffer(); - triangleVertices.put(verticesData).position(0); - return triangleVertices; - } - - private int loadTexture(Bitmap bitmap) { - mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - - int[] textures = new int[1]; - - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glGenTextures(1, textures, 0); - checkGlError(); - - int texture = textures[0]; - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture); - checkGlError(); - - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); - - GLES20.glTexParameteri( - GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); - GLES20.glTexParameteri( - GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); - - GLUtils.texImage2D( - GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap, GLES20.GL_UNSIGNED_BYTE, 0); - checkGlError(); - - mIsOpenGlTextureLoaded = true; - - return texture; - } - - private int buildProgram(String vertex, String fragment) { - int vertexShader = buildShader(vertex, GLES20.GL_VERTEX_SHADER); - if (vertexShader == 0) { - return 0; - } - - int fragmentShader = buildShader(fragment, GLES20.GL_FRAGMENT_SHADER); - if (fragmentShader == 0) { - return 0; - } - - int program = GLES20.glCreateProgram(); - GLES20.glAttachShader(program, vertexShader); - GLES20.glAttachShader(program, fragmentShader); - GLES20.glLinkProgram(program); - checkGlError(); - - GLES20.glDeleteShader(vertexShader); - GLES20.glDeleteShader(fragmentShader); - - int[] status = new int[1]; - GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0); - if (status[0] != GLES20.GL_TRUE) { - String error = GLES20.glGetProgramInfoLog(program); - Log.d(GL_LOG_TAG, "Error while linking program:\n" + error); - GLES20.glDeleteProgram(program); - return 0; - } - - return program; - } - - private int buildShader(String source, int type) { - int shader = GLES20.glCreateShader(type); - - GLES20.glShaderSource(shader, source); - checkGlError(); - - GLES20.glCompileShader(shader); - checkGlError(); - - int[] status = new int[1]; - GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, status, 0); - if (status[0] != GLES20.GL_TRUE) { - String error = GLES20.glGetShaderInfoLog(shader); - Log.d(GL_LOG_TAG, "Error while compiling shader:\n" + error); - GLES20.glDeleteShader(shader); - return 0; - } - - return shader; - } - - private void checkEglError() { - int error = mEgl.eglGetError(); - if (error != EGL10.EGL_SUCCESS) { - Log.w(GL_LOG_TAG, "EGL error = " + GLUtils.getEGLErrorString(error)); - } - } - - private void checkGlError() { - int error = GLES20.glGetError(); - if (error != GLES20.GL_NO_ERROR) { - Log.w(GL_LOG_TAG, "GL error = 0x" + Integer.toHexString(error), new Throwable()); - } - } - - private void deleteTexture(int texture) { - int[] textures = new int[1]; - textures[0] = texture; - - mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - GLES20.glDeleteTextures(1, textures, 0); - mTexture = 0; - } - - private void finishGL(int texture, int program) { - if (mEgl == null) { - return; - } - - mOpenGlContextCounter--; - - mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - deleteTexture(mTexture); - GLES20.glDeleteProgram(program); - mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - mEgl.eglDestroySurface(mEglDisplay, mEglSurface); - mEgl.eglDestroyContext(mEglDisplay, mEglContext); - if (mOpenGlContextCounter == 0) { - mEgl.eglTerminate(mEglDisplay); - } - - mEgl = null; - } - - private boolean initGL(SurfaceHolder surfaceHolder) { - mEgl = (EGL10) EGLContext.getEGL(); - - mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { - throw new RuntimeException("eglGetDisplay failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } - - int[] version = new int[2]; - if (!mEgl.eglInitialize(mEglDisplay, version)) { - throw new RuntimeException("eglInitialize failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } - - mOpenGlContextCounter++; - - mEglConfig = chooseEglConfig(); - if (mEglConfig == null) { - throw new RuntimeException("eglConfig not initialized"); - } - - mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); - if (mEglContext == EGL_NO_CONTEXT) { - throw new RuntimeException("createContext failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } - - int attribs[] = { - EGL10.EGL_WIDTH, 1, - EGL10.EGL_HEIGHT, 1, - EGL10.EGL_NONE - }; - EGLSurface tmpSurface = mEgl.eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs); - mEgl.eglMakeCurrent(mEglDisplay, tmpSurface, tmpSurface, mEglContext); - - int[] maxSize = new int[1]; - Rect frame = surfaceHolder.getSurfaceFrame(); - GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxSize, 0); - - mEgl.eglMakeCurrent( - mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - mEgl.eglDestroySurface(mEglDisplay, tmpSurface); - - if (frame.width() > maxSize[0] || frame.height() > maxSize[0]) { - mEgl.eglDestroyContext(mEglDisplay, mEglContext); - mEgl.eglTerminate(mEglDisplay); - Log.e(GL_LOG_TAG, "requested texture size " + frame.width() + "x" + frame.height() - + " exceeds the support maximum of " + maxSize[0] + "x" + maxSize[0]); - return false; - } - - mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null); - if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) { - int error = mEgl.eglGetError(); - if (error == EGL10.EGL_BAD_NATIVE_WINDOW || error == EGL10.EGL_BAD_ALLOC) { - Log.e(GL_LOG_TAG, "createWindowSurface returned " + GLUtils.getEGLErrorString(error) - + "."); - return false; - } - throw new RuntimeException("createWindowSurface failed " - + GLUtils.getEGLErrorString(error)); - } - - if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { - throw new RuntimeException("eglMakeCurrent failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } - - mProgram = buildProgram(S_SIMPLE_VS, S_SIMPLE_FS); - if (mBackground != null) { - mTexture = loadTexture(mBackground); - } - - return true; - } - - - EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { - int[] attribList = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE}; - return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList); - } - - private EGLConfig chooseEglConfig() { - int[] configsCount = new int[1]; - EGLConfig[] configs = new EGLConfig[1]; - int[] configSpec = getConfig(); - if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) { - throw new IllegalArgumentException("eglChooseConfig failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } else if (configsCount[0] > 0) { - return configs[0]; - } - return null; - } - - private int[] getConfig() { - return new int[]{ - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL10.EGL_RED_SIZE, 8, - EGL10.EGL_GREEN_SIZE, 8, - EGL10.EGL_BLUE_SIZE, 8, - EGL10.EGL_ALPHA_SIZE, 0, - EGL10.EGL_DEPTH_SIZE, 0, - EGL10.EGL_STENCIL_SIZE, 0, - EGL10.EGL_CONFIG_CAVEAT, EGL10.EGL_NONE, - EGL10.EGL_NONE - }; - } - } -} diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerActivity.java b/src/com/android/wallpaper/picker/individual/IndividualPickerActivity.java index 367181a..f2b31d4 100755 --- a/src/com/android/wallpaper/picker/individual/IndividualPickerActivity.java +++ b/src/com/android/wallpaper/picker/individual/IndividualPickerActivity.java @@ -16,8 +16,6 @@ package com.android.wallpaper.picker.individual; import android.app.Activity; -import android.app.WallpaperManager; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Resources.NotFoundException; @@ -44,12 +42,9 @@ import com.android.wallpaper.model.PickerIntentFactory; import com.android.wallpaper.model.WallpaperInfo; import com.android.wallpaper.module.Injector; import com.android.wallpaper.module.InjectorProvider; -import com.android.wallpaper.module.LiveWallpaperStatusChecker; -import com.android.wallpaper.module.NoBackupImageWallpaper; import com.android.wallpaper.module.WallpaperPersister; import com.android.wallpaper.picker.BaseActivity; import com.android.wallpaper.picker.PreviewActivity.PreviewActivityIntentFactory; -import com.android.wallpaper.util.ActivityUtils; import com.android.wallpaper.util.DiskBasedLogger; /** @@ -61,13 +56,11 @@ public class IndividualPickerActivity extends BaseActivity { private static final String EXTRA_CATEGORY_COLLECTION_ID = "com.android.wallpaper.category_collection_id"; private static final int PREVIEW_WALLPAPER_REQUEST_CODE = 0; - private static final int NO_BACKUP_IMAGE_WALLPAPER_REQUEST_CODE = 1; private static final int PREVIEW_LIVEWALLPAPER_REQUEST_CODE = 2; private static final String KEY_CATEGORY_COLLECTION_ID = "key_category_collection_id"; private InlinePreviewIntentFactory mPreviewIntentFactory; private WallpaperPersister mWallpaperPersister; - private LiveWallpaperStatusChecker mLiveWallpaperStatusChecker; private Category mCategory; private String mCategoryCollectionId; @@ -83,7 +76,6 @@ public class IndividualPickerActivity extends BaseActivity { mPreviewIntentFactory = new PreviewActivityIntentFactory(); Injector injector = InjectorProvider.getInjector(); mWallpaperPersister = injector.getWallpaperPersister(this); - mLiveWallpaperStatusChecker = injector.getLiveWallpaperStatusChecker(this); FragmentManager fm = getSupportFragmentManager(); Fragment fragment = fm.findFragmentById(R.id.fragment_container); @@ -184,18 +176,6 @@ public class IndividualPickerActivity extends BaseActivity { finishWithResultOk(shouldShowMessage); } break; - - case NO_BACKUP_IMAGE_WALLPAPER_REQUEST_CODE: - // User clicked "Set wallpaper" in live wallpaper preview UI. - // NOTE: Don't check for the result code prior to KitKat MR2 because a bug on those versions - // caused the result code to be discarded from LivePicker so we can't rely on it. - if ((!BuildCompat.isAtLeastL() || resultCode == Activity.RESULT_OK) - && mLiveWallpaperStatusChecker.isNoBackupImageWallpaperSet() - && mCategory.getWallpaperRotationInitializer().startRotation(getApplicationContext())) { - finishWithResultOk(true); - } - break; - default: Log.e(TAG, "Invalid request code: " + requestCode); } @@ -211,18 +191,6 @@ public class IndividualPickerActivity extends BaseActivity { : PREVIEW_WALLPAPER_REQUEST_CODE); } - /** - * Shows the system live wallpaper preview for the {@link NoBackupImageWallpaper} which is used to - * draw rotating wallpapers on pre-N Android builds. - */ - public void showNoBackupImageWallpaperPreview() { - Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); - ComponentName componentName = new ComponentName(this, NoBackupImageWallpaper.class); - intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, componentName); - ActivityUtils.startActivityForResultSafely( - this, intent, NO_BACKUP_IMAGE_WALLPAPER_REQUEST_CODE); - } - private void finishWithResultOk(boolean shouldShowMessage) { if (shouldShowMessage) { try { -- cgit v1.2.3 From f5ea92dc867ade4d83eba2d83c6a461bffc86a6b Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 11 Oct 2019 08:31:54 -0700 Subject: Import translations. DO NOT MERGE Change-Id: I7de50da703850fd9c497c18cb104395ff16a93bc Auto-generated-cl: translation import --- res/values-ar/strings.xml | 4 +-- res/values-en-rCA/strings.xml | 83 +++++++++++++++++++++++++++++++++++++++++++ res/values-en-rXC/strings.xml | 83 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 res/values-en-rCA/strings.xml create mode 100644 res/values-en-rXC/strings.xml diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 2a6c183..b35d76f 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -30,11 +30,11 @@ "خلفية يومية" "الشاشة الرئيسية وشاشة التأمين" "الشاشة الرئيسية" - "شاشة التأمين" + "شاشة القفل" "الشاشة الرئيسية وشاشة التأمين" "تعيين كخلفية" "الشاشة الرئيسية" - "شاشة التأمين" + "شاشة القفل" "الشاشة الرئيسية وشاشة التأمين" "خلفية الصور التي يتم عرضها بالتناوب" "لعرض الخلفية الحالية هنا، يحتاج تطبيق %1$s إلى الوصول إلى مساحة تخزين الجهاز." diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml new file mode 100644 index 0000000..158ce10 --- /dev/null +++ b/res/values-en-rCA/strings.xml @@ -0,0 +1,83 @@ + + + + + "Wallpapers" + + + "Wallpaper categories" + "Set Wallpaper" + "Setting wallpaper…" + "Try again" + "Unable to set wallpaper." + "Unable to load wallpaper. The image is either corrupted or unavailable." + "Currently set" + "Daily wallpaper" + "Home & Lock screen" + "Home screen" + "Lock screen" + "Home & Lock" + "Set wallpaper" + "Home screen" + "Lock screen" + "Home screen and lock screen" + "Rotating Image Wallpaper" + "To display the current wallpaper here, %1$s needs access to your device\'s storage." + "To display the current wallpaper here, Wallpapers needs access to your device’s storage.\n\nTo change this setting, go to the Permissions area of the Wallpapers’ app info." + "Allow access" + "Live wallpaper service for rotating wallpapers" + "Daily wallpaper" + "Tap to turn on" + "Wallpaper will change automatically every day. To finish setup, tap <strong>Set wallpaper</strong> on the next screen." + "Download future wallpapers on Wi-Fi only" + "Continue" + "Downloading first wallpaper…" + "Unable to download first wallpaper. Please check your network settings and try again." + "Wallpaper will change automatically every day" + "Settings" + "Explore" + "Next wallpaper" + "Setting a wallpaper is disabled on this device" + "Setting a wallpaper is disabled by your device administrator" + "Wallpaper set successfully" + "You need an Internet connection to view wallpapers. Please connect and try again." + "Currently set home screen wallpaper thumbnail" + "Currently set lock screen wallpaper thumbnail" + "Currently set wallpaper thumbnail" + "Wallpaper thumbnail" + "Explore home screen wallpaper" + "Explore lock screen wallpaper" + "Refresh daily home screen wallpaper" + "Refresh daily wallpaper" + "Refreshing daily wallpaper…" + "Failed to refresh daily wallpaper. Please check your network connection and try again." + "Collapse wallpaper info panel" + "Expand wallpaper info panel" + "On-device wallpapers" + "On device" + "Android wallpaper" + "Live wallpapers" + "My photos" + "My photo" + "Wallpaper" + "App isn\'t installed." + "Centre" + "Centre crop" + "Stretch" + "Preview" + diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml new file mode 100644 index 0000000..b06a217 --- /dev/null +++ b/res/values-en-rXC/strings.xml @@ -0,0 +1,83 @@ + + + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎Wallpapers‎‏‎‎‏‎" + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎Wallpaper categories‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎Set Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‏‎Setting wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‎Try again‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎Unable to set wallpaper.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎Unable to load wallpaper. The image is either corrupted or unavailable.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‎‎Currently set‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎Daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎Home & Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎Home screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎Home & Lock‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‎Set wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎Home screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎Home screen and lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎Rotating Image Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎To display the current wallpaper here, ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ needs access to your device\'s storage.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‎To display the current wallpaper here, Wallpapers needs access to your device’s storage.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎To change this setting, go to the Permissions area of Wallpapers’ app info.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎Allow access‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎Live wallpaper service for rotating wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎Daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎Tap to turn on‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎Wallpaper will change automatically every day. To finish setup, tap <strong>Set wallpaper</strong> on the next screen.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎Download future wallpapers on Wi-Fi only‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎Continue‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎Downloading first wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎Unable to download first wallpaper. Please check your network settings and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎Wallpaper will change automatically every day‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎Settings‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎Explore‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎Next wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎Setting a wallpaper is disabled on this device‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‎Setting a wallpaper is disabled by your device administrator‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎Wallpaper set successfully‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎You need an Internet connection to view wallpapers. Please connect and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎Currently set home screen wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎Currently set lock screen wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎Currently set wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎Wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎Explore home screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‏‎Explore lock screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎Refresh daily home screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎Refresh daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎Refreshing daily wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎Failed to refresh daily wallpaper. Please check your network connection and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‎Collapse wallpaper info panel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎Expand wallpaper info panel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎On-device wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎On device‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎Android wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎Live wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎My photos‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎My photo‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎App isn\'t installed.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎Center‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎Center crop‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‎Stretch‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎Preview‎‏‎‎‏‎" + -- cgit v1.2.3 From 564c9628390066b39e5d8abbb7f70368e7ceb80b Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 11 Oct 2019 08:32:25 -0700 Subject: Import translations. DO NOT MERGE Change-Id: Id1cb58bdd9c0828e60a68351350691472fed7ae4 Auto-generated-cl: translation import --- res/values-ar/strings.xml | 4 +-- res/values-en-rCA/strings.xml | 83 +++++++++++++++++++++++++++++++++++++++++++ res/values-en-rXC/strings.xml | 83 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 res/values-en-rCA/strings.xml create mode 100644 res/values-en-rXC/strings.xml diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 2a6c183..b35d76f 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -30,11 +30,11 @@ "خلفية يومية" "الشاشة الرئيسية وشاشة التأمين" "الشاشة الرئيسية" - "شاشة التأمين" + "شاشة القفل" "الشاشة الرئيسية وشاشة التأمين" "تعيين كخلفية" "الشاشة الرئيسية" - "شاشة التأمين" + "شاشة القفل" "الشاشة الرئيسية وشاشة التأمين" "خلفية الصور التي يتم عرضها بالتناوب" "لعرض الخلفية الحالية هنا، يحتاج تطبيق %1$s إلى الوصول إلى مساحة تخزين الجهاز." diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml new file mode 100644 index 0000000..158ce10 --- /dev/null +++ b/res/values-en-rCA/strings.xml @@ -0,0 +1,83 @@ + + + + + "Wallpapers" + + + "Wallpaper categories" + "Set Wallpaper" + "Setting wallpaper…" + "Try again" + "Unable to set wallpaper." + "Unable to load wallpaper. The image is either corrupted or unavailable." + "Currently set" + "Daily wallpaper" + "Home & Lock screen" + "Home screen" + "Lock screen" + "Home & Lock" + "Set wallpaper" + "Home screen" + "Lock screen" + "Home screen and lock screen" + "Rotating Image Wallpaper" + "To display the current wallpaper here, %1$s needs access to your device\'s storage." + "To display the current wallpaper here, Wallpapers needs access to your device’s storage.\n\nTo change this setting, go to the Permissions area of the Wallpapers’ app info." + "Allow access" + "Live wallpaper service for rotating wallpapers" + "Daily wallpaper" + "Tap to turn on" + "Wallpaper will change automatically every day. To finish setup, tap <strong>Set wallpaper</strong> on the next screen." + "Download future wallpapers on Wi-Fi only" + "Continue" + "Downloading first wallpaper…" + "Unable to download first wallpaper. Please check your network settings and try again." + "Wallpaper will change automatically every day" + "Settings" + "Explore" + "Next wallpaper" + "Setting a wallpaper is disabled on this device" + "Setting a wallpaper is disabled by your device administrator" + "Wallpaper set successfully" + "You need an Internet connection to view wallpapers. Please connect and try again." + "Currently set home screen wallpaper thumbnail" + "Currently set lock screen wallpaper thumbnail" + "Currently set wallpaper thumbnail" + "Wallpaper thumbnail" + "Explore home screen wallpaper" + "Explore lock screen wallpaper" + "Refresh daily home screen wallpaper" + "Refresh daily wallpaper" + "Refreshing daily wallpaper…" + "Failed to refresh daily wallpaper. Please check your network connection and try again." + "Collapse wallpaper info panel" + "Expand wallpaper info panel" + "On-device wallpapers" + "On device" + "Android wallpaper" + "Live wallpapers" + "My photos" + "My photo" + "Wallpaper" + "App isn\'t installed." + "Centre" + "Centre crop" + "Stretch" + "Preview" + diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml new file mode 100644 index 0000000..b06a217 --- /dev/null +++ b/res/values-en-rXC/strings.xml @@ -0,0 +1,83 @@ + + + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎Wallpapers‎‏‎‎‏‎" + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎Wallpaper categories‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎Set Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‏‎Setting wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‎Try again‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎Unable to set wallpaper.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎Unable to load wallpaper. The image is either corrupted or unavailable.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‎‎Currently set‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎Daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎Home & Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎Home screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎Home & Lock‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‎Set wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎Home screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎Home screen and lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎Rotating Image Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎To display the current wallpaper here, ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ needs access to your device\'s storage.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‎To display the current wallpaper here, Wallpapers needs access to your device’s storage.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎To change this setting, go to the Permissions area of Wallpapers’ app info.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎Allow access‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎Live wallpaper service for rotating wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎Daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎Tap to turn on‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎Wallpaper will change automatically every day. To finish setup, tap <strong>Set wallpaper</strong> on the next screen.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎Download future wallpapers on Wi-Fi only‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎Continue‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎Downloading first wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎Unable to download first wallpaper. Please check your network settings and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎Wallpaper will change automatically every day‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎Settings‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎Explore‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎Next wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎Setting a wallpaper is disabled on this device‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‎Setting a wallpaper is disabled by your device administrator‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎Wallpaper set successfully‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎You need an Internet connection to view wallpapers. Please connect and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎Currently set home screen wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎Currently set lock screen wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎Currently set wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎Wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎Explore home screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‏‎Explore lock screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎Refresh daily home screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎Refresh daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎Refreshing daily wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎Failed to refresh daily wallpaper. Please check your network connection and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‎Collapse wallpaper info panel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎Expand wallpaper info panel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎On-device wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎On device‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎Android wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎Live wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎My photos‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎My photo‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎App isn\'t installed.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎Center‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎Center crop‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‎Stretch‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎Preview‎‏‎‎‏‎" + -- cgit v1.2.3 From 6a768aa3ee1c521550f6262a29c46caaf60bce68 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 11 Oct 2019 08:32:50 -0700 Subject: Import translations. DO NOT MERGE Change-Id: Ia844d33e39ffdebdc2e976c61d1e2bdf1f113268 Auto-generated-cl: translation import --- res/values-ar/strings.xml | 4 +-- res/values-en-rCA/strings.xml | 83 +++++++++++++++++++++++++++++++++++++++++++ res/values-en-rXC/strings.xml | 83 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 res/values-en-rCA/strings.xml create mode 100644 res/values-en-rXC/strings.xml diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 2a6c183..b35d76f 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -30,11 +30,11 @@ "خلفية يومية" "الشاشة الرئيسية وشاشة التأمين" "الشاشة الرئيسية" - "شاشة التأمين" + "شاشة القفل" "الشاشة الرئيسية وشاشة التأمين" "تعيين كخلفية" "الشاشة الرئيسية" - "شاشة التأمين" + "شاشة القفل" "الشاشة الرئيسية وشاشة التأمين" "خلفية الصور التي يتم عرضها بالتناوب" "لعرض الخلفية الحالية هنا، يحتاج تطبيق %1$s إلى الوصول إلى مساحة تخزين الجهاز." diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml new file mode 100644 index 0000000..158ce10 --- /dev/null +++ b/res/values-en-rCA/strings.xml @@ -0,0 +1,83 @@ + + + + + "Wallpapers" + + + "Wallpaper categories" + "Set Wallpaper" + "Setting wallpaper…" + "Try again" + "Unable to set wallpaper." + "Unable to load wallpaper. The image is either corrupted or unavailable." + "Currently set" + "Daily wallpaper" + "Home & Lock screen" + "Home screen" + "Lock screen" + "Home & Lock" + "Set wallpaper" + "Home screen" + "Lock screen" + "Home screen and lock screen" + "Rotating Image Wallpaper" + "To display the current wallpaper here, %1$s needs access to your device\'s storage." + "To display the current wallpaper here, Wallpapers needs access to your device’s storage.\n\nTo change this setting, go to the Permissions area of the Wallpapers’ app info." + "Allow access" + "Live wallpaper service for rotating wallpapers" + "Daily wallpaper" + "Tap to turn on" + "Wallpaper will change automatically every day. To finish setup, tap <strong>Set wallpaper</strong> on the next screen." + "Download future wallpapers on Wi-Fi only" + "Continue" + "Downloading first wallpaper…" + "Unable to download first wallpaper. Please check your network settings and try again." + "Wallpaper will change automatically every day" + "Settings" + "Explore" + "Next wallpaper" + "Setting a wallpaper is disabled on this device" + "Setting a wallpaper is disabled by your device administrator" + "Wallpaper set successfully" + "You need an Internet connection to view wallpapers. Please connect and try again." + "Currently set home screen wallpaper thumbnail" + "Currently set lock screen wallpaper thumbnail" + "Currently set wallpaper thumbnail" + "Wallpaper thumbnail" + "Explore home screen wallpaper" + "Explore lock screen wallpaper" + "Refresh daily home screen wallpaper" + "Refresh daily wallpaper" + "Refreshing daily wallpaper…" + "Failed to refresh daily wallpaper. Please check your network connection and try again." + "Collapse wallpaper info panel" + "Expand wallpaper info panel" + "On-device wallpapers" + "On device" + "Android wallpaper" + "Live wallpapers" + "My photos" + "My photo" + "Wallpaper" + "App isn\'t installed." + "Centre" + "Centre crop" + "Stretch" + "Preview" + diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml new file mode 100644 index 0000000..b06a217 --- /dev/null +++ b/res/values-en-rXC/strings.xml @@ -0,0 +1,83 @@ + + + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎Wallpapers‎‏‎‎‏‎" + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎Wallpaper categories‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎Set Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‏‎Setting wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‎Try again‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎Unable to set wallpaper.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎Unable to load wallpaper. The image is either corrupted or unavailable.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‎‎Currently set‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎Daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎Home & Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎Home screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎Home & Lock‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‎Set wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎Home screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎Lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎Home screen and lock screen‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎Rotating Image Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎To display the current wallpaper here, ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ needs access to your device\'s storage.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‎To display the current wallpaper here, Wallpapers needs access to your device’s storage.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎To change this setting, go to the Permissions area of Wallpapers’ app info.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎Allow access‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎Live wallpaper service for rotating wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎Daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎Tap to turn on‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎Wallpaper will change automatically every day. To finish setup, tap <strong>Set wallpaper</strong> on the next screen.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎Download future wallpapers on Wi-Fi only‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎Continue‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎Downloading first wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎Unable to download first wallpaper. Please check your network settings and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎Wallpaper will change automatically every day‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎Settings‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎Explore‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎Next wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎Setting a wallpaper is disabled on this device‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‎Setting a wallpaper is disabled by your device administrator‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎Wallpaper set successfully‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎You need an Internet connection to view wallpapers. Please connect and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎Currently set home screen wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎Currently set lock screen wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎Currently set wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎Wallpaper thumbnail‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎Explore home screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‏‎Explore lock screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎Refresh daily home screen wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎Refresh daily wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎Refreshing daily wallpaper…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎Failed to refresh daily wallpaper. Please check your network connection and try again.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‎Collapse wallpaper info panel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎Expand wallpaper info panel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎On-device wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎On device‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎Android wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎Live wallpapers‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎My photos‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎My photo‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎Wallpaper‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎App isn\'t installed.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎Center‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎Center crop‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‎Stretch‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎Preview‎‏‎‎‏‎" + -- cgit v1.2.3 From 8cad0dda590d675e0e84f34582e80b7b91f8364c Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Thu, 17 Oct 2019 10:52:39 -0700 Subject: Set up test infrastructure for WallpaperPicker2 Add instrumented and robolectric tests support. Bug: 141954442 Change-Id: Id9331b5962819d126f29d4854b7b7d87bf5e79ea --- Android.mk | 4 +- .../individual/IndividualPickerActivity.java | 4 +- .../individual/IndividualPickerFragment.java | 53 +-- tests/Android.mk | 59 +++ tests/AndroidManifest.xml | 33 ++ .../individual/IndividualPickerActivityTest.java | 496 +++++++++++++++++++++ .../wallpaper/testing/TestAlarmManagerWrapper.java | 71 +++ .../com/android/wallpaper/testing/TestAsset.java | 99 ++++ .../wallpaper/testing/TestBitmapCropper.java | 58 +++ .../wallpaper/testing/TestCategoryProvider.java | 94 ++++ .../testing/TestCurrentWallpaperInfoFactory.java | 70 +++ .../testing/TestExploreIntentChecker.java | 44 ++ .../wallpaper/testing/TestFormFactorChecker.java | 41 ++ .../android/wallpaper/testing/TestInjector.java | 244 ++++++++++ .../testing/TestLoggingOptInStatusProvider.java | 27 ++ .../testing/TestNetworkStatusNotifier.java | 61 +++ .../wallpaper/testing/TestPartnerProvider.java | 58 +++ .../wallpaper/testing/TestPerformanceMonitor.java | 28 ++ .../testing/TestSystemFeatureChecker.java | 41 ++ .../wallpaper/testing/TestUserEventLogger.java | 289 ++++++++++++ .../wallpaper/testing/TestWallpaperCategory.java | 59 +++ .../wallpaper/testing/TestWallpaperInfo.java | 228 ++++++++++ .../testing/TestWallpaperManagerCompat.java | 135 ++++++ .../wallpaper/testing/TestWallpaperPersister.java | 226 ++++++++++ .../testing/TestWallpaperPreferences.java | 457 +++++++++++++++++++ .../wallpaper/testing/TestWallpaperRefresher.java | 81 ++++ .../testing/TestWallpaperRotationInitializer.java | 133 ++++++ 27 files changed, 3160 insertions(+), 33 deletions(-) create mode 100644 tests/Android.mk create mode 100644 tests/AndroidManifest.xml create mode 100644 tests/src/com/android/wallpaper/picker/individual/IndividualPickerActivityTest.java create mode 100644 tests/src/com/android/wallpaper/testing/TestAlarmManagerWrapper.java create mode 100644 tests/src/com/android/wallpaper/testing/TestAsset.java create mode 100644 tests/src/com/android/wallpaper/testing/TestBitmapCropper.java create mode 100644 tests/src/com/android/wallpaper/testing/TestCategoryProvider.java create mode 100644 tests/src/com/android/wallpaper/testing/TestCurrentWallpaperInfoFactory.java create mode 100644 tests/src/com/android/wallpaper/testing/TestExploreIntentChecker.java create mode 100644 tests/src/com/android/wallpaper/testing/TestFormFactorChecker.java create mode 100644 tests/src/com/android/wallpaper/testing/TestInjector.java create mode 100644 tests/src/com/android/wallpaper/testing/TestLoggingOptInStatusProvider.java create mode 100644 tests/src/com/android/wallpaper/testing/TestNetworkStatusNotifier.java create mode 100644 tests/src/com/android/wallpaper/testing/TestPartnerProvider.java create mode 100644 tests/src/com/android/wallpaper/testing/TestPerformanceMonitor.java create mode 100644 tests/src/com/android/wallpaper/testing/TestSystemFeatureChecker.java create mode 100644 tests/src/com/android/wallpaper/testing/TestUserEventLogger.java create mode 100644 tests/src/com/android/wallpaper/testing/TestWallpaperCategory.java create mode 100644 tests/src/com/android/wallpaper/testing/TestWallpaperInfo.java create mode 100644 tests/src/com/android/wallpaper/testing/TestWallpaperManagerCompat.java create mode 100644 tests/src/com/android/wallpaper/testing/TestWallpaperPersister.java create mode 100644 tests/src/com/android/wallpaper/testing/TestWallpaperPreferences.java create mode 100644 tests/src/com/android/wallpaper/testing/TestWallpaperRefresher.java create mode 100644 tests/src/com/android/wallpaper/testing/TestWallpaperRotationInitializer.java diff --git a/Android.mk b/Android.mk index fec9941..369f739 100755 --- a/Android.mk +++ b/Android.mk @@ -53,7 +53,7 @@ LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../../../external/subsampling-scale-image-vi LOCAL_PROGUARD_ENABLED := disabled LOCAL_SDK_VERSION := current -LOCAL_MIN_SDK_VERSION := 21 +LOCAL_MIN_SDK_VERSION := 26 LOCAL_MODULE := wallpaper-subsampling-scale-image-view LOCAL_MANIFEST_FILE := ../../../external/subsampling-scale-image-view/library/src/main/AndroidManifest.xml @@ -118,3 +118,5 @@ LOCAL_PACKAGE_NAME := WallpaperPicker2 LOCAL_JETIFIER_ENABLED := true include $(BUILD_PACKAGE) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerActivity.java b/src/com/android/wallpaper/picker/individual/IndividualPickerActivity.java index f2b31d4..de5ba84 100755 --- a/src/com/android/wallpaper/picker/individual/IndividualPickerActivity.java +++ b/src/com/android/wallpaper/picker/individual/IndividualPickerActivity.java @@ -152,8 +152,8 @@ public class IndividualPickerActivity extends BaseActivity { public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { - // Handle Up as a Global back since the only entry point to IndividualPickerActivity is from - // TopLevelPickerActivity. + // Handle Up as a Global back since the only entry point to IndividualPickerActivity is + // from TopLevelPickerActivity. onBackPressed(); return true; } diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java index 401634d..c0c4ce5 100755 --- a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java +++ b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java @@ -58,7 +58,6 @@ import com.android.wallpaper.model.WallpaperRotationInitializer; import com.android.wallpaper.model.WallpaperRotationInitializer.Listener; import com.android.wallpaper.model.WallpaperRotationInitializer.NetworkPreference; import com.android.wallpaper.model.WallpaperRotationInitializer.RotationInitializationState; -import com.android.wallpaper.model.WallpaperRotationInitializer.RotationStateListener; import com.android.wallpaper.module.FormFactorChecker; import com.android.wallpaper.module.FormFactorChecker.FormFactor; import com.android.wallpaper.module.Injector; @@ -441,7 +440,8 @@ public class IndividualPickerFragment extends Fragment public void onResume() { super.onResume(); - WallpaperPreferences preferences = InjectorProvider.getInjector().getPreferences(getActivity()); + WallpaperPreferences preferences = InjectorProvider.getInjector() + .getPreferences(getActivity()); preferences.setLastAppActiveTimestamp(new Date().getTime()); // Reset Glide memory settings to a "normal" level of usage since it may have been lowered in @@ -537,31 +537,23 @@ public class IndividualPickerFragment extends Fragment * state of the user's device and binds the state of the current category's rotation to the "start * rotation" tile. */ - private void refreshRotationHolder(final RotationHolder rotationHolder) { + private void refreshRotationHolder(RotationHolder rotationHolder) { mWallpaperRotationInitializer.fetchRotationInitializationState(getContext(), - new RotationStateListener() { - @Override - public void onRotationStateReceived( - @RotationInitializationState final int rotationInitializationState) { - - // Update the UI state of the "start rotation" tile displayed on screen. Do this in a - // Handler so it is scheduled at the end of the message queue. This is necessary to - // ensure we do not remove or add data from the adapter while the layout is still being - // computed. RecyclerView documentation therefore recommends performing such changes in - // a Handler. - new android.os.Handler().post(new Runnable() { - @Override - public void run() { - // A config change may have destroyed the activity since the refresh started, so - // check for that to avoid an NPE. - if (getActivity() == null) { - return; - } + rotationState -> { + // Update the UI state of the "start rotation" tile displayed on screen. + // Do this in a Handler so it is scheduled at the end of the message queue. + // This is necessary to ensure we do not remove or add data from the adapter + // while the layout is still being computed. RecyclerView documentation + // therefore recommends performing such changes in a Handler. + new Handler().post(() -> { + // A config change may have destroyed the activity since the refresh + // started, so check for that to avoid an NPE. + if (getActivity() == null) { + return; + } - rotationHolder.bindRotationInitializationState(rotationInitializationState); - } - }); - } + rotationHolder.bindRotationInitializationState(rotationState); + }); }); } @@ -723,10 +715,10 @@ public class IndividualPickerFragment extends Fragment super(itemView); itemView.setOnClickListener(this); - mTileLayout = (FrameLayout) itemView.findViewById(R.id.daily_refresh); - mRotationMessage = (TextView) itemView.findViewById(R.id.rotation_tile_message); - mRotationTitle = (TextView) itemView.findViewById(R.id.rotation_tile_title); - mRefreshIcon = (ImageView) itemView.findViewById(R.id.rotation_tile_refresh_icon); + mTileLayout = itemView.findViewById(R.id.daily_refresh); + mRotationMessage = itemView.findViewById(R.id.rotation_tile_message); + mRotationTitle = itemView.findViewById(R.id.rotation_tile_title); + mRefreshIcon = itemView.findViewById(R.id.rotation_tile_refresh_icon); mTileLayout.getLayoutParams().height = mTileSizePx.y; // If the feature flag for "dynamic start rotation tile" is not enabled, fall back to the @@ -740,7 +732,8 @@ public class IndividualPickerFragment extends Fragment mRotationMessage.setTextColor( getResources().getColor(R.color.rotation_tile_enabled_subtitle_text_color)); mRefreshIcon.setColorFilter( - getResources().getColor(R.color.rotation_tile_enabled_refresh_icon_color), Mode.SRC_IN); + getResources().getColor(R.color.rotation_tile_enabled_refresh_icon_color), + Mode.SRC_IN); return; } diff --git a/tests/Android.mk b/tests/Android.mk new file mode 100644 index 0000000..be224e3 --- /dev/null +++ b/tests/Android.mk @@ -0,0 +1,59 @@ +# Copyright (C) 2019 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH := $(call my-dir) + +# +# Build rule for WallpaperPicker2 tests +# +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_STATIC_JAVA_LIBRARIES := \ + androidx.annotation_annotation \ + androidx.test.core \ + androidx.test.runner \ + androidx.test.rules \ + androidx.test.espresso.contrib \ + androidx.test.espresso.intents \ + mockito-target-minus-junit4 \ + androidx.test.espresso.core \ + hamcrest-library \ + hamcrest + +ifneq (,$(wildcard frameworks/base)) + LOCAL_PRIVATE_PLATFORM_APIS := true +else + LOCAL_SDK_VERSION := 29 + LOCAL_MIN_SDK_VERSION := 26 +endif + +LOCAL_PROGUARD_ENABLED := disabled + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_STATIC_ANDROID_LIBRARIES := WallpaperPicker2CommonDepsLib + +LOCAL_FULL_LIBS_MANIFEST_FILES := $(LOCAL_PATH)/AndroidManifest.xml +LOCAL_MANIFEST_FILE := AndroidManifest.xml + +LOCAL_INSTRUMENTATION_FOR := WallpaperPicker2 + +LOCAL_PACKAGE_NAME := WallpaperPicker2Tests + +include $(BUILD_PACKAGE) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml new file mode 100644 index 0000000..1e35c92 --- /dev/null +++ b/tests/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/tests/src/com/android/wallpaper/picker/individual/IndividualPickerActivityTest.java b/tests/src/com/android/wallpaper/picker/individual/IndividualPickerActivityTest.java new file mode 100644 index 0000000..e98fabd --- /dev/null +++ b/tests/src/com/android/wallpaper/picker/individual/IndividualPickerActivityTest.java @@ -0,0 +1,496 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.picker.individual; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.intent.Intents.intended; +import static androidx.test.espresso.intent.Intents.intending; +import static androidx.test.espresso.intent.matcher.ComponentNameMatchers.hasShortClassName; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static androidx.test.espresso.matcher.ViewMatchers.isChecked; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static junit.framework.TestCase.assertFalse; + +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import android.app.Activity; +import android.app.Instrumentation.ActivityResult; +import android.app.WallpaperManager; +import android.content.Context; +import android.content.Intent; +import android.graphics.drawable.ColorDrawable; +import android.widget.FrameLayout; + +import androidx.recyclerview.widget.RecyclerView; +import androidx.test.espresso.contrib.RecyclerViewActions; +import androidx.test.espresso.intent.Intents; +import androidx.test.filters.LargeTest; +import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; + +import com.android.wallpaper.R; +import com.android.wallpaper.config.Flags; +import com.android.wallpaper.model.Category; +import com.android.wallpaper.model.PickerIntentFactory; +import com.android.wallpaper.model.WallpaperInfo; +import com.android.wallpaper.model.WallpaperRotationInitializer; +import com.android.wallpaper.model.WallpaperRotationInitializer.RotationInitializationState; +import com.android.wallpaper.module.FormFactorChecker; +import com.android.wallpaper.module.Injector; +import com.android.wallpaper.module.InjectorProvider; +import com.android.wallpaper.testing.TestCategoryProvider; +import com.android.wallpaper.testing.TestFormFactorChecker; +import com.android.wallpaper.testing.TestInjector; +import com.android.wallpaper.testing.TestUserEventLogger; +import com.android.wallpaper.testing.TestWallpaperCategory; +import com.android.wallpaper.testing.TestWallpaperInfo; +import com.android.wallpaper.testing.TestWallpaperRotationInitializer; + +import org.hamcrest.Matcher; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Tests for {@link IndividualPickerActivity}. + */ +@RunWith(AndroidJUnit4ClassRunner.class) +@LargeTest +public class IndividualPickerActivityTest { + + private static final String EXTRA_WALLPAPER_INFO = + "com.android.wallpaper.picker.wallpaper_info"; + private static final TestWallpaperInfo sWallpaperInfo1 = new TestWallpaperInfo( + TestWallpaperInfo.COLOR_BLACK, "test-wallpaper-1"); + private static final TestWallpaperInfo sWallpaperInfo2 = new TestWallpaperInfo( + TestWallpaperInfo.COLOR_BLACK, "test-wallpaper-2"); + private static final TestWallpaperInfo sWallpaperInfo3 = new TestWallpaperInfo( + TestWallpaperInfo.COLOR_BLACK, "test-wallpaper-3"); + + private TestCategoryProvider mTestCategoryProvider; + + private TestFormFactorChecker mTestFormFactorChecker; + private Injector mInjector; + + private TestWallpaperCategory mTestCategory; + + @Rule + public ActivityTestRule mActivityRule = + new ActivityTestRule<>(IndividualPickerActivity.class, false, false); + + @Before + public void setUp() { + Intents.init(); + + mInjector = new TestInjector(); + InjectorProvider.setInjector(mInjector); + + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + mTestFormFactorChecker = (TestFormFactorChecker) mInjector.getFormFactorChecker(context); + mTestCategoryProvider = (TestCategoryProvider) mInjector.getCategoryProvider(context); + + sWallpaperInfo1.setAttributions(Arrays.asList( + "Attribution 0", "Attribution 1", "Attribution 2")); + } + + @After + public void tearDown() { + Intents.release(); + mActivityRule.finishActivity(); + } + + private IndividualPickerActivity getActivity() { + return mActivityRule.getActivity(); + } + + private void setUpFragmentForTesting() { + IndividualPickerFragment fragment = (IndividualPickerFragment) + getActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_container); + fragment.setTestingMode(true); + } + + private void setActivityWithMockWallpapers(boolean isRotationEnabled, + @RotationInitializationState int rotationState) { + sWallpaperInfo1.setCollectionId("collection"); + + ArrayList wallpapers = new ArrayList<>(); + wallpapers.add(sWallpaperInfo1); + wallpapers.add(sWallpaperInfo2); + wallpapers.add(sWallpaperInfo3); + + mTestCategory = new TestWallpaperCategory( + "Test category", "collection", wallpapers, 0 /* priority */); + mTestCategory.setIsRotationEnabled(isRotationEnabled); + mTestCategory.setRotationInitializationState(rotationState); + + List testCategories = mTestCategoryProvider.getTestCategories(); + testCategories.set(0, mTestCategory); + + PickerIntentFactory intentFactory = + new IndividualPickerActivity.IndividualPickerActivityIntentFactory(); + Intent intent = intentFactory.newIntent( + InstrumentationRegistry.getInstrumentation().getTargetContext(), + mTestCategory.getCollectionId()); + mActivityRule.launchActivity(intent); + } + + @Test + public void testDrawsTilesForProvidedWallpapers() { + setActivityWithMockWallpapers(false /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + IndividualPickerActivity activity = getActivity(); + + RecyclerView recyclerView = activity.findViewById(R.id.wallpaper_grid); + + // There are only three wallpapers in the category, so the grid should only have three + // items. + assertNotNull(recyclerView.findViewHolderForAdapterPosition(0)); + assertNotNull(recyclerView.findViewHolderForAdapterPosition(1)); + assertNotNull(recyclerView.findViewHolderForAdapterPosition(2)); + assertNull(recyclerView.findViewHolderForAdapterPosition(3)); + } + + @Test + public void testClickTile_Mobile_LaunchesPreviewActivityWithWallpaper() { + mTestFormFactorChecker.setFormFactor(FormFactorChecker.FORM_FACTOR_MOBILE); + + setActivityWithMockWallpapers(false /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + onView(withId(R.id.wallpaper_grid)).perform( + RecyclerViewActions.actionOnItemAtPosition(0, click())); + intended(allOf( + hasComponent(hasShortClassName(".picker.PreviewActivity")), + hasExtra(equalTo(EXTRA_WALLPAPER_INFO), equalTo(sWallpaperInfo1)))); + + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + TestUserEventLogger eventLogger = (TestUserEventLogger) mInjector.getUserEventLogger( + context); + assertEquals(1, eventLogger.getNumIndividualWallpaperSelectedEvents()); + assertEquals(sWallpaperInfo1.getCollectionId(context), eventLogger.getLastCollectionId()); + } + + /** + * Tests that the static daily rotation tile (with flag dynamicStartRotationTileEnabled=false) + * has a background of the light blue accent color and says "Tap to turn on". + */ + @Test + public void testRotationEnabled_StaticDailyRotationTile() { + Flags.dynamicStartRotationTileEnabled = false; + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + onView(withText(R.string.daily_refresh_tile_title)).check(matches(isDisplayed())); + onView(withText(R.string.daily_refresh_tile_subtitle)).check(matches(isDisplayed())); + + // Check that the background color of the "daily refresh" tile is the blue accent color. + FrameLayout rotationTile = getActivity().findViewById(R.id.daily_refresh); + int backgroundColor = ((ColorDrawable) rotationTile.getBackground()).getColor(); + assertEquals(getActivity().getResources().getColor(R.color.accent_color), + backgroundColor); + } + + /** + * Tests that when rotation is enabled and the rotation for this category is already in effect + * on both home & lock screens, then the "start rotation" tile reads "Home & Lock". + */ + @Test + public void testRotationEnabled_RotationInitializedHomeAndLock() { + Flags.dynamicStartRotationTileEnabled = true; + + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_HOME_AND_LOCK); + getActivity(); + + onView(withText(R.string.daily_refresh_tile_title)).check(matches(isDisplayed())); + onView(withText(R.string.home_and_lock_short_label)).check(matches(isDisplayed())); + } + + /** + * Tests that when rotation is enabled and the rotation is aleady for this category is already + * in + * effect on the home-screen only, then the "start rotation" tile reads "Home screen". + */ + @Test + public void testRotationEnabled_RotationInitializedHomeScreenOnly() { + Flags.dynamicStartRotationTileEnabled = true; + + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_HOME_ONLY); + getActivity(); + + onView(withText(R.string.daily_refresh_tile_title)).check(matches(isDisplayed())); + onView(withText(R.string.home_screen_message)).check(matches(isDisplayed())); + } + + /** + * Tests that after the IndividualPickerActivity loads, if the state of the current category's + * rotation changes while the activity is restarted, then the UI for the "start rotation" tile + * changes to reflect that new state. + */ + @Test + public void testActivityRestarted_RotationStateChanges_StartRotationTileUpdates() + throws Throwable { + Flags.dynamicStartRotationTileEnabled = true; + + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_HOME_ONLY); + + onView(withText(R.string.daily_refresh_tile_title)).check(matches(isDisplayed())); + onView(withText(R.string.home_screen_message)).check(matches(isDisplayed())); + + // Now change the rotation initialization state such that the tile should say + // "Tap to turn on" after the activity resumes. + setUpFragmentForTesting(); + TestWallpaperRotationInitializer + testWPRotationInitializer = (TestWallpaperRotationInitializer) + mTestCategory.getWallpaperRotationInitializer(); + testWPRotationInitializer.setRotationInitializationState( + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + + // Restart the activity. + IndividualPickerActivity activity = getActivity(); + mActivityRule.runOnUiThread(activity::recreate); + + onView(withText(R.string.daily_refresh_tile_title)).check(matches(isDisplayed())); + onView(withText(R.string.daily_refresh_tile_subtitle)).check(matches(isDisplayed())); + } + + @Test + public void testRotationDisabled_DoesNotRenderDailyRefreshTile() { + setActivityWithMockWallpapers(false /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + onView(withText(R.string.daily_refresh_tile_title)).check(doesNotExist()); + onView(withText(R.string.daily_refresh_tile_subtitle)).check(doesNotExist()); + } + + @Test + public void testClickDailyRefreshTile_ShowsStartRotationDialog() { + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + onView(withId(R.id.daily_refresh)).perform(click()); + + onView(withId(R.id.start_rotation_wifi_only_checkbox)) + .check(matches(isDisplayed())); + // WiFi-only option should be checked by default. + onView(withId(R.id.start_rotation_wifi_only_checkbox)) + .check(matches(isChecked())); + } + + @Test + public void testShowStartRotationDialog_WifiOnly_ClickOK_StartsRotation() throws Throwable { + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + setUpFragmentForTesting(); + TestWallpaperRotationInitializer + testWPRotationInitializer = (TestWallpaperRotationInitializer) + mTestCategory.getWallpaperRotationInitializer(); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + // Mock out the intent and response for the live wallpaper preview. + Matcher expectedIntent = hasAction(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); + intending(expectedIntent).respondWith(new ActivityResult(Activity.RESULT_OK, null)); + + onView(withId(R.id.daily_refresh)).perform(click()); + + onView(withText(android.R.string.ok)).perform(click()); + mActivityRule.runOnUiThread(() -> { + testWPRotationInitializer.finishDownloadingFirstWallpaper(true /* isSuccessful */); + assertTrue(testWPRotationInitializer.isRotationInitialized()); + assertTrue(testWPRotationInitializer.isWifiOnly()); + + // The activity should finish if starting a rotation was successful. + assertTrue(getActivity().isFinishing()); + }); + } + + @Test + public void testShowStartRotationDialog_WifiOnly_ClickOK_Fails_ShowsErrorDialog() { + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + setUpFragmentForTesting(); + TestWallpaperRotationInitializer + testWPRotationInitializer = (TestWallpaperRotationInitializer) + mTestCategory.getWallpaperRotationInitializer(); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + onView(withId(R.id.daily_refresh)).perform(click()); + onView(withText(android.R.string.ok)).perform(click()); + + testWPRotationInitializer.finishDownloadingFirstWallpaper(false /* isSuccessful */); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + // Error dialog should be shown with retry option. + onView(withText(R.string.start_rotation_error_message)).check(matches(isDisplayed())); + onView(withText(R.string.try_again)).check(matches(isDisplayed())); + } + + @Test + public void testStartRotation_WifiOnly_FailOnce_Retry() throws Throwable { + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + setUpFragmentForTesting(); + TestWallpaperRotationInitializer + testWPRotationInitializer = (TestWallpaperRotationInitializer) + mTestCategory.getWallpaperRotationInitializer(); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + onView(withId(R.id.daily_refresh)).perform(click()); + onView(withText(android.R.string.ok)).perform(click()); + + testWPRotationInitializer.finishDownloadingFirstWallpaper(false /* isSuccessful */); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + // Click try again to retry. + onView(withText(R.string.try_again)).perform(click()); + + mActivityRule.runOnUiThread(() -> { + testWPRotationInitializer.finishDownloadingFirstWallpaper(true /* isSuccessful */); + assertTrue(testWPRotationInitializer.isRotationInitialized()); + assertTrue(testWPRotationInitializer.isWifiOnly()); + }); + } + + @Test + public void testShowStartRotationDialog_TurnOffWifiOnly_ClickOK_StartsRotation() + throws Throwable { + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + setUpFragmentForTesting(); + TestWallpaperRotationInitializer + testWPRotationInitializer = (TestWallpaperRotationInitializer) + mTestCategory.getWallpaperRotationInitializer(); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + onView(withId(R.id.daily_refresh)).perform(click()); + // Click on WiFi-only option to toggle it off. + onView(withId(R.id.start_rotation_wifi_only_checkbox)).perform(click()); + onView(withText(android.R.string.ok)).perform(click()); + + mActivityRule.runOnUiThread(() -> { + testWPRotationInitializer.finishDownloadingFirstWallpaper(true /* isSuccessful */); + assertTrue(testWPRotationInitializer.isRotationInitialized()); + assertFalse(testWPRotationInitializer.isWifiOnly()); + }); + } + + @Test + public void testStartRotation_WifiOnly_FailOnce_Retry_ShouldStillHaveWifiTurnedOff() + throws Throwable { + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + setUpFragmentForTesting(); + TestWallpaperRotationInitializer + testWPRotationInitializer = (TestWallpaperRotationInitializer) + mTestCategory.getWallpaperRotationInitializer(); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + onView(withId(R.id.daily_refresh)).perform(click()); + // Click on WiFi-only option to toggle it off. + onView(withId(R.id.start_rotation_wifi_only_checkbox)).perform(click()); + onView(withText(android.R.string.ok)).perform(click()); + + testWPRotationInitializer.finishDownloadingFirstWallpaper(false /* isSuccessful */); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + // Click try again to retry. + onView(withText(R.string.try_again)).perform(click()); + + mActivityRule.runOnUiThread(() -> { + testWPRotationInitializer.finishDownloadingFirstWallpaper(true /* isSuccessful */); + assertTrue(testWPRotationInitializer.isRotationInitialized()); + assertFalse(testWPRotationInitializer.isWifiOnly()); + }); + } + + @Test + public void testShowStartRotationDialog_ClickCancel_DismissesDialog() { + setActivityWithMockWallpapers(true /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + getActivity(); + + setUpFragmentForTesting(); + TestWallpaperRotationInitializer + testWPRotationInitializer = (TestWallpaperRotationInitializer) + mTestCategory.getWallpaperRotationInitializer(); + assertFalse(testWPRotationInitializer.isRotationInitialized()); + + onView(withId(R.id.daily_refresh)).perform(click()); + onView(withId(R.id.start_rotation_wifi_only_checkbox)).check(matches(isDisplayed())); + // WiFi-only option should be checked by default. + onView(withId(R.id.start_rotation_wifi_only_checkbox)).check(matches(isChecked())); + + // Click "Cancel" to dismiss the dialog. + onView(withText(android.R.string.cancel)).perform(click()); + + // Rotation was not initialized and dialog is no longer visible. + assertFalse(testWPRotationInitializer.isRotationInitialized()); + onView(withId(R.id.start_rotation_wifi_only_checkbox)).check(doesNotExist()); + } + + /** + * Tests that when no title is present, a wallpaper tile's content description attribute is + * set to the first attribution. + */ + @Test + public void testWallpaperHasContentDescriptionFromAttribution() { + setActivityWithMockWallpapers(false /* isRotationEnabled */, + WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED); + IndividualPickerActivity activity = getActivity(); + + RecyclerView recyclerView = activity.findViewById(R.id.wallpaper_grid); + + RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(0); + assertEquals("Attribution 0", holder.itemView.findViewById(R.id.tile) + .getContentDescription()); + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestAlarmManagerWrapper.java b/tests/src/com/android/wallpaper/testing/TestAlarmManagerWrapper.java new file mode 100644 index 0000000..c9bbdd2 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestAlarmManagerWrapper.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.app.PendingIntent; + +import com.android.wallpaper.module.AlarmManagerWrapper; + +/** + * Mock of {@link AlarmManagerWrapper}. + */ +public class TestAlarmManagerWrapper implements AlarmManagerWrapper { + + private int mExactAlarmSetCount; + private int mInexactAlarmSetCount; + private int mAlarmCanceledCount; + + private long mLastInexactTriggerAtMillis; + + @Override + public void set(int type, long triggerAtMillis, PendingIntent operation) { + mExactAlarmSetCount++; + } + + @Override + public void setWindow(int type, long windowStartMillis, long windowLengthMillis, + PendingIntent operation) { + mExactAlarmSetCount++; + } + + @Override + public void setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, + PendingIntent operation) { + mInexactAlarmSetCount++; + mLastInexactTriggerAtMillis = triggerAtMillis; + } + + @Override + public void cancel(PendingIntent operation) { + mAlarmCanceledCount++; + } + + public int getExactAlarmSetCount() { + return mExactAlarmSetCount; + } + + public int getInexactAlarmSetCount() { + return mInexactAlarmSetCount; + } + + public int getAlarmCanceledCount() { + return mAlarmCanceledCount; + } + + public long getLastInexactTriggerAtMillis() { + return mLastInexactTriggerAtMillis; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestAsset.java b/tests/src/com/android/wallpaper/testing/TestAsset.java new file mode 100644 index 0000000..368919a --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestAsset.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.Point; +import android.graphics.Rect; +import android.widget.ImageView; + +import androidx.annotation.Nullable; + +import com.android.wallpaper.asset.Asset; + + +/** + * Test implementation of Asset which blocks on Bitmap decoding operations. + */ +public final class TestAsset extends Asset { + + private Bitmap mBitmap; + private boolean mIsCorrupt; + + /** + * Constructs an asset underpinned by a 1x1 bitmap uniquely identifiable by the given pixel + * color. + * + * @param pixelColor Color of the asset's single pixel. + * @param isCorrupt Whether or not the asset is corrupt and fails to validly decode bitmaps and + * dimensions. + */ + public TestAsset(int pixelColor, boolean isCorrupt) { + mIsCorrupt = isCorrupt; + + if (!mIsCorrupt) { + mBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888); + mBitmap.setPixel(0, 0, pixelColor); + } else { + mBitmap = null; + } + } + + @Override + public void decodeBitmap(int targetWidth, int targetHeight, BitmapReceiver receiver) { + receiver.onBitmapDecoded(mBitmap); + } + + @Override + public void decodeBitmapRegion(Rect unused, int targetWidth, int targetHeight, + BitmapReceiver receiver) { + receiver.onBitmapDecoded(mBitmap); + } + + @Override + public void decodeRawDimensions(Activity unused, DimensionsReceiver receiver) { + receiver.onDimensionsDecoded(mIsCorrupt ? null : new Point(1, 1)); + } + + @Override + public boolean supportsTiling() { + return false; + } + + @Override + public void loadDrawableWithTransition( + Context context, + ImageView imageView, + int transitionDurationMillis, + @Nullable DrawableLoadedListener drawableLoadedListener, + int placeholderColor) { + if (drawableLoadedListener != null) { + drawableLoadedListener.onDrawableLoaded(); + } + } + + /** Returns the bitmap synchronously. Convenience method for tests. */ + public Bitmap getBitmap() { + return mBitmap; + } + + public void setBitmap(Bitmap bitmap) { + mBitmap = bitmap; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestBitmapCropper.java b/tests/src/com/android/wallpaper/testing/TestBitmapCropper.java new file mode 100644 index 0000000..7daeeab --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestBitmapCropper.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.graphics.Bitmap; +import android.graphics.Rect; + +import com.android.wallpaper.asset.Asset; +import com.android.wallpaper.asset.Asset.BitmapReceiver; +import com.android.wallpaper.module.BitmapCropper; + +/** + * Test double for BitmapCropper. + */ +public class TestBitmapCropper implements BitmapCropper { + + private boolean mFailNextCall; + + public TestBitmapCropper() { + mFailNextCall = false; + } + + @Override + public void cropAndScaleBitmap(Asset asset, float scale, Rect cropRect, + Callback callback) { + if (mFailNextCall) { + callback.onError(null /* throwable */); + return; + } + // Crop rect in pixels of source image. + Rect scaledCropRect = new Rect( + Math.round((float) cropRect.left / scale), + Math.round((float) cropRect.top / scale), + Math.round((float) cropRect.right / scale), + Math.round((float) cropRect.bottom / scale)); + + asset.decodeBitmapRegion(scaledCropRect, cropRect.width(), cropRect.height(), + new BitmapReceiver() { + @Override + public void onBitmapDecoded(Bitmap bitmap) { + callback.onBitmapCropped(bitmap); + } + }); + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestCategoryProvider.java b/tests/src/com/android/wallpaper/testing/TestCategoryProvider.java new file mode 100644 index 0000000..310840c --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestCategoryProvider.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.os.Handler; + +import com.android.wallpaper.model.Category; +import com.android.wallpaper.model.CategoryProvider; +import com.android.wallpaper.model.CategoryReceiver; +import com.android.wallpaper.model.ImageCategory; +import com.android.wallpaper.model.WallpaperInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * Test implementation of {@link CategoryProvider}. + */ +public class TestCategoryProvider implements CategoryProvider { + private final List mCategories; + + public TestCategoryProvider() { + Category category1 = new ImageCategory( + "My photos" /* title */, + "image_wallpapers" /* collection */, + 0 /* priority */); + + ArrayList wallpapers = new ArrayList<>(); + WallpaperInfo wallpaperInfo = new com.android.wallpaper.testing.TestWallpaperInfo(0); + wallpapers.add(wallpaperInfo); + Category category2 = new com.android.wallpaper.testing.TestWallpaperCategory( + "Test category", "init_collection", wallpapers, + 1 /* priority */); + + mCategories = new ArrayList<>(); + mCategories.add(category1); + mCategories.add(category2); + } + + @Override + public void fetchCategories(CategoryReceiver receiver, boolean forceRefresh) { + // Mimic real behavior by fetching asynchronously. + new Handler().post(new Runnable() { + @Override + public void run() { + List categories = getTestCategories(); + for (Category category : categories) { + receiver.onCategoryReceived(category); + } + receiver.doneFetchingCategories(); + } + }); + } + + @Override + public int getSize() { + return mCategories == null ? 0 : mCategories.size(); + } + + @Override + public Category getCategory(int index) { + return mCategories == null ? null : mCategories.get(index); + } + + @Override + public Category getCategory(String collectionId) { + Category category; + for (int i = 0; i < mCategories.size(); i++) { + category = mCategories.get(i); + if (category.getCollectionId().equals(collectionId)) { + return category; + } + } + return null; + } + + /** Returns a list of test Category objects used by this TestCategoryProvider. */ + public List getTestCategories() { + return mCategories; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestCurrentWallpaperInfoFactory.java b/tests/src/com/android/wallpaper/testing/TestCurrentWallpaperInfoFactory.java new file mode 100644 index 0000000..3e8c665 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestCurrentWallpaperInfoFactory.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.content.Context; + +import com.android.wallpaper.compat.BuildCompat; +import com.android.wallpaper.model.WallpaperInfo; +import com.android.wallpaper.module.CurrentWallpaperInfoFactory; +import com.android.wallpaper.module.InjectorProvider; +import com.android.wallpaper.module.WallpaperRefresher; + +import java.util.List; + +/** + * Test double of {@link CurrentWallpaperInfoFactory}. + */ +public class TestCurrentWallpaperInfoFactory implements CurrentWallpaperInfoFactory { + + private WallpaperRefresher mRefresher; + + public TestCurrentWallpaperInfoFactory(Context context) { + mRefresher = InjectorProvider.getInjector().getWallpaperRefresher( + context.getApplicationContext()); + } + + @Override + public void createCurrentWallpaperInfos(final WallpaperInfoCallback callback, + boolean forceRefresh) { + mRefresher.refresh((homeWallpaperMetadata, lockWallpaperMetadata, presentationMode) -> { + + WallpaperInfo homeWallpaper = createTestWallpaperInfo( + homeWallpaperMetadata.getAttributions(), + homeWallpaperMetadata.getActionUrl(), + homeWallpaperMetadata.getCollectionId()); + + WallpaperInfo lockWallpaper = null; + if (lockWallpaperMetadata != null && BuildCompat.isAtLeastN()) { + lockWallpaper = createTestWallpaperInfo( + lockWallpaperMetadata.getAttributions(), + lockWallpaperMetadata.getActionUrl(), + lockWallpaperMetadata.getCollectionId()); + } + + callback.onWallpaperInfoCreated(homeWallpaper, lockWallpaper, presentationMode); + }); + } + + private static WallpaperInfo createTestWallpaperInfo(List attributions, + String actionUrl, String collectionId) { + TestWallpaperInfo wallpaper = new TestWallpaperInfo(TestWallpaperInfo.COLOR_BLACK); + wallpaper.setAttributions(attributions); + wallpaper.setActionUrl(actionUrl); + wallpaper.setCollectionId(collectionId); + return wallpaper; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestExploreIntentChecker.java b/tests/src/com/android/wallpaper/testing/TestExploreIntentChecker.java new file mode 100644 index 0000000..dc1f1a8 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestExploreIntentChecker.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.content.Intent; +import android.net.Uri; + +import com.android.wallpaper.module.ExploreIntentChecker; + +/** + * Test implementation of ExploreIntentChecker. + */ +public class TestExploreIntentChecker implements ExploreIntentChecker { + + private boolean mViewHandlerExists; + + public TestExploreIntentChecker() { + // True by default. + mViewHandlerExists = true; + } + + @Override + public void fetchValidActionViewIntent(Uri uri, IntentReceiver receiver) { + Intent intent = mViewHandlerExists ? new Intent(Intent.ACTION_VIEW, uri) : null; + receiver.onIntentReceived(intent); + } + + public void setViewHandlerExists(boolean exists) { + mViewHandlerExists = exists; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestFormFactorChecker.java b/tests/src/com/android/wallpaper/testing/TestFormFactorChecker.java new file mode 100644 index 0000000..ba77172 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestFormFactorChecker.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import com.android.wallpaper.module.FormFactorChecker; + +/** + * Test implementation of {@code FormFactorChecker}. + */ +public class TestFormFactorChecker implements FormFactorChecker { + + @FormFactor + private int mFormFactor; + + public TestFormFactorChecker() { + mFormFactor = FORM_FACTOR_MOBILE; + } + + @FormFactor + @Override + public int getFormFactor() { + return mFormFactor; + } + + public void setFormFactor(@FormFactor int formFactor) { + mFormFactor = formFactor; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestInjector.java b/tests/src/com/android/wallpaper/testing/TestInjector.java new file mode 100644 index 0000000..0da755e --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestInjector.java @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.content.Context; + +import androidx.fragment.app.Fragment; + +import com.android.wallpaper.compat.WallpaperManagerCompat; +import com.android.wallpaper.model.CategoryProvider; +import com.android.wallpaper.model.WallpaperInfo; +import com.android.wallpaper.module.AlarmManagerWrapper; +import com.android.wallpaper.module.BitmapCropper; +import com.android.wallpaper.module.CurrentWallpaperInfoFactory; +import com.android.wallpaper.module.DefaultLiveWallpaperInfoFactory; +import com.android.wallpaper.module.DrawableLayerResolver; +import com.android.wallpaper.module.ExploreIntentChecker; +import com.android.wallpaper.module.FormFactorChecker; +import com.android.wallpaper.module.Injector; +import com.android.wallpaper.module.LiveWallpaperInfoFactory; +import com.android.wallpaper.module.LoggingOptInStatusProvider; +import com.android.wallpaper.module.NetworkStatusNotifier; +import com.android.wallpaper.module.PackageStatusNotifier; +import com.android.wallpaper.module.PartnerProvider; +import com.android.wallpaper.module.SystemFeatureChecker; +import com.android.wallpaper.module.UserEventLogger; +import com.android.wallpaper.module.WallpaperPersister; +import com.android.wallpaper.module.WallpaperPreferences; +import com.android.wallpaper.module.WallpaperRefresher; +import com.android.wallpaper.module.WallpaperRotationRefresher; +import com.android.wallpaper.monitor.PerformanceMonitor; +import com.android.wallpaper.network.Requester; +import com.android.wallpaper.picker.ImagePreviewFragment; +import com.android.wallpaper.picker.individual.IndividualPickerFragment; + +/** + * Test implementation of the dependency injector. + */ +public class TestInjector implements Injector { + + private BitmapCropper mBitmapCropper; + private CategoryProvider mCategoryProvider; + private PartnerProvider mPartnerProvider; + private WallpaperPreferences mPrefs; + private WallpaperPersister mWallpaperPersister; + private WallpaperRefresher mWallpaperRefresher; + private Requester mRequester; + private WallpaperManagerCompat mWallpaperManagerCompat; + private CurrentWallpaperInfoFactory mCurrentWallpaperInfoFactory; + private NetworkStatusNotifier mNetworkStatusNotifier; + private AlarmManagerWrapper mAlarmManagerWrapper; + private UserEventLogger mUserEventLogger; + private ExploreIntentChecker mExploreIntentChecker; + private SystemFeatureChecker mSystemFeatureChecker; + private FormFactorChecker mFormFactorChecker; + private WallpaperRotationRefresher mWallpaperRotationRefresher; + private PerformanceMonitor mPerformanceMonitor; + private LoggingOptInStatusProvider mLoggingOptInStatusProvider; + + @Override + public BitmapCropper getBitmapCropper() { + if (mBitmapCropper == null) { + mBitmapCropper = new com.android.wallpaper.testing.TestBitmapCropper(); + } + return mBitmapCropper; + } + + @Override + public CategoryProvider getCategoryProvider(Context context) { + if (mCategoryProvider == null) { + mCategoryProvider = new TestCategoryProvider(); + } + return mCategoryProvider; + } + + @Override + public PartnerProvider getPartnerProvider(Context context) { + if (mPartnerProvider == null) { + mPartnerProvider = new TestPartnerProvider(); + } + return mPartnerProvider; + } + + @Override + public WallpaperPreferences getPreferences(Context context) { + if (mPrefs == null) { + mPrefs = new TestWallpaperPreferences(); + } + return mPrefs; + } + + @Override + public WallpaperPersister getWallpaperPersister(Context context) { + if (mWallpaperPersister == null) { + mWallpaperPersister = new TestWallpaperPersister(context.getApplicationContext()); + } + return mWallpaperPersister; + } + + @Override + public WallpaperRefresher getWallpaperRefresher(Context context) { + if (mWallpaperRefresher == null) { + mWallpaperRefresher = new TestWallpaperRefresher(context.getApplicationContext()); + } + return mWallpaperRefresher; + } + + @Override + public Requester getRequester(Context unused) { + return null; + } + + @Override + public WallpaperManagerCompat getWallpaperManagerCompat(Context context) { + if (mWallpaperManagerCompat == null) { + mWallpaperManagerCompat = new com.android.wallpaper.testing.TestWallpaperManagerCompat( + context.getApplicationContext()); + } + return mWallpaperManagerCompat; + } + + @Override + public CurrentWallpaperInfoFactory getCurrentWallpaperFactory(Context context) { + if (mCurrentWallpaperInfoFactory == null) { + mCurrentWallpaperInfoFactory = + new TestCurrentWallpaperInfoFactory(context.getApplicationContext()); + } + return mCurrentWallpaperInfoFactory; + } + + @Override + public LoggingOptInStatusProvider getLoggingOptInStatusProvider(Context context) { + if (mLoggingOptInStatusProvider == null) { + mLoggingOptInStatusProvider = new TestLoggingOptInStatusProvider(); + } + return mLoggingOptInStatusProvider; + } + + @Override + public NetworkStatusNotifier getNetworkStatusNotifier(Context context) { + if (mNetworkStatusNotifier == null) { + mNetworkStatusNotifier = new TestNetworkStatusNotifier(); + } + return mNetworkStatusNotifier; + } + + @Override + public AlarmManagerWrapper getAlarmManagerWrapper(Context unused) { + if (mAlarmManagerWrapper == null) { + mAlarmManagerWrapper = new TestAlarmManagerWrapper(); + } + return mAlarmManagerWrapper; + } + + @Override + public UserEventLogger getUserEventLogger(Context unused) { + if (mUserEventLogger == null) { + mUserEventLogger = new com.android.wallpaper.testing.TestUserEventLogger(); + } + return mUserEventLogger; + } + + @Override + public ExploreIntentChecker getExploreIntentChecker(Context unused) { + if (mExploreIntentChecker == null) { + mExploreIntentChecker = new TestExploreIntentChecker(); + } + return mExploreIntentChecker; + } + + @Override + public SystemFeatureChecker getSystemFeatureChecker() { + if (mSystemFeatureChecker == null) { + mSystemFeatureChecker = new com.android.wallpaper.testing.TestSystemFeatureChecker(); + } + return mSystemFeatureChecker; + } + + @Override + public FormFactorChecker getFormFactorChecker(Context unused) { + if (mFormFactorChecker == null) { + mFormFactorChecker = new TestFormFactorChecker(); + } + return mFormFactorChecker; + } + + @Override + public WallpaperRotationRefresher getWallpaperRotationRefresher() { + if (mWallpaperRotationRefresher == null) { + mWallpaperRotationRefresher = (context, listener) -> { + // Not implemented + listener.onError(); + }; + } + return mWallpaperRotationRefresher; + } + + @Override + public Fragment getPreviewFragment(Context context, WallpaperInfo wallpaperInfo, int mode, + boolean testingModeEnabled) { + return ImagePreviewFragment.newInstance(wallpaperInfo, mode, testingModeEnabled); + } + + @Override + public PackageStatusNotifier getPackageStatusNotifier(Context context) { + return null; + } + + @Override + public IndividualPickerFragment getIndividualPickerFragment(String collectionId) { + return IndividualPickerFragment.newInstance(collectionId); + } + + @Override + public LiveWallpaperInfoFactory getLiveWallpaperInfoFactory(Context context) { + return new DefaultLiveWallpaperInfoFactory(); + } + + @Override + public DrawableLayerResolver getDrawableLayerResolver() { + return null; + } + + @Override + public PerformanceMonitor getPerformanceMonitor() { + if (mPerformanceMonitor == null) { + mPerformanceMonitor = new TestPerformanceMonitor(); + } + return mPerformanceMonitor; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestLoggingOptInStatusProvider.java b/tests/src/com/android/wallpaper/testing/TestLoggingOptInStatusProvider.java new file mode 100644 index 0000000..f4434b1 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestLoggingOptInStatusProvider.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import com.android.wallpaper.module.LoggingOptInStatusProvider; + +/** Test implementation of {@link LoggingOptInStatusProvider}. */ +public class TestLoggingOptInStatusProvider implements LoggingOptInStatusProvider { + + @Override + public void fetchOptInValue(OptInValueReceiver receiver) { + receiver.onOptInValueReady(true /* optedIn */); + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestNetworkStatusNotifier.java b/tests/src/com/android/wallpaper/testing/TestNetworkStatusNotifier.java new file mode 100644 index 0000000..b09ee43 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestNetworkStatusNotifier.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + + +import com.android.wallpaper.module.NetworkStatusNotifier; + +import java.util.ArrayList; +import java.util.List; + +/** + * Test implementation of {@link NetworkStatusNotifier} which enables clients to manually notify + * listeners of a network status change. + */ +public class TestNetworkStatusNotifier implements NetworkStatusNotifier { + + private List mListeners; + @NetworkStatus + private int mNetworkStatus; + + public TestNetworkStatusNotifier() { + mListeners = new ArrayList<>(); + mNetworkStatus = NETWORK_CONNECTED; + } + + @Override + public int getNetworkStatus() { + return mNetworkStatus; + } + + @Override + public void registerListener(Listener listener) { + mListeners.add(listener); + listener.onNetworkChanged(mNetworkStatus); + } + + @Override + public void unregisterListener(Listener listener) { + mListeners.remove(listener); + } + + public void setAndNotifyNetworkStatus(@NetworkStatus int networkStatus) { + mNetworkStatus = networkStatus; + for (Listener listener : mListeners) { + listener.onNetworkChanged(mNetworkStatus); + } + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestPartnerProvider.java b/tests/src/com/android/wallpaper/testing/TestPartnerProvider.java new file mode 100644 index 0000000..fbdd0af --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestPartnerProvider.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.content.res.Resources; + +import com.android.wallpaper.module.PartnerProvider; + +import java.io.File; + +/** + * Test implementation for PartnerProvider. + */ +public class TestPartnerProvider implements PartnerProvider { + private File mLegacyWallpaperDirectory; + + @Override + public Resources getResources() { + return null; + } + + @Override + public File getLegacyWallpaperDirectory() { + return mLegacyWallpaperDirectory; + } + + /** + * Sets the File to be returned by subsequent calls to getLegacyWallpaperDirectory(). + * + * @param dir The legacy wallpaper directory. + */ + public void setLegacyWallpaperDirectory(File dir) { + mLegacyWallpaperDirectory = dir; + } + + @Override + public String getPackageName() { + return null; + } + + @Override + public boolean shouldHideDefaultWallpaper() { + return false; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestPerformanceMonitor.java b/tests/src/com/android/wallpaper/testing/TestPerformanceMonitor.java new file mode 100644 index 0000000..7fe3ade --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestPerformanceMonitor.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import com.android.wallpaper.monitor.PerformanceMonitor; + +/** + * No-op performance monitor for test. + */ +public class TestPerformanceMonitor implements PerformanceMonitor { + + @Override + public void recordFullResPreviewLoadedMemorySnapshot() { + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestSystemFeatureChecker.java b/tests/src/com/android/wallpaper/testing/TestSystemFeatureChecker.java new file mode 100644 index 0000000..775e693 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestSystemFeatureChecker.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.content.Context; + +import com.android.wallpaper.module.SystemFeatureChecker; + +/** + * Test implementation of {@link SystemFeatureChecker}. + */ +public class TestSystemFeatureChecker implements SystemFeatureChecker { + + private boolean mHasTelephony; + + public TestSystemFeatureChecker() { + mHasTelephony = true; + } + + @Override + public boolean hasTelephony(Context context) { + return mHasTelephony; + } + + public void setHasTelephony(boolean hasTelephony) { + mHasTelephony = hasTelephony; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestUserEventLogger.java b/tests/src/com/android/wallpaper/testing/TestUserEventLogger.java new file mode 100644 index 0000000..9f0489e --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestUserEventLogger.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import com.android.wallpaper.module.UserEventLogger; +import com.android.wallpaper.module.WallpaperPersister.WallpaperPosition; + +/** + * Test implementation of {@link UserEventLogger}. + */ +public class TestUserEventLogger implements UserEventLogger { + + private int mNumDailyRefreshTurnedOnEvents; + private int mNumCurrentWallpaperPreviewedEvents; + private int mNumActionClickedEvents; + private int mNumIndividualWallpaperSelectedEvents; + private int mNumCategorySelectedEvents; + private int mNumWallpaperSetEvents; + private int mNumWallpaperSetResultEvents; + private String mLastCollectionId; + private String mLastWallpaperId; + @WallpaperSetResult + private int mLastWallpaperSetResult; + private int mLastDailyRotationHour; + private int mNum1DayActiveLogs; + private int mNum7DayActiveLogs; + private int mNum14DayActiveLogs; + private int mNum28DayActiveLogs; + private int mLastDailyWallpaperRotationStatus; + private int mNumDaysDailyRotationFailed; + private int mNumDaysDailyRotationNotAttempted; + private int mLastDailyWallpaperUpdateResult; + private int mStandalonePreviewLaunches; + private int mNumRestores; + @WallpaperPosition + private int mWallpaperPosition; + + public TestUserEventLogger() { + mLastDailyRotationHour = -1; + mLastDailyWallpaperRotationStatus = -1; + mNumDaysDailyRotationFailed = -1; + mNumDaysDailyRotationNotAttempted = -1; + } + + @Override + public void logResumed(boolean provisioned, boolean wallpaper) { + + } + + @Override + public void logStopped() { + + } + + @Override + public void logAppLaunched() { + // Do nothing. + } + + @Override + public void logDailyRefreshTurnedOn() { + mNumDailyRefreshTurnedOnEvents++; + } + + public int getNumDailyRefreshTurnedOnEvents() { + return mNumDailyRefreshTurnedOnEvents; + } + + @Override + public void logCurrentWallpaperPreviewed() { + mNumCurrentWallpaperPreviewedEvents++; + } + + @Override + public void logActionClicked(String collectionId, int actionLabelResId) { + mNumActionClickedEvents++; + mLastCollectionId = collectionId; + } + + public int getNumCurrentWallpaperPreviewedEvents() { + return mNumCurrentWallpaperPreviewedEvents; + } + + public int getNumActionClickedEvents() { + return mNumActionClickedEvents; + } + + @Override + public void logIndividualWallpaperSelected(String collectionId) { + mNumIndividualWallpaperSelectedEvents++; + mLastCollectionId = collectionId; + } + + public int getNumIndividualWallpaperSelectedEvents() { + return mNumIndividualWallpaperSelectedEvents; + } + + @Override + public void logCategorySelected(String collectionId) { + mNumCategorySelectedEvents++; + mLastCollectionId = collectionId; + } + + public int getNumCategorySelectedEvents() { + return mNumCategorySelectedEvents; + } + + @Override + public void logWallpaperSet(String collectionId, String wallpaperId) { + mNumWallpaperSetEvents++; + mLastCollectionId = collectionId; + mLastWallpaperId = wallpaperId; + } + + @Override + public void logWallpaperSetResult(@WallpaperSetResult int result) { + mNumWallpaperSetResultEvents++; + mLastWallpaperSetResult = result; + } + + @Override + public void logWallpaperSetFailureReason(@WallpaperSetFailureReason int reason) { + // No-op + } + + + @Override + public void logNumDailyWallpaperRotationsInLastWeek() { + // No-op + } + + @Override + public void logNumDailyWallpaperRotationsPreviousDay() { + // No-op + } + + @Override + public void logDailyWallpaperRotationHour(int hour) { + mLastDailyRotationHour = hour; + } + + @Override + public void logDailyWallpaperDecodes(boolean decodes) { + // No-op + } + + @Override + public void logRefreshDailyWallpaperButtonClicked() { + // No-op + } + + @Override + public void logDailyWallpaperRotationStatus(int status) { + mLastDailyWallpaperRotationStatus = status; + } + + @Override + public void logDailyWallpaperSetNextWallpaperResult(@DailyWallpaperUpdateResult int result) { + mLastDailyWallpaperUpdateResult = result; + } + + @Override + public void logDailyWallpaperSetNextWallpaperCrash(@DailyWallpaperUpdateCrash int crash) { + // No-op + } + + @Override + public void logNumDaysDailyRotationFailed(int days) { + mNumDaysDailyRotationFailed = days; + } + + @Override + public void logDailyWallpaperMetadataRequestFailure( + @DailyWallpaperMetadataFailureReason int reason) { + // No-op + } + + @Override + public void logNumDaysDailyRotationNotAttempted(int days) { + mNumDaysDailyRotationNotAttempted = days; + } + + @Override + public void logStandalonePreviewLaunched() { + mStandalonePreviewLaunches++; + } + + @Override + public void logStandalonePreviewImageUriHasReadPermission(boolean isReadPermissionGranted) { + // No-op + } + + @Override + public void logStandalonePreviewStorageDialogApproved(boolean isApproved) { + // No-op + } + + @Override + public void logWallpaperPresentationMode() { + // No-op + } + + @Override + public void logRestored() { + mNumRestores++; + } + + public int getNumWallpaperSetEvents() { + return mNumWallpaperSetEvents; + } + + public String getLastCollectionId() { + return mLastCollectionId; + } + + public String getLastWallpaperId() { + return mLastWallpaperId; + } + + public int getNumWallpaperSetResultEvents() { + return mNumWallpaperSetResultEvents; + } + + @WallpaperSetResult + public int getLastWallpaperSetResult() { + return mLastWallpaperSetResult; + } + + public int getLastDailyRotationHour() { + return mLastDailyRotationHour; + } + + public int getNum1DayActiveLogs() { + return mNum1DayActiveLogs; + } + + public int getNum7DayActiveLogs() { + return mNum7DayActiveLogs; + } + + public int getNum14DayActiveLogs() { + return mNum14DayActiveLogs; + } + + public int getNum28DayActiveLogs() { + return mNum28DayActiveLogs; + } + + public int getLastDailyWallpaperRotationStatus() { + return mLastDailyWallpaperRotationStatus; + } + + public int getNumDaysDailyRotationFailed() { + return mNumDaysDailyRotationFailed; + } + + public int getNumDaysDailyRotationNotAttempted() { + return mNumDaysDailyRotationNotAttempted; + } + + public int getLastDailyWallpaperUpdateResult() { + return mLastDailyWallpaperUpdateResult; + } + + public int getStandalonePreviewLaunches() { + return mStandalonePreviewLaunches; + } + + public int getNumRestores() { + return mNumRestores; + } + + public int getWallpaperPosition() { + return mWallpaperPosition; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestWallpaperCategory.java b/tests/src/com/android/wallpaper/testing/TestWallpaperCategory.java new file mode 100644 index 0000000..c69ecf8 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestWallpaperCategory.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + + +import com.android.wallpaper.model.WallpaperCategory; +import com.android.wallpaper.model.WallpaperInfo; +import com.android.wallpaper.model.WallpaperRotationInitializer; +import com.android.wallpaper.model.WallpaperRotationInitializer.RotationInitializationState; + +import java.util.List; + +/** + * Test-only subclass of {@link WallpaperCategory} which can be configured to provide a test double + * {@link WallpaperRotationInitializer}. + */ +public class TestWallpaperCategory extends WallpaperCategory { + private boolean mIsRotationEnabled; + private TestWallpaperRotationInitializer mWallpaperRotationInitializer; + + public TestWallpaperCategory(String title, String collectionId, List wallpapers, + int priority) { + super(title, collectionId, wallpapers, priority); + mIsRotationEnabled = false; + mWallpaperRotationInitializer = new TestWallpaperRotationInitializer(); + } + + @Override + public WallpaperRotationInitializer getWallpaperRotationInitializer() { + return (mIsRotationEnabled) ? mWallpaperRotationInitializer : null; + } + + @Override + public List getMutableWallpapers() { + return super.getMutableWallpapers(); + } + + /** Sets whether rotation is enabled on this category. */ + public void setIsRotationEnabled(boolean isRotationEnabled) { + mIsRotationEnabled = isRotationEnabled; + } + + public void setRotationInitializationState(@RotationInitializationState int rotationState) { + mWallpaperRotationInitializer.setRotationInitializationState(rotationState); + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestWallpaperInfo.java b/tests/src/com/android/wallpaper/testing/TestWallpaperInfo.java new file mode 100644 index 0000000..c0ccee6 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestWallpaperInfo.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.app.Activity; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.wallpaper.asset.Asset; +import com.android.wallpaper.model.InlinePreviewIntentFactory; +import com.android.wallpaper.model.WallpaperInfo; + +import java.util.Arrays; +import java.util.List; + +/** + * Test model object for a wallpaper coming from local drawable resources. + */ +public class TestWallpaperInfo extends WallpaperInfo { + public static final int COLOR_BLACK = 0; + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public TestWallpaperInfo createFromParcel(Parcel in) { + return new TestWallpaperInfo(in); + } + + @Override + public TestWallpaperInfo[] newArray(int size) { + return new TestWallpaperInfo[size]; + } + }; + private int mPixelColor; + private TestAsset mAsset; + private TestAsset mThumbAsset; + private List mAttributions; + private android.app.WallpaperInfo mWallpaperComponent; + private String mActionUrl; + private String mBaseImageUrl; + private String mCollectionId; + private String mWallpaperId; + private boolean mIsAssetCorrupt; + private int mBackupPermission; + + /** Constructs a test WallpaperInfo object representing a 1x1 wallpaper of the given color. */ + public TestWallpaperInfo(int pixelColor) { + this(pixelColor, "test-wallpaper"); + } + + /** Constructs a test WallpaperInfo object representing a 1x1 wallpaper of the given color. */ + public TestWallpaperInfo(int pixelColor, String id) { + mPixelColor = pixelColor; + mAttributions = Arrays.asList("Test wallpaper"); + mWallpaperComponent = null; + mIsAssetCorrupt = false; + mBackupPermission = BACKUP_ALLOWED; + mWallpaperId = id; + } + + private TestWallpaperInfo(Parcel in) { + mPixelColor = in.readInt(); + mAttributions = in.createStringArrayList(); + mActionUrl = in.readString(); + mBaseImageUrl = in.readString(); + mCollectionId = in.readString(); + mWallpaperId = in.readString(); + mIsAssetCorrupt = in.readInt() == 1; + mBackupPermission = in.readInt(); + } + + @Override + public Drawable getOverlayIcon(Context context) { + return null; + } + + @Override + public List getAttributions(Context context) { + return mAttributions; + } + + /** + * Override default "Test wallpaper" attributions for testing. + */ + public void setAttributions(List attributions) { + mAttributions = attributions; + } + + @Override + public String getActionUrl(Context unused) { + return mActionUrl; + } + + /** Sets the action URL for this wallpaper. */ + public void setActionUrl(String actionUrl) { + mActionUrl = actionUrl; + } + + @Override + public String getBaseImageUrl() { + return mBaseImageUrl; + } + + /** Sets the base image URL for this wallpaper. */ + public void setBaseImageUrl(String baseImageUrl) { + mBaseImageUrl = baseImageUrl; + } + + @Override + public String getCollectionId(Context unused) { + return mCollectionId; + } + + /** Sets the collection ID for this wallpaper. */ + public void setCollectionId(String collectionId) { + mCollectionId = collectionId; + } + + @Override + public String getWallpaperId() { + return mWallpaperId; + } + + /** Sets the ID for this wallpaper. */ + public void setWallpaperId(String wallpaperId) { + mWallpaperId = wallpaperId; + } + + @Override + public Asset getAsset(Context context) { + if (mAsset == null) { + mAsset = new TestAsset(mPixelColor, mIsAssetCorrupt); + } + return mAsset; + } + + @Override + public Asset getThumbAsset(Context context) { + if (mThumbAsset == null) { + mThumbAsset = new TestAsset(mPixelColor, mIsAssetCorrupt); + } + return mThumbAsset; + } + + @Override + public void showPreview(Activity srcActivity, + InlinePreviewIntentFactory inlinePreviewIntentFactory, int requestCode) { + srcActivity.startActivityForResult( + inlinePreviewIntentFactory.newIntent(srcActivity, this), requestCode); + } + + @Override + @BackupPermission + public int getBackupPermission() { + return mBackupPermission; + } + + public void setBackupPermission(@BackupPermission int backupPermission) { + mBackupPermission = backupPermission; + } + + @Override + public android.app.WallpaperInfo getWallpaperComponent() { + return mWallpaperComponent; + } + + public void setWallpaperComponent(android.app.WallpaperInfo wallpaperComponent) { + mWallpaperComponent = wallpaperComponent; + } + + /** + * Simulates that the {@link Asset} instances returned by calls to #getAsset and #getThumbAsset + * on + * this object are "corrupt" and will fail to perform decode operations such as #decodeBitmap, + * #decodeBitmapRegion, #decodeRawDimensions, etc (these methods will call their callbacks with + * null instead of meaningful objects). + */ + public void corruptAssets() { + mIsAssetCorrupt = true; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeInt(mPixelColor); + parcel.writeStringList(mAttributions); + parcel.writeString(mActionUrl); + parcel.writeString(mBaseImageUrl); + parcel.writeString(mCollectionId); + parcel.writeString(mWallpaperId); + parcel.writeInt(mIsAssetCorrupt ? 1 : 0); + parcel.writeInt(mBackupPermission); + } + + @Override + public boolean equals(Object object) { + if (object == this) { + return true; + } + if (object instanceof TestWallpaperInfo) { + return mPixelColor == ((TestWallpaperInfo) object).mPixelColor; + } + return false; + } + + @Override + public int hashCode() { + return mPixelColor; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestWallpaperManagerCompat.java b/tests/src/com/android/wallpaper/testing/TestWallpaperManagerCompat.java new file mode 100644 index 0000000..69f6839 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestWallpaperManagerCompat.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.app.WallpaperManager; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import com.android.wallpaper.compat.WallpaperManagerCompat; + +import java.io.IOException; +import java.io.InputStream; + +/** Test double for {@link WallpaperManagerCompat}. */ +public class TestWallpaperManagerCompat extends WallpaperManagerCompat { + private static final String TAG = "TestWPManagerCompat"; + + ParcelFileDescriptor mSystemParcelFd; + ParcelFileDescriptor mLockParcelFd; + int mHomeWallpaperId = 0; + int mLockWallpaperId = 0; + + private boolean mAllowBackup; + private Context mAppContext; + private Drawable mTestDrawable; + + public TestWallpaperManagerCompat(Context appContext) { + mAppContext = appContext; + mAllowBackup = true; + } + + @Override + public int setStream(InputStream stream, Rect visibleCropHint, boolean allowBackup, + int whichWallpaper) throws IOException { + mAllowBackup = allowBackup; + return ++mHomeWallpaperId; + } + + @Override + public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup, + int whichWallpaper) throws IOException { + mAllowBackup = allowBackup; + return ++mLockWallpaperId; + } + + @Override + public ParcelFileDescriptor getWallpaperFile(int whichWallpaper) { + if (whichWallpaper == WallpaperManagerCompat.FLAG_SYSTEM) { + return mSystemParcelFd; + } else if (whichWallpaper == WallpaperManagerCompat.FLAG_LOCK) { + return mLockParcelFd; + } else { + // :( + return null; + } + } + + @Override + public Drawable getDrawable() { + if (mTestDrawable != null) { + return mTestDrawable; + } + + // Retrieve WallpaperManager using Context#getSystemService instead of + // WallpaperManager#getInstance so it can be mocked out in test. + WallpaperManager wallpaperManager = + (WallpaperManager) mAppContext.getSystemService(Context.WALLPAPER_SERVICE); + return wallpaperManager.getDrawable(); + } + + @Override + public int getWallpaperId(@WallpaperLocation int whichWallpaper) { + switch (whichWallpaper) { + case WallpaperManagerCompat.FLAG_SYSTEM: + return mHomeWallpaperId; + case WallpaperManagerCompat.FLAG_LOCK: + return mLockWallpaperId; + default: + throw new IllegalArgumentException( + "Wallpaper location must be one of FLAG_SYSTEM or " + + "FLAG_LOCK but the value " + whichWallpaper + " was provided."); + } + } + + public void setWallpaperFile(int whichWallpaper, ParcelFileDescriptor file) { + if (whichWallpaper == WallpaperManagerCompat.FLAG_SYSTEM) { + mSystemParcelFd = file; + } else if (whichWallpaper == WallpaperManagerCompat.FLAG_LOCK) { + mLockParcelFd = file; + } else { + Log.e(TAG, "Called setWallpaperFile without a valid distinct 'which' argument."); + } + } + + public void setWallpaperId(@WallpaperLocation int whichWallpaper, int wallpaperId) { + switch (whichWallpaper) { + case WallpaperManagerCompat.FLAG_SYSTEM: + mHomeWallpaperId = wallpaperId; + break; + case WallpaperManagerCompat.FLAG_LOCK: + mLockWallpaperId = wallpaperId; + break; + default: + throw new IllegalArgumentException( + "Wallpaper location must be one of FLAG_SYSTEM or " + + "FLAG_LOCK but the value " + whichWallpaper + " was provided."); + } + } + + public void setDrawable(Drawable drawable) { + mTestDrawable = drawable; + } + + /** Returns whether backup is allowed for the last set wallpaper. */ + public boolean isBackupAllowed() { + return mAllowBackup; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestWallpaperPersister.java b/tests/src/com/android/wallpaper/testing/TestWallpaperPersister.java new file mode 100644 index 0000000..44a8167 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestWallpaperPersister.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Rect; + +import androidx.annotation.Nullable; + +import com.android.wallpaper.asset.Asset; +import com.android.wallpaper.asset.Asset.BitmapReceiver; +import com.android.wallpaper.model.WallpaperInfo; +import com.android.wallpaper.module.InjectorProvider; +import com.android.wallpaper.module.WallpaperChangedNotifier; +import com.android.wallpaper.module.WallpaperPersister; +import com.android.wallpaper.module.WallpaperPreferences; + +import java.util.List; + +/** + * Test double for {@link WallpaperPersister}. + */ +public class TestWallpaperPersister implements WallpaperPersister { + + private Context mAppContext; + private WallpaperPreferences mPrefs; + private WallpaperChangedNotifier mWallpaperChangedNotifier; + private Bitmap mCurrentHomeWallpaper; + private Bitmap mCurrentLockWallpaper; + private Bitmap mPendingHomeWallpaper; + private Bitmap mPendingLockWallpaper; + private List mHomeAttributions; + private String mHomeActionUrl; + @Destination + private int mDestination; + private WallpaperPersister.SetWallpaperCallback mCallback; + private boolean mFailNextCall; + private Rect mCropRect; + private float mScale; + @WallpaperPosition + private int mWallpaperPosition; + + public TestWallpaperPersister(Context appContext) { + mAppContext = appContext; + mPrefs = InjectorProvider.getInjector().getPreferences(appContext); + mWallpaperChangedNotifier = WallpaperChangedNotifier.getInstance(); + + mCurrentHomeWallpaper = null; + mCurrentLockWallpaper = null; + mPendingHomeWallpaper = null; + mPendingLockWallpaper = null; + mFailNextCall = false; + mScale = -1.0f; + } + + @Override + public void setIndividualWallpaper(final WallpaperInfo wallpaperInfo, Asset asset, + @Nullable final Rect cropRect, final float scale, final @Destination int destination, + final WallpaperPersister.SetWallpaperCallback callback) { + asset.decodeBitmap(50, 50, new BitmapReceiver() { + @Override + public void onBitmapDecoded(@Nullable Bitmap bitmap) { + if (destination == DEST_HOME_SCREEN || destination == DEST_BOTH) { + mPendingHomeWallpaper = bitmap; + mPrefs.setHomeWallpaperAttributions(wallpaperInfo.getAttributions(mAppContext)); + mPrefs.setWallpaperPresentationMode( + WallpaperPreferences.PRESENTATION_MODE_STATIC); + mPrefs.setHomeWallpaperRemoteId(wallpaperInfo.getWallpaperId()); + } + if (destination == DEST_LOCK_SCREEN || destination == DEST_BOTH) { + mPendingLockWallpaper = bitmap; + mPrefs.setLockWallpaperAttributions(wallpaperInfo.getAttributions(mAppContext)); + } + mDestination = destination; + mCallback = callback; + mCropRect = cropRect; + mScale = scale; + } + }); + } + + @Override + public void setIndividualWallpaperWithPosition(Activity activity, WallpaperInfo wallpaper, + @WallpaperPosition int wallpaperPosition, SetWallpaperCallback callback) { + wallpaper.getAsset(activity).decodeBitmap(50, 50, new BitmapReceiver() { + @Override + public void onBitmapDecoded(@Nullable Bitmap bitmap) { + mPendingHomeWallpaper = bitmap; + mPrefs.setHomeWallpaperAttributions(wallpaper.getAttributions(mAppContext)); + mPrefs.setHomeWallpaperBaseImageUrl(wallpaper.getBaseImageUrl()); + mPrefs.setHomeWallpaperActionUrl(wallpaper.getActionUrl(mAppContext)); + mPrefs.setHomeWallpaperCollectionId(wallpaper.getCollectionId(mAppContext)); + mPrefs.setHomeWallpaperRemoteId(wallpaper.getWallpaperId()); + mPrefs.setWallpaperPresentationMode(WallpaperPreferences.PRESENTATION_MODE_STATIC); + mPendingLockWallpaper = bitmap; + mPrefs.setLockWallpaperAttributions(wallpaper.getAttributions(mAppContext)); + + mDestination = WallpaperPersister.DEST_BOTH; + mCallback = callback; + mWallpaperPosition = wallpaperPosition; + } + }); + } + + @Override + public boolean setWallpaperInRotation(Bitmap wallpaperBitmap, List attributions, + int actionLabelRes, int actionIconRes, String actionUrl, String collectionId) { + if (mFailNextCall) { + return false; + } + + mCurrentHomeWallpaper = wallpaperBitmap; + mCurrentLockWallpaper = wallpaperBitmap; + mHomeAttributions = attributions; + mHomeActionUrl = actionUrl; + return true; + } + + @Override + public int setWallpaperBitmapInNextRotation(Bitmap wallpaperBitmap) { + mCurrentHomeWallpaper = wallpaperBitmap; + mCurrentLockWallpaper = wallpaperBitmap; + return 1; + } + + @Override + public boolean finalizeWallpaperForNextRotation(List attributions, String actionUrl, + int actionLabelRes, int actionIconRes, String collectionId, int wallpaperId) { + mHomeAttributions = attributions; + mHomeActionUrl = actionUrl; + return true; + } + + /** Returns mock system wallpaper bitmap. */ + public Bitmap getCurrentHomeWallpaper() { + return mCurrentHomeWallpaper; + } + + /** Returns mock lock screen wallpaper bitmap. */ + public Bitmap getCurrentLockWallpaper() { + return mCurrentLockWallpaper; + } + + /** Returns mock home attributions. */ + public List getHomeAttributions() { + return mHomeAttributions; + } + + /** Returns the home wallpaper action URL. */ + public String getHomeActionUrl() { + return mHomeActionUrl; + } + + /** Returns the Destination a wallpaper was most recently set on. */ + @Destination + public int getLastDestination() { + return mDestination; + } + + /** + * Sets whether the next "set wallpaper" operation should fail or succeed. + */ + public void setFailNextCall(Boolean failNextCall) { + mFailNextCall = failNextCall; + } + + /** + * Implemented so synchronous test methods can control the completion of what would otherwise be + * an asynchronous operation. + */ + public void finishSettingWallpaper() { + if (mFailNextCall) { + mCallback.onError(null /* throwable */); + } else { + if (mDestination == DEST_HOME_SCREEN || mDestination == DEST_BOTH) { + mCurrentHomeWallpaper = mPendingHomeWallpaper; + mPendingHomeWallpaper = null; + } + if (mDestination == DEST_LOCK_SCREEN || mDestination == DEST_BOTH) { + mCurrentLockWallpaper = mPendingLockWallpaper; + mPendingLockWallpaper = null; + } + mCallback.onSuccess(); + mWallpaperChangedNotifier.notifyWallpaperChanged(); + } + } + + @Override + public void setWallpaperInfoInPreview(WallpaperInfo wallpaperInfo) { + } + + @Override + public void onLiveWallpaperSet() { + } + + /** Returns the last requested wallpaper bitmap scale. */ + public float getScale() { + return mScale; + } + + /** Returns the last requested wallpaper crop. */ + public Rect getCropRect() { + return mCropRect; + } + + /** Returns the last selected wallpaper position option. */ + @WallpaperPosition + public int getWallpaperPosition() { + return mWallpaperPosition; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestWallpaperPreferences.java b/tests/src/com/android/wallpaper/testing/TestWallpaperPreferences.java new file mode 100644 index 0000000..715e81b --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestWallpaperPreferences.java @@ -0,0 +1,457 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import androidx.annotation.Nullable; + +import com.android.wallpaper.module.WallpaperPreferences; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Test implementation of the WallpaperPreferences interface. Just keeps prefs in memory. + */ +public class TestWallpaperPreferences implements WallpaperPreferences { + + @PresentationMode + private int mWallpaperPresentationMode; + + private List mHomeScreenAttributions; + private long mHomeScreenBitmapHashCode; + private int mHomeWallpaperManagerId; + private String mHomeScreenPackageName; + private String mHomeActionUrl; + private String mHomeBaseImageUrl; + private String mHomeCollectionId; + private String mHomeWallpaperRemoteId; + + private List mLockScreenAttributions; + private long mLockScreenBitmapHashCode; + private int mLockWallpaperManagerId; + private String mLockActionUrl; + private String mLockCollectionId; + + private List mDailyRotations; + private long mDailyWallpaperEnabledTimestamp; + private long mLastDailyLogTimestamp; + private long mLastAppActiveTimestamp; + private int mLastDailyWallpaperRotationStatus; + private long mLastDailyWallpaperRotationStatusTimestamp; + private long mLastSyncTimestamp; + @PendingWallpaperSetStatus + private int mPendingWallpaperSetStatus; + @PendingDailyWallpaperUpdateStatus + private int mPendingDailyWallpaperUpdateStatus; + private int mNumDaysDailyRotationFailed; + private int mNumDaysDailyRotationNotAttempted; + private int mHomeWallpaperActionLabelRes; + private int mHomeWallpaperActionIconRes; + private int mLockWallpaperActionLabelRes; + private int mLockWallpaperActionIconRes; + + public TestWallpaperPreferences() { + mWallpaperPresentationMode = WallpaperPreferences.PRESENTATION_MODE_STATIC; + mHomeScreenAttributions = Arrays.asList("Android wallpaper"); + mHomeScreenBitmapHashCode = 0; + mHomeWallpaperManagerId = 0; + + mLockScreenAttributions = Arrays.asList("Android wallpaper"); + mLockScreenBitmapHashCode = 0; + mLockWallpaperManagerId = 0; + + mDailyRotations = new ArrayList<>(); + mDailyWallpaperEnabledTimestamp = -1; + mLastDailyLogTimestamp = -1; + mLastDailyWallpaperRotationStatus = -1; + mLastDailyWallpaperRotationStatusTimestamp = 0; + mLastSyncTimestamp = 0; + mPendingWallpaperSetStatus = WALLPAPER_SET_NOT_PENDING; + } + + @Override + public int getWallpaperPresentationMode() { + return mWallpaperPresentationMode; + } + + @Override + public void setWallpaperPresentationMode(@PresentationMode int presentationMode) { + mWallpaperPresentationMode = presentationMode; + } + + @Override + public List getHomeWallpaperAttributions() { + return mHomeScreenAttributions; + } + + @Override + public void setHomeWallpaperAttributions(List attributions) { + mHomeScreenAttributions = attributions; + } + + @Override + public String getHomeWallpaperActionUrl() { + return mHomeActionUrl; + } + + @Override + public void setHomeWallpaperActionUrl(String actionUrl) { + mHomeActionUrl = actionUrl; + } + + @Override + public int getHomeWallpaperActionLabelRes() { + return mHomeWallpaperActionLabelRes; + } + + @Override + public void setHomeWallpaperActionLabelRes(int resId) { + mHomeWallpaperActionLabelRes = resId; + } + + @Override + public int getHomeWallpaperActionIconRes() { + return mHomeWallpaperActionIconRes; + } + + @Override + public void setHomeWallpaperActionIconRes(int resId) { + mHomeWallpaperActionIconRes = resId; + } + + @Override + public String getHomeWallpaperBaseImageUrl() { + return mHomeBaseImageUrl; + } + + @Override + public void setHomeWallpaperBaseImageUrl(String baseImageUrl) { + mHomeBaseImageUrl = baseImageUrl; + } + + @Override + public String getHomeWallpaperCollectionId() { + return mHomeCollectionId; + } + + @Override + public void setHomeWallpaperCollectionId(String collectionId) { + mHomeCollectionId = collectionId; + } + + @Override + public String getHomeWallpaperBackingFileName() { + return null; + } + + @Override + public void setHomeWallpaperBackingFileName(String fileName) { + + } + + @Override + public void clearHomeWallpaperMetadata() { + mHomeScreenAttributions = null; + mWallpaperPresentationMode = WallpaperPreferences.PRESENTATION_MODE_STATIC; + mHomeScreenBitmapHashCode = 0; + mHomeScreenPackageName = null; + mHomeWallpaperManagerId = 0; + } + + @Override + public long getHomeWallpaperHashCode() { + return mHomeScreenBitmapHashCode; + } + + @Override + public void setHomeWallpaperHashCode(long hashCode) { + mHomeScreenBitmapHashCode = hashCode; + } + + @Override + public String getHomeWallpaperPackageName() { + return mHomeScreenPackageName; + } + + @Override + public void setHomeWallpaperPackageName(String packageName) { + mHomeScreenPackageName = packageName; + } + + @Override + public int getHomeWallpaperManagerId() { + return mHomeWallpaperManagerId; + } + + @Override + public void setHomeWallpaperManagerId(int homeWallpaperId) { + mHomeWallpaperManagerId = homeWallpaperId; + } + + @Override + public String getHomeWallpaperRemoteId() { + return mHomeWallpaperRemoteId; + } + + @Override + public void setHomeWallpaperRemoteId(String wallpaperRemoteId) { + mHomeWallpaperRemoteId = wallpaperRemoteId; + } + + @Override + public List getLockWallpaperAttributions() { + return mLockScreenAttributions; + } + + @Override + public void setLockWallpaperAttributions(List attributions) { + mLockScreenAttributions = attributions; + } + + @Override + public String getLockWallpaperActionUrl() { + return mLockActionUrl; + } + + @Override + public void setLockWallpaperActionUrl(String actionUrl) { + mLockActionUrl = actionUrl; + } + + @Override + public int getLockWallpaperActionLabelRes() { + return mLockWallpaperActionLabelRes; + } + + @Override + public void setLockWallpaperActionLabelRes(int resId) { + mLockWallpaperActionLabelRes = resId; + } + + @Override + public int getLockWallpaperActionIconRes() { + return mLockWallpaperActionIconRes; + } + + @Override + public void setLockWallpaperActionIconRes(int resId) { + mLockWallpaperActionIconRes = resId; + } + + @Override + public String getLockWallpaperCollectionId() { + return mLockCollectionId; + } + + @Override + public void setLockWallpaperCollectionId(String collectionId) { + mLockCollectionId = collectionId; + } + + @Override + public String getLockWallpaperBackingFileName() { + return null; + } + + @Override + public void setLockWallpaperBackingFileName(String fileName) { + + } + + @Override + public void clearLockWallpaperMetadata() { + mLockScreenAttributions = null; + mLockScreenBitmapHashCode = 0; + mLockWallpaperManagerId = 0; + } + + @Override + public long getLockWallpaperHashCode() { + return mLockScreenBitmapHashCode; + } + + @Override + public void setLockWallpaperHashCode(long hashCode) { + mLockScreenBitmapHashCode = hashCode; + } + + @Override + public int getLockWallpaperId() { + return mLockWallpaperManagerId; + } + + @Override + public void setLockWallpaperId(int lockWallpaperId) { + mLockWallpaperManagerId = lockWallpaperId; + } + + @Override + public void addDailyRotation(long timestamp) { + mDailyRotations.add(timestamp); + } + + @Override + public long getLastDailyRotationTimestamp() { + if (mDailyRotations.size() == 0) { + return -1; + } + + return mDailyRotations.get(mDailyRotations.size() - 1); + } + + @Override + public List getDailyRotationsInLastWeek() { + return mDailyRotations; + } + + @Nullable + @Override + public List getDailyRotationsPreviousDay() { + return null; + } + + @Override + public long getDailyWallpaperEnabledTimestamp() { + return mDailyWallpaperEnabledTimestamp; + } + + @Override + public void setDailyWallpaperEnabledTimestamp(long timestamp) { + mDailyWallpaperEnabledTimestamp = timestamp; + } + + @Override + public void clearDailyRotations() { + mDailyRotations.clear(); + } + + @Override + public long getLastDailyLogTimestamp() { + return mLastDailyLogTimestamp; + } + + @Override + public void setLastDailyLogTimestamp(long timestamp) { + mLastDailyLogTimestamp = timestamp; + } + + @Override + public long getLastAppActiveTimestamp() { + return mLastAppActiveTimestamp; + } + + @Override + public void setLastAppActiveTimestamp(long timestamp) { + mLastAppActiveTimestamp = timestamp; + } + + @Override + public void setDailyWallpaperRotationStatus(int status, long timestamp) { + mLastDailyWallpaperRotationStatus = status; + mLastDailyWallpaperRotationStatusTimestamp = timestamp; + } + + @Override + public int getDailyWallpaperLastRotationStatus() { + return mLastDailyWallpaperRotationStatus; + } + + @Override + public long getDailyWallpaperLastRotationStatusTimestamp() { + return mLastDailyWallpaperRotationStatusTimestamp; + } + + @Override + public long getLastSyncTimestamp() { + return mLastSyncTimestamp; + } + + @Override + public void setLastSyncTimestamp(long timestamp) { + mLastSyncTimestamp = timestamp; + } + + @Override + public void setPendingWallpaperSetStatusSync(@PendingWallpaperSetStatus int setStatus) { + mPendingWallpaperSetStatus = setStatus; + } + + @Override + public int getPendingWallpaperSetStatus() { + return mPendingWallpaperSetStatus; + } + + @Override + public void setPendingWallpaperSetStatus(@PendingWallpaperSetStatus int setStatus) { + mPendingWallpaperSetStatus = setStatus; + } + + @Override + public void setPendingDailyWallpaperUpdateStatusSync( + @PendingDailyWallpaperUpdateStatus int updateStatus) { + mPendingDailyWallpaperUpdateStatus = updateStatus; + } + + @Override + public int getPendingDailyWallpaperUpdateStatus() { + return mPendingDailyWallpaperUpdateStatus; + } + + @Override + public void setPendingDailyWallpaperUpdateStatus( + @PendingDailyWallpaperUpdateStatus int updateStatus) { + mPendingDailyWallpaperUpdateStatus = updateStatus; + } + + @Override + public void incrementNumDaysDailyRotationFailed() { + mNumDaysDailyRotationFailed++; + } + + @Override + public int getNumDaysDailyRotationFailed() { + return mNumDaysDailyRotationFailed; + } + + public void setNumDaysDailyRotationFailed(int days) { + mNumDaysDailyRotationFailed = days; + } + + @Override + public void resetNumDaysDailyRotationFailed() { + mNumDaysDailyRotationFailed = 0; + } + + @Override + public void incrementNumDaysDailyRotationNotAttempted() { + mNumDaysDailyRotationNotAttempted++; + } + + @Override + public int getNumDaysDailyRotationNotAttempted() { + return mNumDaysDailyRotationNotAttempted; + } + + public void setNumDaysDailyRotationNotAttempted(int days) { + mNumDaysDailyRotationNotAttempted = days; + } + + @Override + public void resetNumDaysDailyRotationNotAttempted() { + mNumDaysDailyRotationNotAttempted = 0; + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestWallpaperRefresher.java b/tests/src/com/android/wallpaper/testing/TestWallpaperRefresher.java new file mode 100644 index 0000000..97961fe --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestWallpaperRefresher.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + + +import android.app.WallpaperManager; +import android.content.Context; + +import com.android.wallpaper.compat.BuildCompat; +import com.android.wallpaper.model.WallpaperMetadata; +import com.android.wallpaper.module.InjectorProvider; +import com.android.wallpaper.module.WallpaperPreferences; +import com.android.wallpaper.module.WallpaperRefresher; + +/** + * Test implementation of {@link WallpaperRefresher} which simply provides whatever metadata is + * saved in WallpaperPreferences and the image wallpaper set to {@link WallpaperManager}. + */ +public class TestWallpaperRefresher implements WallpaperRefresher { + + private final Context mAppContext; + + /** + * @param context The application's context. + */ + public TestWallpaperRefresher(Context context) { + mAppContext = context.getApplicationContext(); + } + + @Override + public void refresh(RefreshListener listener) { + + WallpaperPreferences prefs = InjectorProvider.getInjector().getPreferences(mAppContext); + + if (BuildCompat.isAtLeastN() && prefs.getLockWallpaperId() > 0) { + listener.onRefreshed( + new WallpaperMetadata( + prefs.getHomeWallpaperAttributions(), + prefs.getHomeWallpaperActionUrl(), + prefs.getHomeWallpaperActionLabelRes(), + prefs.getHomeWallpaperActionIconRes(), + prefs.getHomeWallpaperCollectionId(), + prefs.getHomeWallpaperBackingFileName(), + null /* wallpaperComponent */), + new WallpaperMetadata( + prefs.getLockWallpaperAttributions(), + prefs.getLockWallpaperActionUrl(), + prefs.getLockWallpaperActionLabelRes(), + prefs.getLockWallpaperActionIconRes(), + prefs.getLockWallpaperCollectionId(), + prefs.getLockWallpaperBackingFileName(), + null /* wallpaperComponent */), + prefs.getWallpaperPresentationMode()); + } else { + listener.onRefreshed( + new WallpaperMetadata( + prefs.getHomeWallpaperAttributions(), + prefs.getHomeWallpaperActionUrl(), + prefs.getHomeWallpaperActionLabelRes(), + prefs.getHomeWallpaperActionIconRes(), + prefs.getHomeWallpaperCollectionId(), + prefs.getHomeWallpaperBackingFileName(), + null /* wallpaperComponent */), + null, + prefs.getWallpaperPresentationMode()); + } + } +} diff --git a/tests/src/com/android/wallpaper/testing/TestWallpaperRotationInitializer.java b/tests/src/com/android/wallpaper/testing/TestWallpaperRotationInitializer.java new file mode 100644 index 0000000..9494d19 --- /dev/null +++ b/tests/src/com/android/wallpaper/testing/TestWallpaperRotationInitializer.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.testing; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.wallpaper.model.WallpaperRotationInitializer; +import com.android.wallpaper.module.InjectorProvider; +import com.android.wallpaper.module.WallpaperPreferences; + +/** + * Test implementation of {@link WallpaperRotationInitializer}. + */ +public class TestWallpaperRotationInitializer implements WallpaperRotationInitializer { + + private boolean mIsRotationInitialized; + @NetworkPreference + private int mNetworkPreference; + private Listener mListener; + @RotationInitializationState + private int mRotationInitializationState; + + TestWallpaperRotationInitializer() { + mIsRotationInitialized = false; + mNetworkPreference = NETWORK_PREFERENCE_WIFI_ONLY; + mRotationInitializationState = WallpaperRotationInitializer.ROTATION_NOT_INITIALIZED; + } + + TestWallpaperRotationInitializer(@RotationInitializationState int rotationState) { + mIsRotationInitialized = false; + mNetworkPreference = NETWORK_PREFERENCE_WIFI_ONLY; + mRotationInitializationState = rotationState; + } + + private TestWallpaperRotationInitializer(Parcel unused) { + mIsRotationInitialized = false; + mNetworkPreference = NETWORK_PREFERENCE_WIFI_ONLY; + } + + @Override + public void setFirstWallpaperInRotation(Context context, + @NetworkPreference int networkPreference, + Listener listener) { + mListener = listener; + mNetworkPreference = networkPreference; + } + + @Override + public boolean startRotation(Context appContext) { + WallpaperPreferences wallpaperPreferences = + InjectorProvider.getInjector().getPreferences(appContext); + wallpaperPreferences.setWallpaperPresentationMode( + WallpaperPreferences.PRESENTATION_MODE_ROTATING); + return true; + } + + @Override + public void fetchRotationInitializationState(Context context, RotationStateListener listener) { + listener.onRotationStateReceived(mRotationInitializationState); + } + + @Override + public int getRotationInitializationStateDirty(Context context) { + return mRotationInitializationState; + } + + /** Sets the mocked rotation initialization state. */ + public void setRotationInitializationState(@RotationInitializationState int rotationState) { + mRotationInitializationState = rotationState; + } + + /** + * Simulates completion of the asynchronous task to download the first wallpaper in a rotation.. + * + * @param isSuccessful Whether the first wallpaper downloaded successfully. + */ + public void finishDownloadingFirstWallpaper(boolean isSuccessful) { + if (isSuccessful) { + mIsRotationInitialized = true; + mListener.onFirstWallpaperInRotationSet(); + } else { + mIsRotationInitialized = false; + mListener.onError(); + } + } + + /** Returns whether a wallpaper rotation is initialized. */ + public boolean isRotationInitialized() { + return mIsRotationInitialized; + } + + /** Returns whether a wallpaper rotation is enabled for WiFi-only. */ + public boolean isWifiOnly() { + return mNetworkPreference == NETWORK_PREFERENCE_WIFI_ONLY; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + } + + @Override + public int describeContents() { + return 0; + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public TestWallpaperRotationInitializer createFromParcel(Parcel in) { + return new TestWallpaperRotationInitializer(in); + } + + @Override + public TestWallpaperRotationInitializer[] newArray(int size) { + return new TestWallpaperRotationInitializer[size]; + } + }; +} -- cgit v1.2.3 From 55822c0f54c3412e07ee07611f343bc79e36ddf0 Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Thu, 24 Oct 2019 14:57:38 -0700 Subject: Add PreviewActivityTests Migrate tests for PreviewActivity Bug: 141954442 Change-Id: I8cdacfd1268ee4817cf1b64b67a73e60aa773f47 --- .../wallpaper/picker/PreviewActivityTest.java | 510 +++++++++++++++++++++ .../individual/IndividualPickerActivityTest.java | 4 +- .../wallpaper/testing/TestWallpaperPersister.java | 33 +- 3 files changed, 527 insertions(+), 20 deletions(-) create mode 100644 tests/src/com/android/wallpaper/picker/PreviewActivityTest.java diff --git a/tests/src/com/android/wallpaper/picker/PreviewActivityTest.java b/tests/src/com/android/wallpaper/picker/PreviewActivityTest.java new file mode 100644 index 0000000..e1feba5 --- /dev/null +++ b/tests/src/com/android/wallpaper/picker/PreviewActivityTest.java @@ -0,0 +1,510 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wallpaper.picker; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; + +import static junit.framework.TestCase.assertFalse; + +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.graphics.Bitmap; +import android.graphics.Point; +import android.graphics.Rect; +import android.widget.TextView; + +import androidx.test.espresso.intent.Intents; +import androidx.test.filters.MediumTest; +import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.rule.ActivityTestRule; + +import com.android.wallpaper.R; +import com.android.wallpaper.module.Injector; +import com.android.wallpaper.module.InjectorProvider; +import com.android.wallpaper.module.UserEventLogger; +import com.android.wallpaper.module.WallpaperPersister; +import com.android.wallpaper.testing.TestAsset; +import com.android.wallpaper.testing.TestExploreIntentChecker; +import com.android.wallpaper.testing.TestInjector; +import com.android.wallpaper.testing.TestUserEventLogger; +import com.android.wallpaper.testing.TestWallpaperInfo; +import com.android.wallpaper.testing.TestWallpaperPersister; +import com.android.wallpaper.util.ScreenSizeCalculator; +import com.android.wallpaper.util.WallpaperCropUtils; + +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tests for {@link PreviewActivity}. + */ +@RunWith(AndroidJUnit4ClassRunner.class) +@MediumTest +public class PreviewActivityTest { + + private static final float FLOAT_ERROR_MARGIN = 0.001f; + private static final String ACTION_URL = "http://google.com"; + + private TestWallpaperInfo mMockWallpaper; + private Injector mInjector; + private TestWallpaperPersister mWallpaperPersister; + private TestUserEventLogger mEventLogger; + private TestExploreIntentChecker mExploreIntentChecker; + + @Rule + public ActivityTestRule mActivityRule = + new ActivityTestRule<>(PreviewActivity.class, false, false); + + @Before + public void setUp() { + + mInjector = new TestInjector(); + InjectorProvider.setInjector(mInjector); + + Intents.init(); + + mMockWallpaper = new TestWallpaperInfo(TestWallpaperInfo.COLOR_BLACK); + List attributions = new ArrayList<>(); + attributions.add("Title"); + attributions.add("Subtitle 1"); + attributions.add("Subtitle 2"); + mMockWallpaper.setAttributions(attributions); + mMockWallpaper.setCollectionId("collection"); + mMockWallpaper.setWallpaperId("wallpaper"); + mMockWallpaper.setActionUrl(ACTION_URL); + + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + mWallpaperPersister = (TestWallpaperPersister) mInjector.getWallpaperPersister(context); + mEventLogger = (TestUserEventLogger) mInjector.getUserEventLogger(context); + mExploreIntentChecker = (TestExploreIntentChecker) + mInjector.getExploreIntentChecker(context); + } + + @After + public void tearDown() { + Intents.release(); + mActivityRule.finishActivity(); + } + + private void launchActivityIntentWithMockWallpaper() { + Intent intent = PreviewActivity.newIntent( + InstrumentationRegistry.getInstrumentation().getTargetContext(), mMockWallpaper); + intent.putExtra(BasePreviewActivity.EXTRA_TESTING_MODE_ENABLED, true); + + mActivityRule.launchActivity(intent); + } + + private void finishSettingWallpaper() throws Throwable { + mActivityRule.runOnUiThread(() -> mWallpaperPersister.finishSettingWallpaper()); + } + + @Test + public void testRendersWallpaperDrawableFromIntent() { + launchActivityIntentWithMockWallpaper(); + PreviewActivity activity = mActivityRule.getActivity(); + SubsamplingScaleImageView mosaicView = activity.findViewById(R.id.full_res_image); + + assertTrue(mosaicView.hasImage()); + } + + @Test + public void testClickSetWallpaper_Success_HomeScreen() throws Throwable { + launchActivityIntentWithMockWallpaper(); + assertNull(mWallpaperPersister.getCurrentHomeWallpaper()); + + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + + // Destination dialog is shown; click "Home screen". + onView(withText(R.string.set_wallpaper_home_screen_destination)).perform(click()); + + assertNull(mWallpaperPersister.getCurrentHomeWallpaper()); + + finishSettingWallpaper(); + + // Mock system wallpaper bitmap should be equal to the mock WallpaperInfo's bitmap. + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + Bitmap srcBitmap = ((TestAsset) mMockWallpaper.getAsset(context)).getBitmap(); + assertTrue(srcBitmap.sameAs(mWallpaperPersister.getCurrentHomeWallpaper())); + + // The wallpaper should have been set on the home screen. + assertEquals(WallpaperPersister.DEST_HOME_SCREEN, mWallpaperPersister.getLastDestination()); + assertEquals(1, mEventLogger.getNumWallpaperSetEvents()); + + assertEquals(1, mEventLogger.getNumWallpaperSetResultEvents()); + assertEquals(UserEventLogger.WALLPAPER_SET_RESULT_SUCCESS, + mEventLogger.getLastWallpaperSetResult()); + } + + @Test + public void testClickSetWallpaper_Success_LockScreen() throws Throwable { + launchActivityIntentWithMockWallpaper(); + assertNull(mWallpaperPersister.getCurrentLockWallpaper()); + + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + + // Destination dialog is shown; click "Lock screen." + onView(withText(R.string.set_wallpaper_lock_screen_destination)).perform(click()); + + assertNull(mWallpaperPersister.getCurrentLockWallpaper()); + + finishSettingWallpaper(); + + // Mock system wallpaper bitmap should be equal to the mock WallpaperInfo's bitmap. + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + Bitmap srcBitmap = ((TestAsset) mMockWallpaper.getAsset(context)).getBitmap(); + assertTrue(srcBitmap.sameAs(mWallpaperPersister.getCurrentLockWallpaper())); + + // The wallpaper should have been set on the lock screen. + assertEquals(WallpaperPersister.DEST_LOCK_SCREEN, mWallpaperPersister.getLastDestination()); + assertEquals(1, mEventLogger.getNumWallpaperSetEvents()); + + assertEquals(1, mEventLogger.getNumWallpaperSetResultEvents()); + assertEquals(UserEventLogger.WALLPAPER_SET_RESULT_SUCCESS, + mEventLogger.getLastWallpaperSetResult()); + } + + @Test + public void testClickSetWallpaper_Success_BothHomeAndLockScreen() throws Throwable { + launchActivityIntentWithMockWallpaper(); + assertNull(mWallpaperPersister.getCurrentHomeWallpaper()); + assertNull(mWallpaperPersister.getCurrentLockWallpaper()); + + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + + // Destination dialog is shown; click "Both." + onView(withText(R.string.set_wallpaper_both_destination)).perform(click()); + + assertNull(mWallpaperPersister.getCurrentHomeWallpaper()); + assertNull(mWallpaperPersister.getCurrentLockWallpaper()); + + finishSettingWallpaper(); + + // Mock system wallpaper bitmap should be equal to the mock WallpaperInfo's bitmap. + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + Bitmap srcBitmap = ((TestAsset) mMockWallpaper.getAsset(context)).getBitmap(); + assertTrue(srcBitmap.sameAs(mWallpaperPersister.getCurrentHomeWallpaper())); + assertTrue(srcBitmap.sameAs(mWallpaperPersister.getCurrentLockWallpaper())); + + // The wallpaper should have been set on both the home and the lock screen. + assertEquals(WallpaperPersister.DEST_BOTH, mWallpaperPersister.getLastDestination()); + assertEquals(1, mEventLogger.getNumWallpaperSetEvents()); + + assertEquals(1, mEventLogger.getNumWallpaperSetResultEvents()); + assertEquals(UserEventLogger.WALLPAPER_SET_RESULT_SUCCESS, + mEventLogger.getLastWallpaperSetResult()); + } + + @Test + public void testClickSetWallpaper_Fails_HomeScreen_ShowsErrorDialog() + throws Throwable { + launchActivityIntentWithMockWallpaper(); + assertNull(mWallpaperPersister.getCurrentHomeWallpaper()); + + mWallpaperPersister.setFailNextCall(true); + + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + + // Destination dialog is shown; click "Home screen." + onView(withText(R.string.set_wallpaper_home_screen_destination)).perform(click()); + + finishSettingWallpaper(); + + assertNull(mWallpaperPersister.getCurrentHomeWallpaper()); + onView(withText(R.string.set_wallpaper_error_message)).check(matches(isDisplayed())); + + assertEquals(1, mEventLogger.getNumWallpaperSetResultEvents()); + assertEquals(UserEventLogger.WALLPAPER_SET_RESULT_FAILURE, + mEventLogger.getLastWallpaperSetResult()); + + // Set next call to succeed and current wallpaper bitmap should not be null and equals to + // the + // mock wallpaper bitmap after clicking "try again". + mWallpaperPersister.setFailNextCall(false); + + onView(withText(R.string.try_again)).perform(click()); + finishSettingWallpaper(); + + assertNotNull(mWallpaperPersister.getCurrentHomeWallpaper()); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + Bitmap srcBitmap = ((TestAsset) mMockWallpaper.getAsset(context)).getBitmap(); + assertTrue(srcBitmap.sameAs(mWallpaperPersister.getCurrentHomeWallpaper())); + + // The wallpaper should have been set on the home screen. + assertEquals(WallpaperPersister.DEST_HOME_SCREEN, mWallpaperPersister.getLastDestination()); + } + + @Test + public void testClickSetWallpaper_Fails_LockScreen_ShowsErrorDialog() + throws Throwable { + launchActivityIntentWithMockWallpaper(); + assertNull(mWallpaperPersister.getCurrentLockWallpaper()); + + mWallpaperPersister.setFailNextCall(true); + + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + + // Destination dialog is shown; click "Lock screen." + onView(withText(R.string.set_wallpaper_lock_screen_destination)).perform(click()); + + finishSettingWallpaper(); + + assertNull(mWallpaperPersister.getCurrentLockWallpaper()); + onView(withText(R.string.set_wallpaper_error_message)).check(matches(isDisplayed())); + + assertEquals(1, mEventLogger.getNumWallpaperSetResultEvents()); + assertEquals(UserEventLogger.WALLPAPER_SET_RESULT_FAILURE, + mEventLogger.getLastWallpaperSetResult()); + + // Set next call to succeed and current wallpaper bitmap should not be null and equals to + // the + // mock wallpaper bitmap after clicking "try again". + mWallpaperPersister.setFailNextCall(false); + + onView(withText(R.string.try_again)).perform(click()); + finishSettingWallpaper(); + + assertNotNull(mWallpaperPersister.getCurrentLockWallpaper()); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + Bitmap srcBitmap = ((TestAsset) mMockWallpaper.getAsset(context)).getBitmap(); + assertTrue(srcBitmap.sameAs(mWallpaperPersister.getCurrentLockWallpaper())); + + // The wallpaper should have been set on the lock screen. + assertEquals(WallpaperPersister.DEST_LOCK_SCREEN, mWallpaperPersister.getLastDestination()); + } + + @Test + public void testClickSetWallpaper_Fails_BothHomeAndLock_ShowsErrorDialog() + throws Throwable { + launchActivityIntentWithMockWallpaper(); + assertNull(mWallpaperPersister.getCurrentHomeWallpaper()); + assertNull(mWallpaperPersister.getCurrentLockWallpaper()); + + mWallpaperPersister.setFailNextCall(true); + + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + + // Destination dialog is shown; click "Both." + onView(withText(R.string.set_wallpaper_both_destination)).perform(click()); + + finishSettingWallpaper(); + + assertNull(mWallpaperPersister.getCurrentHomeWallpaper()); + assertNull(mWallpaperPersister.getCurrentLockWallpaper()); + onView(withText(R.string.set_wallpaper_error_message)).check(matches(isDisplayed())); + + assertEquals(1, mEventLogger.getNumWallpaperSetResultEvents()); + assertEquals(UserEventLogger.WALLPAPER_SET_RESULT_FAILURE, + mEventLogger.getLastWallpaperSetResult()); + + // Set next call to succeed and current wallpaper bitmap should not be null and equals to + // the mock wallpaper bitmap after clicking "try again". + mWallpaperPersister.setFailNextCall(false); + + onView(withText(R.string.try_again)).perform(click()); + finishSettingWallpaper(); + + assertNotNull(mWallpaperPersister.getCurrentHomeWallpaper()); + assertNotNull(mWallpaperPersister.getCurrentLockWallpaper()); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + Bitmap srcBitmap = ((TestAsset) mMockWallpaper.getAsset(context)).getBitmap(); + assertTrue(srcBitmap.sameAs(mWallpaperPersister.getCurrentHomeWallpaper())); + assertTrue(srcBitmap.sameAs(mWallpaperPersister.getCurrentLockWallpaper())); + + // The wallpaper should have been set on both the home screen and the lock screen. + assertEquals(WallpaperPersister.DEST_BOTH, mWallpaperPersister.getLastDestination()); + } + + @Test + public void testClickSetWallpaper_CropsAndScalesWallpaper() { + launchActivityIntentWithMockWallpaper(); + // Scale should not have a meaningful value before clicking "set wallpaper". + assertTrue(mWallpaperPersister.getScale() < 0); + + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + + // Destination dialog is shown; click "Home screen". + onView(withText(R.string.set_wallpaper_home_screen_destination)).perform(click()); + + // WallpaperPersister's scale should match the ScaleImageView's scale. + float zoom = ((SubsamplingScaleImageView) + mActivityRule.getActivity().findViewById(R.id.full_res_image)).getScale(); + assertEquals(mWallpaperPersister.getScale(), zoom, FLOAT_ERROR_MARGIN); + + Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize( + mActivityRule.getActivity().getWindowManager().getDefaultDisplay()); + int maxDim = Math.max(screenSize.x, screenSize.y); + Rect cropRect = mWallpaperPersister.getCropRect(); + + // Crop rect should be greater or equal than screen size in both directions. + assertTrue(cropRect.width() >= maxDim); + assertTrue(cropRect.height() >= maxDim); + } + + @Test + public void testClickSetWallpaper_FailsCroppingAndScalingWallpaper_ShowsErrorDialog() + throws Throwable { + launchActivityIntentWithMockWallpaper(); + mWallpaperPersister.setFailNextCall(true); + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + // Destination dialog is shown; click "Home screen". + onView(withText(R.string.set_wallpaper_home_screen_destination)).perform(click()); + + finishSettingWallpaper(); + + onView(withText(R.string.set_wallpaper_error_message)).check(matches(isDisplayed())); + } + + /** + * Tests that tapping Set Wallpaper shows the destination dialog (i.e., choosing + * between Home screen, Lock screen, or Both). + */ + @Test + public void testClickSetWallpaper_ShowsDestinationDialog() { + launchActivityIntentWithMockWallpaper(); + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + onView(withText(R.string.set_wallpaper_dialog_message)).check(matches(isDisplayed())); + } + + @Test + public void testSetsDefaultWallpaperZoomAndScroll() { + float expectedWallpaperZoom; + int expectedWallpaperScrollX; + int expectedWallpaperScrollY; + + launchActivityIntentWithMockWallpaper(); + PreviewActivity activity = mActivityRule.getActivity(); + SubsamplingScaleImageView fullResImageView = activity.findViewById(R.id.full_res_image); + + Point defaultCropSurfaceSize = WallpaperCropUtils.getDefaultCropSurfaceSize( + activity.getResources(), activity.getWindowManager().getDefaultDisplay()); + Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize( + activity.getWindowManager().getDefaultDisplay()); + TestAsset asset = (TestAsset) mMockWallpaper.getAsset(activity); + Point wallpaperSize = new Point(asset.getBitmap().getWidth(), + asset.getBitmap().getHeight()); + + expectedWallpaperZoom = WallpaperCropUtils.calculateMinZoom( + wallpaperSize, defaultCropSurfaceSize); + + // Current zoom should match the minimum zoom required to fit wallpaper + // completely on the crop surface. + assertEquals(expectedWallpaperZoom, fullResImageView.getScale(), FLOAT_ERROR_MARGIN); + + Point scaledWallpaperSize = new Point( + (int) (wallpaperSize.x * expectedWallpaperZoom), + (int) (wallpaperSize.y * expectedWallpaperZoom)); + Point cropSurfaceToScreen = WallpaperCropUtils.calculateCenterPosition( + defaultCropSurfaceSize, screenSize, true /* alignStart */, false /* isRtl */); + Point wallpaperToCropSurface = WallpaperCropUtils.calculateCenterPosition( + scaledWallpaperSize, defaultCropSurfaceSize, false /* alignStart */, + false /* isRtl */); + + expectedWallpaperScrollX = wallpaperToCropSurface.x + cropSurfaceToScreen.x; + expectedWallpaperScrollY = wallpaperToCropSurface.y + cropSurfaceToScreen.y; + + // ZoomView should be scrolled in X and Y directions such that the crop surface is centered + // relative to the wallpaper and the screen is centered (and aligned left) relative to the + // crop surface. + assertEquals(expectedWallpaperScrollX, fullResImageView.getScrollX()); + assertEquals(expectedWallpaperScrollY, fullResImageView.getScrollY()); + } + + @Test + public void testSetWallpaper_TemporarilyLocksScreenOrientation() throws Throwable { + launchActivityIntentWithMockWallpaper(); + PreviewActivity activity = mActivityRule.getActivity(); + + assertFalse(activity.getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LOCKED); + + onView(withId(R.id.preview_attribution_pane_set_wallpaper_button)).perform(click()); + + // Destination dialog is shown; click "Home screen". + onView(withText(R.string.set_wallpaper_home_screen_destination)).perform(click()); + + assertEquals(ActivityInfo.SCREEN_ORIENTATION_LOCKED, activity.getRequestedOrientation()); + + // Finish setting the wallpaper to check that the screen orientation is no longer locked. + finishSettingWallpaper(); + + assertNotEquals(activity.getRequestedOrientation(), ActivityInfo.SCREEN_ORIENTATION_LOCKED); + } + @Test + public void testShowsWallpaperAttribution() { + launchActivityIntentWithMockWallpaper(); + PreviewActivity activity = mActivityRule.getActivity(); + + TextView titleView = activity.findViewById(R.id.preview_attribution_pane_title); + assertEquals("Title", titleView.getText()); + + TextView subtitle1View = activity.findViewById(R.id.preview_attribution_pane_subtitle1); + assertEquals("Subtitle 1", subtitle1View.getText()); + + TextView subtitle2View = activity.findViewById(R.id.preview_attribution_pane_subtitle2); + assertEquals("Subtitle 2", subtitle2View.getText()); + } + + /** + * Tests that if there was a failure decoding the wallpaper bitmap, then the activity shows an + * informative error dialog with an "OK" button, when clicked finishes the activity. + */ + @Test + public void testLoadWallpaper_Failed_ShowsErrorDialog() { + // Simulate a corrupted asset that fails to perform decoding operations. + mMockWallpaper.corruptAssets(); + launchActivityIntentWithMockWallpaper(); + + onView(withText(R.string.load_wallpaper_error_message)).check(matches(isDisplayed())); + + onView(withText(android.R.string.ok)).perform(click()); + + assertTrue(mActivityRule.getActivity().isFinishing()); + } + + /** + * Tests that the explore button is not visible, even if there is an action URL present, if + * there is no activity on the device which can handle such an explore action. + */ + @Test + public void testNoActionViewHandler_ExploreButtonNotVisible() { + mExploreIntentChecker.setViewHandlerExists(false); + + launchActivityIntentWithMockWallpaper(); + onView(withId(R.id.preview_attribution_pane_explore_button)).check( + matches(not(isDisplayed()))); + } +} diff --git a/tests/src/com/android/wallpaper/picker/individual/IndividualPickerActivityTest.java b/tests/src/com/android/wallpaper/picker/individual/IndividualPickerActivityTest.java index e98fabd..59e94ba 100644 --- a/tests/src/com/android/wallpaper/picker/individual/IndividualPickerActivityTest.java +++ b/tests/src/com/android/wallpaper/picker/individual/IndividualPickerActivityTest.java @@ -50,7 +50,7 @@ import android.widget.FrameLayout; import androidx.recyclerview.widget.RecyclerView; import androidx.test.espresso.contrib.RecyclerViewActions; import androidx.test.espresso.intent.Intents; -import androidx.test.filters.LargeTest; +import androidx.test.filters.MediumTest; import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; @@ -88,7 +88,7 @@ import java.util.List; * Tests for {@link IndividualPickerActivity}. */ @RunWith(AndroidJUnit4ClassRunner.class) -@LargeTest +@MediumTest public class IndividualPickerActivityTest { private static final String EXTRA_WALLPAPER_INFO = diff --git a/tests/src/com/android/wallpaper/testing/TestWallpaperPersister.java b/tests/src/com/android/wallpaper/testing/TestWallpaperPersister.java index 44a8167..5fc9421 100644 --- a/tests/src/com/android/wallpaper/testing/TestWallpaperPersister.java +++ b/tests/src/com/android/wallpaper/testing/TestWallpaperPersister.java @@ -72,25 +72,22 @@ public class TestWallpaperPersister implements WallpaperPersister { public void setIndividualWallpaper(final WallpaperInfo wallpaperInfo, Asset asset, @Nullable final Rect cropRect, final float scale, final @Destination int destination, final WallpaperPersister.SetWallpaperCallback callback) { - asset.decodeBitmap(50, 50, new BitmapReceiver() { - @Override - public void onBitmapDecoded(@Nullable Bitmap bitmap) { - if (destination == DEST_HOME_SCREEN || destination == DEST_BOTH) { - mPendingHomeWallpaper = bitmap; - mPrefs.setHomeWallpaperAttributions(wallpaperInfo.getAttributions(mAppContext)); - mPrefs.setWallpaperPresentationMode( - WallpaperPreferences.PRESENTATION_MODE_STATIC); - mPrefs.setHomeWallpaperRemoteId(wallpaperInfo.getWallpaperId()); - } - if (destination == DEST_LOCK_SCREEN || destination == DEST_BOTH) { - mPendingLockWallpaper = bitmap; - mPrefs.setLockWallpaperAttributions(wallpaperInfo.getAttributions(mAppContext)); - } - mDestination = destination; - mCallback = callback; - mCropRect = cropRect; - mScale = scale; + asset.decodeBitmap(50, 50, bitmap -> { + if (destination == DEST_HOME_SCREEN || destination == DEST_BOTH) { + mPendingHomeWallpaper = bitmap; + mPrefs.setHomeWallpaperAttributions(wallpaperInfo.getAttributions(mAppContext)); + mPrefs.setWallpaperPresentationMode( + WallpaperPreferences.PRESENTATION_MODE_STATIC); + mPrefs.setHomeWallpaperRemoteId(wallpaperInfo.getWallpaperId()); + } + if (destination == DEST_LOCK_SCREEN || destination == DEST_BOTH) { + mPendingLockWallpaper = bitmap; + mPrefs.setLockWallpaperAttributions(wallpaperInfo.getAttributions(mAppContext)); } + mDestination = destination; + mCallback = callback; + mCropRect = cropRect; + mScale = scale; }); } -- cgit v1.2.3 From 312c245a25fdc83b3da4747a1958b92fb3df1fde Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Thu, 7 Nov 2019 14:24:56 -0800 Subject: Disallow split-screen for WallpaperPicker There's no good use case for split-screen when PreviewActivity is already full screen and it causes other issues. Fixes: 141968921 Change-Id: Ia79bde4c0428f15e41a1d95087d6ad3c6bcb5fad --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 1415226..6d04f6f 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -37,7 +37,7 @@ + android:resizeableActivity="false"> @@ -57,7 +57,7 @@ -- cgit v1.2.3 From c23573f876c95ceb8c063c4e65140a2a483e54f3 Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Thu, 7 Nov 2019 15:12:22 -0800 Subject: Remove LAUNCHER category from main activity We don't want it in launcher all-apps Bug: 124429591 Change-Id: I3177e1621e339030741da0289e8b38c9d2e9c0b2 --- AndroidManifest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 1415226..1a7eeee 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -50,7 +50,6 @@ android:label="@string/app_name"> - -- cgit v1.2.3 From 4ecb6aa2bd603c14c51bfd2f1aeae9f38df5bf07 Mon Sep 17 00:00:00 2001 From: Santiago Etchebehere Date: Thu, 7 Nov 2019 11:48:58 -0800 Subject: [LivePicker 2/n] Add LiveWallpaper preview support Create a new LivePreviewFragment with the same UI and functionality of Android's LivePicker. Note that there's still redundancy between ImagePreviewFragment and LivePreviewFragment, follow up CLs will clean this up and share as much as possible. Still missing is support for delete and settings action buttons. The new LivePreviewFragment won't be hooked up until all the functionality is implemented. Bug: 141391722 Change-Id: I859f9122c368c01575c23f73a80ffdb519ef0e71 --- Android.mk | 11 +- res/drawable/gradient_background.xml | 24 + res/layout/fragment_image_preview.xml | 80 +++ res/layout/fragment_live_preview.xml | 93 ++++ res/layout/fragment_preview.xml | 59 --- res/layout/preview_page_info.xml | 3 +- res/layout/preview_page_settings.xml | 45 ++ res/values/dimens.xml | 1 + res/values/strings.xml | 6 + res/values/styles.xml | 14 + .../android/wallpaper/model/LiveWallpaperInfo.java | 27 +- .../wallpaper/picker/ImagePreviewFragment.java | 55 +- .../wallpaper/picker/LivePreviewFragment.java | 590 +++++++++++++++++++++ .../android/wallpaper/picker/PreviewFragment.java | 62 +-- .../wallpaper/widget/ConstraintViewPager.java | 62 +++ .../individual/IndividualPickerActivityTest.java | 4 +- 16 files changed, 997 insertions(+), 139 deletions(-) create mode 100644 res/drawable/gradient_background.xml create mode 100755 res/layout/fragment_image_preview.xml create mode 100755 res/layout/fragment_live_preview.xml delete mode 100755 res/layout/fragment_preview.xml create mode 100644 res/layout/preview_page_settings.xml create mode 100644 src/com/android/wallpaper/picker/LivePreviewFragment.java create mode 100644 src/com/android/wallpaper/widget/ConstraintViewPager.java diff --git a/Android.mk b/Android.mk index 369f739..39eeeb6 100755 --- a/Android.mk +++ b/Android.mk @@ -71,6 +71,7 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \ androidx.appcompat_appcompat \ androidx.cardview_cardview \ androidx.recyclerview_recyclerview \ + androidx.slice_slice-view \ androidx-constraintlayout_constraintlayout \ com.google.android.material_material \ androidx.exifinterface_exifinterface \ @@ -113,7 +114,15 @@ LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res LOCAL_PROGUARD_FLAG_FILES := proguard.flags LOCAL_PROGUARD_ENABLED := disabled -LOCAL_SDK_VERSION := system_current +LOCAL_PRIVILEGED_MODULE := true + +ifneq (,$(wildcard frameworks/base)) + LOCAL_PRIVATE_PLATFORM_APIS := true +else + LOCAL_SDK_VERSION := system_current + LOCAL_STATIC_JAVA_LIBRARIES += libSharedWallpaper +endif + LOCAL_PACKAGE_NAME := WallpaperPicker2 LOCAL_JETIFIER_ENABLED := true diff --git a/res/drawable/gradient_background.xml b/res/drawable/gradient_background.xml new file mode 100644 index 0000000..47d864a --- /dev/null +++ b/res/drawable/gradient_background.xml @@ -0,0 +1,24 @@ + + + + \ No newline at end of file diff --git a/res/layout/fragment_image_preview.xml b/res/layout/fragment_image_preview.xml new file mode 100755 index 0000000..6c3e324 --- /dev/null +++ b/res/layout/fragment_image_preview.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/fragment_live_preview.xml b/res/layout/fragment_live_preview.xml new file mode 100755 index 0000000..418a289 --- /dev/null +++ b/res/layout/fragment_live_preview.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/fragment_preview.xml b/res/layout/fragment_preview.xml deleted file mode 100755 index 82c481f..0000000 --- a/res/layout/fragment_preview.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/layout/preview_page_info.xml b/res/layout/preview_page_info.xml index 9299426..2489561 100644 --- a/res/layout/preview_page_info.xml +++ b/res/layout/preview_page_info.xml @@ -21,8 +21,7 @@ android:layout_width="match_parent" android:orientation="vertical" android:paddingHorizontal="@dimen/preview_attribution_pane_horizontal_padding" - android:background="@drawable/preview_bottom_sheet_background" - android:theme="@android:style/Theme.DeviceDefault.Settings"> + android:theme="@style/WallpaperPicker.BottomPaneStyle"> + + + + + + + + + +