From 5809c259087075f3cffebfd3b54030e5626bf2fd Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Thu, 1 Nov 2012 23:55:34 -0700 Subject: [PATCH 01/21] Import translations. DO NOT MERGE Change-Id: I5eb0827d8034bb574ff30abc1f8311d3d3ad91ad Auto-generated-cl: translation import --- core/res/res/values-af/strings.xml | 20 ++++++++++++- core/res/res/values-am/strings.xml | 23 +++++++++++++-- core/res/res/values-ar/strings.xml | 20 ++++++++++++- core/res/res/values-be/strings.xml | 20 ++++++++++++- core/res/res/values-bg/strings.xml | 23 +++++++++++++-- core/res/res/values-ca/strings.xml | 20 ++++++++++++- core/res/res/values-cs/strings.xml | 20 ++++++++++++- core/res/res/values-da/strings.xml | 23 +++++++++++++-- core/res/res/values-de/strings.xml | 27 +++++++++++++++++- core/res/res/values-el/strings.xml | 22 +++++++++++++-- core/res/res/values-en-rGB/strings.xml | 20 ++++++++++++- core/res/res/values-es-rUS/strings.xml | 23 +++++++++++++-- core/res/res/values-es/strings.xml | 20 ++++++++++++- core/res/res/values-et/strings.xml | 20 ++++++++++++- core/res/res/values-fa/strings.xml | 20 ++++++++++++- core/res/res/values-fi/strings.xml | 20 ++++++++++++- core/res/res/values-fr/strings.xml | 27 +++++++++++++++++- core/res/res/values-hi/strings.xml | 20 ++++++++++++- core/res/res/values-hr/strings.xml | 20 ++++++++++++- core/res/res/values-hu/strings.xml | 20 ++++++++++++- core/res/res/values-in/strings.xml | 20 ++++++++++++- core/res/res/values-it/strings.xml | 20 ++++++++++++- core/res/res/values-iw/strings.xml | 20 ++++++++++++- core/res/res/values-ja/strings.xml | 20 ++++++++++++- core/res/res/values-ko/strings.xml | 23 +++++++++++++-- core/res/res/values-lt/strings.xml | 20 ++++++++++++- core/res/res/values-lv/strings.xml | 22 +++++++++++++-- core/res/res/values-ms/strings.xml | 20 ++++++++++++- core/res/res/values-nb/strings.xml | 23 +++++++++++++-- core/res/res/values-nl/strings.xml | 20 ++++++++++++- core/res/res/values-pl/strings.xml | 37 +++++++++++++++++++++++- core/res/res/values-pt-rPT/strings.xml | 20 ++++++++++++- core/res/res/values-pt/strings.xml | 20 ++++++++++++- core/res/res/values-rm/strings.xml | 36 +++++++++++++++++++++++- core/res/res/values-ro/strings.xml | 23 +++++++++++++-- core/res/res/values-ru/strings.xml | 23 +++++++++++++-- core/res/res/values-sk/strings.xml | 23 +++++++++++++-- core/res/res/values-sl/strings.xml | 20 ++++++++++++- core/res/res/values-sr/strings.xml | 20 ++++++++++++- core/res/res/values-sv/strings.xml | 20 ++++++++++++- core/res/res/values-sw/strings.xml | 20 ++++++++++++- core/res/res/values-th/strings.xml | 20 ++++++++++++- core/res/res/values-tl/strings.xml | 20 ++++++++++++- core/res/res/values-tr/strings.xml | 23 +++++++++++++-- core/res/res/values-uk/strings.xml | 20 ++++++++++++- core/res/res/values-vi/strings.xml | 20 ++++++++++++- core/res/res/values-zh-rCN/strings.xml | 39 ++++++++++++++++++-------- core/res/res/values-zh-rTW/strings.xml | 22 +++++++++++++-- core/res/res/values-zu/strings.xml | 22 +++++++++++++-- 49 files changed, 1001 insertions(+), 83 deletions(-) diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index fe77b054ae467..b00495b19a869 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -810,10 +810,26 @@ "Patroon uitgevee" "Sel bygevoeg" "Patroon klaar" - "%1$s. Legstuk %2$d van %3$d." + "Voeg legstuk by." + "Leeg" + "Ontsluitruimte uitgevou." + "Ontsluitruimte het in duie gestort." + "%1$s legstuk." "Gebruikerkieser" "Status" + "Kamera" "Media-kontroles" + "Herordening van legstuk begin." + "Herordening van legstuk beëindig." + "Legstuk %1$s verwyder." + "Vou ontsluitruimte uit." + "Skyfie ontsluit." + "Patroon ontsluit." + "Gesigslot." + "PIN ontsluit." + "Wagwoord ontsluit." + "Patroonarea." + "Skyfie-area." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Jy het %d keer verkeerdelik gepoog om die foon te ontsluit. Die foon sal nou na fabrieksverstek teruggestel word." "Jy het jou ontsluitpatroon %d keer verkeerdelik geteken. Na nog %d onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor %d sekondes." "Jy het jou ontsluitpatroon %d keer verkeerdelik geteken. Na nog %d onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor %d sekondes." + + "Moet volume bo veilige vlak verhoog word?"\n"Deur vir lang tydperke op hoë volume te luister, kan jou gehoor beskadig." "Hou aan met twee vingers inhou om toeganklikheid te aktiveer." "Toeganklikheid geaktiveer." diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index b89e01bc365b1..debb0b3a3be93 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -585,8 +585,7 @@ "በተጠቃሚ መዝገበ ቃላት ውስጥ አዲስ ቃል እንዲጽፍ ለመተግበሪያው ይፈቅዳሉ፡፡" "ጥበቃ ወደሚደረግለት ማከማቻ ያለ መዳረሻን ፈትሽ" "ጥበቃ ወደሚደረግለት ማከማቻ ያለ መዳረሻን ፈትሽ" - - + "መተግበሪያው በወደፊት መሳሪዎች ላይ ለሚኖር የUSB ማህደረ ትውስታ ፈቃድ እንዲሞክር ይፈቅድለታል።" "መተግበሪያው በወደፊት መሳሪዎች ላይ ለሚኖረው SD ካርድ ፈቃድ እንዲሞክር ይፈቅድለታል።" "የUSB ማከማቻህን ይዘቶች ቀይር ወይም ሰርዝ" "የSD ካርድህን ይዘቶች ቀይር ወይም ሰርዝ" @@ -811,10 +810,26 @@ "ንድፍ ጸድቷል" "ሕዋስ ታክሏል" "ንድፍ ተጠናቋል" - "%1$s። ምግብር %2$d ከ%3$d።" + "ንዑስ ፕሮግራም አክል" + "ባዶ" + "የመክፈቻ አካባቢ ተስፋፍቷል።" + "የመክፈቻ አካባቢ ተሰብስቧል።" + "የ%1$s ንዑስ ፕሮግራም።" "ተጠቃሚ መራጭ" "ሁኔታ" + "ካሜራ" "የሚዲያ መቆጣጠሪያዎች" + "የንዑስ ፕሮግራም ዳግም መደርደር ተጀምሯል።" + "የንዑስ ፕሮግራም ዳግም መደርደር አብቅቷል።" + "ንዑስ ፕሮግራም %1$s ተሰርዟል።" + "የመክፈቻ አካባቢውን አስፋፋ።" + "በማንሸራተት ክፈት።" + "በስርዓተ-ጥለት መክፈት።" + "በፊት መክፈት።" + "በፒን መክፈት።" + "በይለፍ ቃል መክፈት።" + "የስርዓተ-ጥለት አካባቢ።" + "የማንሸራተቻ አካባቢ።" "?123" "ABC" "ALT" @@ -1421,6 +1436,8 @@ "ስልኩን %d ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ስልኩ አሁን በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመራል።" "የመክፈቻ ስርዓተ ጥለቱን %d ጊዜ በትክክል አልሳሉትም። ከ%d ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።"\n\n" ከ%d ከሰከንዶች በኋላ እንደገና ይሞክሩ።" "የመክፈቻ ስርዓተ ጥለቱን %d ጊዜ በትክክል አልሳሉትም። ከ%d ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።"\n\n"እባክዎ ከ%d ሰከንዶች በኋላ እንደገና ይሞክሩ።" + + "ድምጽ አደጋ ከሌለው መጠን በላይ ይጨመር??"\n"ለረጅም ጊዜ በከፍተኛ ድምጽ መስማት የመስማት ችሎታዎን ሊጎዳይ ይችላል።" "ተደራሽነትን ለማንቃት ሁለት ጣቶችዎን ባሉበት ያቆዩዋቸው።" "ተደራሽነት ነቅቷል።" diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 5bd5f28fdb892..b10ce53722e14 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -810,10 +810,26 @@ "تم محو النمط" "تمت إضافة الخلية" "اكتمل النمط" - "%1$s. الأداة %2$d من %3$d." + "إضافة أداة." + "فارغة" + "تم توسيع منطقة إلغاء القفل." + "تم تصغير منطقة إلغاء القفل." + "أداة %1$s." "محدد المستخدم" "الحالة" + "الكاميرا" "أدوات التحكم في الوسائط" + "بدأت إعادة ترتيب الأدوات." + "انتهت إعادة ترتيب الأدوات." + "تم حذف أداة %1$s." + "توسيع منطقة إلغاء القفل." + "إلغاء القفل باستخدام التمرير." + "إلغاء القفل باستخدام النقش." + "تأمين الجهاز بالوجه." + "إلغاء القفل باستخدام رقم التعريف الشخصي." + "إلغاء القفل باستخدام كلمة المرور." + "منطقة النقش." + "منطقة التمرير." "?123" "ب ت ث" "ALT" @@ -1420,6 +1436,8 @@ "لقد حاولت إلغاء تأمين الهاتف بشكل غير صحيح %d مرة. سيتم الآن إعادة تعيين الهاتف على الإعدادات الافتراضية للمصنع." "لقد رسمت نقش إلغاء التأمين بشكل غير صحيح %d مرة. بعد إجراء %d من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني."\n\n" أعد المحاولة خلال %d ثانية." "لقد رسمت نقش إلغاء التأمين بشكل غير صحيح %d مرة. بعد إجراء %d من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف."\n\n" أعد المحاولة خلال %d ثانية." + + "هل تريد رفع مستوى الصوت فوق المستوى الآمن؟"\n"قد يضر سماع صوت عالٍ لفترات طويلة بسمعك." "اضغط بإصبعين لأسفل مع الاستمرار لتمكين تسهيل الدخول." "تم تمكين إمكانية الدخول." diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 5d7009bdb3f38..f0c3725743e93 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -810,10 +810,26 @@ "Ключ выдалены" "Сотавы дададзены" "Ключ завершаны" - "%1$s. ВIджэт %2$d з %3$d." + "Дадаць віджэт" + "Пусты" + "Вобласць разблакіроўкі разгарнута." + "Вобласць разблакіроўкі згарнута." + "Віджэт %1$s." "Селектар карыстальнiка" "Стан" + "Камера" "Налады мультымедыя" + "Змяненне парадку віджэтаў пачалося." + "Змяненне парадку віджэтаў скончылася." + "Віджэт %1$s выдалены." + "Разгарнуць вобласць разблакіроўкі." + "Разблакiроўка слайда." + "Узор разблакiроўкі." + "Фэйскантроль" + "PIN-код разблакiроўкі." + "Пароль разблакiроўкі." + "Вобласць узора." + "Вобласць слайда." "123" "ABC" "Alt" @@ -1420,6 +1436,8 @@ "Вы няправільна спрабавалі разблакiраваць тэлефон некалькi разоў (%d). Цяпер ён будзе скінуты да завадскіх налад." "Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: %d. Пасля яшчэ некалькiх няўдалых спроб (%d) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз %d с." "Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: %d. Пасля яшчэ некалькiх няўдалых спроб (%d) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз %d с." + + "Павялiчыць гук больш за рэкамендаваны ўзровень?"\n"Доўгае слуханне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых." "Утрымлiвайце два пальцы, каб уключыць доступ." "Даступнасць уключана." diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index d55d89ee793b8..13b5fe87ffafc 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -585,8 +585,7 @@ "Разрешава на приложението да записва нови думи в потребителския речник." "изпробване на достъп до защитено хранилище" "изпробване на достъп до защитено хранилище" - - + "Разрешава на приложението да изпробва разрешение за USB хран., което ще е налице на бъдещи у-ва." "Разрешава на приложението да изпробва разрешение за SD картата, което ще бъде налице на бъдещи устройства." "промяна или изтрив. на съдърж. от USB хран. ви" "промяна или изтриване на съдържанието от SD картата ви" @@ -811,10 +810,26 @@ "Фигурата е изчистена" "Клетката е добавена" "Фигурата е завършена" - "%1$s. Приспособление %2$d от %3$d." + "Добавяне на приспособление." + "Празно" + "Областта за отключване е разгъната." + "Областта за отключване е свита." + "Приспособление за %1$s." "Инструмент за избор на потребители" "Състояние" + "Камера" "Контроли за мултимедията" + "Пренареждането на приспособленията започна." + "Пренареждането на приспособленията завърши." + "Приспособлението за %1$s е изтрито." + "Разгъване на областта за отключване." + "Отключване с плъзгане." + "Отключване с фигура." + "Отключване с лице." + "Отключване с ПИН код." + "Отключване с парола." + "Област на фигурата." + "Област на плъзгане." "?123" "АБВ" "ALT" @@ -1421,6 +1436,8 @@ "Направихте опит да отключите неправилно телефона %d пъти. Сега ще бъдат възстановени стандартните му фабрични настройки." "Начертахте неправилно фигурата си за отключване %d пъти. След още %d неуспешни опита ще бъдете помолени да отключите таблета посредством имейл адрес."\n\n" Опитайте отново след %d секунди." "Начертахте неправилно фигурата си за отключване %d пъти. След още %d неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес."\n\n" Опитайте отново след %d секунди." + + "Да се увеличи ли силата на звука над безопасното ниво?"\n"Продължителното слушане при висока сила на звука може да увреди слуха ви." "Продължете да натискате с два пръста, за да активирате функцията за достъпност." "Достъпността е активирана." diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index df2d08566e779..e56522363b88a 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -810,10 +810,26 @@ "Patró esborrat" "S\'ha afegit una cel·la" "Patró completat" - "%1$s. Widget %2$d de %3$d." + "Afegeix un widget" + "Buit" + "S\'ha ampliat l\'àrea de desbloqueig." + "L\'àrea de desbloqueig està col·lapsada." + "Widget de %1$s." "Selector d\'usuaris" "Estat" + "Càmera" "Controls multimèdia" + "S\'ha iniciat la reorganització del widget." + "Ha finalitzat la reorganització del widget." + "S\'ha suprimit el widget de %1$s." + "Amplia l\'àrea de desbloqueig." + "Desbloqueig per control lliscant." + "Desbloqueig per patró." + "Desbloqueig facial." + "Desbloqueig per PIN." + "Desbloqueig per contrasenya." + "Zona de patró." + "Àrea de control lliscant." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Has provat de desbloquejar el telèfon %d vegades de manera incorrecta. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica." "Has dibuixat el patró de desbloqueig %d vegades de manera incorrecta. Després de %d intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a %d segons." "Has dibuixat el patró de desbloqueig %d vegades de manera incorrecta. Després de %d intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a %d segons." + + "Vols augmentar el volum per sobre del nivell de seguretat?"\n"Escoltar música a un volum alt durant períodes llargs pot perjudicar l\'oïda." "Mantén premuts els dos dits per activar l\'accessibilitat." "S\'ha activat l\'accessibilitat." diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index d7af330b8954c..4a409d369dc33 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -810,10 +810,26 @@ "Bezpečnostní gesto vymazáno" "Buňka přidána" "Bezpečnostní gesto dokončeno" - "%1$s. Widget %2$d z %3$d." + "Přidat widget" + "Prázdné" + "Oblast odemknutí byla rozšířena." + "Oblast odemknutí byla sbalena." + "Widget %1$s" "Výběr uživatele" "Stav" + "Fotoaparát" "Ovládání médií" + "Přeuspořádání widgetů bylo zahájeno." + "Přeuspořádání widgetů bylo dokončeno." + "Widget %1$s byl smazán." + "Rozšířit oblast odemknutí" + "Odemknutí přejetím prstem." + "Odemknutí gestem." + "Odemknutí obličejem." + "Odemknutí kódem PIN." + "Odemknutí heslem." + "Oblast pro zadání bezpečnostního gesta." + "Oblast pro přejetí prstem." "?123" "ABC" "Alt" @@ -1420,6 +1436,8 @@ "Již jste se %dkrát pokusili odemknout telefon nesprávným způsobem. V telefonu se nyní obnoví výchozí tovární nastavení." "Již %dkrát jste nesprávně nakreslili své heslo odemknutí. Po %ddalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu."\n\n" Zkuste to znovu za %d s." "Již %dkrát jste nesprávně nakreslili své heslo odemknutí. Po %d dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu."\n\n" Zkuste to znovu za %d s." + + "Chcete hlasitost zvýšit nad bezpečnou úroveň?"\n"Dlouhodobý poslech hlasitého zvuku může poškodit sluch." "Usnadnění zapnete dlouhým stisknutím dvěma prsty." "Usnadnění přístupu je aktivováno." diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 7d0394c071c1f..6c64c694b2185 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -585,8 +585,7 @@ "Tillader, at appen kan skrive nye ord i brugerordbogen." "test adgangen til beskyttet lagring" "test adgangen til beskyttet lagring" - - + "Tillader, at appen tester en tilladelse til USB-lagring, der vil være tilgængelig på fremtidige enheder." "Tillader, at appen kan teste en tilladelse for SD-kortet, der vil være tilgængelig på fremtidige enheder." "ændre eller slette indhold på USB-lager" "ændre eller slette indholdet på dit SD-kort" @@ -811,10 +810,26 @@ "Mønster er ryddet" "Celle er tilføjet" "Mønster er afsluttet" - "%1$s. Widget %2$d af %3$d." + "Tilføj widget." + "Tom" + "Oplåsningsområdet er udvidet." + "Oplåsningsområdet er skjult." + "Widget til %1$s." "Brugervælger" "Status" + "Kamera" "Mediekontrolelementer" + "Omrokering af widgets er påbegyndt." + "Omrokering af widgets er afsluttet." + "Widgetten %1$s er slettet." + "Udvid oplåsningsområdet." + "Lås op ved at stryge." + "Lås op med mønster." + "Lås op med ansigt." + "Lås op med pinkode." + "Lås op med adgangskode." + "Mønsterområde." + "Strygeområde." "?123" "ABC" "ALT" @@ -1421,6 +1436,8 @@ "Du har forsøgt at låse telefonen op forkert %d gange. Telefonen nulstilles til fabriksindstillingerne." "Du har tegnet dit oplåsningsmønster forkert %d gange. Efter %d yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto"\n\n" Prøv igen om %d sekunder." "Du har tegnet dit oplåsningsmønster forkert %d gange. Efter %d yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto."\n\n" Prøv igen om %d sekunder." + + "Skal lydstyrken være over det sikre niveau?"\n"Du kan skade din hørelse ved at lytte ved høj lydstyrke i længere tid." "Hold fortsat to fingre nede for at aktivere tilgængelighed." "Tilgængelighed aktiveret." diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 0fa14b342f711..fc12d90462d36 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -810,10 +810,33 @@ "Muster gelöscht" "Zelle hinzugefügt" "Muster abgeschlossen" - "%1$s. Widget %2$d von %3$d." + "Widget hinzufügen" + "Leer" + "Entsperrter Bereich maximiert" + "Entsperrten Bereich minimieren" + "Widget %1$s" "Nutzerauswahl" "Status" + "Kamera" "Mediensteuerelemente" + "Neuordnung der Widgets gestartet" + "Neuordnung der Widgets abgeschlossen" + "Widget %1$s gelöscht" + "Entsperrten Bereich maximieren" + + + + + + + + + + + + + + "?123" "ABC" "ALT" @@ -1420,6 +1443,8 @@ "Sie haben %d-mal erfolglos versucht, das Telefon zu entsperren. Das Telefon wird nun auf die Werkseinstellungen zurückgesetzt." "Sie haben Ihr Entsperrungsmuster %d-mal falsch gezeichnet. Nach %d weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in %d Sekunden erneut." "Sie haben Ihr Entsperrungsmuster %d-mal falsch gezeichnet. Nach %d weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in %d Sekunden erneut." + + "Lautstärke höher als Schwellenwert stellen?"\n"Wenn Sie über längere Zeiträume hinweg Musik in hoher Lautstärke hören, kann dies Ihr Gehör schädigen." "Drücken Sie mit zwei Fingern, um die Bedienungshilfen zu aktivieren." "Bedienungshilfen aktiviert" diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 33899baf7f83e..b2a2bbde1bdc3 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -585,7 +585,7 @@ "Επιτρέπει στην εφαρμογή την εγγραφή νέων λέξεων στο λεξικό χρήστη." "δοκιμή πρόσβασης σε προστατευμένο χώρο αποθήκευσης" "δοκιμή πρόσβασης σε προστατευμένο χώρο αποθήκευσης" - "Επιτρ.στην εφαρμ. τη δοκ.άδειας αποθ. χώρ.USB που θα διατ. σε μελλ.συσκ." + "Επιτρέπει USB για άλλες συσκ." "Επιτρέπει στην εφαρμογή τη δοκιμή μια άδειας για την κάρτα SD που θα διατίθεται σε μελλοντικές συσκευές." "τροπ. ή διαγρ. περιεχ. αποθ. χώρ. USB" "τροποποίηση ή διαγραφή των περιεχομένων της κάρτας SD" @@ -810,10 +810,26 @@ "Το μοτίβο απαλείφθηκε" "Προστέθηκε κελί" "Το μοτίβο ολοκληρώθηκε" - "%1$s. Γραφικό στοιχείο %2$d από %3$d." + "Προσθήκη γραφικού στοιχείου" + "Κενή" + "Ανάπτυξη της περιοχής ξεκλειδώματος." + "Σύμπτυξη της περιοχής ξεκλειδώματος." + "Γραφικό στοιχείο %1$s." "Επιλογέας χρήστη" "Κατάσταση" + "Φωτογραφική μηχανή" "Στοιχεία ελέγχου μέσων" + "Έχει ξεκινήσει η αναδιάταξη των γραφικών στοιχείων." + "Έχει ολοκληρωθεί η αναδιάταξη των γραφικών στοιχείων." + "Το γραφικό στοιχείο %1$s έχει διαγραφεί." + "Ανάπτυξη περιοχής ξεκλειδώματος." + "Ξεκλείδωμα ολίσθησης." + "Ξεκλείδωμα μοτίβου." + "Face unlock." + "Ξεκλείδωμα κωδικού ασφαλείας" + "Ξεκλείδωμα κωδικού πρόσβασης." + "Περιοχή μοτίβου." + "Περιοχή ολίσθησης" "?123" "ΑΒΓ" "ALT" @@ -1420,6 +1436,8 @@ "Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το τηλέφωνο %d φορές. Το τηλέφωνο θα επαναφερθεί στις εργοστασιακές ρυθμίσεις." "Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα %d φορές. Μετά από %d ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε να συνδεθείτε ξανά σε %d δευτερόλεπτα." "Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα %d φορές. Μετά από %d ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε ξανά σε %d δευτερόλεπτα." + + "Αύξηση έντασης ήχου πάνω από το επίπεδο ασφαλείας;"\n"Αν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας." "Αγγίξτε παρατεταμένα με δύο δάχτυλα για να ενεργοποιήσετε τη λειτουργία προσβασιμότητας." "Ενεργοποιήθηκε η προσβασιμότητα." diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 1267b14ab5ab4..260e93188c726 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -810,10 +810,26 @@ "Pattern cleared" "Cell added" "Pattern completed" - "%1$s. Widget %2$d of %3$d." + "Add widget" + "Empty" + "Unlock area expanded." + "Unlock area collapsed." + "%1$s widget." "User selector" "Status" + "Camera" "Media controls" + "Widget reordering started." + "Widget reordering ended." + "Widget %1$s deleted." + "Expand unlock area." + "Slide unlock." + "Pattern unlock." + "Face unlock." + "Pin unlock." + "Password unlock." + "Pattern area." + "Slide area." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "You have incorrectly attempted to unlock the phone %d times. The phone will now be reset to factory default." "You have incorrectly drawn your unlock pattern %d times. After %d more unsuccessful attempts, you will be asked to unlock your tablet using an email account."\n\n" Try again in %d seconds." "You have incorrectly drawn your unlock pattern %d times. After %d more unsuccessful attempts, you will be asked to unlock your phone using an email account."\n\n" Try again in %d seconds." + + "Raise volume above safe level?"\n"Listening at high volume for long periods may damage your hearing." "Keep holding down two fingers to enable accessibility." "Accessibility enabled." diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index ebeb2960c349e..a4c72c0e8fe58 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -585,8 +585,7 @@ "Permite que la aplicación ingrese palabras nuevas en el diccionario del usuario." "probar acceso a almacenamiento protegido" "probar acceso a almacenamiento protegido" - - + "Prueba permiso almac. USB." "Permite que la aplicación pruebe un permiso para la tarjeta SD que estará disponible en futuros dispositivos." "modificar/borrar contenido USB" "modificar o eliminar el contenido de la tarjeta SD" @@ -811,10 +810,26 @@ "Se eliminó el patrón" "Se agregó una celda." "Se completó el patrón" - "%1$s. Widget %2$d de %3$d" + "Agrega un widget." + "Vacío" + "Se expandió el área desbloqueada." + "El área desbloqueada colapsó." + "%1$s widget" "Selector de usuarios" "Estado" + "Cámara" "Controles de medios" + "El reordenamiento de widget ha empezado." + "El reordenamiento de widget ha finalizado." + "Widget %1$s eliminado" + "Expandir el área desbloqueada." + "Desbloqueo por desliz" + "Desbloqueo por patrón" + "Desbloqueo facial" + "Desbloqueo por PIN" + "Desbloqueo por contraseña" + "Área de patrón" + "Área de desliz" "?123" "ABC" "ALT" @@ -1421,6 +1436,8 @@ "Intentaste desbloquear el dispositivo %d veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica del dispositivo." "Dibujaste incorrectamente tu patrón de desbloqueo %d veces. Luego de %d intentos incorrectos más, se te solicitará que desbloquees tu tableta mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en %d segundos." "Dibujaste incorrectamente tu patrón de desbloqueo %d veces. Luego de %d intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en %d segundos." + + "¿Aumentar el volumen por encima del nivel seguro?"\n"Si escuchas con el volumen alto durante períodos prolongados, puedes dañar tu audición." "Mantén presionado con dos dedos para activar la accesibilidad." "Se activó la accesibilidad." diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 3ea30d14bd683..2172c003e8d13 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -810,10 +810,26 @@ "Patrón borrado" "Se ha añadido una celda." "Patrón completado" - "%1$s. Widget %2$d de %3$d" + "Añadir widget" + "Vacío" + "Área de desbloqueo ampliada" + "Área de desbloqueo contraída" + "Widget de %1$s" "Selector de usuarios" "Estado" + "Cámara" "Controles multimedia" + "Se ha empezado a cambiar el orden de los widgets." + "Se ha terminado de cambiar el orden de los widgets." + "Widget %1$s eliminado" + "Ampliar área desbloqueada" + "Desbloqueo deslizando el dedo" + "Desbloqueo mediante patrón" + "Desbloqueo facial" + "Desbloqueo mediante PIN" + "Desbloqueo mediante contraseña" + "Área de patrón" + "Área para deslizar" "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Has intentado desbloquear el teléfono %d veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo." "Has fallado %d veces al dibujar el patrón de desbloqueo. Si fallas otras %d veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet."\n\n" Inténtalo de nuevo en %d segundos." "Has fallado %d veces al dibujar el patrón de desbloqueo. Si fallas otras %d veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono."\n\n" Inténtalo de nuevo en %d segundos." + + "¿Subir el volumen por encima del nivel de seguridad?"\n"Escuchar sonidos a alto volumen durante largos períodos de tiempo puede dañar tus oídos." "Mantén la pantalla pulsada con dos dedos para habilitar las funciones de accesibilidad." "Accesibilidad habilitada" diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 03fcfbbee8a61..ac154203c8e6b 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -810,10 +810,26 @@ "Muster on kustutatud" "Lahter on lisatud" "Muster on valmis" - "%1$s. Vidin %2$d/%3$d." + "Vidina lisamine." + "Tühi" + "Avamisala on laiendatud." + "Avamisala on ahendatud." + "Vidin %1$s." "Kasutaja valija" "Olek" + "Kaamera" "Meedia juhtnupud" + "Vidina ümberkorraldamine on alanud." + "Vidina ümberkorraldamine on lõppenud." + "Vidin %1$s on kustutatud." + "Avamisala laiendamine." + "Lohistamisega avamine." + "Mustriga avamine." + "Näoga avamine." + "PIN-koodiga avamine." + "Parooliga avamine." + "Mustri ala." + "Lohistamisala." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Olete püüdnud telefoni %d korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele." "Joonistasite oma avamismustri %d korda valesti. Pärast veel %d ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga."\n\n" Proovige uuesti %d sekundi pärast." "Joonistasite oma avamismustri %d korda valesti. Pärast veel %d ebaõnnestunud katset palutakse teil telefon avada meilikontoga."\n\n" Proovige uuesti %d sekundi pärast." + + "Kas suurendada helitugevust üle ohutu piiri?"\n"Pikaajaline suure helitugevusega muusika kuulamine võib kahjustada kuulmist." "Hõlbustuse lubamiseks hoidke kaht sõrme all." "Hõlbustus on lubatud." diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index de1e9a9ef6d5e..76fd591ab4d7c 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -810,10 +810,26 @@ "الگو پاک شد" "سلول اضافه شد" "الگو تکمیل شد" - "%1$s. ابزارک %2$d از %3$d." + "ابزارک اضافه کنید." + "خالی" + "منطقه بازگشایی گسترده شد." + "منطقه بازگشایی کوچک شد." + "ابزارک %1$s." "انتخابگر کاربر" "وضعیت" + "دوربین" "کنترل‌های رسانه" + "مرتب سازی مجدد ابزارک آغاز شد." + "مرتب‌سازی مجدد ابزارک به پایان رسید." + "ابزارک %1$s حذف شد.‍" + "گسترده کردن منطقه بازگشایی شده." + "باز کردن قفل با کشیدن انگشت روی صفحه." + "باز کردن قفل با الگو." + "باز کردن قفل با چهره." + "باز کردن قفل با پین." + "باز کردن قفل با گذرواژه." + "ناحیه الگو." + "ناحیه کشیدن انگشت روی صفحه." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "شما به اشتباه %d بار اقدام به باز کردن قفل تلفن کرده‌اید. این تلفن اکنون به پیش‌فرض کارخانه بازنشانی می‌شود." "شما الگوی بازگشایی قفل خود را %d بار اشتباه کشیده‎اید. بعد از %d تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید."\n\n" لطفاً پس از %d ثانیه دوباره امتحان کنید." "شما الگوی بازگشایی قفل خود را %d بار اشتباه کشیده‌اید. پس از %d تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید."\n\n" لطفاً پس از %d ثانیه دوباره امتحان کنید." + + "صدا به بالاتر از سطح ایمن افزایش یابد؟"\n"گوش دادن به صدای بلند برای زمان‌های طولانی می‌تواند به شنوایی شما آسیب برساند." "برای فعال کردن قابلیت دسترسی، با دو انگشت خود همچنان به طرف پایین فشار دهید." "قابلیت دسترسی فعال شد." diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index ec48526bbbc56..9da7d3d5fbb5b 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -810,10 +810,26 @@ "Kuvio tyhjennetty" "Solu lisätty" "Kuvio valmis" - "%1$s. Widget %2$d/%3$d." + "Lisää widget." + "Tyhjä" + "Lukituksen poiston alue laajennettu." + "Lukituksen poiston alue tiivistetty." + "%1$s-widget." "Käyttäjävalitsin" "Tila" + "Kamera" "Mediaohjaimet" + "Widgetien järjestely aloitettu." + "Widgetien järjestely päättyi." + "Widget %1$s poistettu." + "Laajenna lukituksen poiston aluetta." + "Lukituksen poisto liu\'uttamalla." + "Lukituksen poisto salasanalla." + "Face Unlock" + "Lukituksen poisto PIN-koodilla." + "Lukituksen poisto salasanalla." + "Kuvioalue." + "Liu\'utusalue." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Puhelimen lukituksen poisto epäonnistui %d kertaa. Puhelimeen palautetaan nyt tehdasasetukset." "Piirsit lukituksenpoistokuvion väärin %d kertaa. Jos piirrät kuvion väärin vielä %d kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen %d sekunnin kuluttua." "Piirsit lukituksenpoistokuvion väärin %d kertaa. Jos piirrät kuvion väärin vielä %d kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen %d sekunnin kuluttua." + + "Nostetaanko äänenvoimakkuus turvallista tasoa voimakkaammaksi?"\n"Jos kuuntelet suurella äänenvoimakkuudella pitkiä aikoja, kuulosi voi vahingoittua." "Ota esteettömyystila käyttöön koskettamalla pitkään kahdella sormella." "Esteettömyystila käytössä." diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 912bda059dba2..b92d4bf25f3cf 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -810,10 +810,33 @@ "Schéma effacé." "Cellule ajoutée." "Schéma terminé." - "%1$s. Widget %2$d sur %3$d." + "Ajouter un widget" + "Vide" + "Développement de la zone de déverrouillage" + "Réduction de la zone de déverrouillage" + "Widget %1$s" "Sélecteur d\'utilisateur" "État" + "Caméra" "Commandes multimédias" + "Début de la réorganisation des widgets" + "Fin de la réorganisation des widgets" + "Le widget %1$s a été supprimé." + "Développer la zone de déverrouillage" + + + + + + + + + + + + + + "?123" "ABC" "ALT" @@ -1420,6 +1443,8 @@ "Vous avez tenté de déverrouiller le téléphone de façon incorrecte à %d reprises. Sa configuration d\'usine va être rétablie." "Vous avez dessiné un schéma de déverrouillage incorrect à %d reprises. Si vous échouez encore %d fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans %d secondes." "Vous avez dessiné un schéma de déverrouillage incorrect à %d reprises. Si vous échouez encore %d fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans %d secondes." + + "Augmenter le volume au-dessus du niveau de sécurité ?"\n"L\'écoute à un volume élevé pendant des périodes prolongées peut endommager votre audition." "Pour activer l\'accessibilité, appuyez de manière prolongée avec deux doigts." "L\'accessibilité a bien été activée." diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 67148f1bc2fc5..57d3ed64e632e 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -810,10 +810,26 @@ "प्रतिमान साफ़ किया गया" "कक्ष जोड़ा गया" "प्रतिमान पूरा किया गया" - "%1$s. %3$d विजेट में से %2$d." + "विजेट जोड़ें" + "रिक्त" + "अनलॉक क्षेत्र को विस्तृत कर दिया गया." + "अनलॉक क्षेत्र को संक्षिप्त कर दिया गया." + "%1$s विजेट." "उपयोगकर्ता चयनकर्ता" "स्थिति" + "कैमरा" "मीडिया नियंत्रण" + "विजेट पुनः क्रमित करना प्रारंभ." + "विजेट पुनः क्रमित करना समाप्त." + "विजेट %1$s को हटा दिया गया." + "अनलॉक क्षेत्र विस्तृत करें." + "स्लाइड अनलॉक." + "प्रतिमान अनलॉक." + "फेस अनलॉक." + "पिन अनलॉक." + "पासवर्ड अनलॉक." + "प्रतिमान क्षेत्र." + "स्लाइड क्षेत्र." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "आप फ़ोन को अनलॉक करने के लिए %d बार गलत तरीके से प्रयास कर चुके हैं. फ़ोन अब फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा." "आपने अपने अनलॉक प्रतिमान को %d बार गलत तरीके से आरेखित किया है. %d और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा."\n\n" %d सेकंड में पुन: प्रयास करें." "आपने अपने अनलॉक प्रतिमान को %d बार गलत तरीके से आरेखित किया है. %d और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा."\n\n" %d सेकंड में पुन: प्रयास करें." + + "वॉल्यूम को सुरक्षित स्तर से अधिक करें?"\n"अधिक देर तक उच्च वॉल्यूम पर सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है." "पहुंच-योग्यता को सक्षम करने के लिए दो अंगुलियों से नीचे दबाए रखें." "पहुंच-योग्यता सक्षम कर दी है." diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 131445838bf86..245aefb826650 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -810,10 +810,26 @@ "Uzorak je obrisan" "Dodan je mobitel" "Uzorak je dovršen" - "%1$s. Widget %2$d od %3$d." + "Dodavanje widgeta." + "Prazno" + "Područje za otključavanje prošireno je." + "Područje za otključavanje sažeto je." + "%1$s widget." "Birač korisnika" "Status" + "Fotoaparat" "Nadzor medija" + "Pokrenuta je promjena redoslijeda widgeta." + "Završena je promjena redoslijeda widgeta." + "Widget %1$s izbrisan je." + "Proširivanje područja za otključavanje." + "Otključavanje kliženjem." + "Uzorak za otključavanje." + "Otključavanje licem." + "Otključavanje PIN-om." + "Otključavanje zaporkom." + "Područje uzorka." + "Područje kliženja." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Netočno ste pokušali otključati telefon %d puta. Sada će se vratiti na tvorničke postavke." "Netočno ste iscrtali obrazac za otključavanje %d puta. Nakon još ovoliko neuspješnih pokušaja: %d morat ćete otključati tabletno računalo pomoću računa e-pošte."\n\n" Pokušajte ponovo za %d s." "Netočno ste iscrtali obrazac za otključavanje %d puta. Nakon još ovoliko neuspješnih pokušaja: %d morat ćete otključati telefon pomoću računa e-pošte."\n\n" Pokušajte ponovo za %d s." + + "Pojačati iznad sigurne razine?"\n"Dulje slušanje preglasne glazbe može vam oštetiti sluh." "Nastavite držati s dva prsta kako biste omogućili pristupačnost." "Dostupnost je omogućena." diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 6a9e54df6d3e1..a97b93ec9925c 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -810,10 +810,26 @@ "Minta törölve" "Cella hozzáadva" "Minta befejezve" - "%1$s. Modul %3$d/%2$d" + "Modul hozzáadása." + "Üres" + "Feloldási terület kiterjesztve." + "Feloldási terület összecsukva." + "%1$s modul." "Felhasználóválasztó" "Állapot" + "Kamera" "Médiaelemek vezérlője" + "A modulátrendezés elkezdődött." + "A modulátrendezés véget ért." + "%1$s modul törölve." + "A feloldási terület kiterjesztése." + "Feloldás csúsztatással" + "Feloldás mintával" + "Arcalapú feloldás" + "Feloldás PIN kóddal" + "Feloldás jelszóval" + "Mintaterület" + "Csúsztatási terület" "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "A telefont %d alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a telefon gyári alapértelmezett beállításait." "%d alkalommal helytelenül rajzolta le a feloldási mintát. További %d sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét."\n\n" Kérjük, próbálja újra %d másodperc múlva." "%d alkalommal helytelenül rajzolta le a feloldási mintát. További %d sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját."\n\n" Kérjük, próbálja újra %d másodperc múlva." + + "A biztonságos szint fölé emeli a hangerőt?"\n"Ha hosszú ideig hangosan hallgatja a zenét, az károsíthatja a hallását." "Továbbra is tartsa lenyomva két ujját a hozzáférés engedélyezéséhez." "Hozzáférés engedélyezve" diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 8822ec19472aa..69ac54f1acaeb 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -810,10 +810,26 @@ "Pola dihapus" "Sel ditambahkan" "Pola selesai" - "%1$s. Widget %2$d dari %3$d." + "Tambahkan widget." + "Kosong" + "Area buka kunci diluaskan." + "Area buka kunci dihapus." + "Widget %1$s." "Pemilih pengguna" "Status" + "Kamera" "Kontrol media" + "Pengurutan ulang widget dimulai." + "Pengurutan ulang widget berakhir." + "Widget %1$s dihapus." + "Luaskan area buka kunci." + "Buka kunci geser." + "Buka kunci pola." + "Buka kunci wajah." + "Buka kunci pin." + "Buka kunci sandi." + "Area pola." + "Area geser." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Anda telah %d kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan disetel ulang ke setelan default pabrik." "Anda telah %d kali salah menggambar pola pembuka kunci. Setelah %d lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email."\n\n"Coba lagi dalam %d detik." "Anda telah %d kali salah menggambar pola pembuka kunci. Setelah %d lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email."\n\n"Coba lagi dalam %d detik." + + "Naikkan volume di atas tingkat aman?"\n"Mendengarkan volume tinggi dalam jangka waktu yang lama dapat merusak pendengaran Anda." "Tahan terus dua jari untuk mengaktifkan aksesibilitas." "Aksesibilitas diaktifkan." diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 214876fe1fff8..2e4dfe41d9b69 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -810,10 +810,26 @@ "Sequenza cancellata" "Cella aggiunta" "Sequenza completata" - "%1$s. Widget %2$d di %3$d." + "Aggiungi widget." + "Vuoto" + "Area di sblocco estesa." + "Area di sblocco compressa." + "%1$s widget." "Selettore utente" "Stato" + "Fotocamera" "Controlli media" + "Riordino dei widget iniziato." + "Riordino dei widget terminato." + "Widget %1$s eliminato." + "Espandi area di sblocco." + "Sblocco con scorrimento." + "Sblocco con sequenza." + "Sblocco col sorriso." + "Sblocco con PIN." + "Sblocco con password." + "Area sequenza." + "Area di scorrimento." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "%d tentativi errati di sblocco del telefono. Il telefono verrà sottoposto a un ripristino dei dati di fabbrica." "%d tentativi errati di inserimento della sequenza di sblocco. Dopo altri %d tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email."\n\n" Riprova tra %d secondi." "%d tentativi errati di inserimento della sequenza di sblocco. Dopo altri %d tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email."\n\n" Riprova tra %d secondi." + + "Aumentare il volume oltre il livello di sicurezza?"\n"Ascoltare musica ad alto volume per lunghi periodi potrebbe danneggiare l\'udito." "Continua a tenere premuto con due dita per attivare l\'accessibilità." "Accessibilità attivata." diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index a2e9f87ac4f7d..58e1d255e93c8 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -810,10 +810,26 @@ "התבנית נמחקה" "התא נוסף" "התבנית הושלמה" - "%1$s. Widget %2$d מתוך %3$d." + "הוסף Widget." + "ריק" + "אזור ביטול הנעילה הורחב." + "אזור ביטול הנעילה כווץ." + "Widget ‏%1$s." "בוחר משתמשים" "סטטוס" + "מצלמה" "פקדי מדיה" + "סידור מחדש של Widgets התחיל." + "סידור מחדש של Widgets הסתיים." + "Widget ‏%1$s נמחק." + "הרחב את אזור ביטול הנעילה." + "ביטול נעילה באמצעות הסטה." + "ביטול נעילה באמצעות ציור קו." + "זיהוי פרצוף." + "ביטול נעילה באמצעות מספר PIN." + "ביטול נעילה באמצעות סיסמה." + "אזור ציור קו." + "אזור הסטה." "?123" "אבג" "ALT" @@ -1420,6 +1436,8 @@ "ביצעת %d ניסיונות שגויים לביטול נעילת הטלפון. הטלפון יעבור כעת איפוס לברירת המחדל של היצרן." "שרטטת את קו ביטול הנעילה באופן שגוי %d פעמים. לאחר %d ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון דוא\"ל‏."\n\n"נסה שוב בעוד %d שניות." "שרטטת את קו ביטול הנעילה באופן שגוי %d פעמים. לאחר %d ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון דוא\"ל‏."\n\n"נסה שוב בעוד %d שניות." + + "האם להעלות את עוצמת הקול מעל לרמה הבטוחה?"\n"האזנה בעוצמת קול גבוהה למשך זמן ארוך עלולה לפגוע בשמיעה." "המשך לגעת בשתי אצבעות כדי להפעיל נגישות." "נגישות הופעלה." diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 34dc52a88f841..8abee85b8def9 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -810,10 +810,26 @@ "パターンを消去しました" "セルを追加しました" "パターンの描画が完了しました" - "%1$s。ウィジェット%2$d/%3$d。" + "ウィジェットを追加します。" + "なし" + "ロック解除エリアを拡大しました。" + "ロック解除エリアを縮小しました。" + "%1$sウィジェットです。" "ユーザー切り替え" "ステータス" + "カメラ" "メディアコントロール" + "ウィジェットの並べ替えを開始しました。" + "ウィジェットの並べ替えを終了しました。" + "%1$sウィジェットを削除しました。" + "ロック解除エリアを拡大します。" + "スライドロックを解除します。" + "パターンロックを解除します。" + "フェイスアンロックを行います。" + "PINロックを解除します。" + "パスワードロックを解除します。" + "パターンエリアです。" + "スライドエリアです。" "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "携帯端末のロック解除を%d回失敗しました。端末は出荷時設定にリセットされます。" "ロック解除パターンの入力を%d回間違えました。あと%d回間違えると、タブレットのロック解除にメールアカウントが必要になります。"\n\n"%d秒以内にもう一度お試しください。" "ロック解除パターンの入力を%d回間違えました。あと%d回間違えると、携帯端末のロック解除にメールアカウントが必要になります。"\n\n"%d秒以内にもう一度お試しください。" + + "安全レベルを超えるまで音量を上げますか?"\n"大音量で長時間聞き続けると、聴力を損なう恐れがあります。" "ユーザー補助機能を有効にするには2本の指で押し続けてください。" "ユーザー補助が有効になりました。" diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index c99dbf14619f6..d640481f749e4 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -585,8 +585,7 @@ "앱이 사용자 사전에 새 단어를 입력할 수 있도록 허용합니다." "보호된 저장소에 액세스 테스트" "보호된 저장소에 액세스 테스트" - - + "앱이 향후 기기에서 사용할 수 있는 USB 저장소의 권한을 테스트하도록 허용합니다." "앱이 미래의 기기에서 사용할 수 있는 SD 카드의 권한을 테스트하도록 허용합니다." "USB 저장소의 콘텐츠 수정 또는 삭제" "SD 카드의 콘텐츠 수정 또는 삭제" @@ -811,10 +810,26 @@ "패턴 삭제" "셀 추가됨" "패턴 완료" - "%1$s. %3$d의 위젯 %2$d." + "위젯 추가" + "비어 있음" + "잠금 해제 지역 확장됨" + "잠금 해제 지역 축소됨" + "%1$s 위젯" "사용자 선택기" "상태" + "카메라" "미디어 조정" + "위젯 재정렬 시작됨" + "위젯 재정렬 완료됨" + "위젯 %1$s이(가) 삭제됨" + "잠금 해제 지역 확장" + "슬라이드하여 잠금해제합니다." + "패턴을 사용하여 잠금해제합니다." + "얼굴 인식을 사용하여 잠금해제합니다." + "핀을 사용하여 잠금해제합니다." + "비밀번호를 사용하여 잠금해제합니다." + "패턴을 그리는 부분입니다." + "슬라이드하는 부분입니다." "?123" "ABC" "ALT" @@ -1421,6 +1436,8 @@ "휴대전화를 잠금해제하려는 시도가 %d회 잘못되었습니다. 휴대전화가 초기화됩니다." "잠금해제 패턴을 %d회 잘못 그렸습니다. %d회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금해제해야 합니다."\n\n" %d초 후에 다시 시도해 주세요." "잠금해제 패턴을 %d회 잘못 그렸습니다. %d회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금해제해야 합니다."\n\n" %d초 후에 다시 시도해 주세요." + + "안전한 수준 이상으로 볼륨을 높이시겠습니까?"\n"높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다." "두 손가락으로 길게 누르면 접근성을 사용하도록 설정됩니다." "접근성을 사용 설정했습니다." diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 0de01b243300e..1dc3f54cc2fa1 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -810,10 +810,26 @@ "Šablonas išvalytas" "Pridėtas langelis" "Šablonas užbaigtas" - "%1$s. %2$d valdiklis iš %3$d." + "Pridėti valdiklį." + "Tuščia" + "Atrakinimo sritis išplėsta." + "Atrakinimo sritis sutraukta." + "Valdiklis %1$s." "Naudotojo pasirinkimo valdiklis" "Būsena" + "Fotoaparatas" "Medijos valdikliai" + "Valdiklių pertvarkymas pradėtas." + "Valdiklių pertvarkymas baigtas." + "Valdiklis %1$s ištrintas." + "Išplėsti atrakinimo sritį." + "Atrakinimas slystant." + "Atrakinimas pagal piešinį." + "Atrakinimas pagal veidą." + "Atrakinimas įvedus PIN kodą." + "Atrakinimas įvedus slaptažodį." + "Atrakinimo pagal piešinį sritis." + "Slydimo sritis." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "%d k. bandėte netinkamai atrakinti telefoną. Telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai." "Netinkamai nupiešėte atrakinimo piešinį %d k. Po dar %d nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po %d sek." "Netinkamai nupiešėte atrakinimo piešinį %d k. Po dar %d nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po %d sek." + + "Padidinti garsumą viršijant saugų lygį?"\n"Ilgai klausantis dideliu garsumu gali sutrikti klausa." "Laikykite palietę dviem pirštais, kad įgalintumėte pritaikymo neįgaliesiems režimą." "Pritaikymas neįgaliesiems įgalintas." diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 0b1519edf14fe..d126477aa4971 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -585,7 +585,7 @@ "Ļauj lietotnei rakstīt jaunus vārdus lietotāja vārdnīcā." "aizsargātai krātuvei pieejamas piekļuves pārbaude" "aizsargātai krātuvei pieejamas piekļuves pārbaude" - "Ļauj lietotnei pārbaudīt atļauju USB krātuvei, kas būs pieejama turpmākajās ierīcēs." + "Ļauj lietotnei pārbaudīt USB krātuves atļauju; krātuve būs pieejama turpmākajās ierīcēs." "Ļauj lietotnei pārbaudīt atļauju SD kartei, kas būs pieejama turpmākajās ierīcēs." "mainīt vai dzēst USB atm. sat." "SD kartes satura pārveidošana vai dzēšana" @@ -810,10 +810,26 @@ "Kombinācija notīrīta" "Šūna pievienota" "Kombinācija pabeigta" - "%1$s. %2$d. logrīks no %3$d." + "Pievienot logrīku." + "Tukšs" + "Atbloķēšanas apgabal ir izvērsts." + "Atbloķēšanas apgabals ir sakļauts." + "Logrīks %1$s." "Lietotāju atlasītājs" "Statuss" + "Kamera" "Multivides vadīklas" + "Logrīku pārkārtošana ir sākusies." + "Logrīku pārkārtošana ir beigusies." + "Logrīks %1$s ir dzēsts." + "Izvērst atbloķēšanas apgabalu." + "Autorizācija, velkot ar pirkstu." + "Autorizācija ar kombināciju." + "Autorizācija pēc sejas" + "Autorizācija ar PIN kodu." + "Autorizācija ar paroli." + "Kombinācijas apgabals." + "Apgabals, kur vilkt ar pirkstu." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Jūs nepareizi veicāt tālruņa atbloķēšanu %d reizes. Tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi." "Jūs nepareizi norādījāt atbloķēšanas kombināciju %d reizes. Pēc vēl %d neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc %d sekundēm." "Jūs nepareizi norādījāt atbloķēšanas kombināciju %d reizes. Pēc vēl %d neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc %d sekundēm." + + "Vai palielināt skaļumu virs drošības līmeņa?"\n"Ilgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde." "Lai iespējotu pieejamību, turiet nospiestus divus pirkstus." "Pieejamības režīms ir iespējots." diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 704a0fdb0880f..6eb3afc3cc382 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -810,10 +810,26 @@ "Corak dipadamkan" "Sel ditambahkan" "Corak siap" - "%1$s. Widget %2$d dari %3$d." + "Tambah widget." + "Kosong" + "Bahagian buka kunci dikembangkan." + "Bahagian buka kunci diruntuhkan." + "Widget %1$s." "Pemilih pengguna" "Status" + "Kamera" "Kawalan media" + "Penyusunan semula widget dimulakan." + "Penyusunan semula widget tamat." + "Widget %1$s dipadamkan." + "Kembangkan bahagian buka kunci." + "Buka kunci luncur." + "Buka kunci corak." + "Wajah Buka Kunci" + "Buka kunci pin." + "Buka kunci kata laluan." + "Kawasan corak." + "Kawasan luncur." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak %d kali. Telefon kini akan ditetapkan semula ke tetapan lalai kilang." "Anda telah tersilap melukis corak buka kunci sebanyak %d kali. Selepas %d lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam %d saat." "Anda telah tersilap lukis corak buka kunci sebanyak %d kali. Selepas %d lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam %d saat." + + "Tingkatkan kelantangan di atas tahap selamat?"\n"Mendengar pada kelantangan tinggi untuk tempoh yang panjang boleh merosakkan pendengaran anda." "Teruskan menahan dengan dua jari untuk mendayakan kebolehcapaian." "Kebolehcapaian didayakan." diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index f54990e2091b7..ed8af78fef9a9 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -585,8 +585,7 @@ "Lar appen skrive nye ord i brukerordlisten." "testadgang til beskyttet lagring" "testadgang til beskyttet lagring" - - + "Lar appen teste en tillatelse for USB-lagring som kommer til å bli tilgjengelig på fremtidige enheter." "Lar appen teste en tillatelse for SD-kortet som kommer til å bli tilgjengelig på fremtidige enheter." "endre eller slette innholdet i USB-lagringen" "endre eller slette innhold i SD-kortet" @@ -811,10 +810,26 @@ "Mønsteret er slettet" "Celle er lagt til" "Mønsteret er fullført" - "%1$s. Modul %2$d av %3$d." + "Legg til modul." + "Tom" + "Opplåsingsfeltet vises." + "Opplåsingsfeltet skjules." + "%1$s-modul." "Brukervelgeren" "Status" + "Kamera" "Mediekontroll" + "Endring av modulplasseringen har startet." + "Endringen av modulplasseringen er ferdig." + "Modulen %1$s ble slettet." + "Vis opplåsingsfeltet." + "Opplåsning ved å dra med fingeren." + "Mønsteropplåsning." + "Ansiktsopplåsning." + "PIN-opplåsning." + "Passordopplåsning." + "Mønsterområde." + "Dra-felt." "?123" "ABC" "ALT" @@ -1421,6 +1436,8 @@ "Du har oppgitt feil opplåsningspassord for telefonen %d ganger. Telefonen tilbakestilles nå til fabrikkstandard." "Du har tegnet opplåsningsmønsteret feil %d ganger. Etter ytterligere %d gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto."\n\n" Prøv på nytt om %d sekunder." "Du har tegnet opplåsningsmønsteret feil %d ganger. Etter ytterligere %d gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto."\n\n" Prøv på nytt om %d sekunder." + + "Vil du øke lydnivået over trygt nivå?"\n"Lytting på høyt lydnivå i lange perioder kan skade hørselen din." "Fortsett å holde nede to fingre for å aktivere tilgjengelighet." "Tilgjengelighet er aktivert." diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index bb48630bb56ef..0680114308367 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -810,10 +810,26 @@ "Patroon gewist" "Cel toegevoegd" "Patroon voltooid" - "%1$s. Widget %2$d van %3$d." + "Widget toevoegen." + "Leeg" + "Ontgrendelingsgebied uitgevouwen." + "Ontgrendelingsgebied samengevouwen." + "Widget %1$s." "Gebruikersselectie" "Status" + "Camera" "Mediabediening" + "Opnieuw indelen van widget gestart." + "Opnieuw indelen van widget beëindigd." + "Widget %1$s verwijderd." + "Ontgrendelingsgebied uitvouwen." + "Ontgrendeling via schuiven." + "Ontgrendeling via patroon." + "Ontgrendeling via gezichtsherkenning." + "Ontgrendeling via pincode." + "Ontgrendeling via wachtwoord." + "Tekengebied voor patroon." + "Schuifgebied." "?123" "ABC" "Alt" @@ -1420,6 +1436,8 @@ "U heeft %d keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon." "U heeft uw ontgrendelingspatroon %d keer onjuist getekend. Na nog eens %d mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount."\n\n" Probeer het over %d seconden opnieuw." "U heeft uw ontgrendelingspatroon %d keer onjuist getekend. Na nog eens %d mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount."\n\n" Probeer het over %d seconden opnieuw." + + "Wilt u het volume verhogen tot boven het aanbevolen geluidsniveau?"\n"Te lang luisteren op een te hoog volume kan leiden tot gehoorbeschadiging." "Blijf het scherm met twee vingers aanraken om toegankelijkheid in te schakelen." "Toegankelijkheid ingeschakeld." diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index da09bcb154ad6..d4c5a6a0310bd 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -810,10 +810,43 @@ "Wzór wyczyszczony" "Dodano komórkę." "Wzór ukończony" - "%1$s. Widżet %2$d z %3$d." + + + + + + + + + + "Wybór użytkownika" "Stan" + + "Elementy sterujące multimediów" + + + + + + + + + + + + + + + + + + + + + + "?123" "ABC" "ALT" @@ -1420,6 +1453,8 @@ "Po raz %d próbowałeś nieprawidłowo odblokować telefon. Telefon zostanie teraz zresetowany do ustawień fabrycznych." "Po raz %d nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych %d nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za %d s." "Po raz %d nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych %d nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za %d s." + + "Chcesz ustawić głośność powyżej bezpiecznego poziomu?"\n"Słuchanie przy dużym poziomie głośności przez dłuższy czas może doprowadzić do uszkodzenia słuchu." "Aby włączyć ułatwienia dostępu, przytrzymaj dwa palce." "Włączono ułatwienia dostępu." diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 7ce4a34979dbc..e4a2778ce4b2b 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -810,10 +810,26 @@ "Sequência apagada" "Célula adicionada" "Sequência concluída" - "%1$s. Widget %2$d de %3$d." + "Adicionar widget." + "Vazio" + "Área de desbloqueio expandida." + "Área de desbloqueio comprimida." + "%1$s widget." "Seletor de utilizadores" "Estado" + "Câmara" "Controlos de multimédia" + "Reordenação de widget iniciada." + "Reordenação de widget concluída." + "Widget %1$s eliminado." + "Expandir área de desbloqueio." + "Desbloqueio através de deslize." + "Desbloqueio através de sequência." + "Desbloqueio através do rosto." + "Desbloqueio através de PIN." + "Desbloqueio através de palavra-passe." + "Área da sequência." + "Área de deslize." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Tentou desbloquear o telemóvel %d vezes de forma incorreta, pelo que será reposta a predefinição de fábrica." "Desenhou a sequência de desbloqueio incorretamente %d vezes. Depois de mais %d tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email."\n\n" Tente novamente dentro de %d segundos." "Desenhou a sequência de desbloqueio incorretamente %d vezes. Depois de mais %d tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email."\n\n" Tente novamente dentro de %d segundos." + + "Aumentar o volume acima do nível de segurança?"\n"Ouvir em volume alto durante longos períodos de tempo poderá prejudicar a sua audição." "Mantenha os dois dedos para ativar a acessibilidade." "Acessibilidade ativada." diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 07806305eefc2..0bb96eebe4fc3 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -810,10 +810,26 @@ "Padrão apagado" "Célula adicionada" "Padrão concluído" - "%1$s. Widget %2$d de %3$d." + "Adicionar widget" + "Vazio" + "Área de desbloqueio expandida." + "Área de desbloqueio recolhida." + "Widget de %1$s." "Seletor de usuários" "Status" + "Câmera" "Controles de mídia" + "Reordenação de widgets iniciada." + "Reordenação de widgets concluída." + "Widget %1$s excluído." + "Expandir a área de desbloqueio." + "Desbloqueio com deslize." + "Desbloqueio com padrão." + "Desbloqueio facial." + "Desbloqueio com PIN." + "Desbloqueio com senha." + "Área do padrão." + "Área de deslize." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Você tentou desbloquear incorretamente o telefone %d vezes. O telefone será redefinido para o padrão de fábrica." "Você desenhou sua sequência de desbloqueio incorretamente %d vezes. Se fizer mais %d tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet."\n\n" Tente novamente em %d segundos." "Você desenhou sua sequência de desbloqueio incorretamente %d vezes. Se fizer mais %d tentativas incorretas, será solicitado que você use o login do Google para desbloquear."\n\n" Tente novamente em %d segundos." + + "Aumentar o volume acima do nível seguro?"\n"A audição em volume elevado por períodos longos pode prejudicar sua audição." "Mantenha pressionado com dois dedos para ativar a acessibilidade." "Acessibilidade ativada." diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml index 5ea84c76db313..71dadfdae685a 100644 --- a/core/res/res/values-rm/strings.xml +++ b/core/res/res/values-rm/strings.xml @@ -1297,14 +1297,46 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "?123" "ABC" "ALT" @@ -2294,6 +2326,8 @@ + + diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 438522d7bd579..f3d91932040bb 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -585,8 +585,7 @@ "Permite aplicaţiei să scrie cuvinte noi în dicţionarul utilizatorului." "testează accesul la stocarea protejată" "testează accesul la stocarea protejată" - - + "Permite aplicaţiei testarea permisiunii pt. stocarea USB, disponibilă pe gadgeturi viitoare." "Permite aplicaţiei să testeze o permisiune pentru cardul SD care va fi disponibil pe dispozitivele viitoare." "modifică sau şterge conţinutul stocării USB" "modifică sau şterge conţinutul cardului SD" @@ -811,10 +810,26 @@ "Modelul a fost şters" "Celulă adăugată" "Modelul a fost desenat" - "%1$s. Widget %2$d din %3$d." + "Adăugaţi un widget." + "Gol" + "Zona de deblocare a fost extinsă." + "Zona de deblocare a fost restrânsă." + "Widget %1$s." "Selector utilizator" "Stare" + "Cameră foto" "Comenzi media" + "A început reordonarea widgeturilor." + "Reordonarea widgeturilor s-a încheiat." + "Widgetul %1$s a fost eliminat." + "Extindeţi zona de deblocare." + "Deblocare prin glisare." + "Deblocare cu model." + "Deblocare facială." + "Deblocare cu PIN." + "Deblocare cu parolă." + "Zonă model." + "Zonă glisare." "?123" "ABC" "ALT" @@ -1421,6 +1436,8 @@ "Aţi efectuat %d încercări incorecte de deblocare a telefonului. Telefonul va fi acum resetat la setările prestabilite din fabrică." "Aţi desenat incorect modelul pentru deblocare de %d ori. După încă %d încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste %d (de) secunde." "Aţi desenat incorect modelul pentru deblocare de %d ori. După încă %d încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste %d (de) secunde." + + "Ridicaţi volumul mai sus de nivelul sigur?"\n"Ascultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul." "Menţineţi două degete pe ecran pentru a activa accesibilitatea." "S-a activat accesibilitatea." diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 85136590ad0c9..c6770b2f7c587 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -585,8 +585,7 @@ "Приложение сможет добавлять слова в пользовательский словарь." "Проверка доступа к защищенному хранилищу" "Проверка доступа к защищенному хранилищу" - - + "Приложение сможет проверять разрешение для USB-накопителя, которое в дальнейшем будет предоставляться на других устройствах." "Приложение сможет проверять разрешение для SD-карты, которое в дальнейшем будет предоставляться на других устройствах." "Изменение/удаление данных на USB-накопителе" "Изменение или удаление содержимого SD-карты" @@ -811,10 +810,26 @@ "Графический ключ сброшен" "Ячейка добавлена" "Графический ключ введен" - "%1$s. Виджет %2$d из %3$d." + "Добавить виджет" + "Пусто" + "Область разблокировки развернута" + "Область разблокировки свернута" + "Виджет \"%1$s\"" "Выбор аккаунта" "Статус" + "Камера" "Управление блокировкой" + "Начато переопределение порядка виджетов" + "Порядок виджетов определен" + "Виджет %1$s удален" + "Развернуть области разблокировки" + "Прокрутка" + "Графический ключ" + "Фейсконтроль" + "PIN-код" + "Пароль" + "Область ввода графического ключа" + "Область прокрутки" "?123" "АБВ" "ALT" @@ -1421,6 +1436,8 @@ "Вы %d раз не смогли разблокировать телефон. Будут восстановлены заводские настройки." "Вы %d раз неверно указали графический ключ. После %d неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google."\n\n"Повтор через %d сек." "Вы %d раз неверно указали графический ключ. После %d неверных попыток для разблокировки телефона потребуется войти в аккаунт Google."\n\n"Повтор через %d сек." + + "Увеличить громкость до небезопасного уровня?"\n"Долговременное прослушивание на такой громкости может повредить слух." "Чтобы включить специальные возможности, удерживайте пальцы на экране." "Специальные возможности включены." diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index fc40852112287..da02bb6ea2996 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -585,8 +585,7 @@ "Umožňuje aplikácii zapisovať nové slová do používateľského slovníka." "testovanie prístupu do chráneného ukladacieho priestoru" "testovanie prístupu do chráneného ukladacieho priestoru" - - + "Umožňuje aplikácii testovať povolenie pre úložisko USB, ktoré bude k dispozícii na zariadeniach." "Umožňuje aplikácii testovať povolenie pre kartu SD, ktorá bude k dispozícii v budúcich zariadeniach." "upraviť alebo odstrániť obsah úložiska USB" "úprava alebo odstránenie obsahu na karte SD" @@ -811,10 +810,26 @@ "Bezpečnostný vzor bol vymazaný" "Bunka bola pridaná" "Bezpečnostný vzor bol dokončený" - "%1$s. Miniaplikácia %2$d z %3$d." + "Pridať miniaplikáciu." + "Prázdne" + "Oblasť na odomknutie bola rozšírená." + "Oblasť na odomknutie bola zúžená." + "Miniaplikácia %1$s." "Výber používateľa" "Stav" + "Fotoaparát" "Ovládacie prvky médií" + "Zmena usporiadania miniaplikácií sa začala." + "Zmena usporiadania miniaplikácií sa skončila." + "Miniaplikácia %1$s bola odstránená." + "Rozšíriť oblasť na odomknutie." + "Odomknutie prejdením prstom." + "Odomknutie vzorom." + "Odomknutie tvárou." + "Odomknutie kódom PIN." + "Odomknutie heslom." + "Oblasť na zadanie bezpečnostného vzoru." + "Oblasť na prejdenie prstom." "?123" "ABC" "ALT" @@ -1421,6 +1436,8 @@ "Telefón ste sa pokúsili odomknúť nesprávnym spôsobom %d-krát. V telefóne sa teraz obnovia predvolené továrenské nastavenia." "%d-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších %d neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu."\n\n" Skúste to znova o %d s." "%d-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po %d ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu."\n\n" Skúste to znova o %d s." + + "Chcete zvýšiť hlasitosť nad bezpečnú úroveň?"\n"Dlhodobé počúvanie pri vysokej hlasitosti môže viesť k poškodeniu vášho sluchu." "Zjednodušenie ovládania povolíte dlhým stlačením dvoma prstami." "Zjednodušenie ovládania je povolené." diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 3dda747f0530d..a7fc8b3fe1473 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -810,10 +810,26 @@ "Vzorec je izbrisan" "Celica je dodana" "Vzorec je končan" - "%1$s. Pripomoček %2$d za %3$d." + "Dodajanje pripomočka." + "Prazno" + "Območje odklepanja razširjeno." + "Območje odklepanja strnjeno." + "Pripomoček %1$s." "Izbirnik uporabnika" "Stanje" + "Fotoaparat" "Kontrolniki predstavnosti" + "Prerazporejanje pripomočkov začeto." + "Prerazporejanje pripomočkov končano." + "Pripomoček %1$s izbrisan." + "Razširitev območja odklepanja." + "Odklepanje s podrsanjem." + "Odklepanje z vzorcem." + "Odklepanje z obrazom." + "Odklepanje s kodo PIN." + "Odklepanje z geslom." + "Območje vzorca." + "Območje podrsanja." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Telefon ste poskusili %d-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve." "Vzorec za odklepanje ste %d-krat napačno vnesli. Po nadaljnjih %d neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom."\n\n"Poskusite znova čez %d s." "Vzorec za odklepanje ste %d-krat napačno vnesli. Po nadaljnjih %d neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo."\n\n"Poskusite znova čez %d s." + + "Želite povečati glasnost nad varno raven?"\n"Dolgotrajna izpostavljenost glasnim tonom lahko poškoduje sluh." "Če želite omogočiti pripomočke za ljudi s posebnimi potrebami, na zaslonu pridržite z dvema prstoma." "Pripomočki za ljudi s posebnimi potrebami so omogočeni." diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 92d8acb2c7087..c31ee7a491e80 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -810,10 +810,26 @@ "Образац је обрисан" "Ћелија је додата" "Образац је довршен" - "%1$s. Виџет %2$d од %3$d." + "Додај виџет." + "Празно" + "Област откључавања је проширена." + "Област откључавања је скупљена." + "Виџет %1$s." "Избор корисника" "Статус" + "Камера" "Контроле за медије" + "Започела је промена редоследа виџета." + "Промена редоследа виџета је завршена." + "Виџет %1$s је избрисан." + "Прошири област откључавања." + "Откључавање превлачењем." + "Откључавање шаблоном." + "Откључавање лицем." + "Откључавање PIN-ом." + "Откључавање лозинком." + "Област шаблона." + "Област превлачења." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Покушали сте да откључате телефон неисправно %d пута. Телефон ће сада бити враћен на подразумевана фабричка подешавања." "Нацртали сте шаблон за откључавање неисправно %d пута. После још %d неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште."\n\n"Покушајте поново за %d секунде(и)." "Нацртали сте шаблон за откључавање неисправно %d пута. После још %d неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште."\n\n"Покушајте поново за %d секунде(и)." + + "Желите да појачате звук изнад безбедног нивоа?"\n"Ако дуже време слушате гласну музику, може доћи до оштећења слуха." "Држите са два прста да бисте омогућили приступачност." "Приступачност је омогућена." diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 97760297bfb9f..bfed28314f6a1 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -810,10 +810,26 @@ "Grafiskt lösenord har tagits bort" "En cell har lagts till" "Grafiskt lösenord har slutförts" - "%1$s. Widget %2$d av %3$d." + "Lägg till en widget." + "Tom" + "Expanderad upplåsningsyta." + "Komprimerad upplåsningsyta." + "Widget för %1$s." "Användarväljare" "Status" + "Kamera" "Mediereglage" + "Ändring av widgetarnas ordning har påbörjats." + "Ändring av widgetarnas ordning har avslutats." + "Widgeten %1$s har tagits bort." + "Expandera upplåsningsytan." + "Lås upp genom att dra." + "Lås upp med grafiskt lösenord." + "Lås upp med Ansiktslås." + "Lås upp med PIN-kod." + "Lås upp med lösenord." + "Fält för grafiskt lösenord." + "Fält med dragreglage." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Du har försökt låsa upp mobilen på fel sätt %d gånger. Mobilen återställs nu till fabriksinställningarna." "Du har ritat ditt grafiska lösenord fel %d gånger. Efter ytterligare %d försök ombeds du låsa upp surfplattan med ett e-postkonto."\n\n" Försök igen om %d sekunder." "Du har ritat ditt grafiska lösenord fel %d gånger. Efter ytterligare %d försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto."\n\n" Försök igen om %d sekunder." + + "Vill du höja volymen över den säkra nivån?"\n"Om du lyssnar på hög volym under långa perioder kan din hörsel skadas." "Fortsätt trycka med två fingrar om du vill aktivera tillgänglighetsläget." "Tillgänglighetsläget har aktiverats." diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index cd397fc8a9839..2bd4972e89a01 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -810,10 +810,26 @@ "Ruwaza imefutwa" "Kiini kimeongezwa" "Ruwaza imekamilika" - "%1$s. Wiji %2$d ya %3$d." + "Ongeza wijeti." + "Tupu" + "Eneo la kufungua limepanuliwa." + "Eneo la kufungua limekunjwa." + "%1$s ya wijeti." "Kiteuzi cha mtumiaji" "Hali" + "Kamera" "Vidhibiti vya media" + "Upangaji upya wa wijeti umeanza." + "Upangaji upya wa wijeti umekamilika." + "Wijeti %1$s imefutwa." + "Panua eneo la kufungua." + "Kufungua slaidi." + "Kufungua kwa ruwaza." + "Kufungua kwa uso." + "Kufungua kwa PIN." + "Kufungua kwa nenosiri." + "Eneo la ruwaza." + "Eneo la slaidi." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Umejaribu kufungua simu kwa njia isiyo sahihi mara %d. Sasa simu itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani." "Umekosea katika kuweka mchoro wako wa kufungua mara %d. Baada ya majaribio %d bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe."\n\n" Jaribu tena baada ya sekunde %d." "Umekosea kuchora mchoro wako wa kufungua mara %d. Baada ya majaribio %d yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe."\n\n" Jaribu tena baada ya sekunde %d." + + "Ongeza sauti zaidi ya kiwango salama? "\n"Kusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia." "Endelea kushikilia chini kwa vidole vyako viwili ili kuwezesha ufikivu." "Ufikivu umewezeshwa." diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 5609a77f690c5..59e7c032709f1 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -810,10 +810,26 @@ "ล้างรูปแบบแล้ว" "เพิ่มเซลแล้ว" "วาดรูปแบบเสร็จสิ้น" - "%1$s วิดเจ็ต %2$d ของ %3$d" + "เพิ่มวิดเจ็ต" + "ว่าง" + "ขยายพื้นที่ปลดล็อกแล้ว" + "ยุบพื้นที่ปลดล็อกแล้ว" + "วิดเจ็ต %1$s" "ตัวเลือกผู้ใช้" "สถานะ" + "กล้องถ่ายรูป" "การควบคุมสื่อ" + "เริ่มเรียงลำดับวิดเจ็ตใหม่" + "เรียงลำดับวิดเจ็ตใหม่เสร็จแล้ว" + "ลบวิดเจ็ต %1$s แล้ว" + "ขยายพื้นที่ปลดล็อก" + "การปลดล็อกด้วยการเลื่อน" + "การปลดล็อกด้วยรูปแบบ" + "การปลดล็อกด้วยใบหน้า" + "การปลดล็อกด้วย PIN" + "การปลดล็อกด้วยรหัสผ่าน" + "พื้นที่สำหรับรูปแบบ" + "พื้นที่สำหรับการเลื่อน" "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "คุณพยายามปลดล็อกโทรศัพท์อย่างไม่ถูกต้อง %d ครั้งแล้ว ขณะนี้โทรศัพท์จะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงาน" "คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง %d ครั้งแล้ว หากทำไม่สำเร็จอีก %d ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล"\n\n" โปรดลองอีกครั้งใน %d วินาที" "คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง %d ครั้งแล้ว หากทำไม่สำเร็จอีก %d ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้ับัญชีอีเมล"\n\n" โปรดลองอีกครั้งในอีก %d วินาที" + + "เพิ่มระดับเสียงจนเกินระดับที่ปลอดภัยหรือไม่"\n"การฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้" "ใช้สองนิ้วแตะค้างไว้เพื่อเปิดใช้งานการเข้าถึง" "เปิดใช้งานการเข้าถึงแล้ว" diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index cf6314fbf6c9b..acb6834a647e1 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -810,10 +810,26 @@ "Na-clear ang pattern" "Idinagdag ang cell" "Nakumpleto ang pattern" - "%1$s. Widget %2$d ng %3$d." + "Magdagdag ng widget." + "Walang laman" + "Pinalaki ang bahagi ng pag-unlock." + "Pinaliit ang bahagi ng pag-unlock." + "%1$s widget." "Tagapili ng user" "Katayuan" + "Camera" "Mga kontrol ng media" + "Nagsimula na ang pagbabago ng ayos ng widget." + "Natapos na ang pagbabago ng ayos ng widget." + "Tinanggal ang widget na %1$s." + "Palakihin ang bahagi ng pag-unlock." + "Pag-unlock ng slide." + "Pag-unlock ng pattern." + "Face unlock." + "Pag-unlock ng pin." + "Pag-unlock ng password." + "Bahagi ng pattern." + "Bahagi ng slide." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang %d (na) beses. Ire-reset na ngayon ang telepono sa factory default." "Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang %d (na) beses. Pagkatapos ng %d pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account."\n\n" Subukang muli sa loob ng %d (na) segundo." "Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang %d (na) beses. Pagkatapos ng %d pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account."\n\n" Subukang muli sa loob ng %d (na) segundo." + + "Lakasan ang volume nang lagpas sa ligtas na antas?"\n"Maaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig." "Panatilihing nakapindot nang matagal ang iyong dalawang daliri upang paganahin ang pagiging naa-access." "Pinagana ang accessibility." diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index f037250247fbe..c0f2537d8bfd5 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -585,8 +585,7 @@ "Uygulamaya, kullanıcı sözlüğüne yeni kelimeler yazma izni verir." "korumalı depolama birimine erişimi test et" "korumalı depolama birimine erişimi test et" - - + "Uygulamaya, gelecekteki cihazlarda kullanılabilecek USB depolama birimi için bir izni test etme olanağı verir." "Uygulamaya gelecekteki cihazlarda kullanılabilecek SD karta ilişkin bir izni test etme olanağı verir." "USB belleğimin içeriğini değiştir veya sil" "SD kartın içeriğini değiştir veya sil" @@ -811,10 +810,26 @@ "Desen temizlendi" "Hücre eklendi" "Desen tamamlandı" - "%1$s. Widget %2$d / %3$d." + "Widget ekleyin." + "Boş" + "Kilit açma alanı genişletildi." + "Kilit açma alanı daraltıldı." + "%1$s widget\'ı." "Kullanıcı seçici" "Durum" + "Kamera" "Medya denetimleri" + "Widget\'ları yeniden sıralama işlemi başladı." + "Widget\'ları yeniden sıralama işlemi bitti." + "%1$s widget\'ı silindi." + "Kilit açma alanını genişletin." + "Kaydırarak kilit açma." + "Desenle kilit açma." + "Yüzle kilit açma." + "Pin koduyla kilit açma." + "Şifreyle kilit açma." + "Desen alanı." + "Kaydırma alanı." "?123" "ABC" "ALT" @@ -1421,6 +1436,8 @@ "Telefon kilidini %d defa yanlış bir şekilde açmaya çalıştınız. Telefon şimdi fabrika varsayılanına sıfırlanacak." "Kilit açma deseninizi %d kez yanlış çizdiniz. %d başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir."\n\n" %d saniye içinde tekrar deneyin." "Kilit açma deseninizi %d kez yanlış çizdiniz. %d başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir."\n\n" %d saniye içinde tekrar deneyin." + + "Ses düzeyi güvenli seviyenin üzerine çıkarılsın mı?"\n"Yüksek sesle uzun süre dinlemek işitme yetinize zarar verebilir." "Erişilebilirliği etkinleştirmek için iki parmağınızı basılı tutmaya devam edin." "Erişilebilirlik etkinleştirildi." diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 8ce89f28b8ee9..1ca6edf7ac42f 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -810,10 +810,26 @@ "Ключ очищено" "Телефон додано" "Малювання ключа закінчено" - "%1$s. Віджет %2$d з %3$d." + "Додати віджет." + "Порожня область" + "Область розблокування розгорнуто." + "Область розблокування згорнуто." + "Віджет %1$s." "Вибір користувача" "Статус" + "Камера" "Елементи керування носієм" + "Змінення порядку віджетів розпочато." + "Змінення порядку віджетів закінчено." + "Віджет %1$s видалено." + "Розгорнути область розблокування." + "Розблокування жестом." + "Розблокування ключем." + "Фейсконтроль" + "Розблокування PIN-кодом." + "Розблокування паролем." + "Область ключа." + "Область жесту." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Кількість невдалих спроб розблокувати телефон: %d. Налаштування телефону буде змінено на заводські за умовчанням." "Ключ розблокування неправильно намальовано стільки разів: %d. У вас є ще стільки спроб: %d. У разі невдачі з’явиться запит розблокувати планшетний ПК за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через %d сек." "Ключ розблокування неправильно намальовано стільки разів: %d. У вас є ще стільки спроб: %d. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через %d сек." + + "Збільшити гучність понад безпечний рівень?"\n"Надто гучне прослуховування впродовж тривалого періоду може пошкодити слух." "Утримуйте двома пальцями, щоб увімкнути доступність." "Доступність увімкнено." diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 160dda7b916ab..fb291a2e26575 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -810,10 +810,26 @@ "Đã xóa hình" "Đã thêm ô" "Đã vẽ xong hình" - "%1$s. Tiện ích %2$d trong số %3$d." + "Thêm tiện ích." + "Trống" + "Đã mở rộng vùng khóa." + "Đã thu gọn vùng khóa." + "%1$s tiện ích." "Bộ chọn người dùng" "Trạng thái" + "Máy ảnh" "Điều khiển phương tiện" + "Đã bắt đầu xắp xếp lại tiện ích." + "Đã kết thúc sắp xếp lại tiện ích." + "Đã xóa tiện ích %1$s." + "Mở rộng vùng khóa." + "Mở khóa bằng cách trượt." + "Mở khóa bằng hình." + "Mở khóa bằng khuôn mặt." + "Mở khóa bằng mã pin." + "Mở khóa bằng mật khẩu." + "Khu vực hình." + "Khu vực trượt." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Bạn đã %d lần mở khóa điện thoại không đúng cách. Bây giờ, điện thoại sẽ được đặt lại về mặc định ban đầu." "Bạn đã %d lần vẽ không chính xác hình mở khóa của mình. Sau %d lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email."\n\n" Vui lòng thử lại sau %d giây." "Bạn đã %d lần vẽ không chính xác hình mở khóa của mình. Sau %d lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email."\n\n" Vui lòng thử lại sau %d giây." + + "Tăng âm lượng trên mức an toàn?"\n"Nghe ở âm lượng cao trong thời gian dài có thể gây hại cho thính giác của bạn." "Tiếp tục giữ hai ngón tay để bật trợ năng." "Trợ năng đã được bật." diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 028b4767d3316..dfb9d99ea5c51 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -344,8 +344,8 @@ "允许用户绑定到 VPN 服务的顶级接口。普通应用绝不需要此权限。" "绑定到壁纸" "允许用户绑定到壁纸的顶级接口。普通应用绝不需要此权限。" - "绑定到窗口小部件服务" - "允许用户绑定到窗口小部件服务的顶级接口。普通应用绝不需要此权限。" + "绑定到小部件服务" + "允许应用绑定到小部件服务的顶级接口。普通应用绝不需要此权限。" "与设备管理器交互" "允许用户将意向发送给设备管理员。普通应用绝不需要此权限。" "更改屏幕显示方向" @@ -495,8 +495,8 @@ "允许应用启用/停用来自无线装置的位置更新通知。普通应用不能使用此权限。" "访问检入属性" "允许应用对登记服务上传的属性拥有读取/写入权限。普通应用不能使用此权限。" - "选择窗口小部件" - "允许应用告知系统哪些窗口小部件可供哪个应用使用。拥有此权限的应用可向其他应用授予对个人资料的访问权限。普通应用不能使用此权限。" + "选择小部件" + "允许应用告知系统哪些小部件可供哪个应用使用。拥有此权限的应用可向其他应用授予对个人资料的访问权限。普通应用不应使用此权限。" "修改手机状态" "允许应用控制设备的电话功能。拥有此权限的应用可在不通知您的情况下执行切换网络、开关手机无线装置等此类操作。" "读取手机状态和身份" @@ -585,8 +585,7 @@ "允许应用向用户词典中写入新词。" "测试对受保护存储空间的访问权限" "测试对受保护存储空间的访问权限" - - + "允许应用测试以后的设备将支持的 USB 存储设备权限。" "允许该应用测试将对以后的设备开放的 SD 卡权限。" "修改或删除您的 USB 存储设备中的内容" "修改或删除您的 SD 卡中的内容" @@ -811,10 +810,26 @@ "图案已清除" "已添加单元格" "图案绘制完成" - "%1$s。%3$d的小部件%2$d。" + "添加小部件。" + "空" + "已展开解锁区域。" + "已折叠解锁区域。" + "%1$s小部件。" "用户选择器" "状态" + "相机" "媒体控制" + "已开始将小部件重新排序。" + "已完成小部件重新排序。" + "已删除小部件%1$s。" + "展开解锁区域。" + "滑动解锁。" + "图案解锁。" + "人脸解锁。" + "PIN 解锁。" + "密码解锁。" + "图案区域。" + "滑动区域。" "?123" "ABC" "ALT" @@ -1198,7 +1213,7 @@ "更改媒体输出线路" "允许该应用将媒体输出线路更改到其他外部设备。" "触摸两次可进行缩放控制" - "无法添加窗口小部件。" + "无法添加小部件。" "开始" "搜索" "发送" @@ -1224,9 +1239,9 @@ "“%s”已激活 VPN" "触摸可管理网络。" "已连接到“%s”。触摸可管理网络。" - "正在连接到始终处于打开状态的 VPN…" - "已连接到始终处于打开状态的 VPN" - "始终处于打开状态的 VPN 出现错误" + "正在连接到始终开启的 VPN…" + "已连接到始终开启的 VPN" + "始终开启的 VPN 出现错误" "触摸即可重置连接" "选择文件" "未选定任何文件" @@ -1421,6 +1436,8 @@ "您已经 %d 次错误地尝试解锁手机。手机现在将重置为出厂默认设置。" "您已经 %d 次错误地绘制了解锁图案。如果再尝试 %d 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。"\n\n"请在 %d 秒后重试。" "您已经 %d 次错误地绘制了解锁图案。如果再尝试 %d 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。"\n\n"请在 %d 秒后重试。" + + "将音量调高到安全级别以上?"\n"长时间聆听高音量可能会损伤听力。" "持续按住双指即可启用辅助功能。" "辅助功能已启用。" diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 10af434423c32..d39df85cb46e6 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -585,7 +585,7 @@ "允許應用程式將新字詞寫入使用者的字典。" "測試能否存取受保護的儲存裝置" "測試能否存取受保護的儲存裝置" - "允許應用程式測試未來裝置將支援的 USB 儲存裝置權限。" + "允許應用程式測試未來裝置將支援的 USB 儲存權限。" "允許應用程式測試未來裝置將支援的 SD 卡權限。" "修改或刪除 USB 儲存裝置的內容" "修改或刪除 SD 卡的內容" @@ -810,10 +810,26 @@ "已清除解鎖圖形" "已加入 1 格" "已畫出解鎖圖形" - "%1$s。第 %2$d 個小工具,共 %3$d 個。" + "新增小工具。" + "空白" + "解鎖區域已展開。" + "解鎖區域已收合。" + "%1$s小工具。" "使用者選取工具" "狀態" + "相機" "媒體控制項" + "已開始將小工具重新排序。" + "小工具已重新排序完成。" + "%1$s小工具已刪除。" + "展開解鎖區域。" + "滑動解鎖。" + "圖形解鎖。" + "人臉解鎖。" + "PIN 解鎖。" + "密碼解鎖。" + "圖形區域。" + "滑動區域。" "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "您嘗試解除這支手機的鎖定已失敗 %d 次,手機現在將恢復原廠設定。" "您的解鎖圖形已畫錯 %d 次,如果再嘗試 %d 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。"\n\n"請在 %d 秒後再試一次。" "您的解鎖圖形已畫錯 %d 次,如果再嘗試 %d 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。"\n\n"請在 %d 秒後再試一次。" + + "要將音量調高到安全等級以上嗎?"\n"長時間聆聽偏高音量可能會損害您的聽力。" "持續用兩指按住即可啟用協助工具。" "協助工具已啟用。" diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 02f97053b4c2f..fc5007d0af30c 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -585,7 +585,7 @@ "Ivumela insiza ukuthi ibhale amagama amasha esichazinimazwi." "ukufinyelela kokuhlola esilondolozini esivikelekile" "ukufinyelela kokuhlola esilondolozini esivikelekile" - "Ivumela uhlelo lokusebenza ukuhlola imvume yokugciniwe okufinyeleleka nge-USB okuzotholakala kumadivayisi alandelayo." + "Ivumela uhlelo lokusebenza ukuhlola imvume yesitoreji se-USB okuzotholakala kumadivayisi alandelayo." "Ivumela uhlelo lokusebenza ukuhlola imvume yekhadi le-SD okuzotholakala kumadivayisi alandelayo." "guqula noma ususe okuqukethwe kwakho okugciniwe okufinyeleleka nge-USB" "shintsha noma ususe okuqukethwe ekhadini lakho le-SD" @@ -810,10 +810,26 @@ "Iphethini isusiwe" "Kwengezwe" "Iphethini isiphelile" - "%1$s. iwijethi %2$d ye-%3$d." + "Engeza iwijethi." + "Akunalutho" + "Indawo yokuvula inwetshisiwe." + "Indawo yokuvula inciphisiwe." + "%1$s iwijethi." "Isikhethi somsebenzisi" "Isimo" + "Ikhamera" "Izilawuli zemidiya" + "Ukuhlelwa kabusha kwewijethi kuqalile" + "Ukuhlelwa kabusha kwewijethi kuphelile." + "Iwijethi %1$s isusiwe." + "Nwebisa indawo yokuvula." + "Ukuvula ngokushelelisa." + "Ukuvula ngephethini." + "Ukuvula ngobuso." + "Ukuvula ngephinikhodi." + "Ukuvula ngephasiwedi." + "Indawo yephethini." + "Indawo yokushelelisa." "?123" "ABC" "ALT" @@ -1420,6 +1436,8 @@ "Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-%d. Ifoni manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo." "Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-%d. Emva %d kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi kwengu-%d imizuzwana." "Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-%d Emva kweminye imizamo engu-%d, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- %d imizuzwana." + + "Khulisa ivolomu ngaphezu kweleveli yokuphepha?"\n"Ukulalela ngevolomu ephezulu izikhathi ezide kungalimaza ukuzwa kwakho." "Gcina ucindezele iminwe yakho emibili ukuze unike amandla ukufinyelela." "Ukufinyelela kunikwe amandla." From 196cde973fd1635f0ac3150caab40287aacb9846 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Fri, 2 Nov 2012 15:25:32 -0700 Subject: [PATCH 02/21] Fix pages disappearing (issue 7456885) Change-Id: I51e4510da06a9b81aaefb8b2165234297ad4de92 --- .../keyguard/KeyguardViewStateManager.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index ddded8e125dc2..2fb4117c67f50 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -23,7 +23,6 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle private KeyguardWidgetPager mPagedView; private ChallengeLayout mChallengeLayout; - private Runnable mHideHintsRunnable; private int[] mTmpPoint = new int[2]; private int[] mTmpLoc = new int[2]; @@ -219,6 +218,15 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle } } + private Runnable mHideHintsRunnable = new Runnable() { + @Override + public void run() { + if (mPagedView != null) { + mPagedView.hideOutlinesAndSidePages(); + } + } + }; + public void showUsabilityHints() { mMainQueue.postDelayed( new Runnable() { @Override @@ -227,15 +235,9 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle } } , SCREEN_ON_RING_HINT_DELAY); mPagedView.showInitialPageHints(); - mHideHintsRunnable = new Runnable() { - @Override - public void run() { - mPagedView.hideOutlinesAndSidePages(); - mHideHintsRunnable = null; - } - }; - - mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION); + if (mHideHintsRunnable != null) { + mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION); + } } public void setTransportState(int state) { From fc9c4cd51b3bdca27726dd6d8a00d47e388ca2aa Mon Sep 17 00:00:00 2001 From: Svetoslav Ganov Date: Fri, 2 Nov 2012 11:49:22 -0700 Subject: [PATCH 03/21] Polish user selector accessibility. 1. The current user was not announced as such. 2. The event for a user switch was not sent. Change-Id: Ib3caf1f9e93ea1f0b5450246601bc37f416be6da --- .../view/accessibility/AccessibilityRecord.java | 11 +++++++++++ .../policy/impl/keyguard/KeyguardMultiUserAvatar.java | 5 +++++ .../accessibility/AccessibilityManagerService.java | 1 + 3 files changed, 17 insertions(+) diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index 5c60a1262ff0e..7147c57c8b0d2 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -167,6 +167,17 @@ public class AccessibilityRecord { mSourceNodeId, GET_SOURCE_PREFETCH_FLAGS); } + /** + * Sets the window id. + * + * @param windowId The window id. + * + * @hide + */ + public void setWindowId(int windowId) { + mSourceWindowId = windowId; + } + /** * Gets the id of the window from which the event comes from. * diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java index a21ebe38b2c7c..7bf2bf9991356 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java @@ -150,6 +150,11 @@ class KeyguardMultiUserAvatar extends FrameLayout { if (active) { KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent(); parent.setTopChild(this); + // TODO: Create an appropriate asset when string changes are possible. + setContentDescription(mUserName.getText() + + ". " + mContext.getString(R.string.user_switched, "")); + } else { + setContentDescription(mUserName.getText()); } } updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete); diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 6b277c7887e24..aee96f9906f34 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1330,6 +1330,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { AccessibilityEvent event = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_ANNOUNCEMENT); event.getText().add(message); + event.setWindowId(mSecurityPolicy.getRetrievalAllowingWindowLocked()); sendAccessibilityEvent(event, mCurrentUserId); } } From 3520774a91aee6fd59200aef4238efbdb580202a Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Fri, 2 Nov 2012 15:33:20 -0700 Subject: [PATCH 04/21] Update DevicePolicyManager documentation with new keyguard flags Change-Id: Idb1fa306a5706ba5b9543d7dff5450a4af5c394f --- core/java/android/app/admin/DevicePolicyManager.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 6966793d26877..4c0eba00e66c9 100755 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1228,7 +1228,7 @@ public class DevicePolicyManager { public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 1 << 1; /** - * Disable all current and future keyguard customizations + * Disable all current and future keyguard customizations. */ public static final int KEYGUARD_DISABLE_FEATURES_ALL = 0x7fffffff; @@ -1381,8 +1381,9 @@ public class DevicePolicyManager { * this method; if it has not, a security exception will be thrown. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. - * @param which {@link DevicePolicyManager#KEYGUARD_DISABLE_WIDGETS_ALL} or - * {@link DevicePolicyManager#KEYGUARD_DISABLE_FEATURES_NONE} (the default). + * @param which {@link #KEYGUARD_DISABLE_FEATURES_NONE} (default), + * {@link #KEYGUARD_DISABLE_WIDGETS_ALL}, {@link #KEYGUARD_DISABLE_SECURE_CAMERA}, + * {@link #KEYGUARD_DISABLE_FEATURES_ALL} */ public void setKeyguardDisabledFeatures(ComponentName admin, int which) { if (mService != null) { @@ -1399,6 +1400,8 @@ public class DevicePolicyManager { * admin, if specified, or all admins. * @param admin The name of the admin component to check, or null to check if any admins * have disabled features in keyguard. + * @return bitfield of flags. See {@link #setKeyguardDisabledFeatures(ComponentName, int)} + * for a list. */ public int getKeyguardDisabledFeatures(ComponentName admin) { return getKeyguardDisabledFeatures(admin, UserHandle.myUserId()); From 75931e05470992d51d135d09031902fd1b3fdbc7 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Fri, 2 Nov 2012 16:39:22 -0700 Subject: [PATCH 05/21] Attempt to fix MENU key issue. Bug 7467642 Change-Id: If9ee91fc17b454dd47945e800e90d76c0faa7f3d --- .../impl/keyguard/KeyguardHostView.java | 22 +++++++++---------- .../impl/keyguard/KeyguardViewManager.java | 9 ++++---- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index 18f8b0c34b293..f042f4bc60324 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -72,7 +72,6 @@ public class KeyguardHostView extends KeyguardViewBase { private KeyguardSecurityViewFlipper mSecurityViewContainer; private KeyguardSelectorView mKeyguardSelectorView; private KeyguardTransportControlView mTransportControl; - private boolean mEnableMenuKey; private boolean mIsVerifyUnlockOnly; private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid; @@ -112,8 +111,6 @@ public class KeyguardHostView extends KeyguardViewBase { mAppWidgetManager = AppWidgetManager.getInstance(mContext); mSecurityModel = new KeyguardSecurityModel(context); - // The following enables the MENU key to work for testing automation - mEnableMenuKey = shouldEnableMenuKey(); mViewStateManager = new KeyguardViewStateManager(); } @@ -1292,20 +1289,21 @@ public class KeyguardHostView extends KeyguardViewBase { return !configDisabled || isTestHarness || fileOverride; } - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_MENU && mEnableMenuKey) { - showNextSecurityScreenOrFinish(false); - return true; - } else { - return super.onKeyDown(keyCode, event); - } - } + public void goToUserSwitcher() { mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_multi_user_selector)); } + public boolean handleMenuKey() { + // The following enables the MENU key to work for testing automation + if (shouldEnableMenuKey()) { + showNextSecurityScreenOrFinish(false); + return true; + } + return false; + } + public boolean handleBackKey() { if (mCurrentSecuritySelection != SecurityMode.None) { mCallback.dismiss(false); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java index b224c0898f4d6..7c117d9f1323c 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java @@ -137,10 +137,11 @@ public class KeyguardViewManager { @Override public boolean dispatchKeyEvent(KeyEvent event) { - if (event.getAction() == KeyEvent.ACTION_DOWN - && event.getKeyCode() == KeyEvent.KEYCODE_BACK - && mKeyguardView != null) { - if (mKeyguardView.handleBackKey()) { + if (event.getAction() == KeyEvent.ACTION_DOWN && mKeyguardView != null) { + int keyCode = event.getKeyCode(); + if (keyCode == KeyEvent.KEYCODE_BACK && mKeyguardView.handleBackKey()) { + return true; + } else if (keyCode == KeyEvent.KEYCODE_MENU && mKeyguardView.handleMenuKey()) { return true; } } From e93d1b4ed9257530271817e53dfdb67366b6f056 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Fri, 2 Nov 2012 17:26:52 -0700 Subject: [PATCH 06/21] Clean up separator string in keyguard view The whitespace in the string was being removed by aapt. Change-Id: I0c6a3e6960feb80cc0263d3f63005aee8bd0a7cd --- core/res/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 06e927b9e12db..73b9021da9436 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2101,7 +2101,7 @@ Charging, %d%% - Charged. + Charged %d%% @@ -3969,7 +3969,7 @@ - \u2014 + " \u2014 " From 45adaa70203a155beb786f22b251fe66b8d6fafd Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Fri, 2 Nov 2012 22:00:57 -0700 Subject: [PATCH 07/21] Making screen hints just side page outlines, as per new design (issue 7467968) Change-Id: Iff66e0b01cca89337227e54033f6245d6833a5ff --- .../impl/keyguard/KeyguardHostView.java | 5 +- .../impl/keyguard/KeyguardWidgetPager.java | 71 +++++-------------- 2 files changed, 19 insertions(+), 57 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index d28656410d992..0902c1e85b5e4 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -172,8 +172,6 @@ public class KeyguardHostView extends KeyguardViewBase { mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view); mViewStateManager.setSecurityViewContainer(mSecurityViewContainer); - mViewStateManager.showUsabilityHints(); - if (!(mContext instanceof Activity)) { setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK); } @@ -182,6 +180,9 @@ public class KeyguardHostView extends KeyguardViewBase { addWidgetsFromSettings(); mSwitchPageRunnable.run(); + // This needs to be called after the pages are all added. + mViewStateManager.showUsabilityHints(); + showPrimarySecurityScreen(false); updateSecurityViews(); } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index acb2913a67824..b176ec677eaad 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -58,10 +58,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit private static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375; private static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 75; protected AnimatorSet mChildrenOutlineFadeAnimation; - private float mChildrenOutlineAlpha = 0; - private float mSidePagesAlpha = 1f; protected int mScreenCenter; - private boolean mHasLayout = false; private boolean mHasMeasure = false; boolean showHintsAfterLayout = false; @@ -526,34 +523,33 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } public void showInitialPageHints() { - if (mHasLayout) { - showOutlinesAndSidePages(); - } else { - // The layout hints depend on layout being run once - showHintsAfterLayout = true; + int count = getChildCount(); + for (int i = 0; i < count; i++) { + KeyguardWidgetFrame child = getWidgetPageAt(i); + if (i != mCurrentPage) { + child.fadeFrame(this, true, KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER, + CHILDREN_OUTLINE_FADE_IN_DURATION); + child.setContentAlpha(0f); + } else { + child.setBackgroundAlpha(0f); + child.setContentAlpha(1f); + } } } + public void showSidePageHints() { + animateOutlinesAndSidePages(true, -1); + } + @Override public void onAttachedToWindow() { super.onAttachedToWindow(); mHasMeasure = false; - mHasLayout = false; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - if (showHintsAfterLayout) { - post(new Runnable() { - @Override - public void run() { - showOutlinesAndSidePages(); - } - }); - showHintsAfterLayout = false; - } - mHasLayout = true; } protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { @@ -616,6 +612,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit finalContentAlpha = 0f; } KeyguardWidgetFrame child = getWidgetPageAt(i); + alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha); ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha); anims.add(a); @@ -645,42 +642,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit mChildrenOutlineFadeAnimation.start(); } - public void setChildrenOutlineAlpha(float alpha) { - mChildrenOutlineAlpha = alpha; - for (int i = 0; i < getChildCount(); i++) { - getWidgetPageAt(i).setBackgroundAlpha(alpha); - } - } - - public void setSidePagesAlpha(float alpha) { - // This gives the current page, or the destination page if in transit. - int curPage = getNextPage(); - mSidePagesAlpha = alpha; - for (int i = 0; i < getChildCount(); i++) { - if (curPage != i) { - getWidgetPageAt(i).setContentAlpha(alpha); - } else { - // We lock the current page alpha to 1. - getWidgetPageAt(i).setContentAlpha(1.0f); - } - } - } - - public void setChildrenOutlineMultiplier(float alpha) { - mChildrenOutlineAlpha = alpha; - for (int i = 0; i < getChildCount(); i++) { - getWidgetPageAt(i).setBackgroundAlphaMultiplier(alpha); - } - } - - public float getSidePagesAlpha() { - return mSidePagesAlpha; - } - - public float getChildrenOutlineAlpha() { - return mChildrenOutlineAlpha; - } - @Override public boolean onLongClick(View v) { // Disallow long pressing to reorder if the challenge is showing From db1c5d596e91713132131601536aaad32e693325 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Sat, 3 Nov 2012 17:10:07 -0700 Subject: [PATCH 08/21] Updating UI to new design, widget shouldn't expand until page settles (issue 7467435) -> If the challenge is showing and the page is swiped, instead of immediately sliding down the security and expanding the small widget, we instead quickly fade out the security and keep the widget+frame small until the page settles and fades out. Change-Id: I0f376dcd863744b977a1c5ccc7a46a5c6fdb891d --- .../keyguard/KeyguardViewStateManager.java | 14 ++-- .../impl/keyguard/KeyguardWidgetFrame.java | 5 +- .../impl/keyguard/KeyguardWidgetPager.java | 18 ++++- .../impl/keyguard/SlidingChallengeLayout.java | 72 +++++++++++++++++-- 4 files changed, 94 insertions(+), 15 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index 2fb4117c67f50..54ac411c34982 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -76,8 +76,10 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle } public void onPageBeginMoving() { - if (mChallengeLayout.isChallengeShowing()) { - mChallengeLayout.showChallenge(false); + if (mChallengeLayout.isChallengeShowing() && + mChallengeLayout instanceof SlidingChallengeLayout) { + SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout; + scl.dismissChallengeWithFade(); } if (mHideHintsRunnable != null) { mMainQueue.removeCallbacks(mHideHintsRunnable); @@ -170,7 +172,11 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle if (frame == null) return; if (!challengeOverlapping) { - frame.resetSize(); + if (!mPagedView.isPageMoving()) { + frame.resetSize(); + } else { + mPagedView.resetWidgetSizeOnPagesFaded(frame); + } } frame.hideFrame(this); @@ -213,7 +219,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle public void onScrollPositionChanged(float scrollPosition, int challengeTop) { mChallengeTop = challengeTop; KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); - if (frame != null) { + if (frame != null && !mPagedView.isPageMoving()) { frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop)); } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java index 9ffabf8f58cda..6fcb05407eee0 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java @@ -366,11 +366,12 @@ public class KeyguardWidgetFrame extends FrameLayout { } public void hideFrame(Object caller) { - fadeFrame(caller, false, 0f, 150); + fadeFrame(caller, false, 0f, KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_OUT_DURATION); } public void showFrame(Object caller) { - fadeFrame(caller, true, OUTLINE_ALPHA_MULTIPLIER, 150); + fadeFrame(caller, true, OUTLINE_ALPHA_MULTIPLIER, + KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_IN_DURATION); } public void fadeFrame(Object caller, boolean takeControl, float alpha, int duration) { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index b176ec677eaad..a011d5e1d6ce0 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -55,8 +55,8 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit private LockPatternUtils mLockPatternUtils; // Related to the fading in / out background outlines - private static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375; - private static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 75; + public static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375; + public static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100; protected AnimatorSet mChildrenOutlineFadeAnimation; protected int mScreenCenter; private boolean mHasMeasure = false; @@ -70,6 +70,8 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit private boolean mCameraWidgetEnabled; + private KeyguardWidgetFrame mWidgetToResetAfterFadeOut; + // Background threads to deal with persistence private HandlerThread mBgPersistenceWorkerThread; private Handler mBgPersistenceWorkerHandler; @@ -587,6 +589,10 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit animateOutlinesAndSidePages(show, -1); } + public void resetWidgetSizeOnPagesFaded(KeyguardWidgetFrame widget) { + mWidgetToResetAfterFadeOut = widget; + } + void animateOutlinesAndSidePages(final boolean show, int duration) { if (mChildrenOutlineFadeAnimation != null) { mChildrenOutlineFadeAnimation.cancel(); @@ -632,10 +638,18 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit enablePageLayers(); } } + @Override public void onAnimationEnd(Animator animation) { if (!show) { disablePageLayers(); + if (mWidgetToResetAfterFadeOut != null) { + if (!(getWidgetPageAt(mCurrentPage) == mWidgetToResetAfterFadeOut && + mViewStateManager.isChallengeShowing())) { + mWidgetToResetAfterFadeOut.resetSize(); + } + mWidgetToResetAfterFadeOut = null; + } } } }); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java index 16e2f9eee0db8..ff9aec15558ef 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java @@ -76,6 +76,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout private boolean mIsBouncing = false; private final Scroller mScroller; + private ObjectAnimator mFader; private int mScrollState; private OnChallengeScrolledListener mScrollListener; private OnBouncerStateChangedListener mBouncerListener; @@ -83,6 +84,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout public static final int SCROLL_STATE_IDLE = 0; public static final int SCROLL_STATE_DRAGGING = 1; public static final int SCROLL_STATE_SETTLING = 2; + public static final int SCROLL_STATE_FADING = 3; + + private static final int CHALLENGE_FADE_DURATION = 70; private static final int MAX_SETTLE_DURATION = 600; // ms @@ -122,7 +126,10 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout private final Rect mTempRect = new Rect(); private boolean mHasGlowpad; - private boolean mChallengeInteractive = true; + + // We have an internal and external version, and we and them together. + private boolean mChallengeInteractiveExternal = true; + private boolean mChallengeInteractiveInternal = true; static final Property HANDLE_ALPHA = new FloatProperty("handleAlpha") { @@ -277,7 +284,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } public void setChallengeInteractive(boolean interactive) { - mChallengeInteractive = interactive; + mChallengeInteractiveExternal = interactive; if (mExpandChallengeView != null) { mExpandChallengeView.setEnabled(interactive); } @@ -409,6 +416,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout void completeChallengeScroll() { setChallengeShowing(mChallengeOffset != 0); setScrollState(SCROLL_STATE_IDLE); + mChallengeInteractiveInternal = true; mChallengeView.setLayerType(LAYER_TYPE_NONE, null); } @@ -433,6 +441,13 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout // Nothing to do. return; } + + if (mFader != null) { + mFader.cancel(); + } + + mChallengeInteractiveInternal = false; + mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null); final int sy = mChallengeView.getBottom(); final int dy = y - sy; if (dy == 0) { @@ -592,7 +607,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout for (int i = 0; i < count; i++) { final float x = ev.getX(i); final float y = ev.getY(i); - if (!mIsBouncing && mChallengeInteractive && mActivePointerId == INVALID_POINTER + if (!mIsBouncing && mActivePointerId == INVALID_POINTER && (crossedDragHandle(x, y, mGestureStartY) || (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING))) { @@ -609,7 +624,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout break; } - if (mBlockDrag) { + if (mBlockDrag || isChallengeInteractionBlocked()) { mActivePointerId = INVALID_POINTER; mDragging = false; } @@ -617,6 +632,10 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout return mDragging; } + private boolean isChallengeInteractionBlocked() { + return !mChallengeInteractiveExternal || !mChallengeInteractiveInternal; + } + private void resetTouch() { mVelocityTracker.recycle(); mVelocityTracker = null; @@ -640,7 +659,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout break; case MotionEvent.ACTION_CANCEL: - if (mDragging && mChallengeInteractive) { + if (mDragging && !isChallengeInteractionBlocked()) { showChallenge(0); } resetTouch(); @@ -651,7 +670,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout break; } case MotionEvent.ACTION_UP: - if (mDragging && mChallengeInteractive) { + if (mDragging && !isChallengeInteractionBlocked()) { mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity); showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId)); } @@ -668,7 +687,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) || (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING)) && mActivePointerId == INVALID_POINTER - && mChallengeInteractive) { + && !isChallengeInteractionBlocked()) { mGestureStartX = x; mGestureStartY = y; mActivePointerId = ev.getPointerId(i); @@ -1045,6 +1064,45 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } } + public void dismissChallengeWithFade() { + if (mChallengeView != null) { + if (!mScroller.isFinished()) { + mScroller.abortAnimation(); + completeChallengeScroll(); + } + + mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", 0f); + mFader.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + onFadeStart(); + } + @Override + public void onAnimationEnd(Animator animation) { + onFadeEnd(); + } + }); + mFader.setDuration(CHALLENGE_FADE_DURATION); + mFader.start(); + } + } + + private void onFadeStart() { + mChallengeInteractiveInternal = false; + mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null); + setScrollState(SCROLL_STATE_FADING); + } + + private void onFadeEnd() { + mChallengeInteractiveInternal = true; + setChallengeShowing(false); + moveChallengeTo(getLayoutBottom() + mChallengeView.getMeasuredHeight()); + mChallengeView.setAlpha(1f); + mChallengeView.setLayerType(LAYER_TYPE_NONE, null); + mFader = null; + setScrollState(SCROLL_STATE_IDLE); + } + private void showChallenge(int velocity) { boolean show = false; if (Math.abs(velocity) > mMinVelocity) { From 5d47a8dc2e86a0513cc09348b5b4da24696fdd46 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Sat, 3 Nov 2012 19:10:56 -0700 Subject: [PATCH 09/21] Cleaning up the overscroll effect Change-Id: I685693fa178fb7b6418145554eb320b1a62d7462 --- core/res/res/values/colors.xml | 2 +- .../impl/keyguard/KeyguardWidgetFrame.java | 18 +++++++++++++++--- .../impl/keyguard/KeyguardWidgetPager.java | 10 +++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index b19e23df9825f..604bf4b6f3c7d 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -118,7 +118,7 @@ #ffffffff #ff808080 - #ff33B5E5 + #ffffffff #CC000000 diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java index 6fcb05407eee0..821c1f5c82ccc 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java @@ -76,6 +76,7 @@ public class KeyguardWidgetFrame extends FrameLayout { private int mSmallFrameHeight; private boolean mWidgetLockedSmall = false; private int mMaxChallengeTop = -1; + private int mFrameStrokeAdjustment; // This will hold the width value before we've actually been measured private int mFrameHeight; @@ -103,9 +104,12 @@ public class KeyguardWidgetFrame extends FrameLayout { Resources res = context.getResources(); // TODO: this padding should really correspond to the padding embedded in the background // drawable (ie. outlines). + float density = res.getDisplayMetrics().density; int padding = (int) (res.getDisplayMetrics().density * 8); setPadding(padding, padding, padding, padding); + mFrameStrokeAdjustment = (int) (2 * density); + mBackgroundDrawable = res.getDrawable(R.drawable.kg_bouncer_bg_white); mGradientColor = res.getColor(com.android.internal.R.color.kg_widget_pager_gradient); mGradientPaint.setXfermode(sAddBlendMode); @@ -394,8 +398,12 @@ public class KeyguardWidgetFrame extends FrameLayout { @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); - mForegroundRect.set(getPaddingLeft(), getPaddingTop(), - w - getPaddingRight(), h - getPaddingBottom()); + + // mFrameStrokeAdjustment is a cludge to prevent the overlay from drawing outside the + // rounded rect background. + mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment, + w - mFrameStrokeAdjustment, h - mFrameStrokeAdjustment); + float x0 = mLeftToRight ? 0 : mForegroundRect.width(); float x1 = mLeftToRight ? mForegroundRect.width(): 0; mLeftToRightGradient = new LinearGradient(x0, 0f, x1, 0f, @@ -438,7 +446,11 @@ public class KeyguardWidgetFrame extends FrameLayout { if (Float.compare(mOverScrollAmount, r) != 0) { mOverScrollAmount = r; mForegroundGradient = left ? mLeftToRightGradient : mRightToLeftGradient; - mForegroundAlpha = (int) Math.round((0.85f * r * 255)); + mForegroundAlpha = (int) Math.round((0.5f * r * 255)); + + // We bump up the alpha of the outline to hide the fact that the overlay is drawing + // over the rounded part of the frame. + setBackgroundAlpha(OUTLINE_ALPHA_MULTIPLIER + r * (1 - OUTLINE_ALPHA_MULTIPLIER)); invalidate(); } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index a011d5e1d6ce0..7ddd9ed906662 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -379,14 +379,14 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } } - protected void enablePageLayers() { + protected void enablePageContentLayers() { int children = getChildCount(); for (int i = 0; i < children; i++) { getWidgetPageAt(i).enableHardwareLayersForContent(); } } - protected void disablePageLayers() { + protected void disablePageContentLayers() { int children = getChildCount(); for (int i = 0; i < children; i++) { getWidgetPageAt(i).disableHardwareLayersForContent(); @@ -506,7 +506,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit @Override protected void onStartReordering() { super.onStartReordering(); - enablePageLayers(); + enablePageContentLayers(); reorderStarting(); } @@ -635,14 +635,14 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit @Override public void onAnimationStart(Animator animation) { if (show) { - enablePageLayers(); + enablePageContentLayers(); } } @Override public void onAnimationEnd(Animator animation) { if (!show) { - disablePageLayers(); + disablePageContentLayers(); if (mWidgetToResetAfterFadeOut != null) { if (!(getWidgetPageAt(mCurrentPage) == mWidgetToResetAfterFadeOut && mViewStateManager.isChallengeShowing())) { From 934d0835c8bae6d8aacf4d661b7134691d8e241b Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Sat, 3 Nov 2012 20:02:33 -0700 Subject: [PATCH 10/21] Fixing up overscroll / hints on tablet Change-Id: I8b0ce30b02b2d13d71826d6765d154f5ab89072b --- .../policy/impl/keyguard/KeyguardWidgetCarousel.java | 11 +++++++++++ .../policy/impl/keyguard/KeyguardWidgetFrame.java | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java index 2e83b42b0e4c2..debf765cf1b24 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java @@ -86,6 +86,17 @@ public class KeyguardWidgetCarousel extends KeyguardWidgetPager { } } + public void showInitialPageHints() { + int count = getChildCount(); + for (int i = 0; i < count; i++) { + KeyguardWidgetFrame child = getWidgetPageAt(i); + if (i >= mCurrentPage - 1 && i <= mCurrentPage + 1) { + child.fadeFrame(this, true, KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER, + CHILDREN_OUTLINE_FADE_IN_DURATION); + } + } + } + @Override protected void screenScrolled(int screenCenter) { mScreenCenter = screenCenter; diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java index 821c1f5c82ccc..f0e231ce5d21f 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java @@ -450,7 +450,9 @@ public class KeyguardWidgetFrame extends FrameLayout { // We bump up the alpha of the outline to hide the fact that the overlay is drawing // over the rounded part of the frame. - setBackgroundAlpha(OUTLINE_ALPHA_MULTIPLIER + r * (1 - OUTLINE_ALPHA_MULTIPLIER)); + float bgAlpha = Math.min(OUTLINE_ALPHA_MULTIPLIER + r * (1 - OUTLINE_ALPHA_MULTIPLIER), + 1f); + setBackgroundAlpha(bgAlpha); invalidate(); } } From f70239a4313010bf0dd3e1ff37f58a806857baa4 Mon Sep 17 00:00:00 2001 From: John Spurlock Date: Sun, 4 Nov 2012 09:42:42 -0500 Subject: [PATCH 11/21] Fully block user interactions when transitioning to camera. Bug:7464265 Change-Id: I654b3d7c455f782495946988bb2e5198ff4252ec --- .../policy/impl/keyguard/CameraWidgetFrame.java | 6 ------ .../policy/impl/keyguard/KeyguardWidgetPager.java | 14 ++++++++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java index 893df2690bc39..0022bc95b663b 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java @@ -60,7 +60,6 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli private boolean mActive; private boolean mTransitioning; private boolean mDown; - private boolean mWindowFocused; private final Runnable mLaunchCameraRunnable = new Runnable() { @Override @@ -243,7 +242,6 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli @Override public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); - mWindowFocused = hasWindowFocus; if (DEBUG) Log.d(TAG, "onWindowFocusChanged: " + hasWindowFocus); if (!hasWindowFocus) { mTransitioning = false; @@ -268,10 +266,6 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli @Override public boolean onUserInteraction(MotionEvent event) { - if (!mWindowFocused) { - if (DEBUG) Log.d(TAG, "onUserInteraction eaten: !mWindowFocused"); - return true; - } if (mTransitioning) { if (DEBUG) Log.d(TAG, "onUserInteraction eaten: mTransitioning"); return true; diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index 7ddd9ed906662..605ad1d2e245d 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -184,11 +184,17 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit @Override public boolean onTouchEvent(MotionEvent ev) { + return captureUserInteraction(ev) || super.onTouchEvent(ev); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return captureUserInteraction(ev) || super.onInterceptTouchEvent(ev); + } + + private boolean captureUserInteraction(MotionEvent ev) { KeyguardWidgetFrame currentWidgetPage = getWidgetPageAt(getCurrentPage()); - if (currentWidgetPage != null && currentWidgetPage.onUserInteraction(ev)) { - return true; - } - return super.onTouchEvent(ev); + return currentWidgetPage != null && currentWidgetPage.onUserInteraction(ev); } public void showPagingFeedback() { From 37d84ae6051ab6d2add1e0ef51cf2aa2605c3225 Mon Sep 17 00:00:00 2001 From: John Spurlock Date: Sun, 4 Nov 2012 11:11:47 -0500 Subject: [PATCH 12/21] Render camera widget on a background thread. Bug:7470978 Change-Id: Ieace005ac42d39ac4c146673910e6681f38e8f56 --- .../impl/keyguard/CameraWidgetFrame.java | 58 ++++++++++++++----- .../impl/keyguard/KeyguardWidgetFrame.java | 10 ++++ .../impl/keyguard/KeyguardWidgetPager.java | 23 ++++---- 3 files changed, 63 insertions(+), 28 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java index 0022bc95b663b..d8a683d00a373 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java @@ -152,37 +152,62 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli } public void render() { + final Throwable[] thrown = new Throwable[1]; + final Bitmap[] offscreen = new Bitmap[1]; try { - int width = getRootView().getWidth(); - int height = getRootView().getHeight(); + final int width = getRootView().getWidth(); + final int height = getRootView().getHeight(); if (mRenderedSize.x == width && mRenderedSize.y == height) { - if (DEBUG) Log.d(TAG, String.format("already rendered at size=%sx%s", + if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s", width, height)); return; } if (width == 0 || height == 0) { return; } - if (DEBUG) Log.d(TAG, String.format("render size=%sx%s instance=%s at %s", - width, height, - Integer.toHexString(hashCode()), - SystemClock.uptimeMillis())); - - Bitmap offscreen = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(offscreen); + final long start = SystemClock.uptimeMillis(); + offscreen[0] = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + final Canvas c = new Canvas(offscreen[0]); mWidgetView.measure( MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); mWidgetView.layout(0, 0, width, height); mWidgetView.draw(c); - ((ImageView)getChildAt(0)).setImageBitmap(offscreen); + + final long end = SystemClock.uptimeMillis(); + if (DEBUG) Log.d(TAG, String.format( + "Rendered camera widget in %sms size=%sx%s instance=%s at %s", + end - start, + width, height, + Integer.toHexString(hashCode()), + end)); mRenderedSize.set(width, height); } catch (Throwable t) { - Log.w(TAG, "Error rendering camera widget", t); - removeAllViews(); - View genericView = inflateGenericWidgetView(mContext); - addView(genericView); + thrown[0] = t; } + + mHandler.post(new Runnable() { + @Override + public void run() { + if (thrown[0] == null) { + try { + ((ImageView) getChildAt(0)).setImageBitmap(offscreen[0]); + } catch (Throwable t) { + thrown[0] = t; + } + } + if (thrown[0] == null) + return; + + Log.w(TAG, "Error rendering camera widget", thrown[0]); + try { + removeAllViews(); + final View genericView = inflateGenericWidgetView(mContext); + addView(genericView); + } catch (Throwable t) { + Log.w(TAG, "Error inflating generic camera widget", t); + } + }}); } private void transitionToCamera() { @@ -332,7 +357,8 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (DEBUG) Log.d(TAG, String.format("onSizeChanged new=%sx%s old=%sx%s at %s", w, h, oldw, oldh, SystemClock.uptimeMillis())); - mHandler.post(mRenderRunnable); + final Handler worker = getWorkerHandler(); + (worker != null ? worker : mHandler).post(mRenderRunnable); super.onSizeChanged(w, h, oldw, oldh); } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java index f0e231ce5d21f..213b82fa55812 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java @@ -31,6 +31,7 @@ import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.Shader; import android.graphics.drawable.Drawable; +import android.os.Handler; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -61,6 +62,7 @@ public class KeyguardWidgetFrame extends FrameLayout { private CheckLongPressHelper mLongPressHelper; private Animator mFrameFade; private boolean mIsSmall = false; + private Handler mWorkerHandler; private float mBackgroundAlpha; private float mContentAlpha; @@ -465,4 +467,12 @@ public class KeyguardWidgetFrame extends FrameLayout { // hook for subclasses return false; } + + public void setWorkerHandler(Handler workerHandler) { + mWorkerHandler = workerHandler; + } + + public Handler getWorkerHandler() { + return mWorkerHandler; + } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index 605ad1d2e245d..74e9389d48711 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -72,9 +72,9 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit private KeyguardWidgetFrame mWidgetToResetAfterFadeOut; - // Background threads to deal with persistence - private HandlerThread mBgPersistenceWorkerThread; - private Handler mBgPersistenceWorkerHandler; + // Background worker thread: used here for persistence, also made available to widget frames + private final HandlerThread mBackgroundWorkerThread; + private final Handler mBackgroundWorkerHandler; public KeyguardWidgetPager(Context context, AttributeSet attrs) { this(context, attrs, 0); @@ -94,19 +94,17 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit Resources r = getResources(); mCameraWidgetEnabled = r.getBoolean(R.bool.kg_enable_camera_default_widget); - mBgPersistenceWorkerThread = new HandlerThread("KeyguardWidgetPager Persistence"); - mBgPersistenceWorkerThread.start(); - mBgPersistenceWorkerHandler = new Handler(mBgPersistenceWorkerThread.getLooper()); + mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker"); + mBackgroundWorkerThread.start(); + mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper()); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - // Clean up the persistence worker thread - if (mBgPersistenceWorkerThread != null) { - mBgPersistenceWorkerThread.quit(); - } + // Clean up the worker thread + mBackgroundWorkerThread.quit(); } public void setViewStateManager(KeyguardViewStateManager viewStateManager) { @@ -230,7 +228,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit public void onRemoveView(View v) { final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId(); - mBgPersistenceWorkerHandler.post(new Runnable() { + mBackgroundWorkerHandler.post(new Runnable() { @Override public void run() { mLockPatternUtils.removeAppWidget(appWidgetId); @@ -245,7 +243,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit boundByReorderablePages(true, pagesRange); // Subtract from the index to take into account pages before the reorderable // pages (e.g. the "add widget" page) - mBgPersistenceWorkerHandler.post(new Runnable() { + mBackgroundWorkerHandler.post(new Runnable() { @Override public void run() { mLockPatternUtils.addAppWidget(appWidgetId, index - pagesRange[0]); @@ -288,6 +286,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit ViewGroup.LayoutParams pageLp = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); frame.setOnLongClickListener(this); + frame.setWorkerHandler(mBackgroundWorkerHandler); if (pageIndex == -1) { addView(frame, pageLp); From 6275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3 Mon Sep 17 00:00:00 2001 From: John Spurlock Date: Sun, 4 Nov 2012 13:48:42 -0500 Subject: [PATCH 13/21] Use better signal for camera launch. Keyguard set-hidden instead of window lost focus. Tested with face unlock. Bug:7464536 Change-Id: I6171c96699d1b1ccfebd7a14179d90963fb8aa54 --- .../impl/keyguard/CameraWidgetFrame.java | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java index d8a683d00a373..bbc53f1ba8ab7 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java @@ -83,6 +83,17 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli transitionToCamera(); }}; + private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { + private boolean mShowing; + + void onKeyguardVisibilityChanged(boolean showing) { + if (mShowing == showing) + return; + mShowing = showing; + CameraWidgetFrame.this.onKeyguardVisibilityChanged(mShowing); + }; + }; + private CameraWidgetFrame(Context context, Callbacks callbacks, KeyguardActivityLauncher activityLauncher) { super(context); @@ -90,6 +101,8 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli mCallbacks = callbacks; mActivityLauncher = activityLauncher; mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + KeyguardUpdateMonitor.getInstance(context).registerCallback(mCallback); + if (DEBUG) Log.d(TAG, "new CameraWidgetFrame instance " + instanceId()); } public static CameraWidgetFrame create(Context context, Callbacks callbacks, @@ -179,7 +192,7 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli "Rendered camera widget in %sms size=%sx%s instance=%s at %s", end - start, width, height, - Integer.toHexString(hashCode()), + instanceId(), end)); mRenderedSize.set(width, height); } catch (Throwable t) { @@ -265,18 +278,11 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli } @Override - public void onWindowFocusChanged(boolean hasWindowFocus) { - super.onWindowFocusChanged(hasWindowFocus); - if (DEBUG) Log.d(TAG, "onWindowFocusChanged: " + hasWindowFocus); - if (!hasWindowFocus) { - mTransitioning = false; - if (mLaunchCameraStart > 0) { - long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart; - if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime)); - mLaunchCameraStart = 0; - onCameraLaunched(); - } - } + protected void onDetachedFromWindow() { + if (DEBUG) Log.d(TAG, "onDetachedFromWindow: instance " + instanceId() + + " at " + SystemClock.uptimeMillis()); + super.onDetachedFromWindow(); + KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback); } @Override @@ -375,4 +381,22 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli mWindowManager.updateViewLayout(root, wlp); } } + + private void onKeyguardVisibilityChanged(boolean showing) { + if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged " + showing + + " at " + SystemClock.uptimeMillis()); + if (mTransitioning && !showing) { + mTransitioning = false; + if (mLaunchCameraStart > 0) { + long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart; + if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime)); + mLaunchCameraStart = 0; + onCameraLaunched(); + } + } + } + + private String instanceId() { + return Integer.toHexString(hashCode()); + } } From 180cfd5feb4fe415d04494bf00f2013896f93b77 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Sun, 4 Nov 2012 12:03:12 -0800 Subject: [PATCH 14/21] If a default keyguard layout isn't specified, fallback to the default layout -> Also fixing a typo in AppWidgetProvider clone() -- this was the cause of the "couldn't load widget". It wasn't getting expressed before for various reasons. Change-Id: Ib7114565a414d66facd8b4baeb97d5a71e96b5e9 --- core/java/android/appwidget/AppWidgetHostView.java | 5 ++++- core/java/android/appwidget/AppWidgetProviderInfo.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index be6a770e6f33b..52771eebecbb9 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -553,7 +553,10 @@ public class AppWidgetHostView extends FrameLayout { if (options.containsKey(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)) { int category = options.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY); if (category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD) { - layoutId = mInfo.initialKeyguardLayout; + int kgLayoutId = mInfo.initialKeyguardLayout; + // If a default keyguard layout is not specified, use the standard + // default layout. + layoutId = kgLayoutId == 0 ? layoutId : kgLayoutId; } } defaultView = inflater.inflate(layoutId, this, false); diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java index 6bf12e681bad0..7b8b286ab643a 100644 --- a/core/java/android/appwidget/AppWidgetProviderInfo.java +++ b/core/java/android/appwidget/AppWidgetProviderInfo.java @@ -260,7 +260,7 @@ public class AppWidgetProviderInfo implements Parcelable { that.minResizeWidth = this.minResizeHeight; that.minResizeHeight = this.minResizeHeight; that.updatePeriodMillis = this.updatePeriodMillis; - that.initialLayout = that.initialLayout; + that.initialLayout = this.initialLayout; that.initialKeyguardLayout = this.initialKeyguardLayout; that.configure = this.configure == null ? null : this.configure.clone(); that.label = this.label == null ? null : this.label.substring(0); From 25228801ba76e3419d598d9820007f4af761b3cd Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Sun, 4 Nov 2012 13:20:26 -0800 Subject: [PATCH 15/21] Fix issue 7468224, make sure to size pages if page changes Change-Id: I8b3d7573eda7ed8e6a9aa479e61737fb12e26b92 --- .../internal/policy/impl/keyguard/KeyguardViewStateManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index 54ac411c34982..ff1ffcf5c41ee 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -115,7 +115,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle // This prevents conflicts. // If the page hasn't switched, don't bother with any of this - if (mCurrentPage != newPageIndex) return; + if (mCurrentPage == newPageIndex) return; if (mPagedView != null && mChallengeLayout != null) { KeyguardWidgetFrame prevPage = mPagedView.getWidgetPageAt(mCurrentPage); From 7f6bb6e460ad7f76742348144b8b1d0dfb3074b3 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Sun, 4 Nov 2012 14:00:05 -0800 Subject: [PATCH 16/21] Ensure edge swiping is enforced immediately upon showing keyguard (issue 7453156) Change-Id: I197a5304bbea904b58494a9dcb7ff95ff3c4a52b --- .../keyguard/KeyguardViewStateManager.java | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index ff1ffcf5c41ee..6d0e191181653 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -21,7 +21,7 @@ import android.view.View; public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChallengeScrolledListener { - private KeyguardWidgetPager mPagedView; + private KeyguardWidgetPager mKeyguardWidgetPager; private ChallengeLayout mChallengeLayout; private int[] mTmpPoint = new int[2]; private int[] mTmpLoc = new int[2]; @@ -50,11 +50,23 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle } public void setPagedView(KeyguardWidgetPager pagedView) { - mPagedView = pagedView; + mKeyguardWidgetPager = pagedView; + updateEdgeSwiping(); } public void setChallengeLayout(ChallengeLayout layout) { mChallengeLayout = layout; + updateEdgeSwiping(); + } + + private void updateEdgeSwiping() { + if (mChallengeLayout != null && mKeyguardWidgetPager != null) { + if (mChallengeLayout.isChallengeOverlapping()) { + mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(true); + } else { + mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(false); + } + } } public boolean isChallengeShowing() { @@ -103,7 +115,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle } public void onPageSwitching(View newPage, int newPageIndex) { - if (mPagedView != null && mChallengeLayout instanceof SlidingChallengeLayout) { + if (mKeyguardWidgetPager != null && mChallengeLayout instanceof SlidingChallengeLayout) { boolean isCameraPage = newPage instanceof CameraWidgetFrame; ((SlidingChallengeLayout) mChallengeLayout).setChallengeInteractive(!isCameraPage); } @@ -117,13 +129,13 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle // If the page hasn't switched, don't bother with any of this if (mCurrentPage == newPageIndex) return; - if (mPagedView != null && mChallengeLayout != null) { - KeyguardWidgetFrame prevPage = mPagedView.getWidgetPageAt(mCurrentPage); + if (mKeyguardWidgetPager != null && mChallengeLayout != null) { + KeyguardWidgetFrame prevPage = mKeyguardWidgetPager.getWidgetPageAt(mCurrentPage); if (prevPage != null && mCurrentPage != mPageListeningToSlider) { prevPage.resetSize(); } - KeyguardWidgetFrame newCurPage = mPagedView.getWidgetPageAt(newPageIndex); + KeyguardWidgetFrame newCurPage = mKeyguardWidgetPager.getWidgetPageAt(newPageIndex); boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping(); if (challengeOverlapping && !newCurPage.isSmall() && mPageListeningToSlider != newPageIndex) { @@ -164,27 +176,22 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle @Override public void onScrollStateChanged(int scrollState) { - if (mPagedView == null || mChallengeLayout == null) return; + if (mKeyguardWidgetPager == null || mChallengeLayout == null) return; boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping(); if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) { - KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); + KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider); if (frame == null) return; if (!challengeOverlapping) { - if (!mPagedView.isPageMoving()) { + if (!mKeyguardWidgetPager.isPageMoving()) { frame.resetSize(); } else { - mPagedView.resetWidgetSizeOnPagesFaded(frame); + mKeyguardWidgetPager.resetWidgetSizeOnPagesFaded(frame); } } frame.hideFrame(this); - - if (challengeOverlapping) { - mPagedView.setOnlyAllowEdgeSwipes(true); - } else { - mPagedView.setOnlyAllowEdgeSwipes(false); - } + updateEdgeSwiping(); if (mChallengeLayout.isChallengeShowing()) { mKeyguardSecurityContainer.onResume(); @@ -196,8 +203,8 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle // Whether dragging or settling, if the last state was idle, we use this signal // to update the current page who will receive events from the sliding challenge. // We resize the frame as appropriate. - mPageListeningToSlider = mPagedView.getNextPage(); - KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); + mPageListeningToSlider = mKeyguardWidgetPager.getNextPage(); + KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider); if (frame == null) return; frame.showFrame(this); @@ -206,7 +213,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle // small to begin with). if (!frame.isSmall()) { // We need to fetch the final page, in case the pages are in motion. - mPageListeningToSlider = mPagedView.getNextPage(); + mPageListeningToSlider = mKeyguardWidgetPager.getNextPage(); frame.shrinkWidget(); } // View is on the move. Pause the security view until it completes. @@ -218,8 +225,8 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle @Override public void onScrollPositionChanged(float scrollPosition, int challengeTop) { mChallengeTop = challengeTop; - KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider); - if (frame != null && !mPagedView.isPageMoving()) { + KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider); + if (frame != null && !mKeyguardWidgetPager.isPageMoving()) { frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop)); } } @@ -227,8 +234,8 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle private Runnable mHideHintsRunnable = new Runnable() { @Override public void run() { - if (mPagedView != null) { - mPagedView.hideOutlinesAndSidePages(); + if (mKeyguardWidgetPager != null) { + mKeyguardWidgetPager.hideOutlinesAndSidePages(); } } }; @@ -240,7 +247,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle mKeyguardSecurityContainer.showUsabilityHint(); } } , SCREEN_ON_RING_HINT_DELAY); - mPagedView.showInitialPageHints(); + mKeyguardWidgetPager.showInitialPageHints(); if (mHideHintsRunnable != null) { mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION); } From 8caabadd02c7bef701c44dc1718a9a493cbd1261 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Sun, 4 Nov 2012 17:23:25 -0800 Subject: [PATCH 17/21] Making challenge come back if within the same gesture you return to the original page (issue 7422999) Change-Id: I8ada54ca39ebebc15295f93a2d9029f3b7915acb --- .../keyguard/KeyguardViewStateManager.java | 49 ++++--- .../impl/keyguard/KeyguardWidgetPager.java | 19 +-- .../impl/keyguard/SlidingChallengeLayout.java | 127 +++++++++++------- 3 files changed, 125 insertions(+), 70 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index 6d0e191181653..054b9b20a69e9 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -43,6 +43,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle // Paged view state private int mPageListeningToSlider = -1; private int mCurrentPage = -1; + private int mPageIndexOnPageBeginMoving = -1; int mChallengeTop = 0; @@ -87,21 +88,6 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle mKeyguardSecurityContainer = container; } - public void onPageBeginMoving() { - if (mChallengeLayout.isChallengeShowing() && - mChallengeLayout instanceof SlidingChallengeLayout) { - SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout; - scl.dismissChallengeWithFade(); - } - if (mHideHintsRunnable != null) { - mMainQueue.removeCallbacks(mHideHintsRunnable); - mHideHintsRunnable = null; - } - } - - public void onPageEndMoving() { - } - public void showBouncer(boolean show) { mChallengeLayout.showBouncer(); } @@ -114,11 +100,38 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration); } + public void onPageBeginMoving() { + if (mChallengeLayout.isChallengeOverlapping() && + mChallengeLayout instanceof SlidingChallengeLayout) { + SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout; + scl.fadeOutChallenge(); + mPageIndexOnPageBeginMoving = mKeyguardWidgetPager.getCurrentPage(); + } + if (mHideHintsRunnable != null) { + mMainQueue.removeCallbacks(mHideHintsRunnable); + mHideHintsRunnable = null; + } + } + + public void onPageEndMoving() { + mPageIndexOnPageBeginMoving = -1; + } + public void onPageSwitching(View newPage, int newPageIndex) { if (mKeyguardWidgetPager != null && mChallengeLayout instanceof SlidingChallengeLayout) { boolean isCameraPage = newPage instanceof CameraWidgetFrame; ((SlidingChallengeLayout) mChallengeLayout).setChallengeInteractive(!isCameraPage); } + + // If the page we're settling to is the same as we started on, and the action of + // moving the page hid the security, we restore it immediately. + if (mPageIndexOnPageBeginMoving == mKeyguardWidgetPager.getNextPage() && + mChallengeLayout instanceof SlidingChallengeLayout) { + SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout; + scl.fadeInChallenge(); + mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(-1); + } + mPageIndexOnPageBeginMoving = -1; } public void onPageSwitched(View newPage, int newPageIndex) { @@ -131,7 +144,8 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle if (mKeyguardWidgetPager != null && mChallengeLayout != null) { KeyguardWidgetFrame prevPage = mKeyguardWidgetPager.getWidgetPageAt(mCurrentPage); - if (prevPage != null && mCurrentPage != mPageListeningToSlider) { + if (prevPage != null && mCurrentPage != mPageListeningToSlider && mCurrentPage + != mKeyguardWidgetPager.getWidgetToResetOnPageFadeOut()) { prevPage.resetSize(); } @@ -142,6 +156,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle newCurPage.shrinkWidget(); } } + mCurrentPage = newPageIndex; } @@ -187,7 +202,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle if (!mKeyguardWidgetPager.isPageMoving()) { frame.resetSize(); } else { - mKeyguardWidgetPager.resetWidgetSizeOnPagesFaded(frame); + mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(mPageListeningToSlider); } } frame.hideFrame(this); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java index 74e9389d48711..7943b23712e15 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java @@ -70,7 +70,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit private boolean mCameraWidgetEnabled; - private KeyguardWidgetFrame mWidgetToResetAfterFadeOut; + private int mWidgetToResetAfterFadeOut; // Background worker thread: used here for persistence, also made available to widget frames private final HandlerThread mBackgroundWorkerThread; @@ -594,10 +594,14 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit animateOutlinesAndSidePages(show, -1); } - public void resetWidgetSizeOnPagesFaded(KeyguardWidgetFrame widget) { + public void setWidgetToResetOnPageFadeOut(int widget) { mWidgetToResetAfterFadeOut = widget; } + public int getWidgetToResetOnPageFadeOut() { + return mWidgetToResetAfterFadeOut; + } + void animateOutlinesAndSidePages(final boolean show, int duration) { if (mChildrenOutlineFadeAnimation != null) { mChildrenOutlineFadeAnimation.cancel(); @@ -648,13 +652,12 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit public void onAnimationEnd(Animator animation) { if (!show) { disablePageContentLayers(); - if (mWidgetToResetAfterFadeOut != null) { - if (!(getWidgetPageAt(mCurrentPage) == mWidgetToResetAfterFadeOut && - mViewStateManager.isChallengeShowing())) { - mWidgetToResetAfterFadeOut.resetSize(); - } - mWidgetToResetAfterFadeOut = null; + KeyguardWidgetFrame frame = getWidgetPageAt(mWidgetToResetAfterFadeOut); + if (frame != null && !(frame == getWidgetPageAt(mCurrentPage) && + mViewStateManager.isChallengeOverlapping())) { + frame.resetSize(); } + mWidgetToResetAfterFadeOut = -1; } } }); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java index ff9aec15558ef..2712494b50e1a 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java @@ -86,7 +86,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout public static final int SCROLL_STATE_SETTLING = 2; public static final int SCROLL_STATE_FADING = 3; - private static final int CHALLENGE_FADE_DURATION = 70; + private static final int CHALLENGE_FADE_OUT_DURATION = 100; + private static final int CHALLENGE_FADE_IN_DURATION = 160; private static final int MAX_SETTLE_DURATION = 600; // ms @@ -442,9 +443,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout return; } - if (mFader != null) { - mFader.cancel(); - } + cancelTransitionsInProgress(); mChallengeInteractiveInternal = false; mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null); @@ -984,6 +983,83 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } } + private void cancelTransitionsInProgress() { + if (!mScroller.isFinished()) { + mScroller.abortAnimation(); + completeChallengeScroll(); + } + if (mFader != null) { + mFader.cancel(); + } + } + + public void fadeInChallenge() { + fadeChallenge(true); + } + + public void fadeOutChallenge() { + fadeChallenge(false); + } + + public void fadeChallenge(final boolean show) { + if (mChallengeView != null) { + + cancelTransitionsInProgress(); + float alpha = show ? 1f : 0f; + int duration = show ? CHALLENGE_FADE_IN_DURATION : CHALLENGE_FADE_OUT_DURATION; + mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", alpha); + mFader.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + onFadeStart(show); + } + @Override + public void onAnimationEnd(Animator animation) { + onFadeEnd(show); + } + }); + mFader.setDuration(duration); + mFader.start(); + } + } + + private int getMaxChallengeBottom() { + if (mChallengeView == null) return 0; + final int layoutBottom = getLayoutBottom(); + final int challengeHeight = mChallengeView.getMeasuredHeight(); + + return (layoutBottom + challengeHeight - mChallengeBottomBound); + } + + private int getMinChallengeBottom() { + return getLayoutBottom(); + } + + + private void onFadeStart(boolean show) { + mChallengeInteractiveInternal = false; + mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null); + + if (show) { + moveChallengeTo(getMinChallengeBottom()); + } + + setScrollState(SCROLL_STATE_FADING); + } + + private void onFadeEnd(boolean show) { + mChallengeInteractiveInternal = true; + setChallengeShowing(show); + + if (!show) { + moveChallengeTo(getMaxChallengeBottom()); + } + + mChallengeView.setLayerType(LAYER_TYPE_NONE, null); + mFader = null; + setScrollState(SCROLL_STATE_IDLE); + } + public int getMaxChallengeTop() { if (mChallengeView == null) return 0; @@ -1009,8 +1085,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout final int layoutBottom = getLayoutBottom(); final int challengeHeight = mChallengeView.getHeight(); - bottom = Math.max(layoutBottom, - Math.min(bottom, layoutBottom + challengeHeight - mChallengeBottomBound)); + bottom = Math.max(getMinChallengeBottom(), + Math.min(bottom, getMaxChallengeBottom())); float offset = 1.f - (float) (bottom - layoutBottom) / (challengeHeight - mChallengeBottomBound); @@ -1064,45 +1140,6 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } } - public void dismissChallengeWithFade() { - if (mChallengeView != null) { - if (!mScroller.isFinished()) { - mScroller.abortAnimation(); - completeChallengeScroll(); - } - - mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", 0f); - mFader.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - onFadeStart(); - } - @Override - public void onAnimationEnd(Animator animation) { - onFadeEnd(); - } - }); - mFader.setDuration(CHALLENGE_FADE_DURATION); - mFader.start(); - } - } - - private void onFadeStart() { - mChallengeInteractiveInternal = false; - mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null); - setScrollState(SCROLL_STATE_FADING); - } - - private void onFadeEnd() { - mChallengeInteractiveInternal = true; - setChallengeShowing(false); - moveChallengeTo(getLayoutBottom() + mChallengeView.getMeasuredHeight()); - mChallengeView.setAlpha(1f); - mChallengeView.setLayerType(LAYER_TYPE_NONE, null); - mFader = null; - setScrollState(SCROLL_STATE_IDLE); - } - private void showChallenge(int velocity) { boolean show = false; if (Math.abs(velocity) > mMinVelocity) { From 08898375fba7cc776857ebf0846c7183563a300f Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Sun, 4 Nov 2012 19:08:40 -0800 Subject: [PATCH 18/21] Show bouncer mode for Slide mode in keyguard if widget isn't expanded Change-Id: If225198b0c6b122fef854ddd91e49c1071b74d50 --- .../internal/policy/impl/keyguard/KeyguardHostView.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index 8a821558a25c0..3a901c8f0b0df 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -537,7 +537,11 @@ public class KeyguardHostView extends KeyguardViewBase { } }); - mCallback.dismiss(false); + if (mViewStateManager.isChallengeShowing()) { + mViewStateManager.showBouncer(true); + } else { + mCallback.dismiss(false); + } return true; } else { return super.onClickHandler(view, pendingIntent, fillInIntent); From 57f928fc4afc02d2fe45523efea687eee7f86c02 Mon Sep 17 00:00:00 2001 From: John Spurlock Date: Fri, 2 Nov 2012 13:09:25 -0400 Subject: [PATCH 19/21] Recover from badly behaving 3rd party secure cameras. Bug:7473953 Change-Id: I8daf18c85d951e03fa1c98dda5f255327f96f0ba --- .../impl/keyguard/CameraWidgetFrame.java | 78 +++++++++++++++---- .../keyguard/KeyguardActivityLauncher.java | 70 ++++++++++++++--- .../impl/keyguard/KeyguardHostView.java | 25 +++--- .../impl/keyguard/KeyguardSelectorView.java | 4 +- 4 files changed, 137 insertions(+), 40 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java index bbc53f1ba8ab7..dbd9999136371 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java @@ -40,12 +40,14 @@ import com.android.internal.policy.impl.keyguard.KeyguardActivityLauncher.Camera public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener { private static final String TAG = CameraWidgetFrame.class.getSimpleName(); private static final boolean DEBUG = KeyguardHostView.DEBUG; - private static final int WIDGET_ANIMATION_DURATION = 250; - private static final int WIDGET_WAIT_DURATION = 650; + private static final int WIDGET_ANIMATION_DURATION = 250; // ms + private static final int WIDGET_WAIT_DURATION = 650; // ms + private static final int RECOVERY_DELAY = 1000; // ms interface Callbacks { void onLaunchingCamera(); - void onCameraLaunched(); + void onCameraLaunchedSuccessfully(); + void onCameraLaunchedUnsuccessfully(); } private final Handler mHandler = new Handler(); @@ -59,16 +61,39 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli private long mLaunchCameraStart; private boolean mActive; private boolean mTransitioning; + private boolean mRecovering; private boolean mDown; - private final Runnable mLaunchCameraRunnable = new Runnable() { + private final Runnable mTransitionToCameraRunnable = new Runnable() { + @Override + public void run() { + transitionToCamera(); + }}; + + private final Runnable mTransitionToCameraEndAction = new Runnable() { @Override public void run() { if (!mTransitioning) return; + Handler worker = getWorkerHandler() != null ? getWorkerHandler() : mHandler; mLaunchCameraStart = SystemClock.uptimeMillis(); if (DEBUG) Log.d(TAG, "Launching camera at " + mLaunchCameraStart); - mActivityLauncher.launchCamera(); + mActivityLauncher.launchCamera(worker, mSecureCameraActivityStartedRunnable); + }}; + + private final Runnable mRecoverRunnable = new Runnable() { + @Override + public void run() { + recover(); + }}; + + private final Runnable mRecoverEndAction = new Runnable() { + @Override + public void run() { + if (!mRecovering) + return; + mCallbacks.onCameraLaunchedUnsuccessfully(); + reset(); }}; private final Runnable mRenderRunnable = new Runnable() { @@ -77,15 +102,15 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli render(); }}; - private final Runnable mTransitionToCameraRunnable = new Runnable() { + private final Runnable mSecureCameraActivityStartedRunnable = new Runnable() { @Override public void run() { - transitionToCamera(); - }}; + onSecureCameraActivityStarted(); + } + }; private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { private boolean mShowing; - void onKeyguardVisibilityChanged(boolean showing) { if (mShowing == showing) return; @@ -97,7 +122,6 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli private CameraWidgetFrame(Context context, Callbacks callbacks, KeyguardActivityLauncher activityLauncher) { super(context); - mCallbacks = callbacks; mActivityLauncher = activityLauncher; mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); @@ -261,12 +285,24 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli .scaleY(scale) .translationY(finishCenter - startCenter) .setDuration(WIDGET_ANIMATION_DURATION) - .withEndAction(mLaunchCameraRunnable) + .withEndAction(mTransitionToCameraEndAction) .start(); mCallbacks.onLaunchingCamera(); } + private void recover() { + if (DEBUG) Log.d(TAG, "recovering at " + SystemClock.uptimeMillis()); + mRecovering = true; + animate() + .scaleX(1) + .scaleY(1) + .translationY(0) + .setDuration(WIDGET_ANIMATION_DURATION) + .withEndAction(mRecoverEndAction) + .start(); + } + @Override public void onClick(View v) { if (DEBUG) Log.d(TAG, "clicked"); @@ -283,6 +319,8 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli + " at " + SystemClock.uptimeMillis()); super.onDetachedFromWindow(); KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback); + cancelTransitionToCamera(); + mHandler.removeCallbacks(mRecoverRunnable); } @Override @@ -320,7 +358,7 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli @Override protected void onFocusLost() { - if (DEBUG) Log.d(TAG, "onFocusLost"); + if (DEBUG) Log.d(TAG, "onFocusLost at " + SystemClock.uptimeMillis()); cancelTransitionToCamera(); super.onFocusLost(); } @@ -342,16 +380,18 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli } private void onCameraLaunched() { - mCallbacks.onCameraLaunched(); + mCallbacks.onCameraLaunchedSuccessfully(); reset(); } private void reset() { - if (DEBUG) Log.d(TAG, "reset"); + if (DEBUG) Log.d(TAG, "reset at " + SystemClock.uptimeMillis()); mLaunchCameraStart = 0; mTransitioning = false; + mRecovering = false; mDown = false; cancelTransitionToCamera(); + mHandler.removeCallbacks(mRecoverRunnable); animate().cancel(); setScaleX(1); setScaleY(1); @@ -376,7 +416,8 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli WindowManager.LayoutParams wlp = (WindowManager.LayoutParams) lp; int newWindowAnimations = isEnabled ? com.android.internal.R.style.Animation_LockScreen : 0; if (newWindowAnimations != wlp.windowAnimations) { - if (DEBUG) Log.d(TAG, "setting windowAnimations to: " + newWindowAnimations); + if (DEBUG) Log.d(TAG, "setting windowAnimations to: " + newWindowAnimations + + " at " + SystemClock.uptimeMillis()); wlp.windowAnimations = newWindowAnimations; mWindowManager.updateViewLayout(root, wlp); } @@ -387,6 +428,8 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli + " at " + SystemClock.uptimeMillis()); if (mTransitioning && !showing) { mTransitioning = false; + mRecovering = false; + mHandler.removeCallbacks(mRecoverRunnable); if (mLaunchCameraStart > 0) { long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart; if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime)); @@ -396,6 +439,11 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnCli } } + private void onSecureCameraActivityStarted() { + if (DEBUG) Log.d(TAG, "onSecureCameraActivityStarted at " + SystemClock.uptimeMillis()); + mHandler.postDelayed(mRecoverRunnable, RECOVERY_DELAY); + } + private String instanceId() { return Integer.toHexString(hashCode()); } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java index 8283af217eca2..fabab75d1e875 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java @@ -18,12 +18,14 @@ package com.android.internal.policy.impl.keyguard; import android.app.ActivityManagerNative; import android.app.ActivityOptions; +import android.app.IActivityManager.WaitResult; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.Handler; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -91,7 +93,7 @@ public abstract class KeyguardActivityLauncher { return info; } - public void launchCamera() { + public void launchCamera(Handler worker, Runnable onSecureCameraStarted) { LockPatternUtils lockPatternUtils = getLockPatternUtils(); if (lockPatternUtils.isSecure()) { // Launch the secure version of the camera @@ -100,26 +102,33 @@ public abstract class KeyguardActivityLauncher { // For now, we'll treat this like launching any other app from secure keyguard. // When they do, user sees the system's ResolverActivity which lets them choose // which secure camera to use. - launchActivity(SECURE_CAMERA_INTENT, false, false); + launchActivity(SECURE_CAMERA_INTENT, false, false, null, null); } else { - launchActivity(SECURE_CAMERA_INTENT, true, false); + launchActivity(SECURE_CAMERA_INTENT, true, false, worker, onSecureCameraStarted); } } else { // Launch the normal camera - launchActivity(INSECURE_CAMERA_INTENT, false, false); + launchActivity(INSECURE_CAMERA_INTENT, false, false, null, null); } } /** * Launches the said intent for the current foreground user. + * * @param intent * @param showsWhileLocked true if the activity can be run on top of keyguard. - * See {@link WindowManager#FLAG_SHOW_WHEN_LOCKED} + * See {@link WindowManager#FLAG_SHOW_WHEN_LOCKED} + * @param useDefaultAnimations true if default transitions should be used, else suppressed. + * @param worker if supplied along with onStarted, used to launch the blocking activity call. + * @param onStarted if supplied along with worker, called after activity is started. */ - public void launchActivity(final Intent intent, boolean showsWhileLocked, boolean animate) { + public void launchActivity(final Intent intent, + boolean showsWhileLocked, + boolean useDefaultAnimations, + final Handler worker, + final Runnable onStarted) { final Context context = getContext(); - final Bundle animation = animate ? null : - ActivityOptions.makeCustomAnimation(context, 0, 0).toBundle(); + final Bundle animation = ActivityOptions.makeCustomAnimation(context, 0, 0).toBundle(); LockPatternUtils lockPatternUtils = getLockPatternUtils(); intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK @@ -135,8 +144,7 @@ public abstract class KeyguardActivityLauncher { try { if (DEBUG) Log.d(TAG, String.format("Starting activity for intent %s at %s", intent, SystemClock.uptimeMillis())); - context.startActivityAsUser(intent, animation, - new UserHandle(UserHandle.USER_CURRENT)); + startActivityForCurrentUser(intent, animation, worker, onStarted); } catch (ActivityNotFoundException e) { Log.w(TAG, "Activity not found for intent + " + intent.getAction()); } @@ -147,14 +155,52 @@ public abstract class KeyguardActivityLauncher { callback.setOnDismissRunnable(new Runnable() { @Override public void run() { - context.startActivityAsUser(intent, animation, - new UserHandle(UserHandle.USER_CURRENT)); + startActivityForCurrentUser(intent, animation, worker, onStarted); } }); callback.dismiss(false); } } + private void startActivityForCurrentUser(final Intent intent, final Bundle options, + Handler worker, final Runnable onStarted) { + final UserHandle user = new UserHandle(UserHandle.USER_CURRENT); + if (worker == null || onStarted == null) { + getContext().startActivityAsUser(intent, options, user); + return; + } + // if worker + onStarted are supplied, run blocking activity launch call in the background + worker.post(new Runnable(){ + @Override + public void run() { + try { + WaitResult result = ActivityManagerNative.getDefault().startActivityAndWait( + null /*caller*/, + intent, + intent.resolveTypeIfNeeded(getContext().getContentResolver()), + null /*resultTo*/, + null /*resultWho*/, + 0 /*requestCode*/, + Intent.FLAG_ACTIVITY_NEW_TASK, + null /*profileFile*/, + null /*profileFd*/, + options, + user.getIdentifier()); + if (DEBUG) Log.d(TAG, String.format("waitResult[%s,%s,%s,%s] at %s", + result.result, result.thisTime, result.totalTime, result.who, + SystemClock.uptimeMillis())); + } catch (RemoteException e) { + Log.w(TAG, "Error starting activity", e); + return; + } + try { + onStarted.run(); + } catch (Throwable t) { + Log.w(TAG, "Error running onStarted callback", t); + } + }}); + } + private Intent getCameraIntent() { return getLockPatternUtils().isSecure() ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT; } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index 3a901c8f0b0df..24834e9135931 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -830,26 +830,29 @@ public class KeyguardHostView extends KeyguardViewBase { new CameraWidgetFrame.Callbacks() { @Override public void onLaunchingCamera() { - SlidingChallengeLayout slider = locateSlider(); - if (slider != null) { - slider.setHandleAlpha(0); - } + setSliderHandleAlpha(0); } @Override - public void onCameraLaunched() { + public void onCameraLaunchedSuccessfully() { if (isCameraPage(mAppWidgetContainer.getCurrentPage())) { mAppWidgetContainer.scrollLeft(); } - SlidingChallengeLayout slider = locateSlider(); - if (slider != null) { - slider.setHandleAlpha(1); - } + setSliderHandleAlpha(1); mShowSecurityWhenReturn = true; } - public SlidingChallengeLayout locateSlider() { - return (SlidingChallengeLayout) findViewById(R.id.sliding_layout); + @Override + public void onCameraLaunchedUnsuccessfully() { + setSliderHandleAlpha(1); + } + + private void setSliderHandleAlpha(float alpha) { + SlidingChallengeLayout slider = + (SlidingChallengeLayout) findViewById(R.id.sliding_layout); + if (slider != null) { + slider.setHandleAlpha(alpha); + } } }; diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java index 938e3bd63aac4..776827c9a4e2e 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java @@ -59,7 +59,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) .getAssistIntent(mContext, UserHandle.USER_CURRENT); if (assistIntent != null) { - mActivityLauncher.launchActivity(assistIntent, false, true); + mActivityLauncher.launchActivity(assistIntent, false, true, null, null); } else { Log.w(TAG, "Failed to get intent for assist activity"); } @@ -67,7 +67,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri break; case com.android.internal.R.drawable.ic_lockscreen_camera: - mActivityLauncher.launchCamera(); + mActivityLauncher.launchCamera(null, null); mCallback.userActivity(0); break; From c0ae9e67ebe6f1298800feaed1b43e867139a904 Mon Sep 17 00:00:00 2001 From: Chris Wren Date: Mon, 5 Nov 2012 13:16:31 -0500 Subject: [PATCH 20/21] bouncer: hide more text and frame less. Bug: 7464865 Change-Id: Ic8dac2582c014922143919f142fd36eb720dd3a9 Proto-Id: Id80601c9ffbdc34669b485e943b42cee237898f3 --- .../res/layout-port/keyguard_host_view.xml | 1 - .../res/layout/keyguard_face_unlock_view.xml | 55 +-- .../res/res/layout/keyguard_password_view.xml | 70 ++-- core/res/res/layout/keyguard_pattern_view.xml | 32 +- core/res/res/layout/keyguard_pin_view.xml | 348 +++++++++--------- core/res/res/layout/keyguard_sim_pin_view.xml | 347 ++++++++--------- core/res/res/layout/keyguard_sim_puk_view.xml | 347 ++++++++--------- core/res/res/values/symbols.xml | 1 + .../keyguard/KeyguardAbsKeyInputView.java | 20 + .../impl/keyguard/KeyguardAccountView.java | 8 + .../impl/keyguard/KeyguardFaceUnlockView.java | 24 ++ .../impl/keyguard/KeyguardHostView.java | 5 + .../impl/keyguard/KeyguardMessageArea.java | 35 +- .../impl/keyguard/KeyguardPatternView.java | 23 +- .../keyguard/KeyguardSecurityContainer.java | 75 +--- .../impl/keyguard/KeyguardSecurityView.java | 14 + .../keyguard/KeyguardSecurityViewFlipper.java | 22 ++ .../keyguard/KeyguardSecurityViewHelper.java | 78 ++++ .../impl/keyguard/KeyguardSelectorView.java | 8 + .../keyguard/KeyguardViewStateManager.java | 4 + 20 files changed, 861 insertions(+), 656 deletions(-) create mode 100644 policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml index 9921313bb723c..b2bf3f147e41a 100644 --- a/core/res/res/layout-port/keyguard_host_view.xml +++ b/core/res/res/layout-port/keyguard_host_view.xml @@ -64,7 +64,6 @@ android:layout_width="wrap_content" android:layout_height="@dimen/keyguard_security_height" androidprv:layout_childType="challenge" - android:background="@drawable/kg_bouncer_bg_white" android:padding="0dp" android:gravity="bottom|center_horizontal"> - + + - + - - + + + - - - + android:layout_width="match_parent" + android:orientation="horizontal" + android:background="#70000000" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + > - + - + + + - + - - - + + diff --git a/core/res/res/layout/keyguard_pin_view.xml b/core/res/res/layout/keyguard_pin_view.xml index d6cfe2acd3243..d486d5ec13f2c 100644 --- a/core/res/res/layout/keyguard_pin_view.xml +++ b/core/res/res/layout/keyguard_pin_view.xml @@ -31,177 +31,185 @@ android:layout_height="wrap_content" /> - - + android:id="@+id/keyguard_bouncer_frame" + android:background="@*android:drawable/kg_bouncer_bg_white" + android:layout_width="match_parent" + android:layout_height="0dp" + android:orientation="vertical" + android:layout_weight="1" + > + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:id="@+id/keyguard_bouncer_frame" + android:background="@*android:drawable/kg_bouncer_bg_white" + android:layout_width="match_parent" + android:layout_height="0dp" + android:orientation="vertical" + android:layout_weight="1" + > + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + android:id="@+id/keyguard_bouncer_frame" + android:background="@*android:drawable/kg_bouncer_bg_white" + android:layout_width="match_parent" + android:layout_height="0dp" + android:orientation="vertical" + android:layout_weight="1" + > + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java index 71526d2653ba7..7c769a705b24f 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java @@ -18,6 +18,7 @@ package com.android.internal.policy.impl.keyguard; import android.content.Context; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.os.CountDownTimer; import android.os.SystemClock; import android.text.Editable; @@ -43,6 +44,8 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout protected TextView mPasswordEntry; protected LockPatternUtils mLockPatternUtils; protected SecurityMessageDisplay mSecurityMessageDisplay; + protected View mEcaView; + private Drawable mBouncerFrame; protected boolean mEnableHaptics; // To avoid accidental lockout due to events while the device in in the pocket, ignore @@ -122,6 +125,11 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout } }); mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); + mEcaView = findViewById(R.id.keyguard_selector_fade_container); + View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame); + if (bouncerFrameView != null) { + mBouncerFrame = bouncerFrameView.getBackground(); + } } @Override @@ -239,5 +247,17 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); } } + + @Override + public void showBouncer(int duration) { + KeyguardSecurityViewHelper. + showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); + } + + @Override + public void hideBouncer(int duration) { + KeyguardSecurityViewHelper. + hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); + } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java index 9c877550d4e08..3ce61d91cfb7d 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java @@ -318,5 +318,13 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit @Override public void showUsabilityHint() { } + + @Override + public void showBouncer(int duration) { + } + + @Override + public void hideBouncer(int duration) { + } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java index c0095de670898..8ca6d2a5ab24b 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java @@ -16,6 +16,7 @@ package com.android.internal.policy.impl.keyguard; import android.content.Context; +import android.graphics.drawable.Drawable; import android.os.PowerManager; import android.telephony.TelephonyManager; import android.util.AttributeSet; @@ -37,6 +38,9 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu private BiometricSensorUnlock mBiometricUnlock; private View mFaceUnlockAreaView; private ImageButton mCancelButton; + private SecurityMessageDisplay mSecurityMessageDisplay; + private View mEcaView; + private Drawable mBouncerFrame; private boolean mIsShowing = false; private final Object mIsShowingLock = new Object(); @@ -54,6 +58,13 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu super.onFinishInflate(); initializeBiometricUnlockView(); + + mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); + mEcaView = findViewById(R.id.keyguard_selector_fade_container); + View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame); + if (bouncerFrameView != null) { + mBouncerFrame = bouncerFrameView.getBackground(); + } } @Override @@ -217,4 +228,17 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu @Override public void showUsabilityHint() { } + + @Override + public void showBouncer(int duration) { + KeyguardSecurityViewHelper. + showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); + } + + @Override + public void hideBouncer(int duration) { + KeyguardSecurityViewHelper. + hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); + } + } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index 3a901c8f0b0df..f8edd5d64cc68 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -196,6 +196,11 @@ public class KeyguardHostView extends KeyguardViewBase { KeyguardSecurityView ksv = (KeyguardSecurityView) view; ksv.setKeyguardCallback(mCallback); ksv.setLockPatternUtils(mLockPatternUtils); + if (mViewStateManager.isBouncing()) { + ksv.showBouncer(0); + } else { + ksv.hideBouncer(0); + } } else { Log.w(TAG, "View " + view + " is not a KeyguardSecurityView"); } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java index f6f3fabbe58cf..ee5c4a68a7be3 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java @@ -240,22 +240,33 @@ class KeyguardMessageArea extends TextView { } private void hideMessage(int duration, boolean thenUpdate) { - Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f); - anim.setDuration(duration); - if (thenUpdate) { - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - update(); - } + if (duration > 0) { + Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f); + anim.setDuration(duration); + if (thenUpdate) { + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + update(); + } }); + } + anim.start(); + } else { + setAlpha(0f); + if (thenUpdate) { + update(); + } } - anim.start(); } private void showMessage(int duration) { - Animator anim = ObjectAnimator.ofFloat(this, "alpha", 1f); - anim.setDuration(duration); - anim.start(); + if (duration > 0) { + Animator anim = ObjectAnimator.ofFloat(this, "alpha", 1f); + anim.setDuration(duration); + anim.start(); + } else { + setAlpha(1f); + } } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java index 82cb44baa9456..3a826877ae530 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java @@ -23,6 +23,7 @@ import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.content.Context; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.CountDownTimer; import android.os.SystemClock; @@ -84,6 +85,8 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit }; private Rect mTempRect = new Rect(); private SecurityMessageDisplay mSecurityMessageDisplay; + private View mEcaView; + private Drawable mBouncerFrame; enum FooterMode { Normal, @@ -136,6 +139,11 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit maybeEnableFallback(mContext); mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); + mEcaView = findViewById(R.id.keyguard_selector_fade_container); + View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame); + if (bouncerFrameView != null) { + mBouncerFrame = bouncerFrameView.getBackground(); + } } private void updateFooter(FooterMode mode) { @@ -381,7 +389,16 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit public KeyguardSecurityCallback getCallback() { return mCallback; } + + @Override + public void showBouncer(int duration) { + KeyguardSecurityViewHelper. + showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); + } + + @Override + public void hideBouncer(int duration) { + KeyguardSecurityViewHelper. + hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration); + } } - - - diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java index 7b115078bdd4e..375a96abc333c 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java @@ -1,11 +1,6 @@ package com.android.internal.policy.impl.keyguard; -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.content.Context; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.widget.FrameLayout; @@ -13,10 +8,6 @@ import android.widget.FrameLayout; import com.android.internal.R; public class KeyguardSecurityContainer extends FrameLayout { - - private float mBackgroundAlpha; - private Drawable mBackgroundDrawable; - public KeyguardSecurityContainer(Context context, AttributeSet attrs) { this(context, attrs, 0); } @@ -27,68 +18,30 @@ public class KeyguardSecurityContainer extends FrameLayout { public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - mBackgroundDrawable = context.getResources().getDrawable(R.drawable.kg_bouncer_bg_white); } - public void setBackgroundAlpha(float alpha) { - if (Float.compare(mBackgroundAlpha, alpha) != 0) { - mBackgroundAlpha = alpha; - invalidate(); - } - } - - public float getBackgroundAlpha() { - return mBackgroundAlpha; - } - - @Override - protected void dispatchDraw(Canvas canvas) { - if (mBackgroundAlpha > 0.0f && mBackgroundDrawable != null) { - Drawable bg = mBackgroundDrawable; - bg.setAlpha((int) (mBackgroundAlpha * 255)); - bg.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); - bg.draw(canvas); - } - super.dispatchDraw(canvas); - } - - public void showBouncer(int duration) { - SecurityMessageDisplay message = new KeyguardMessageArea.Helper(getSecurityView()); - message.showBouncer(duration); - AnimatorSet anim = new AnimatorSet(); - anim.playTogether(ObjectAnimator.ofFloat(this, "backgroundAlpha", 1f), getEcaAnim(0f)); - anim.setDuration(duration); - anim.start(); - } - - public void hideBouncer(int duration) { - SecurityMessageDisplay message = new KeyguardMessageArea.Helper(getSecurityView()); - message.hideBouncer(duration); - AnimatorSet anim = new AnimatorSet(); - anim.playTogether(ObjectAnimator.ofFloat(this, "backgroundAlpha", 0f), getEcaAnim(1f)); - anim.setDuration(duration); - anim.start(); - } - - View getSecurityView() { + KeyguardSecurityViewFlipper getFlipper() { for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); if (child instanceof KeyguardSecurityViewFlipper) { - return (View) (((KeyguardSecurityViewFlipper) child).getSecurityView()); + return (KeyguardSecurityViewFlipper) child; } } return null; } - Animator getEcaAnim(float alpha) { - Animator anim = null; - View securityView = getSecurityView(); - if (securityView != null) { - View ecaView = securityView.findViewById(R.id.keyguard_selector_fade_container); - if (ecaView != null) { - anim = ObjectAnimator.ofFloat(ecaView, "alpha", alpha); - } + public void showBouncer(int duration) { + KeyguardSecurityViewFlipper flipper = getFlipper(); + if (flipper != null) { + flipper.showBouncer(duration); + } + } + + public void hideBouncer(int duration) { + KeyguardSecurityViewFlipper flipper = getFlipper(); + if (flipper != null) { + flipper.hideBouncer(duration); } - return anim; } } + diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java index 26517435d8f04..027b16e5fabc6 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java @@ -66,4 +66,18 @@ public interface KeyguardSecurityView { * */ void showUsabilityHint(); + + /** + * Place the security view into bouncer mode. + * Animate transisiton if duration is non-zero. + * @param duration millisends for the transisiton animation. + */ + void showBouncer(int duration); + + /** + * Place the security view into non-bouncer mode. + * Animate transisiton if duration is non-zero. + * @param duration millisends for the transisiton animation. + */ + void hideBouncer(int duration); } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java index 58cf56767b0c7..3d4cb194bcf39 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java @@ -125,4 +125,26 @@ public class KeyguardSecurityViewFlipper extends ViewFlipper implements Keyguard ksv.showUsabilityHint(); } } + + @Override + public void showBouncer(int duration) { + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + if (child instanceof KeyguardSecurityView) { + KeyguardSecurityView ksv = (KeyguardSecurityView) child; + ksv.showBouncer(child.getVisibility() == View.VISIBLE ? duration : 0); + } + } + } + + @Override + public void hideBouncer(int duration) { + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + if (child instanceof KeyguardSecurityView) { + KeyguardSecurityView ksv = (KeyguardSecurityView) child; + ksv.hideBouncer(child.getVisibility() == View.VISIBLE ? duration : 0); + } + } + } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java new file mode 100644 index 0000000000000..2ccdc1d9c5fc3 --- /dev/null +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 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.internal.policy.impl.keyguard; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.graphics.drawable.Drawable; +import android.view.View; + +/** + * Some common functions that are useful for KeyguardSecurityViews. + */ +public class KeyguardSecurityViewHelper { + + public static void showBouncer(SecurityMessageDisplay securityMessageDisplay, + View ecaView, Drawable bouncerFrame, int duration) { + if (securityMessageDisplay != null) { + securityMessageDisplay.showBouncer(duration); + } + if (ecaView != null) { + if (duration > 0) { + Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 0f); + anim.setDuration(duration); + anim.start(); + } else { + ecaView.setAlpha(0f); + } + } + if (bouncerFrame != null) { + if (duration > 0) { + Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 255); + anim.setDuration(duration); + anim.start(); + } else { + bouncerFrame.setAlpha(255); + } + } + } + + public static void hideBouncer(SecurityMessageDisplay securityMessageDisplay, + View ecaView, Drawable bouncerFrame, int duration) { + if (securityMessageDisplay != null) { + securityMessageDisplay.hideBouncer(duration); + } + if (ecaView != null) { + if (duration > 0) { + Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 1f); + anim.setDuration(duration); + anim.start(); + } else { + ecaView.setAlpha(1f); + } + } + if (bouncerFrame != null) { + if (duration > 0) { + Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 0); + anim.setDuration(duration); + anim.start(); + } else { + bouncerFrame.setAlpha(0); + } + } + } +} diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java index 938e3bd63aac4..365256f2e7d58 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java @@ -261,4 +261,12 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri public KeyguardSecurityCallback getCallback() { return mCallback; } + + @Override + public void showBouncer(int duration) { + } + + @Override + public void hideBouncer(int duration) { + } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java index 054b9b20a69e9..969b65ef1ef58 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java @@ -92,6 +92,10 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle mChallengeLayout.showBouncer(); } + public boolean isBouncing() { + return mChallengeLayout.isBouncing(); + } + public void fadeOutSecurity(int duration) { ((View) mKeyguardSecurityContainer).animate().alpha(0).setDuration(duration); } From 025fb93e3e5518b7db5fec049d285cfb2d28a074 Mon Sep 17 00:00:00 2001 From: Steven Ross Date: Mon, 5 Nov 2012 13:49:31 -0500 Subject: [PATCH 21/21] Clearing connected message in stop fixes 7401152 We can stop before the service connected message is processed, in which case we should clear the message. Otherwise it can cause us to start up the UI before the camera is open, causing a crash. I was unable to reproduce this issue, but it theoretically will happen, and the bug report shows all the symptoms of this series of events. Change-Id: I60d295883b08ac58ccf0f3fc6d152b8b75fe9b18 --- .../com/android/internal/policy/impl/keyguard/FaceUnlock.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java index 9858c7734f983..259f1e4f6f45b 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java @@ -149,6 +149,9 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback { Log.e(TAG, "stop() called from non-UI thread"); } + // Clearing any old service connected messages. + mHandler.removeMessages(MSG_SERVICE_CONNECTED); + boolean mWasRunning = mIsRunning; stopUi();