merge in jb-release history after reset to master
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 8abba06..a269901 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopieer bladsy-URL"</string>
<string name="share_page" msgid="593756995297268343">"Deel bladsy"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Stoor vir vanlyn lees"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Kon nie stoor om vanlyn te lees nie."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> boekmerke"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Leë vouer"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index e7f804f..74adabe 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"url ገፅ ቅዳ"</string>
<string name="share_page" msgid="593756995297268343">"ገፅ አጋራ"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"ከመስመር ውጪ የሚነበብ አስቀምጥ"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"ከመስመር ውጪ ለሚደረግ ንባብ ማስቀመጥ አልተቻለም፡፡"</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> ዕልባቶች"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"ባዶ አቃፊ"</string>
@@ -182,7 +184,7 @@
<string name="autofill_profile_successful_delete" msgid="1790262652460723127">"ራስ ሰር-ሙላ ጽሑፍ ተሰርዟል::"</string>
<string name="autofill_profile_editor_delete_profile" msgid="3098369314558164153">"ሰርዝ"</string>
<string name="autofill_setup_dialog_message" msgid="7123905786076456503">"አሳሹ እንደዚህ ዓይነቶቹን የድር ቅርጾች በራስ ሰር ያሟላል፡፡ የራስህን ራስ-ሙላ ጽሑፍ ማዘጋጀት ትፈልጋለህ?"</string>
- <string name="autofill_setup_dialog_negative_toast" msgid="3288881675232206984">"የራስህን ራስ ሰር ሙላ ጽሑፍ ከአሳሽ ላይ> ቅንጅቶች> አጠቃላይ ማያ ላይ ሁልጊዜ ማዘጋጀት ትችላለህ፡፡"</string>
+ <string name="autofill_setup_dialog_negative_toast" msgid="3288881675232206984">"የራስህን ራስ ሰር ሙላ ጽሑፍ ከአሳሽ ላይ> ቅንብሮች > አጠቃላይ ማያ ላይ ሁልጊዜ ማዘጋጀት ትችላለህ፡፡"</string>
<string name="disable_autofill" msgid="8305901059849400354">"ራስ-ሙላ አቦዝን"</string>
<string name="pref_privacy_security_title" msgid="3480313968942160914">"ግላዊነት& ደህንነት"</string>
<string name="pref_privacy_clear_cache" msgid="3380316479925886998">"መሸጎጫ አጥራ"</string>
@@ -334,7 +336,7 @@
<string name="geolocation_permissions_prompt_share" msgid="9084486342048347976">"ሥፍራ አጋራ"</string>
<string name="geolocation_permissions_prompt_dont_share" msgid="6303025160237860300">"አትቀበል"</string>
<string name="geolocation_permissions_prompt_remember" msgid="3118526300707348308">"ምርጫ አስታውስ"</string>
- <string name="geolocation_permissions_prompt_toast_allowed" msgid="7201417941112726112">"ይህ ድረ ገፅ የአንተን ሥፍራ መድረስ አይችልም። በቅንጅቶች ውስጥ ይህን-> ከፍተኛ-> የድረ ገፅ ቅንጅቶች ለውጥ::"</string>
+ <string name="geolocation_permissions_prompt_toast_allowed" msgid="7201417941112726112">"ይህ ድረ ገፅ የአንተን ሥፍራ መድረስ አይችልም። በቅንብሮች ውስጥ ይህን-> ከፍተኛ-> የድረ ገፅ ቅንብሮች ለውጥ::"</string>
<string name="geolocation_permissions_prompt_toast_disallowed" msgid="156443445797377409">"ይህ ድረ ገፅ የአንተን ሥፍራ መድረስ አይችልም። በቅንጅቶች ውስጥ ይህን-> ከፍተኛ-> የድረ ገፅ ቅንብሮች ለውጥ::"</string>
<string name="geolocation_settings_page_title" msgid="1745477985097536528">"የስፍራ መድረሻ አጥራ"</string>
<string name="geolocation_settings_page_summary_allowed" msgid="9180251524290811398">"ይህ ድረ ገፅ በአሁኑ ጊዜ የእርስዎን ስፍራ መድረስ ይችላል"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 077f798..71fa0d3 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"نسخ عنوان URL للصفحة"</string>
<string name="share_page" msgid="593756995297268343">"مشاركة الصفحة"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"حفظ للقراءة في وضع عدم الاتصال"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"تعذر الحفظ للقراءة في وضع عدم الاتصال."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> من الإشارات المرجعية"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"المجلد فارغ"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 3f885f4..927de05 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Капіяваць URL-адрас старонкі"</string>
<string name="share_page" msgid="593756995297268343">"Адправіць старонку"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Захаваць для чытання ў аўтаномным рэжыме"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Немагчыма захаваць для чытання ў аўтаномным рэжыме."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Закладак: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Ачысцiць тэчку"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index d639fcf..6290383 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Копиране на URL адреса на страницата"</string>
<string name="share_page" msgid="593756995297268343">"Споделяне на страницата"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Запазване за четене офлайн"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Не можа да се запази за четене офлайн."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> отметки"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Празна папка"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index e43c2e6..2c2b8a8 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copia l\'URL de la pàgina"</string>
<string name="share_page" msgid="593756995297268343">"Comparteix la pàgina"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Desa per a lectura fora de línia"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"No s\'ha pogut desar per llegir-la fora de línia."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> marcadors"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Carpeta buida"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index c749e4a..5a6173c 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopírovat adresu URL stránky"</string>
<string name="share_page" msgid="593756995297268343">"Sdílet stránku"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Uložit ke čtení offline"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Uložení ke čtení offline se nezdařilo."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Počet záložek: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Prázdná složka"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 477c601..cb94370 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopier sidens webadresse"</string>
<string name="share_page" msgid="593756995297268343">"Del side"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Gem til læsning offline"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Siden kunne ikke gemmes til læsning offline."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> bogmærker"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Mappen er tom"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index cbe512f..a1de811 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Seiten-URL kopieren"</string>
<string name="share_page" msgid="593756995297268343">"Seitenlink teilen"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Für Offline-Lesen speichern"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Speichern für Offline-Lesen fehlgeschlagen"</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> Lesezeichen"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Leerer Ordner"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index c312349..c96e6fd 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Αντιγραφή διεύθυνσης URL σελίδας"</string>
<string name="share_page" msgid="593756995297268343">"Κοινή χρήση σελίδας"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Αποθήκευση για ανάγνωση εκτός σύνδεσης"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Δεν αποθηκεύτηκε για ανάγνωση εκτ. σύνδεσης"</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> σελιδοδείκτες"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Κενός φάκελος"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 1fcebde..c06f3ac 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copy page URL"</string>
<string name="share_page" msgid="593756995297268343">"Share page"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Save for offline reading"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Couldn\'t save for offline reading."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> bookmarks"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Empty folder"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index bfb3a56..55a25b1 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copiar la URL de la página"</string>
<string name="share_page" msgid="593756995297268343">"Compartir página"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Guardar para leer sin conexión"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"La página no se guardó para leer sin conexión."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> Marcadores"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Vaciar carpeta"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index b42618a..978311c 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copiar URL de página"</string>
<string name="share_page" msgid="593756995297268343">"Compartir página"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Disponible sin conexión"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"No se ha podido guardar para leer sin conexión."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> marcadores"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Carpeta vacía"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 1680ebb..6f4d392 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopeeri lehe URL"</string>
<string name="share_page" msgid="593756995297268343">"Jaga lehte"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Salvesta offlainis lugemiseks"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Võrguühenduseta lugemiseks salvestam. ebaõnnestus."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> järjehoidjat"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Tühi kaust"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 5a8e87a..8baad4c 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"کپی URL صفحه"</string>
<string name="share_page" msgid="593756995297268343">"اشتراک گذاری صفحه"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"ذخیره برای مطالعه در حالت آفلاین"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"برای خواندن آفلاین قابل ذخیره نیست."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> نشانک"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"پوشه خالی"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 594eae3..9827a59 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopioi sivun URL-osoite"</string>
<string name="share_page" msgid="593756995297268343">"Jaa sivu"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Tallenna offline-tilassa luettavaksi"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Ei voitu tallentaa offline-käyttöä varten."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> kirjanmerkkiä"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Tyhjä kansio"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 379523f..a7598da 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copier l\'URL de la page"</string>
<string name="share_page" msgid="593756995297268343">"Partager la page"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Enreg. pour lire hors connex."</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Échec enregistrement pour lecture hors connexion."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> favori(s)"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Dossier vide"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index dace797..6bb492d 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"पृष्ठ url की प्रतिलिपि बनाएं"</string>
<string name="share_page" msgid="593756995297268343">"पृष्ठ शेयर करें"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"ऑफ़लाइन पढ़ने के लिए सहेजें"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"ऑफ़लाइन पढ़ने के लिए सहेजा नहीं जा सका."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> बुकमार्क"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"रिक्त फ़ोल्डर"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index b86ec0b..89a19ac 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopiraj URL stranice"</string>
<string name="share_page" msgid="593756995297268343">"Dijeli stranicu"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Spremi za izvanmrežno čitanje"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Spremanje za izvanmrežno čitanje nije uspjelo."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Br. oznaka: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Prazna mapa"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 698778c..7694f09 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Az oldal URL-jének másolása"</string>
<string name="share_page" msgid="593756995297268343">"Oldal megosztása"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Mentés offline olvasáshoz"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Nem sikerült menteni offline olvasáshoz."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> könyvjelző"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Üres mappa"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index e25771b..89d27aa 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Salin URL laman"</string>
<string name="share_page" msgid="593756995297268343">"Bagikan lama"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Simpan untuk dibaca secara offline"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Tidak dapat menyimpan untuk dibaca secara offline."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> bookmark"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Folder kosong"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index aaf0b72..5728108 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copia URL della pagina"</string>
<string name="share_page" msgid="593756995297268343">"Condividi pagina"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Salva per lettura offline"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Salvataggio per lettura offline non riuscito."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> segnalibri"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Cartella vuota"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 021aad2..e462253 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"העתק כתובת אתר של דף"</string>
<string name="share_page" msgid="593756995297268343">"שתף דף"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"שמור לקריאה במצב לא מקוון"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"השמירה לקריאה במצב לא מקוון לא הצליחה."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> סימניות"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"תיקיה ריקה"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 50417a3..5b4e2b0 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"ページのURLをコピー"</string>
<string name="share_page" msgid="593756995297268343">"ページを共有"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"オフラインで読めるよう保存"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"オフラインでの閲覧用に保存できませんでした。"</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g>件のブックマーク"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"空のフォルダ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index cca8540..0e47f86 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"페이지 URL 복사"</string>
<string name="share_page" msgid="593756995297268343">"페이지 공유"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"오프라인 보기로 저장"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"오프라인 읽기용으로 저장하지 못했습니다."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"북마크 <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>개"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"빈 폴더"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 758b431..a3ce6b7 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopijuoti puslapio URL"</string>
<string name="share_page" msgid="593756995297268343">"Bendrinti puslapį"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Išsaugoti, kad būtų galima skaityti neprisijungus"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Nepavyko išsaugoti, kad skaitytumėte neprisij."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Žymių: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Tuščias aplankas"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 75dc841..6a19115 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopēt lapas URL"</string>
<string name="share_page" msgid="593756995297268343">"Kopīgot lapu"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Saglabāt, lai lasītu bezsaistē"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Nevarēja saglabāt lasīšanai bezsaistē."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> grāmatzīmes"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Tukša mape"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 0b005c0..bc9e562 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Salin URL halaman"</string>
<string name="share_page" msgid="593756995297268343">"Kongsi halaman"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Simpan untuk pembacaan di luar talian"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Tidak dapat disimpan untuk pembacaan di luar talian."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> penanda halaman"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Folder kosong"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 8ff8b6d..cedfa8c 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopier nettadresse"</string>
<string name="share_page" msgid="593756995297268343">"Del side"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Lagre for frakoblet lesing"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Kunne ikke lagre for frakoblet lesing."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> bokmerker"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Tøm mappe"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 692e7ad..8f01f59 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Pagina-URL kopiëren"</string>
<string name="share_page" msgid="593756995297268343">"Pagina delen"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Opslaan voor offline lezen"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Kan pagina niet opslaan voor offline lezen."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> bladwijzers"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Lege map"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 8acb401..c64788b 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopiuj URL strony"</string>
<string name="share_page" msgid="593756995297268343">"Udostępnij stronę"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Zapisz do czytania offline"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Nie można zapisać do czytania w trybie offline."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Zakładki: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Pusty folder"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 93595f9..52a1031 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copiar URL da página"</string>
<string name="share_page" msgid="593756995297268343">"Partilhar página"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Guardar para leitura off-line"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Não foi possível guardar para leitura off-line."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> marcadores"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Pasta vazia"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 767f2b3..35445bb 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copiar URL da página"</string>
<string name="share_page" msgid="593756995297268343">"Compartilhar página"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Salvar para leitura off-line"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Não foi possível salvar para leitura off-line."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> favoritos"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Pasta vazia"</string>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 7d52a3c..e01da51 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -139,6 +139,8 @@
<string name="share_page" msgid="593756995297268343">"Barattar la pagina"</string>
<!-- no translation found for menu_save_snapshot (6935080344031126139) -->
<skip />
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<!-- no translation found for snapshot_failed (4584580873565876033) -->
<skip />
<!-- no translation found for contextheader_folder_bookmarkcount (353987136645619089) -->
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index ae93e00..81f00d0 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Copiaţi adresa URL a paginii"</string>
<string name="share_page" msgid="593756995297268343">"Distribuiţi pagina"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Salvaţi pentru lectură offline"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Nu s-a putut salva pentru citire offline."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> (de) marcaje"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Dosar gol"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index ac4a717..d5ae7e6 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Скопировать URL страницы"</string>
<string name="share_page" msgid="593756995297268343">"Отправить страницу"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Сохранить страницу"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Не удалось сохранить страницу."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Закладок: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Папка пуста"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 670b5f2..5843255 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopírovať adresu URL stránky"</string>
<string name="share_page" msgid="593756995297268343">"Zdieľať stránku"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Uložiť na čítanie offline"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Nepodarilo sa uložiť na čítanie v režime offline."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Počet záložiek: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Prázdny priečinok"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 563e831..f9c61c3 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopiraj URL strani"</string>
<string name="share_page" msgid="593756995297268343">"Stran deli z drugimi"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Shrani za branje brez povezave"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Ni bilo mogoče shraniti za branje brez povezave."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Število zaznamkov: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Prazna mapa"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 81a75d0..72d2996 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Копирај URL адресу странице"</string>
<string name="share_page" msgid="593756995297268343">"Дели страницу"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Сачувај за читање ван мреже"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Није било могуће сачувати за читање ван мреже."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> обележивача"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Празан директоријум"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 75dabf9..951a35d 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopiera sidans webbadress"</string>
<string name="share_page" msgid="593756995297268343">"Dela sida"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Spara för läsning offline"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Det gick inte att spara för läsning offline."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> bokmärken"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Tom mapp"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 72d17b8..b41ef9a 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Nakili URL ya ukurasa"</string>
<string name="share_page" msgid="593756995297268343">"Shiriki ukurasa"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Hifadhi kwa usomaji wa nje ya mtandao"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Haikuweza kuhifadhi usomaji mkondoni."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Alamisho <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Folda iko tupu"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 021be1b..4a4997f 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"คัดลอก URL ของหน้าเว็บ"</string>
<string name="share_page" msgid="593756995297268343">"แบ่งปันหน้าเว็บ"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"บันทึกไว้อ่านออฟไลน์"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"ไม่สามารถบันทึกไว้อ่านแบบออฟไลน์ได้"</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"บุ๊กมาร์ก <xliff:g id="BOOKMARK_COUNT">%d</xliff:g> รายการ"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"โฟลเดอร์ว่าง"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index be6ae22..a668e3f 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopyahin ang URL ng pahina"</string>
<string name="share_page" msgid="593756995297268343">"Ibahagi ang pahina"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"I-save para sa offline na pagbabasa"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Hindi ma-save para sa offline na pagbabasa."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> (na) bookmark"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Walang lamang folder"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index ae7cc53..75b8135 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Sayfa URL\'sini kopyala"</string>
<string name="share_page" msgid="593756995297268343">"Sayfayı paylaş"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Çevrimdışı okuma için kaydet"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Çevrimdışı okuma için kaydedilemedi."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> yer işareti"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Boş klasör"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index c995f53..96bc596 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Копіювати URL-адресу сторінки"</string>
<string name="share_page" msgid="593756995297268343">"Надісл. стор."</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Зберегти для читання в режимі офлайн"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Не вдалося зберегти для читання в режимі офлайн."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"Закладок: <xliff:g id="BOOKMARK_COUNT">%d</xliff:g>"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Порожня папка"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 0b834cd..53a26d3 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Sao chép url của trang"</string>
<string name="share_page" msgid="593756995297268343">"Chia sẻ trang"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Lưu để đọc ngoại tuyến"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Không thể lưu để đọc ngoại tuyến."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> dấu trang"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Thư mục trống"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 59b7d1a..eef5ead 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"复制网页网址"</string>
<string name="share_page" msgid="593756995297268343">"分享网页"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"保存以供离线阅读"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"无法保存以供离线阅读。"</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> 个书签"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"空文件夹"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 536941b..159cf8d 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"複製網頁網址"</string>
<string name="share_page" msgid="593756995297268343">"分享網頁"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"儲存頁面以供離線閱讀"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"無法儲存網頁以供離線閱讀。"</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> 個書籤"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"空資料夾"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index cc3d0a6..71b780c 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -102,6 +102,8 @@
<string name="copy_page_url" msgid="1188679152608889555">"Kopisha i-url yekhasi"</string>
<string name="share_page" msgid="593756995297268343">"Yabelana ngekhasi"</string>
<string name="menu_save_snapshot" msgid="6935080344031126139">"Gcina ukufunda ungaxhumekile kwi-inthanethi"</string>
+ <!-- no translation found for saving_snapshot (1693789062351182809) -->
+ <skip />
<string name="snapshot_failed" msgid="4584580873565876033">"Angikwazanga ukulondolozela ukufunda ngaphandle kwe-inthanethi."</string>
<string name="contextheader_folder_bookmarkcount" msgid="353987136645619089">"<xliff:g id="BOOKMARK_COUNT">%d</xliff:g> amabhukimakhi"</string>
<string name="contextheader_folder_empty" msgid="974171637803391651">"Ifolda engenalutho"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 95d383c..90ec428 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -215,6 +215,8 @@
<string name="share_page">Share page</string>
<!-- Menu item for saving a page for offline reading. This is a view-only snapshot of the page. [CHAR LIMIT=50] -->
<string name="menu_save_snapshot">Save for offline reading</string>
+ <!-- Dialog message that is shown while saving a page for offline reading. [CHAR LIMIT=50] -->
+ <string name="saving_snapshot">Saving\u2026</string>
<!-- Toast informing the user that saving the page for offline reading has failed. [CHAR LIMIT=50] -->
<string name="snapshot_failed">Couldn\'t save for offline reading.</string>
<!-- The number of bookmarks in a folder [CHAR LIMT=50] -->
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 415e72d..cddeda6 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -336,6 +336,9 @@
settings.setAppCachePath(getAppCachePath());
settings.setDatabasePath(mContext.getDir("databases", 0).getPath());
settings.setGeolocationDatabasePath(mContext.getDir("geolocation", 0).getPath());
+ // origin policy for file access
+ settings.setAllowUniversalAccessFromFileURLs(false);
+ settings.setAllowFileAccessFromFileURLs(false);
}
private void syncSharedSettings() {
diff --git a/src/com/android/browser/BrowserSnapshotPage.java b/src/com/android/browser/BrowserSnapshotPage.java
index be4f9af..b0d8205 100644
--- a/src/com/android/browser/BrowserSnapshotPage.java
+++ b/src/com/android/browser/BrowserSnapshotPage.java
@@ -61,7 +61,7 @@
private static final String[] PROJECTION = new String[] {
Snapshots._ID,
Snapshots.TITLE,
- "length(" + Snapshots.VIEWSTATE + ")",
+ Snapshots.VIEWSTATE_SIZE,
Snapshots.THUMBNAIL,
Snapshots.FAVICON,
Snapshots.URL,
@@ -69,7 +69,7 @@
};
private static final int SNAPSHOT_ID = 0;
private static final int SNAPSHOT_TITLE = 1;
- private static final int SNAPSHOT_VIEWSTATE_LENGTH = 2;
+ private static final int SNAPSHOT_VIEWSTATE_SIZE = 2;
private static final int SNAPSHOT_THUMBNAIL = 3;
private static final int SNAPSHOT_FAVICON = 4;
private static final int SNAPSHOT_URL = 5;
@@ -281,7 +281,7 @@
title.setText(cursor.getString(SNAPSHOT_TITLE));
TextView size = (TextView) view.findViewById(R.id.size);
if (size != null) {
- int stateLen = cursor.getInt(SNAPSHOT_VIEWSTATE_LENGTH);
+ int stateLen = cursor.getInt(SNAPSHOT_VIEWSTATE_SIZE);
size.setText(String.format("%.2fMB", stateLen / 1024f / 1024f));
}
long timestamp = cursor.getLong(SNAPSHOT_DATE_CREATED);
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index fcbe387..36f6a1a 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -17,7 +17,10 @@
package com.android.browser;
import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
import android.app.DownloadManager;
+import android.app.ProgressDialog;
import android.app.SearchManager;
import android.content.ClipboardManager;
import android.content.ContentProvider;
@@ -26,6 +29,8 @@
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -945,14 +950,15 @@
}
@Override
- public void onUnhandledKeyEvent(KeyEvent event) {
+ public boolean onUnhandledKeyEvent(KeyEvent event) {
if (!isActivityPaused()) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
- mActivity.onKeyDown(event.getKeyCode(), event);
+ return mActivity.onKeyDown(event.getKeyCode(), event);
} else {
- mActivity.onKeyUp(event.getKeyCode(), event);
+ return mActivity.onKeyUp(event.getKeyCode(), event);
}
}
+ return false;
}
@Override
@@ -1633,37 +1639,7 @@
case R.id.save_snapshot_menu_id:
final Tab source = getTabControl().getCurrentTab();
if (source == null) break;
- final ContentResolver cr = mActivity.getContentResolver();
- final ContentValues values = source.createSnapshotValues();
- if (values != null) {
- new AsyncTask<Tab, Void, Long>() {
-
- @Override
- protected Long doInBackground(Tab... params) {
- Uri result = cr.insert(Snapshots.CONTENT_URI, values);
- if (result == null) {
- return null;
- }
- long id = ContentUris.parseId(result);
- return id;
- }
-
- @Override
- protected void onPostExecute(Long id) {
- if (id == null) {
- Toast.makeText(mActivity, R.string.snapshot_failed,
- Toast.LENGTH_SHORT).show();
- return;
- }
- Bundle b = new Bundle();
- b.putLong(BrowserSnapshotPage.EXTRA_ANIMATE_ID, id);
- mUi.showComboView(ComboViews.Snapshots, b);
- };
- }.execute(source);
- } else {
- Toast.makeText(mActivity, R.string.snapshot_failed,
- Toast.LENGTH_SHORT).show();
- }
+ new SaveSnapshotTask(source).execute();
break;
case R.id.page_info_menu_id:
@@ -1731,6 +1707,69 @@
return true;
}
+ private class SaveSnapshotTask extends AsyncTask<Void, Void, Long>
+ implements OnCancelListener {
+
+ private Tab mTab;
+ private Dialog mProgressDialog;
+ private ContentValues mValues;
+
+ private SaveSnapshotTask(Tab tab) {
+ mTab = tab;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ CharSequence message = mActivity.getText(R.string.saving_snapshot);
+ mProgressDialog = ProgressDialog.show(mActivity, null, message,
+ true, true, this);
+ mValues = mTab.createSnapshotValues();
+ }
+
+ @Override
+ protected Long doInBackground(Void... params) {
+ if (!mTab.saveViewState(mValues)) {
+ return null;
+ }
+ if (isCancelled()) {
+ String path = mValues.getAsString(Snapshots.VIEWSTATE_PATH);
+ File file = mActivity.getFileStreamPath(path);
+ if (!file.delete()) {
+ file.deleteOnExit();
+ }
+ return null;
+ }
+ final ContentResolver cr = mActivity.getContentResolver();
+ Uri result = cr.insert(Snapshots.CONTENT_URI, mValues);
+ if (result == null) {
+ return null;
+ }
+ long id = ContentUris.parseId(result);
+ return id;
+ }
+
+ @Override
+ protected void onPostExecute(Long id) {
+ if (isCancelled()) {
+ return;
+ }
+ mProgressDialog.dismiss();
+ if (id == null) {
+ Toast.makeText(mActivity, R.string.snapshot_failed,
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+ Bundle b = new Bundle();
+ b.putLong(BrowserSnapshotPage.EXTRA_ANIMATE_ID, id);
+ mUi.showComboView(ComboViews.Snapshots, b);
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ cancel(true);
+ }
+ }
+
@Override
public void toggleUserAgent() {
WebView web = getCurrentWebView();
diff --git a/src/com/android/browser/PreloadController.java b/src/com/android/browser/PreloadController.java
index 0efe119..66b89f4 100644
--- a/src/com/android/browser/PreloadController.java
+++ b/src/com/android/browser/PreloadController.java
@@ -130,8 +130,9 @@
}
@Override
- public void onUnhandledKeyEvent(KeyEvent event) {
+ public boolean onUnhandledKeyEvent(KeyEvent event) {
if (LOGD_ENABLED) Log.d(LOGTAG, "onUnhandledKeyEvent()");
+ return false;
}
@Override
diff --git a/src/com/android/browser/SnapshotByteArrayOutputStream.java b/src/com/android/browser/SnapshotByteArrayOutputStream.java
deleted file mode 100644
index 127eee8..0000000
--- a/src/com/android/browser/SnapshotByteArrayOutputStream.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2011 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.browser;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-public class SnapshotByteArrayOutputStream extends OutputStream {
-
- // Maximum size, this needs to be small enough such that an entire row
- // can fit in CursorWindow's 2MB limit
- private static final int MAX_SIZE = 1700000;
- private ByteArrayOutputStream mStream;
-
- public SnapshotByteArrayOutputStream() {
- mStream = new ByteArrayOutputStream(MAX_SIZE);
- }
-
- @Override
- public synchronized void write(int oneByte) throws IOException {
- checkError(1);
- mStream.write(oneByte);
- }
-
- @Override
- public void write(byte[] buffer, int offset, int count) throws IOException {
- checkError(count);
- mStream.write(buffer, offset, count);
- }
-
- private void checkError(int expandBy) throws IOException {
- if ((size() + expandBy) > MAX_SIZE) {
- throw new IOException("Exceeded max size!");
- }
- }
-
- public int size() {
- return mStream.size();
- }
-
- public byte[] toByteArray() {
- return mStream.toByteArray();
- }
-
-}
diff --git a/src/com/android/browser/SnapshotTab.java b/src/com/android/browser/SnapshotTab.java
index f58f88b..e14f095 100644
--- a/src/com/android/browser/SnapshotTab.java
+++ b/src/com/android/browser/SnapshotTab.java
@@ -18,11 +18,13 @@
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
+import android.content.Context;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClassic;
@@ -30,6 +32,8 @@
import com.android.browser.provider.SnapshotProvider.Snapshots;
import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
import java.util.Map;
import java.util.zip.GZIPInputStream;
@@ -75,7 +79,7 @@
void loadData() {
if (mLoadTask == null) {
- mLoadTask = new LoadData(this, mContext.getContentResolver());
+ mLoadTask = new LoadData(this, mContext);
mLoadTask.execute();
}
}
@@ -152,20 +156,31 @@
static final String[] PROJECTION = new String[] {
Snapshots._ID, // 0
- Snapshots.TITLE, // 1
- Snapshots.URL, // 2
+ Snapshots.URL, // 1
+ Snapshots.TITLE, // 2
Snapshots.FAVICON, // 3
Snapshots.VIEWSTATE, // 4
Snapshots.BACKGROUND, // 5
Snapshots.DATE_CREATED, // 6
+ Snapshots.VIEWSTATE_PATH, // 7
};
+ static final int SNAPSHOT_ID = 0;
+ static final int SNAPSHOT_URL = 1;
+ static final int SNAPSHOT_TITLE = 2;
+ static final int SNAPSHOT_FAVICON = 3;
+ static final int SNAPSHOT_VIEWSTATE = 4;
+ static final int SNAPSHOT_BACKGROUND = 5;
+ static final int SNAPSHOT_DATE_CREATED = 6;
+ static final int SNAPSHOT_VIEWSTATE_PATH = 7;
private SnapshotTab mTab;
private ContentResolver mContentResolver;
+ private Context mContext;
- public LoadData(SnapshotTab t, ContentResolver cr) {
+ public LoadData(SnapshotTab t, Context context) {
mTab = t;
- mContentResolver = cr;
+ mContentResolver = context.getContentResolver();
+ mContext = context;
}
@Override
@@ -175,26 +190,35 @@
return mContentResolver.query(uri, PROJECTION, null, null, null);
}
+ private InputStream getInputStream(Cursor c) throws FileNotFoundException {
+ String path = c.getString(SNAPSHOT_VIEWSTATE_PATH);
+ if (!TextUtils.isEmpty(path)) {
+ return mContext.openFileInput(path);
+ }
+ byte[] data = c.getBlob(SNAPSHOT_VIEWSTATE);
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ return bis;
+ }
+
@Override
protected void onPostExecute(Cursor result) {
try {
if (result.moveToFirst()) {
- mTab.mCurrentState.mTitle = result.getString(1);
- mTab.mCurrentState.mUrl = result.getString(2);
- byte[] favicon = result.getBlob(3);
+ mTab.mCurrentState.mTitle = result.getString(SNAPSHOT_TITLE);
+ mTab.mCurrentState.mUrl = result.getString(SNAPSHOT_URL);
+ byte[] favicon = result.getBlob(SNAPSHOT_FAVICON);
if (favicon != null) {
mTab.mCurrentState.mFavicon = BitmapFactory
.decodeByteArray(favicon, 0, favicon.length);
}
WebViewClassic web = mTab.getWebViewClassic();
if (web != null) {
- byte[] data = result.getBlob(4);
- ByteArrayInputStream bis = new ByteArrayInputStream(data);
- GZIPInputStream stream = new GZIPInputStream(bis);
+ InputStream ins = getInputStream(result);
+ GZIPInputStream stream = new GZIPInputStream(ins);
web.loadViewState(stream);
}
- mTab.mBackgroundColor = result.getInt(5);
- mTab.mDateCreated = result.getLong(6);
+ mTab.mBackgroundColor = result.getInt(SNAPSHOT_BACKGROUND);
+ mTab.mDateCreated = result.getLong(SNAPSHOT_DATE_CREATED);
mTab.mWebViewController.onPageFinished(mTab);
}
} catch (Exception e) {
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 9b5a675..cbda456 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -64,8 +64,8 @@
import android.webkit.WebResourceResponse;
import android.webkit.WebStorage;
import android.webkit.WebView;
-import android.webkit.WebViewClassic;
import android.webkit.WebView.PictureListener;
+import android.webkit.WebViewClassic;
import android.webkit.WebViewClient;
import android.widget.CheckBox;
import android.widget.Toast;
@@ -76,12 +76,16 @@
import com.android.common.speech.LoggingEvents;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
+import java.util.UUID;
import java.util.Vector;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;
@@ -892,7 +896,9 @@
if (!mInForeground) {
return;
}
- mWebViewController.onUnhandledKeyEvent(event);
+ if (!mWebViewController.onUnhandledKeyEvent(event)) {
+ super.onUnhandledKeyEvent(view, event);
+ }
}
@Override
@@ -2057,26 +2063,29 @@
return false;
}
- public ContentValues createSnapshotValues() {
- if (mMainView == null) return null;
- SnapshotByteArrayOutputStream bos = new SnapshotByteArrayOutputStream();
- try {
- GZIPOutputStream stream = new GZIPOutputStream(bos);
- if (!getWebViewClassic().saveViewState(stream)) {
- return null;
+ private static class SaveCallback implements ValueCallback<Boolean> {
+ boolean mResult;
+
+ @Override
+ public void onReceiveValue(Boolean value) {
+ mResult = value;
+ synchronized (this) {
+ notifyAll();
}
- stream.flush();
- stream.close();
- } catch (Exception e) {
- Log.w(LOGTAG, "Failed to save view state", e);
- return null;
}
- byte[] data = bos.toByteArray();
+
+ }
+
+ /**
+ * Must be called on the UI thread
+ */
+ public ContentValues createSnapshotValues() {
+ WebViewClassic web = getWebViewClassic();
+ if (web == null) return null;
ContentValues values = new ContentValues();
values.put(Snapshots.TITLE, mCurrentState.mTitle);
values.put(Snapshots.URL, mCurrentState.mUrl);
- values.put(Snapshots.VIEWSTATE, data);
- values.put(Snapshots.BACKGROUND, getWebViewClassic().getPageBackgroundColor());
+ values.put(Snapshots.BACKGROUND, web.getPageBackgroundColor());
values.put(Snapshots.DATE_CREATED, System.currentTimeMillis());
values.put(Snapshots.FAVICON, compressBitmap(getFavicon()));
Bitmap screenshot = Controller.createScreenshot(mMainView,
@@ -2086,6 +2095,50 @@
return values;
}
+ /**
+ * Probably want to call this on a background thread
+ */
+ public boolean saveViewState(ContentValues values) {
+ WebViewClassic web = getWebViewClassic();
+ if (web == null) return false;
+ String path = UUID.randomUUID().toString();
+ SaveCallback callback = new SaveCallback();
+ OutputStream outs = null;
+ try {
+ outs = mContext.openFileOutput(path, Context.MODE_PRIVATE);
+ GZIPOutputStream stream = new GZIPOutputStream(outs);
+ synchronized (callback) {
+ web.saveViewState(stream, callback);
+ callback.wait();
+ }
+ stream.flush();
+ stream.close();
+ } catch (Exception e) {
+ Log.w(LOGTAG, "Failed to save view state", e);
+ if (outs != null) {
+ try {
+ outs.close();
+ } catch (IOException ignore) {}
+ }
+ File file = mContext.getFileStreamPath(path);
+ if (file.exists() && !file.delete()) {
+ file.deleteOnExit();
+ }
+ return false;
+ }
+ File savedFile = mContext.getFileStreamPath(path);
+ if (!callback.mResult) {
+ if (!savedFile.delete()) {
+ savedFile.deleteOnExit();
+ }
+ return false;
+ }
+ long size = savedFile.length();
+ values.put(Snapshots.VIEWSTATE_PATH, path);
+ values.put(Snapshots.VIEWSTATE_SIZE, size);
+ return true;
+ }
+
public byte[] compressBitmap(Bitmap bitmap) {
if (bitmap == null) {
return null;
diff --git a/src/com/android/browser/WebViewController.java b/src/com/android/browser/WebViewController.java
index 30eec4f..235fe97 100644
--- a/src/com/android/browser/WebViewController.java
+++ b/src/com/android/browser/WebViewController.java
@@ -63,7 +63,7 @@
boolean shouldOverrideKeyEvent(KeyEvent event);
- void onUnhandledKeyEvent(KeyEvent event);
+ boolean onUnhandledKeyEvent(KeyEvent event);
void doUpdateVisitedHistory(Tab tab, boolean isReload);
diff --git a/src/com/android/browser/homepages/RequestHandler.java b/src/com/android/browser/homepages/RequestHandler.java
index 13b52e3..823935e 100644
--- a/src/com/android/browser/homepages/RequestHandler.java
+++ b/src/com/android/browser/homepages/RequestHandler.java
@@ -112,34 +112,37 @@
History.CONTENT_URI, PROJECTION, SELECTION,
null, History.VISITS + " DESC LIMIT 12");
Cursor cursor = historyResults;
- if (cursor.getCount() < 12) {
- Cursor bookmarkResults = mContext.getContentResolver().query(
- Bookmarks.CONTENT_URI, PROJECTION, SELECTION,
- null, Bookmarks.DATE_CREATED + " DESC LIMIT 12");
- cursor = new MergeCursor(new Cursor[] { historyResults, bookmarkResults }) {
- @Override
- public int getCount() {
- return Math.min(12, super.getCount());
- }
- };
- }
-
- t.assignLoop("most_visited", new Template.CursorListEntityWrapper(cursor) {
- @Override
- public void writeValue(OutputStream stream, String key) throws IOException {
- Cursor cursor = getCursor();
- if (key.equals("url")) {
- stream.write(htmlEncode(cursor.getString(0)));
- } else if (key.equals("title")) {
- stream.write(htmlEncode(cursor.getString(1)));
- } else if (key.equals("thumbnail")) {
- stream.write("data:image/png;base64,".getBytes());
- byte[] thumb = cursor.getBlob(2);
- stream.write(Base64.encode(thumb, Base64.DEFAULT));
- }
+ try {
+ if (cursor.getCount() < 12) {
+ Cursor bookmarkResults = mContext.getContentResolver().query(
+ Bookmarks.CONTENT_URI, PROJECTION, SELECTION,
+ null, Bookmarks.DATE_CREATED + " DESC LIMIT 12");
+ cursor = new MergeCursor(new Cursor[] { historyResults, bookmarkResults }) {
+ @Override
+ public int getCount() {
+ return Math.min(12, super.getCount());
+ }
+ };
}
- });
- t.write(mOutput);
+ t.assignLoop("most_visited", new Template.CursorListEntityWrapper(cursor) {
+ @Override
+ public void writeValue(OutputStream stream, String key) throws IOException {
+ Cursor cursor = getCursor();
+ if (key.equals("url")) {
+ stream.write(htmlEncode(cursor.getString(0)));
+ } else if (key.equals("title")) {
+ stream.write(htmlEncode(cursor.getString(1)));
+ } else if (key.equals("thumbnail")) {
+ stream.write("data:image/png;base64,".getBytes());
+ byte[] thumb = cursor.getBlob(2);
+ stream.write(Base64.encode(thumb, Base64.DEFAULT));
+ }
+ }
+ });
+ t.write(mOutput);
+ } finally {
+ cursor.close();
+ }
}
private static final Comparator<File> sFileComparator = new Comparator<File>() {
diff --git a/src/com/android/browser/provider/SnapshotProvider.java b/src/com/android/browser/provider/SnapshotProvider.java
index 437a867..291e93b 100644
--- a/src/com/android/browser/provider/SnapshotProvider.java
+++ b/src/com/android/browser/provider/SnapshotProvider.java
@@ -15,13 +15,10 @@
*/
package com.android.browser.provider;
-import android.content.BroadcastReceiver;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
@@ -29,15 +26,11 @@
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
-import android.os.Environment;
+import android.os.FileUtils;
import android.provider.BrowserContract;
import java.io.File;
-/**
- * This provider is expected to be potentially flaky. It uses a database
- * stored on external storage, which could be yanked unexpectedly.
- */
public class SnapshotProvider extends ContentProvider {
public static interface Snapshots {
@@ -45,6 +38,7 @@
public static final Uri CONTENT_URI = Uri.withAppendedPath(
SnapshotProvider.AUTHORITY_URI, "snapshots");
public static final String _ID = "_id";
+ @Deprecated
public static final String VIEWSTATE = "view_state";
public static final String BACKGROUND = "background";
public static final String TITLE = "title";
@@ -52,6 +46,8 @@
public static final String FAVICON = "favicon";
public static final String THUMBNAIL = "thumbnail";
public static final String DATE_CREATED = "date_created";
+ public static final String VIEWSTATE_PATH = "viewstate_path";
+ public static final String VIEWSTATE_SIZE = "viewstate_size";
}
public static final String AUTHORITY = "com.android.browser.snapshots";
@@ -61,6 +57,8 @@
static final int SNAPSHOTS = 10;
static final int SNAPSHOTS_ID = 11;
static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+ // Workaround that we can't remove the "NOT NULL" constraint on VIEWSTATE
+ static final byte[] NULL_BLOB_HACK = new byte[0];
SnapshotDatabaseHelper mOpenHelper;
@@ -72,15 +70,10 @@
final static class SnapshotDatabaseHelper extends SQLiteOpenHelper {
static final String DATABASE_NAME = "snapshots.db";
- static final int DATABASE_VERSION = 2;
+ static final int DATABASE_VERSION = 3;
public SnapshotDatabaseHelper(Context context) {
- super(context, getFullDatabaseName(context), null, DATABASE_VERSION);
- }
-
- static String getFullDatabaseName(Context context) {
- File dir = context.getExternalFilesDir(null);
- return new File(dir, DATABASE_NAME).getAbsolutePath();
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
@@ -93,7 +86,9 @@
Snapshots.FAVICON + " BLOB," +
Snapshots.THUMBNAIL + " BLOB," +
Snapshots.BACKGROUND + " INTEGER," +
- Snapshots.VIEWSTATE + " BLOB NOT NULL" +
+ Snapshots.VIEWSTATE + " BLOB NOT NULL," +
+ Snapshots.VIEWSTATE_PATH + " TEXT," +
+ Snapshots.VIEWSTATE_SIZE + "INTEGER" +
");");
}
@@ -103,64 +98,52 @@
db.execSQL("DROP TABLE " + TABLE_SNAPSHOTS);
onCreate(db);
}
+ if (oldVersion < 3) {
+ db.execSQL("ALTER TABLE " + TABLE_SNAPSHOTS + " ADD COLUMN "
+ + Snapshots.VIEWSTATE_PATH + " TEXT");
+ db.execSQL("ALTER TABLE " + TABLE_SNAPSHOTS + " ADD COLUMN "
+ + Snapshots.VIEWSTATE_SIZE + " INTEGER");
+ db.execSQL("UPDATE " + TABLE_SNAPSHOTS + " SET "
+ + Snapshots.VIEWSTATE_SIZE + " = length("
+ + Snapshots.VIEWSTATE + ")");
+ }
}
}
+ static File getOldDatabasePath(Context context) {
+ File dir = context.getExternalFilesDir(null);
+ return new File(dir, SnapshotDatabaseHelper.DATABASE_NAME);
+ }
+
+ private void migrateToDataFolder() {
+ File dbPath = getContext().getDatabasePath(SnapshotDatabaseHelper.DATABASE_NAME);
+ if (dbPath.exists()) return;
+ File oldPath = getOldDatabasePath(getContext());
+ if (oldPath.exists()) {
+ // Try to move
+ if (!oldPath.renameTo(dbPath)) {
+ // Failed, do a copy
+ FileUtils.copyFile(oldPath, dbPath);
+ }
+ // Cleanup
+ oldPath.delete();
+ }
+ }
+
@Override
public boolean onCreate() {
- IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_EJECT);
- filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
- getContext().registerReceiver(mExternalStorageReceiver, filter);
+ migrateToDataFolder();
+ mOpenHelper = new SnapshotDatabaseHelper(getContext());
return true;
}
- final BroadcastReceiver mExternalStorageReceiver = new BroadcastReceiver() {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (mOpenHelper != null) {
- try {
- mOpenHelper.close();
- } catch (Throwable t) {
- // We failed to close the open helper, which most likely means
- // another thread is busy attempting to open the database
- // or use the database. Let that thread try to gracefully
- // deal with the error
- }
- }
- }
- };
-
SQLiteDatabase getWritableDatabase() {
- String state = Environment.getExternalStorageState();
- if (Environment.MEDIA_MOUNTED.equals(state)) {
- try {
- if (mOpenHelper == null) {
- mOpenHelper = new SnapshotDatabaseHelper(getContext());
- }
- return mOpenHelper.getWritableDatabase();
- } catch (Throwable t) {
- return null;
- }
- }
- return null;
+ return mOpenHelper.getWritableDatabase();
}
SQLiteDatabase getReadableDatabase() {
- String state = Environment.getExternalStorageState();
- if (Environment.MEDIA_MOUNTED.equals(state)
- || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
- try {
- if (mOpenHelper == null) {
- mOpenHelper = new SnapshotDatabaseHelper(getContext());
- }
- return mOpenHelper.getReadableDatabase();
- } catch (Throwable t) {
- return null;
- }
- }
- return null;
+ return mOpenHelper.getReadableDatabase();
}
@Override
@@ -186,15 +169,11 @@
default:
throw new UnsupportedOperationException("Unknown URL " + uri.toString());
}
- try {
- Cursor cursor = qb.query(db, projection, selection, selectionArgs,
- null, null, sortOrder, limit);
- cursor.setNotificationUri(getContext().getContentResolver(),
- AUTHORITY_URI);
- return cursor;
- } catch (Throwable t) {
- return null;
- }
+ Cursor cursor = qb.query(db, projection, selection, selectionArgs,
+ null, null, sortOrder, limit);
+ cursor.setNotificationUri(getContext().getContentResolver(),
+ AUTHORITY_URI);
+ return cursor;
}
@Override
@@ -212,11 +191,10 @@
long id = -1;
switch (match) {
case SNAPSHOTS:
- try {
- id = db.insert(TABLE_SNAPSHOTS, Snapshots.TITLE, values);
- } catch (Throwable t) {
- id = -1;
+ if (!values.containsKey(Snapshots.VIEWSTATE)) {
+ values.put(Snapshots.VIEWSTATE, NULL_BLOB_HACK);
}
+ id = db.insert(TABLE_SNAPSHOTS, Snapshots.TITLE, values);
break;
default:
throw new UnsupportedOperationException("Unknown insert URI " + uri);
@@ -229,6 +207,25 @@
return inserted;
}
+ static final String[] DELETE_PROJECTION = new String[] {
+ Snapshots.VIEWSTATE_PATH,
+ };
+ private void deleteDataFiles(SQLiteDatabase db, String selection,
+ String[] selectionArgs) {
+ Cursor c = db.query(TABLE_SNAPSHOTS, DELETE_PROJECTION, selection,
+ selectionArgs, null, null, null);
+ final Context context = getContext();
+ while (c.moveToNext()) {
+ File f = context.getFileStreamPath(c.getString(0));
+ if (f.exists()) {
+ if (!f.delete()) {
+ f.deleteOnExit();
+ }
+ }
+ }
+ c.close();
+ }
+
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = getWritableDatabase();
@@ -245,10 +242,8 @@
// fall through
}
case SNAPSHOTS:
- try {
- deleted = db.delete(TABLE_SNAPSHOTS, selection, selectionArgs);
- } catch (Throwable t) {
- }
+ deleteDataFiles(db, selection, selectionArgs);
+ deleted = db.delete(TABLE_SNAPSHOTS, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown delete URI " + uri);