diff --git a/res/values-az/cm_strings.xml b/res/values-az/cm_strings.xml index d8a073c7a3a7bc0de6da17219ca47ac51c6c244f..fde23218cbc550fd07594864bdb61eb30d95b37c 100644 --- a/res/values-az/cm_strings.xml +++ b/res/values-az/cm_strings.xml @@ -77,10 +77,10 @@ 30 dəqiqə Tək çəkilişdə avto-parlaqlıq Parlaqlıq nizamı yalnız ekran açılanda icra edilir - Şəbəkə müraciətinə icazə ver + Şəbəkə erişiminə icazə ver Şəbəkə istifadəsini fəallaşdır - Mobil internet - Mobil internet istifadəsini fəallaşdır + Mobil veri + Mobil veri istifadəsini fəallaşdır VPN VPN istifadəsini fəallaşdır Wi\u2011Fi @@ -101,9 +101,9 @@ Planşetin kilidini açmaq üçün barmaq izi sensoruna uzun basın Cihazın kilidini açmaq üçün barmaq izi sensoruna uzun basın Ekranı oyandırmaq və kilidi açmaq üçün, ekran altındakı barmaq izi sensoruna uzun basın. - Xəbərdarlıq: Bu seçim, düzgün işləməyə və ya məlumat itkisinə səbəb ola bilər, buna görə də tövsiyə edilmir! + Xəbərdarlıq: Bu seçim, düzgün işləməyə və ya veri itkisinə səbəb ola bilər, buna görə də tövsiyə edilmir! Köməkli GPS istifadə edin - GPS-in başlatma performansını əhəmiyyətli dərəcədə artıra bilən peyk köməkçi datalarını internetdən endirin. Fövqəladə hal zəngləri üçün köməkçi GPS-ə həmişə icazə verilir. + GPS-in başlatma performansını əhəmiyyətli dərəcədə artırmaq üçün internetdən peyk köməkçi verilərini endirin. Fövqəladə hal zəngləri üçün köməkçi GPS-ə həmişə icazə verilir. Texnologiya Sağlamlıq Yaxşı diff --git a/res/values-be/cm_strings.xml b/res/values-be/cm_strings.xml index f446e0670bbc2619afd455ff6265205878be6a41..a9df9513c6587860d1d4a450905fd5c0d4e9f167 100644 --- a/res/values-be/cm_strings.xml +++ b/res/values-be/cm_strings.xml @@ -16,6 +16,7 @@ --> Дадаткі + Адладка суперкарыстальнікам Змяніць пастаўшчыка рэзервовага капіявання Націсніце для сну Двойчы націсніце на панэль стану або экран блакіроўкі, каб перавесці прыладу ў рэжым сну diff --git a/res/values-it/cm_strings.xml b/res/values-it/cm_strings.xml index 1c53843d949dc7257668c8ce448c50b192acf184..41fe33cda61ac903e94edcc0ed28105ca46b657d 100644 --- a/res/values-it/cm_strings.xml +++ b/res/values-it/cm_strings.xml @@ -43,7 +43,7 @@ Scegli la dimensione della sequenza Mostra sequenza errata Mostra punti sequenza - Frequenza massima di aggiornamento + Frequenza di aggiornamento massima Frequenza di aggiornamento minima Individua il sensore d\'impronte digitali sulla parte anteriore del tuo tablet. Individua il sensore d\'impronte digitali sulla parte anteriore del tuo dispositivo. diff --git a/res/values-iw/cm_strings.xml b/res/values-iw/cm_strings.xml index eb6438b939927eccacfa9ce74ece94a923d95cb7..652e4cb64add9f05193b0c79842b4cf5be618738 100644 --- a/res/values-iw/cm_strings.xml +++ b/res/values-iw/cm_strings.xml @@ -15,18 +15,57 @@ limitations under the License. --> + תוספות + הגדרות מתקדמות + ניפוי תקלות עם גישת שורש + אפשר הרצת ניפוי תקלות באנדרואיד עם גישת שורש + החלפת ספק גיבוי + בחירת ספק גיבוי + שחור נקי + רקע שחור נקי לערכת נושא כהה LineageOS משפטי + {count, plural, + =1 {הינך צעד אחד מהפעלת הגדרות למפתחים.} + other {הינך # צעדים מהפעלת הגדרות למפתחים.} + } אפשרויות מפתח פעילות! אין צורך. כבר הפעלת את אפשרויות המפתח. הקש בכדי לכבות מסך - הקש פעמיים על שורת המצב או על מסך נעילה בכדי לכבות את המסך + הקשה פעמיים על שורת המצב או על מסך נעילה בכדי לכבות את המסך + קצב דיגום נגיעה גבוה + הגברת קצב דיגום מסך מגע התראות קופצות הראה התראות חשובות בחלון צף קטן רגישות גבוהה למגע - הגבר את רגישות מסך המגע, כך שניתן יהיה להשתמש בו בעת לבישת כפפות - בחר גודל תבנית - הצג שגיאות דפוס - הצג נקודות דפוס + הגברת רגישות מסך המגע, כך שניתן יהיה להשתמש בו בעת עטיית כפפות + אפשר ללקוחות להשתמש ב-VPN + אפשר ללקוחות נקודת חמה להשתמש בחיבורי ה-VPN של התקן זה לצורך גישה לרשת + בחירת גודל תבנית + הצגת שגיאת תבנית + הצגת נקודות תבנית + קצב רענון מקסימלי + קצב רענון מינימלי + ניתן למצוא את חיישן טביעת אצבע בחזית הטאבלט שלך. + ניתן למצוא את חיישן טביעת אצבע בחזית ההתקן שלך. + ניתן למצוא את חיישן טביעת אצבע בחזית הטלפון שלך. + ניתן למצוא את חיישן טביעת אצבע בגב הטאבלט שלך. + ניתן למצוא את חיישן טביעת אצבע בגב ההתקן שלך. + ניתן למצוא את חיישן טביעת אצבע בגב הטלפון שלך. + ניתן למצוא את חיישן טביעת אצבע בצד הטאבלט שלך. + ניתן למצוא את חיישן טביעת אצבע בצד ההתקן שלך. + ניתן למצוא את חיישן טביעת אצבע בצד הטלפון שלך. + יש לגעת בחיישן בחזית הטאבלט שלך. + יש לגעת בחיישן בחזית ההתקן שלך. + יש לגעת בחיישן בחזית הטלפון שלך. + יש לגעת בחיישן בגב הטאבלט שלך. + יש לגעת בחיישן בגב ההתקן שלך. + יש לגעת בחיישן בגב הטלפון שלך. + יש לגעת בחיישן בצד הטאבלט שלך. + יש לגעת בחיישן בצד ההתקן שלך. + יש לגעת בחיישן בצד הטלפון שלך. + יש לגעת בחיישן כדי לפתוח את הנעילה, גם כשהמסך כבוי. חיישן קירבה מונע פתיחה מקרית. + רמז לניווט + הצגת רמזי ניווט בתחתית המסך זמן מינימלי בין צלילי התראות אפשר צלילים או רטט לא יותר מפעם אחת בכל %1$s ללא מגבלה @@ -34,7 +73,16 @@ 30 שניות דקה 1 5 דקות + רבע שעה 30 דקות + בהירות אוטומטית בלחיצה אחת + התאמת הבהירות תתבצע רק כאשר המסך דלוק + אפשר גישה לרשת + אפשר שימוש ברשת + נתונים ניידים + אפשר שימוש בנתונים ניידים + נתוני VPN + אפשר שימוש בנתוני VPN ‏נתוני Wi‑Fi אפשר שימוש בנתוני Wi‑Fi ערבב פריסה @@ -45,6 +93,31 @@ השתמש במחוות מגע שונות לפעולות מהירות מגע בריחוף מאפשר להעביר את האצבע מעל המסך כמו עכבר של מחשב בדפדפנים, בעמדות שליטה מרחוק וכד\' - הער מסך בעת חיבור + יעירו בעת חיבור הפעל את המסך כאשר מקור חשמל מתחבר או מתנתק מהמכשיר + טעינה מהירה + ניתן להשבית על מנת להפחית את חימום ההתקן בזמן טעינה או להאריך את חיי הסוללה + לחיצה ארוכה על חיישן טביעת אצבע לשחרור נעילת הטלפון + לחיצה ארוכה על חיישן טביעת אצבע לשחרור נעילת טאבלט + לחיצה ארוכה על חיישן טביעת אצבע לשחרור נעילת ההתקן + לפתיחת הנעילה ולעורר את המסך, יש ללחוץ לחיצה ארוכה על חיישן טביעת אצבע שמתחת למסך. + אזהרה: אפשרות זו לא מומלצת! ייתכן שלא תפעל כראוי, או תגרום לאובדן נתונים. + שימוש במסייע GPS + הורדת נתוני סיוע לווייני מהאינטרנט שיכולים לשפר מאוד את ביצועי ההפעלה של ה-GPS. בקריאות חירום, נתוני סיוע ל-GPS מאופשרים תמיד. + טכנולוגיה + בריאות + טובה + התחממות יתר + תקולה + מתח חשמלי גבוה + כשל לא מוגדר + קרה + לא ידוע + טמפרטורה + מתח + %1$d מיליאמפר/שעה + קיבולת מקורית + %1$d מיליאמפר/שעה + קיבולת מרבית + %1$d מיליאמפר/שעה (%2$d%%) diff --git a/res/values-ug/cm_strings.xml b/res/values-ug/cm_strings.xml index 21d5fafd596192b8f74d7174c155a515e60b7b55..5ea73f3cff4d2c1a7b6017d6244bd3ef214c74a8 100644 --- a/res/values-ug/cm_strings.xml +++ b/res/values-ug/cm_strings.xml @@ -15,18 +15,109 @@ limitations under the License. --> + قوشۇمچە ئىقتىدار + ئالىي تەڭشەك + Root سالاھىيىتىدە سازلايدۇ + Root سالاھىيىتىدە Android سازلاشنى ئىجرا قىلىشقا يول قويىدۇ + زاپاس تەمىنلىگۈچىنى ئۆزگەرتىدۇ + زاپاس تەمىنلىگۈچى تاللىنىدۇ + ساپ قارا رەڭ + قاراڭغۇ ئۆرنەك ئۈچۈن ساق قارا تەگلىك LineageOS قانۇن ئۇچۇرى + {count, plural, + one {}=1 {سىز ئىجادىيەت تەڭشىكىنى قوزغىتىشقا يەنە # قەدەم قالدىڭىز.} + other {سىز ئىجادىيەت تەڭشىكىنى قوزغىتىشقا يەنە # قەدەم قالدىڭىز.} + } ئىجادكارلار تەڭشەكلىرىنى قوزغاتتىڭىز! ھاجەتسىز، سىز ئاللىبۇرۇن ئىجادكارلار تەڭشەكلىرىنى قوزغاتقان. + ئۇخلىتىشتا چېكىلىدۇ + ئېكراننى تاقاشتا ھالەت بالداق ياكى قۇلۇپ ئېكران قوش چېكىلىدۇ + سەزگۈرلۈكى يۇقىرى ئېكراننىڭ نۇسخا ئېلىش نىسبىتى + سەزگۈر ئېكراننىڭ نۇسخا ئېلىش نىسبىتىنى ئۆرلىتىدۇ + لەيلىمە ئۇقتۇرۇش + كىچىك بىر لەيلىمە كۆزنەكتە ئالدىنلىق ئۇقتۇرۇشىنى كۆرسىتىدۇ سەزگۈر ئېكراننىڭ يۇقىرى سېزىمچانلىقى سەزگۈر ئېكراننىڭ سېزىمچانلىقىنى كۈچەيتىپ پەلەي كىيگەندە ئىشلىتىشكە قولايلىق يارىتىدۇ + خېرىدارنىڭ VPN ئىشلىتىشىگە يول قويىدۇ + قىزىق نۇقتا خېرىدارىنىڭ بۇ ئۈسكۈنىنىڭ VPN نى ئىشلىتىپ يۇقىرى ئېقىمغا باغلىنىشىغا يول قويىدۇ + ئەندىزە چوڭلۇقى تاللىنىدۇ ئەندىزە خاتالىقىنى كۆرسىتىش ئەندىزە نۇقتىسىنى كۆرسىتىش + ئەڭ يۇقىرى يېڭىلاش نىسبىتى + ئەڭ تۆۋەن يېڭىلاش نىسبىتى + تاختا كومپيۇتېرىڭىزنىڭ ئالدى تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + ئۈسكۈنىڭىزنىڭ ئالدى تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + تېلېفونىڭىزنىڭ ئالدى تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + تاختا كومپيۇتېرىڭىزنىڭ كەينى تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + ئۈسكۈنىڭىزنىڭ كەينى تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + تېلېفونىڭىزنىڭ كەينى تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + تاختا كومپيۇتېرىڭىزنىڭ يان تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + ئۈسكۈنىڭىزنىڭ يان تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + تېلېفونىڭىزنىڭ يان تەرىپىدىكى بارماق ئىزى سەزگۈچىنى تېپىڭ. + تاختا كومپيۇتېرىڭىزنىڭ ئالدى تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + ئۈسكۈنىڭىزنىڭ ئالدى تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + تېلېفونىڭىزنىڭ ئالدى تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + تاختا كومپيۇتېرىڭىزنىڭ كەينى تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + ئۈسكۈنىڭىزنىڭ كەينى تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + تېلېفونىڭىزنىڭ كەينى تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + تاختا كومپيۇتېرىڭىزنىڭ يان تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + ئۈسكۈنىڭىزنىڭ يان تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + تېلېفونىڭىزنىڭ يان تەرىپىدىكى سەزگۈچكە تەگكۈزۈڭ. + ئېكران تاقالغان تەقدىردىمۇ، تېگىش سەزگۈچى ئارقىلىق قۇلۇپنى ئاچقىلى بولىدۇ. سەزگۈچكە يېقىنلاشقاندا تاسادىپىي قۇلۇپ ئېچىلىپ كېتىشنىڭ ئالدىنى ئالىدۇ. + يولباشچى ئەسكەرتىشى + ئېكراننىڭ ئاستىدا يولباشچى ئەسكەرتىش بالداقنى كۆرسىتىدۇ + ئۇقتۇرۇش ئاۋازى ئارىسىدىكى ئەڭ قىسقا ۋاقىت + قوڭغۇراق ياكى تىترەشنىڭ ھەر %1$s قېتىمدا بىر قېتىم يۈز بېرىشىگە يول قويىدۇ + ھېچقانداق چەكلىمە يوق + 10 سېكۇنت + 30 سېكۇنت + 1 مىنۇت + 5 مىنۇت + 15 مىنۇت + 30 مىنۇت + بىر كۇنۇپكىدا يورۇقلۇقنى ئۆزلۈكىدىن تەڭشەش + يورۇقلۇق تەڭشەش پەقەت ئېكران ئېچىلغان پەيتتىلا يۈز بېرىدۇ + تور زىيارىتىگە يول قويىدۇ + تور ئىشلىتىشنى قوزغىتىدۇ + كۆچمە سانلىق مەلۇمات + كۆچمە سانلىق مەلۇمات ئىشلىتىشنى قوزغىتىدۇ + VPN سانلىق مەلۇمات + VPN سانلىق مەلۇماتى ئىشلىتىشنى قوزغىتىدۇ + Wi\u2011Fi سانلىق مەلۇماتى + WiFi سانلىق مەلۇماتى ئىشلىتىشنى قوزغىتىدۇ قالايمىقان جايلاشتۇرۇش ئۈسكۈنە قۇلۇپىنى ئاچقاندا قالايمىقان تەرتىپتىكى PIN جايلاشتۇرۇشنى ئىشلىتىدۇ تاسادىپىي ئويغىتىشنىڭ ئالدىنى ئېلىش + ئېكراننىڭ ئويغىتىشتىن ئىلگىرى ئارىلىق سەزگۈچنى تەكشۈرىدۇ + سەزگۈر ئېكران قول ئىشارىتى + تېز مەشغۇلاتنىڭ نۇرغۇن سەزگۈر ئېكران قول ئىشارىتىنى ئىجرا قىلىدۇ لەيلىتىش مەشغۇلاتى بارمىقىڭىزنى ئېكراننىڭ ئۈستىگە لەيلىتىپ توركۆرگۈ، يىراقتىكى ئۈستەلئۈستى قاتارلىقلارنىڭ چاشقىنەك ئىستىرىلكىسى سۈپىتىدە ئىشلىتىشىگە يول قويىدۇ چېتىلغاندا ئويغات توكقا چېتىلغان ياكى ئۈزۈلگەندە ئېكراننى ئاچىدۇ + تېز توكلاش + چەكلەپ ئۈسكۈنىگە توك قاچىلىغاندا قىزىپ كېتىشنى ئازايتىدۇ ياكى توكداننىڭ ئىشلىتىش ئۆمرىنى ئۇزارتىدۇ + بارماق ئىزى سەزگۈچ ئۇزۇن بېسىلسا تېلېفون قۇلۇپى ئېچىلىدۇ + بارماق ئىزى سەزگۈچ ئۇزۇن بېسىلسا تاختا كومپيۇتېر قۇلۇپى ئېچىلىدۇ + بارماق ئىزى سەزگۈچ ئۇزۇن بېسىلسا ئۈسكۈنە قۇلۇپى ئېچىلىدۇ + ئېكراننى ئويغىتىپ قۇلۇپ ئېچىشتا، ئېكران ئاستىدىكى بارماق ئىزى سەزگۈچ ئۇزۇن بېسىلىدۇ. + ئاگاھلاندۇرۇش: بۇ تاللانما ئادەتتىكىدەك ئىشلىمەسلىكى مۇمكىن ياكى سانلىق مەلۇماتنىڭ يوقىلىشىنى كەلتۈرۈپ چىقىرىشى مۇمكىن شۇڭا تەۋسىيە قىلىنمايدۇ! + كۈچەيتىلگەن GPS ئىشلەت + ئىنتېرنېتتىن سۈنئىي ھەمراھ قوشۇمچە سانلىق مەلۇماتىنى چۈشۈرىدۇ، بۇ GPS نىڭ قوزغىلىش ئۈنۈمىنى زور دەرىجىدە ئۆستۈرىدۇ. جىددىي چاقىرىشقا نىسبەتەن ھەمىشە GPS قوشۇمچە ئورۇن بەلگىلە ئىقتىدارىغا يول قويىدۇ. + تېخنىكا + ساغلاملىق + ياخشى + زىيادە قىزىق + توك يوق + توك بېسىمى يۇقىرى + بىلىنمىگەن خاتالىق + سوغۇق + يوچۇن + تېمپېراتۇرا + توك بېسىمى + %1$d mAh + لايىھەلەش ئىقتىدارى + %1$d mAh + ئەڭ چوڭ سىغىمى + %1$d mAh (%2$d%%) diff --git a/src/com/android/settings/accounts/AccountTypePreferenceLoader.java b/src/com/android/settings/accounts/AccountTypePreferenceLoader.java index ff2d59167106b0ac869abaeaf44213bb319919da..ded0f872c1126d39b8b85930351f094cd91ed216 100644 --- a/src/com/android/settings/accounts/AccountTypePreferenceLoader.java +++ b/src/com/android/settings/accounts/AccountTypePreferenceLoader.java @@ -270,7 +270,14 @@ public class AccountTypePreferenceLoader { try { // Allows to launch only authenticator owned activities. ApplicationInfo authenticatorAppInf = pm.getApplicationInfo(authDesc.packageName, 0); - return resolvedAppInfo.uid == authenticatorAppInf.uid; + if (resolvedAppInfo.uid == authenticatorAppInf.uid) { + // Explicitly set the component to be same as authenticator to + // prevent launching arbitrary activities. + intent.setComponent(resolvedActivityInfo.getComponentName()); + return true; + } else { + return false; + } } catch (NameNotFoundException e) { Log.e(TAG, "Intent considered unsafe due to exception.", diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java index 1b9a70f5d465c3126fcbcab9af0b5d91efb1181a..5c6ac49694247864eb50a1e15d9d286554419b37 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java @@ -48,6 +48,8 @@ import com.google.android.setupdesign.span.LinkSpan; import com.google.android.setupdesign.template.RequireScrollMixin; import com.google.android.setupdesign.util.DynamicColorPalette; +import java.util.List; + /** * Abstract base class for the intro onboarding activity for biometric enrollment. */ @@ -238,6 +240,19 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase }); } + @Override + protected void onStart() { + super.onStart(); + + if (!getPackageName().equals(getCallingPackage())) { + for (String key : List.of(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, + MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE, + MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT)) { + getIntent().removeExtra(key); + } + } + } + @Override protected void onResume() { super.onResume(); @@ -465,14 +480,15 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase getIntent().removeExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT); } - protected void removeEnrollNextBiometricIfSkipEnroll(@Nullable Intent data) { + private void removeEnrollNextBiometricIfSkipEnroll(@Nullable Intent data) { if (data != null && data.getBooleanExtra( MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, false)) { removeEnrollNextBiometric(); } } - protected void handleBiometricResultSkipOrFinished(int resultCode, @Nullable Intent data) { + + private void handleBiometricResultSkipOrFinished(int resultCode, @Nullable Intent data) { removeEnrollNextBiometricIfSkipEnroll(data); if (resultCode == RESULT_SKIP) { onEnrollmentSkipped(data); diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java index 197aca03e0bfc925d9bddc135ac4e60f54cc6048..cac13c640839bd49349efa7b677e33662cbcbd40 100644 --- a/src/com/android/settings/biometrics/face/FaceSettings.java +++ b/src/com/android/settings/biometrics/face/FaceSettings.java @@ -73,8 +73,8 @@ public class FaceSettings extends DashboardFragment { private FaceManager mFaceManager; private DevicePolicyManager mDevicePolicyManager; private int mUserId; - private int mSensorId; - private long mChallenge; + private int mSensorId = -1; + private long mChallenge = 0; private byte[] mToken; private FaceSettingsAttentionPreferenceController mAttentionController; private FaceSettingsRemoveButtonPreferenceController mRemoveController; @@ -155,12 +155,19 @@ public class FaceSettings extends DashboardFragment { mUserManager = context.getSystemService(UserManager.class); mFaceManager = context.getSystemService(FaceManager.class); mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class); - mToken = getIntent().getByteArrayExtra(KEY_TOKEN); - mSensorId = getIntent().getIntExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, -1); - mChallenge = getIntent().getLongExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, 0L); - mUserId = getActivity().getIntent().getIntExtra( - Intent.EXTRA_USER_ID, UserHandle.myUserId()); + final SettingsActivity activity = (SettingsActivity) requireActivity(); + final String callingPackage = activity.getInitialCallingPackage(); + if (callingPackage == null || !callingPackage.equals(activity.getPackageName())) { + mUserId = UserHandle.myUserId(); + } else { + // only allow these extras when called internally by Settings + mToken = getIntent().getByteArrayExtra(KEY_TOKEN); + mSensorId = getIntent().getIntExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, -1); + mChallenge = getIntent().getLongExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, 0L); + mUserId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId()); + } + mFaceFeatureProvider = FeatureFactory.getFeatureFactory().getFaceFeatureProvider(); if (mUserManager.getUserInfo(mUserId).isManagedProfile()) { diff --git a/src/com/android/settings/notification/history/NotificationHistoryActivity.java b/src/com/android/settings/notification/history/NotificationHistoryActivity.java index 156df96e04e428b1479ff702e9bac0156266900e..6609d7d583f7ea0d37c289c26b1dde9743c71152 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryActivity.java +++ b/src/com/android/settings/notification/history/NotificationHistoryActivity.java @@ -16,6 +16,7 @@ package com.android.settings.notification.history; +import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS; import static android.provider.Settings.Secure.NOTIFICATION_HISTORY_ENABLED; import static androidx.core.view.accessibility.AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED; @@ -25,9 +26,11 @@ import android.annotation.ColorInt; import android.app.ActionBar; import android.app.ActivityManager; import android.app.INotificationManager; +import android.app.KeyguardManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; +import android.content.pm.UserInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Outline; @@ -58,6 +61,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; +import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.NotificationExpandButton; import com.android.settings.R; import com.android.settings.notification.NotificationBackend; @@ -68,6 +72,7 @@ import com.android.settingslib.widget.MainSwitchBar; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -113,6 +118,8 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity { }; private UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); + private ArrayList mContentRestrictedUsers = new ArrayList<>(); + enum NotificationHistoryEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "User turned on notification history") NOTIFICATION_HISTORY_ON(504), @@ -212,14 +219,14 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity { final NotificationHistoryRecyclerView rv = viewForPackage.findViewById(R.id.notification_list); - rv.setAdapter(new NotificationHistoryAdapter(mNm, rv, + rv.setAdapter(new NotificationHistoryAdapter(NotificationHistoryActivity.this, mNm, rv, newCount -> { count.setText(StringUtil.getIcuPluralsString(this, newCount, R.string.notification_history_count)); if (newCount == 0) { viewForPackage.setVisibility(View.GONE); } - }, mUiEventLogger)); + }, mUiEventLogger, mContentRestrictedUsers)); ((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete( new ArrayList<>(nhp.notifications)); @@ -263,6 +270,19 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity { mPm = getPackageManager(); mUm = getSystemService(UserManager.class); + + List users = mUm.getProfiles(getUserId()); + for (UserInfo user : users) { + if (Settings.Secure.getIntForUser(getContentResolver(), + LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, user.id) == 0) { + LockPatternUtils lpu = new LockPatternUtils(this); + KeyguardManager km = getSystemService(KeyguardManager.class); + if (lpu.isSecure(user.id) && km.isDeviceLocked(user.id)) { + mContentRestrictedUsers.add(user.id); + } + } + } + // wait for history loading and recent/snooze loading mCountdownLatch = new CountDownLatch(2); @@ -406,7 +426,7 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity { mSnoozedRv.setLayoutManager(lm); mSnoozedRv.setAdapter( new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm, mUm, - true, mUiEventLogger)); + true, mUiEventLogger, mContentRestrictedUsers)); mSnoozedRv.setNestedScrollingEnabled(false); if (snoozed == null || snoozed.length == 0) { @@ -422,7 +442,7 @@ public class NotificationHistoryActivity extends CollapsingToolbarBaseActivity { mDismissedRv.setLayoutManager(dismissLm); mDismissedRv.setAdapter( new NotificationSbnAdapter(NotificationHistoryActivity.this, mPm, mUm, - false, mUiEventLogger)); + false, mUiEventLogger, mContentRestrictedUsers)); mDismissedRv.setNestedScrollingEnabled(false); if (dismissed == null || dismissed.length == 0) { diff --git a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java index 96bc14a6fb2e9f6603197077bb350b68903a8e1b..275ff4e2c95260133ef46ae1794750610b1521d9 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java +++ b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java @@ -22,6 +22,7 @@ import static android.provider.Settings.EXTRA_CONVERSATION_ID; import android.app.INotificationManager; import android.app.NotificationHistory.HistoricalNotification; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.RemoteException; @@ -52,16 +53,23 @@ public class NotificationHistoryAdapter extends private List mValues; private OnItemDeletedListener mListener; private UiEventLogger mUiEventLogger; - public NotificationHistoryAdapter(INotificationManager nm, + private ArrayList mContentRestrictedUsers = new ArrayList<>(); + Context mContext; + + public NotificationHistoryAdapter(Context context, + INotificationManager nm, NotificationHistoryRecyclerView listView, OnItemDeletedListener listener, - UiEventLogger uiEventLogger) { + UiEventLogger uiEventLogger, + ArrayList contentRestrictedUsers) { + mContext = context; mValues = new ArrayList<>(); setHasStableIds(true); listView.setOnItemSwipeDeleteListener(this); mNm = nm; mListener = listener; mUiEventLogger = uiEventLogger; + mContentRestrictedUsers = contentRestrictedUsers; } @Override @@ -80,8 +88,13 @@ public class NotificationHistoryAdapter extends public void onBindViewHolder(final @NonNull NotificationHistoryViewHolder holder, int position) { final HistoricalNotification hn = mValues.get(position); - holder.setTitle(hn.getTitle()); - holder.setSummary(hn.getText()); + if (mContentRestrictedUsers.contains(hn.getUserId())) { + holder.setSummary(mContext.getString( + com.android.internal.R.string.notification_hidden_text)); + } else { + holder.setTitle(hn.getTitle()); + holder.setSummary(hn.getText()); + } holder.setPostedTime(hn.getPostedTimeMs()); final View.OnClickListener onClick = v -> { mUiEventLogger.logWithPosition(NotificationHistoryActivity.NotificationHistoryEvent diff --git a/src/com/android/settings/notification/history/NotificationSbnAdapter.java b/src/com/android/settings/notification/history/NotificationSbnAdapter.java index c556b55179eba24ecbfd0dcdd5e93a76b35af9b9..6d4ad8d0d1ab8f8b383f5a1f57bf2ef7eb813667 100644 --- a/src/com/android/settings/notification/history/NotificationSbnAdapter.java +++ b/src/com/android/settings/notification/history/NotificationSbnAdapter.java @@ -74,9 +74,11 @@ public class NotificationSbnAdapter extends private List mEnabledProfiles = new ArrayList<>(); private boolean mIsSnoozed; private UiEventLogger mUiEventLogger; + private ArrayList mContentRestrictedUsers = new ArrayList<>(); public NotificationSbnAdapter(Context context, PackageManager pm, UserManager um, - boolean isSnoozed, UiEventLogger uiEventLogger) { + boolean isSnoozed, UiEventLogger uiEventLogger, + ArrayList contentRestrictedUsers) { mContext = context; mPm = pm; mUserBadgeCache = new HashMap<>(); @@ -97,6 +99,7 @@ public class NotificationSbnAdapter extends // If true, this is the panel for snoozed notifs, otherwise the one for dismissed notifs. mIsSnoozed = isSnoozed; mUiEventLogger = uiEventLogger; + mContentRestrictedUsers = contentRestrictedUsers; } @Override @@ -114,8 +117,13 @@ public class NotificationSbnAdapter extends holder.setIconBackground(loadBackground(sbn)); holder.setIcon(loadIcon(sbn)); holder.setPackageLabel(loadPackageLabel(sbn.getPackageName()).toString()); - holder.setTitle(getTitleString(sbn.getNotification())); - holder.setSummary(getTextString(mContext, sbn.getNotification())); + if (mContentRestrictedUsers.contains(sbn.getNormalizedUserId())) { + holder.setSummary(mContext.getString( + com.android.internal.R.string.notification_hidden_text)); + } else { + holder.setTitle(getTitleString(sbn.getNotification())); + holder.setSummary(getTextString(mContext, sbn.getNotification())); + } holder.setPostedTime(sbn.getPostTime()); holder.setDividerVisible(position < (mValues.size() -1)); int userId = normalizeUserId(sbn); diff --git a/src/com/android/settings/security/CredentialStorage.java b/src/com/android/settings/security/CredentialStorage.java index ea336314566ad2d50f68469a9642c89883c10fbf..57a59cd287fc1482dd7ab4805c2d3971aa5bd1b3 100644 --- a/src/com/android/settings/security/CredentialStorage.java +++ b/src/com/android/settings/security/CredentialStorage.java @@ -17,6 +17,7 @@ package com.android.settings.security; import android.app.Activity; +import android.app.ActivityManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.DialogInterface; @@ -331,15 +332,25 @@ public final class CredentialStorage extends FragmentActivity { } } + private String getCallingPackageName() { + try { + return ActivityManager.getService().getLaunchedFromPackage(getActivityToken()); + } catch (RemoteException re) { + // Error talking to ActivityManager, just give up + return null; + } + } + /** * Check that the caller is either certinstaller or Settings running in a profile of this user. */ private boolean checkCallerIsCertInstallerOrSelfInProfile() { - if (TextUtils.equals("com.android.certinstaller", getCallingPackage())) { + String callingPackage = getCallingPackageName(); + if (TextUtils.equals("com.android.certinstaller", callingPackage)) { // CertInstaller is allowed to install credentials if it has the same signature as // Settings package. return getPackageManager().checkSignatures( - getCallingPackage(), getPackageName()) == PackageManager.SIGNATURE_MATCH; + callingPackage, getPackageName()) == PackageManager.SIGNATURE_MATCH; } final int launchedFromUserId; diff --git a/src/com/android/settings/spa/SpaAppBridgeActivity.kt b/src/com/android/settings/spa/SpaAppBridgeActivity.kt index a68d2204c3b15dfee67076fedf63e916863c39f9..67a5be951fd1b242a8bf6623e9ba844659f25cdc 100644 --- a/src/com/android/settings/spa/SpaAppBridgeActivity.kt +++ b/src/com/android/settings/spa/SpaAppBridgeActivity.kt @@ -38,7 +38,7 @@ class SpaAppBridgeActivity : Activity() { companion object { fun getDestinationForApp(destinationPrefix: String, intent: Intent): String? { - val packageName = intent.data?.schemeSpecificPart ?: return null + val packageName = intent.data?.schemeSpecificPart?.takeIf { Regex("^([a-zA-Z]\\w*\\.)*[a-zA-Z]\\w*$").matches(it) } ?: return null return "$destinationPrefix/$packageName/${UserHandle.myUserId()}" } } diff --git a/src/com/android/settings/users/AppRestrictionsFragment.java b/src/com/android/settings/users/AppRestrictionsFragment.java index c42e2f57b1dfcf9b085d1bf2dcf2c1a1e486fa5e..5b2a86fff421ce7366afeb7356c5cdaa4db8a3cb 100644 --- a/src/com/android/settings/users/AppRestrictionsFragment.java +++ b/src/com/android/settings/users/AppRestrictionsFragment.java @@ -639,8 +639,11 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen } else if (restrictionsIntent != null) { preference.setRestrictions(restrictions); if (invokeIfCustom && AppRestrictionsFragment.this.isResumed()) { + // We don't necessarily trust the given intent to launch its component. + // We will first check it, and only use parts of it that were indeed checked. + final Intent vettedIntent; try { - assertSafeToStartCustomActivity(restrictionsIntent); + vettedIntent = assertSafeToStartCustomActivity(restrictionsIntent); } catch (ActivityNotFoundException | SecurityException e) { // return without startActivity Log.e(TAG, "Cannot start restrictionsIntent " + e); @@ -651,15 +654,20 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen int requestCode = generateCustomActivityRequestCode( RestrictionsResultReceiver.this.preference); AppRestrictionsFragment.this.startActivityForResult( - new Intent(restrictionsIntent), requestCode); + vettedIntent, requestCode); } } } - private void assertSafeToStartCustomActivity(Intent intent) { + /** + * Checks that it is safe to start the custom activity, and, if so, returns a copy of the + * Intent using its vetted components. + */ + private Intent assertSafeToStartCustomActivity(Intent intent) { EventLog.writeEvent(0x534e4554, "223578534", -1 /* UID */, ""); + final Intent vettedIntent = new Intent(intent); ResolveInfo resolveInfo = mPackageManager.resolveActivity( - intent, PackageManager.MATCH_DEFAULT_ONLY); + vettedIntent, PackageManager.MATCH_DEFAULT_ONLY); if (resolveInfo == null) { throw new ActivityNotFoundException("No result for resolving " + intent); @@ -670,6 +678,12 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen throw new SecurityException("Application " + packageName + " is not allowed to start activity " + intent); } + + // We were able to vet the given intent this time. Make a copy using the components + // that were used to do the vetting, since that's as much as we've verified is safe. + vettedIntent.setComponent(activityInfo.getComponentName()); + vettedIntent.setPackage(activityInfo.packageName); + return vettedIntent; } }