"עובד כמתוכנן"

ידוע כי תכונת הנגישות של אנדרואיד גורמת לפיגור של ממשק המשתמש. האם זה באג, או שזו תכונה? למה זה מתרחש? אנו ב-XDA חוקרים את הסיבה השורשית.

היופי של אנדרואיד טמון בדרכים השונות בהן יישומי צד שלישי יכולים לתקשר עם המערכת. אפליקציות למנהל סיסמאות כגון מעבר אחרון לספק את היכולת להזין באופן אוטומטי נתוני שם משתמש/סיסמה רלוונטיים כמעט לכל מסך התחברות. עוזר טקסט מאפשר לך לקצר משמעותית את הזמן שלך לשלוח הודעות טקסט לחברים שלך על ידי כך שאתה מאפשר לך ליצור פקודות מאקרו של הרחבת טקסט. לוח מקורי מקטין את הטרחה הכרוכה במעבר תכוף בין אפליקציות להעתקת כמויות גדולות של טקסט על ידי כך שהוא מאפשר לך להקיש פעמיים על כל שדה קלט כדי להעלות לוח. מי יכול לשכוח Greenify, אולי האפליקציה מספר 1 המומלצת ביותר על ידי חובבים, ששומרת על אפליקציות רקע נוכלות ובכך יכולה לשפר את חיי הסוללה? לבסוף, אם כי פחות מכיר את רוב המשתמשים, יש קלט אוטומטי - תוסף Tasker שנועד להפוך את הקשות המסך לאוטומטיות, הזנת טקסט, מחוות החלקה ועוד הרבה יותר. אפליקציות אלו משרתות כולן מקרי שימוש שונים בתכלית, אך כל אחת מהאפליקציות הללו מסתמכת על חלק מאוד לא מובן בפונקציונליות הליבה של אנדרואיד: נְגִישׁוּת.

למשתמש אנדרואיד ממוצע, זה עשוי להיראות מוזר שרבות מהתכונות המדהימות הללו המשמשות את האפליקציה האהובה עליך נשלטות על ידי הגדרה תחת נְגִישׁוּת תפריט משנה. יצירת אפליקציה נגיש בדרך כלל אמור להיות אפליקציית אנדרואיד שמישה לאדם עם מוגבלויות. אז למה בכלל ל-LastPass, Native Clipboard, Text Aide, Greenify או AutoInput יש נְגִישׁוּת שֵׁרוּת? יתר על כן, מדוע נראה הפעלת שירות נגישות לגרום לכל כך הרבה פיגור בממשק המשתמש? נראה שזה לא משנה באיזו גרסה של אנדרואיד אתה נמצא - בין אם זה יהיה אנדרואיד 5.0 Lollipop אוֹ אנדרואיד 7.0 נוגט - מכיוון שהפיגור שנגרם על ידי שירותי נגישות מסוימים יכול להשפיע על החוויה שלך. פתרון פשוט לבעיה זו הוא פשוט להשבית את שירותי הנגישות שאולי הפעלתם - אך בכך אנו מאבדים כל כך הרבה פונקציונליות שימושית. פתרון נוסף הוא להגיש עתירה לגוגל כדי "לתקן" את פיגור הנגישות של אנדרואיד, אך גוגל טוענת שנגישות אנדרואיד כן עובד כמתוכנן. דיברנו עם כמה מפתחים שמכירים מקרוב את שירותי הנגישות וחקרנו איך הפונקציונליות עובדת, ואנחנו כאן כדי לבדוק את הטענה הזו: האם פיגור הנגישות של אנדרואיד הוא באג או שזו תכונה?


הבנת נגישות אנדרואיד

כפי שאתה יכול לדמיין לפי השם, נגישות מיועדת בעיקר למפתחים כדי לספק פונקציונליות נוספת לכל משתמש עם מוגבלות. אכן, הצצה מהירה על דפי תיעוד רשמיים עבור נגישות מגלה שלגוגל יש דעה די צרה לגבי סוגי השירותים ששירותי הנגישות צריכים לספק.

למשתמשי אנדרואיד רבים יש יכולות שונות שדורשות מהם ליצור אינטראקציה עם מכשירי האנדרואיד שלהם בדרכים שונות. אלה כוללים משתמשים שיש להם מגבלות חזותיות, פיזיות או הקשורות לגיל המונעות מהם לראות באופן מלא או באמצעות מסך מגע, ומשתמשים עם אובדן שמיעה שאולי לא יוכלו לקלוט מידע קולי והתראות.

אנדרואיד מספקת תכונות ושירותי נגישות כדי לעזור למשתמשים אלו לנווט יותר במכשירים שלהם בקלות, כולל טקסט לדיבור, משוב הפטי, ניווט מחוות, כדור עקיבה ומשטח כיוון ניווט.

של גוגל TalkBack, שמגיע מותקן מראש בכל טלפון אנדרואיד, הוא דוגמה מצוינת למה ששירות הנגישות ה'טיפוסי' אמור להיות. גישה קולית לוקח את הנגישות צעד קדימה ומאפשר שליטה כמעט מלאה בטלפון שלך באמצעות הקול שלך בלבד. אבל העובדה שגוגל התכוונה להשתמש בשירותי נגישות באופן זה אינה מונעת מפתחים מליישם אותם בכל דרך שהם רוצים - וזה בדיוק מה שיש למפתחים בוצע. זה בדיוק בגלל אופן הפעולה של Accessibility שעושה את התכונה שימושי להפליא למשתמשים עם או בלי מוגבלויות.

כדי לפשט קצת את הדברים, הנה סקירה בסיסית של אופן הפעולה של הנגישות של אנדרואיד. מפתח יוצר שירות נגישות שמנוי על שונים אירועי נגישות הנשלחים על ידי המערכת לשירות בהתאם לעמידה בקריטריונים מסוימים או לא. כאשר כל השירותים מושבתים תחת הגדרות --> נגישות, אנדרואיד לא אוספת או שולחת אירועי נגישות. אבל כשהמשתמש יתחיל להפעיל את שירותי הנגישות, אנדרואיד יתחיל לנטר ולאסוף רק אותם אירועי נגישות ששירות הנגישות מבקש. לדוגמה, שירות נגישות המנוי על אירוע הנגישות TYPE_WINDOW_CONTENT_CHANGED יקבל הודעה על ידי המערכת כל פעם מחדש שמתרחש שינוי בחלון הנוכחי. אירוע נגישות נוסף נקרא TYPE_VIEW_CLICKED יורה כל פעם מחדש המשתמש לוחץ על כפתור כלשהו.

הדגמת נגישות אנדרואיד. בסרטון זה, הפעלתי את האפליקציה טאסקר לפקח על שינויים בכותרת החלון. זה מחייב הפעלת שירות הנגישות של Tasker. אתה יכול לשכפל זאת על ידי יצירת פרופיל חדש ב-Tasker עם ההקשר של 'אירוע' מוגדר ל-'Variable Set' ובחירה ב-%WIN כמשתנה למעקב. בסך הכל, הסרטון הזה של כדקה אחד צולם 107 שינויים בחלון הנוכחי.

אירועי נגישות מסוג זה מתרחשים בתדירות רבה במהלך אינטראקציה רגילה של המשתמש. אז תארו לעצמכם מה קורה כאשר משתמש מאפשר שירותי נגישות מרובים המבקשים לבטל אירועי נגישות בתדירות גבוהה. זה נכון - לְפַגֵר. כדי למתן את זה, מפתחים יכולים להגדיר בצורה מצומצמת יותר אילו סוגי אירועי נגישות שלהם השירות צריך להגיב ובאיזה הקשר, כגון היכולת להגביל את השירות להגיב בלבד כאשר בפנים אפליקציות מסוימות או להגביל את תקופת הסקרים בין אירועים. אבל חוץ מזה כמות התקורה שנוצרת על ידי שירות נגישות תלויה בעיקר אילו סוגי אירועי נגישות הוא נרשם אליו. למעשה, לא כל שירות נגישות יגרום לפיגור. שירות נגישות יחיד הדורש אירוע בתדירות גבוהה עלול לגרום לפיגור, במיוחד אם השירות האמור משולב עם שירות אחר שדורש אירוע נוסף בתדירות גבוהה מפוקח.


צולל עמוק לתוך הנגישות עם APK Teardowns

כפי שניתן היה להבין מהסרטון שפורסם למעלה, שירות נגישות שעוקב אחר שינויים בתוכן החלון יכול לעשות זאת לגרום לשינויים בולטים למדי בביצועי ממשק המשתמש עקב הכמות העצומה של אירועי נגישות שנתפסו על ידי מערכת. עם זאת, די קשה לקבוע בדיוק כמה תקורה נגרמת על ידי שירות נגישות מסוים. ניטור LogCat בדרך כלל לא יביא אותך לשום מקום, שכן אירועי נגישות מודפסים ל-LogCat רק אם מפתח שירות הנגישות בוחר לעשות זאת. למרבה המזל, האבא של כל שירותי הנגישות של אנדרואיד, קלט אוטומטי, עושה בדיוק את זה. והפלט של LogCat מבולגן בדיוק כפי שהיית מדמיין.

AutoInput לא מסתיר מאיתנו את האמת. התקורה הנגרמת על ידי האפליקציה יכולה להיות די עצומה בהתאם לאירועים שאתה מנטר. אבל התקורה הזו נחוצה כדי שהאפליקציה תפעל. כדי ש-AutoInput יירט כל לחיצה על מקש, כל תנועת מסך, כל עדכון ממשק משתמש וכל לחיצה על כפתור, צרכי כדי לפקח על אירועי הנגישות המתאימים. ללא אירועים אלה, AutoInput לא יכול להתחבר למערכת ולספק את האוטומציה הכמעט בלתי מוגבלת של ממשק המשתמש שהיא מאפשרת כעת. לפיכך, כל הפונקציות של AutoInput הגיוניות לחלוטין בהקשר של נגישות. אבל עבור אפליקציות אחרות, עלינו להסתכל קצת יותר לעומק כדי להבין כיצד מטופלים בשירותי הנגישות שלהם.

שירות נגישות תכונות מוגדרים ב-an קובץ משאבי XML בתוך ה-APK. לכן, אנו יכולים לבצע א פירוק APK באפליקציה עם שירות נגישות כדי להבין את תכונות השירות. כל אפליקציה מתפקדת אחרת, אז אנסה להסביר כיצד תכונות השירות שלה קשורות לפונקציה הספציפית שהיא מבצעת.

לוח מקורי

Native Clipboard הוא הבחירה שלי בכל הנוגע למנהלי לוח. אם אתם מחפשים מנהל לוח הניתן להתאמה אישית, Native Clipboard היא אפליקציה די נהדרת. יש לו אפילו רכיב Xposed Module המאפשר לך ללחוץ לחיצה ארוכה על כפתור 'הדבק' כדי להעלות את מנהל הלוח! למרבה הצער, אם אין לך גישה ל-Xposed Framework (כגון לכל משתמש בנוגט), תצטרך להסתפק להפעלת שירות הנגישות שיאפשר לך להקיש פעמיים על כל קלט טקסט כדי להעלות את הלוח מנהל. הנה מה שזה כרוך.


"@string/access_decs"
android: accessibilityEventTypes="typeViewClicked|typeViewFocused|typeViewLongClicked|typeWindowStateChanged"
android: accessibilityFeedbackType="feedbackGeneric"
android: notificationTimeout="100"
android: accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows"
android: canRetrieveWindowContent="true"
xmlns: andro />

שירות הנגישות של Native Clipboard מבקש לפטר אירוע נגישות בכל פעם שלוחצים על תצוגה, לוחצים לחיצה ארוכה, ממוקדים או אם יש שינוי במצב החלון. בלי שיש לי גישה לקוד המקור, אני לא יכול להגיד בדיוק איך Native Clipboard עובד, אבל סביר להניח ש Native Clipboard ממתין שמצב החלון יציין שהמקלדת הרכה פתוחה כעת, ואז היא עוקבת אחר הקשות על הקלט שדה. לאפליקציה יש תקופת סקרים של 100 אלפיות השנייה, כך שהיא בהחלט מהירה מספיק כדי להגיב באופן מיידי לשינויים בנראות המקלדת הרכה וגם ללחיצות כפולות. זה עלול לגרום לתקורה מסוימת של ממשק המשתמש בכל פעם שהמשתמש משתמש במקלדת הרכה כדי להקליד כל טקסט, מה שעלול לגרום לפיגור.

Greenify

הבא הוא חיסכון הסוללה המועדף על כולם, Greenify. Greenify משתמשת באירועי נגישות כדי להפעיל את הפונקציות הלא-שורש שלה.


"@string/accessibility_service_description"
android: settingsActivity="com.oasisfeng.greenify.accessibility.AccessibilitySettings"
android: accessibilityEventTypes="typeAnnouncement|typeNotificationStateChanged|typeWindowStateChanged"
android: accessibilityFeedbackType="feedbackGeneric" android: notificationTimeout="0"
android: accessibilityFlags="flagReportViewIds"
android: canRetrieveWindowContent="true"
xmlns: andro />

הוא משתמש בשינויים במצב החלון כדי לקבוע מתי מסך הטלפון נכבה, והוא מחייב לעכב את הפעלת מסך הנעילה על ידי שינוי אפשרות בהגדרות האבטחה. Greenify תקבל גם אירועים מסוג 'הודעה' או 'מצב התראה' השתנה, האחרון מיותר במכשירי אנדרואיד 5.0+ הודות לתכונת הגישה להודעות. עם זאת, היא עדיין תקבל את האירועים הללו ללא קשר לעובדה זו. Greenify לא אמורה לגרום לתקורה רבה בעצמה, אבל האפשרות נותרה בעינה.

נובה לאנצ'ר

כנראה אפליקציית המשגר ​​של צד שלישי הפופולרית ביותר בשוק, Nova Launcher היא דוגמה מצוינת לאפליקציה המשתמשת בשירות נגישות עם תקורה מינימלית עד ללא תקורה. הסיבה היחידה לקיומו של השירות היא לסייע למכשירים מסוימים בביצוע מחוות.


"@string/accessibility_service_description"
android: accessibilityEventTypes=""
android: packageNames="com.teslacoilsw.launcher"
android: accessibilityFeedbackType=""
android: notificationTimeout="10000"
android: canRetrieveWindowContent="false"
xmlns: andro />

כפי שאתה יכול לראות, לא מוגדר אירוע נגישות בקובץ ה-XML. כל מה שמוזכר הוא שם חבילה - Nova Launcher. מה שקורה כאן הוא מעקף למכשירים מסוימים שעבורם המחוות של Nova Launcher לא עובדות. שירות זה יספק ל-Nova Launcher את כל אירועי הנגישות שבוצעו מהם רק בתוך Nova Launcher. זה נשמע מוזר, אבל זו כנראה דרך לתקן את מחוות מסך הבית של נובה אם המכשיר שלך לא עובד איתן. מכיוון שזה רק מבקש אירועים מנובה עצמה, השירות מהווה מעט מאוד תקורה.

מעבר אחרון

לבסוף, אולי שירות הנגישות הידוע לשמצה ביותר שגורם לפיגור (כנראה בשל הפופולריות העצומה שלו) - LastPass. סוגיית הפיגור בתוך LastPass היא כל כך בולט שלחברה יש פקיד דף שאלות נפוצות המתאר את הבעיה. כפי שצוין בשאלות הנפוצות, אין שום דבר שאתה יכול לעשות בנוגע לפיגור מלבד להשבית את השירות. מדוע השירות של LastPass נראה כה מופרך כשמדובר בפיגור? בואו נסתכל על תכונות השירות.


"@string/accessibility_service_description"
android: accessibilityEventTypes="typeViewFocused|typeWindowContentChanged"
android: accessibilityFeedbackType="feedbackGeneric"
android: notificationTimeout="200"
android: accessibilityFlags="flagReportViewIds"
android: canRetrieveWindowContent="true"
android: canRequestEnhancedWebAccessibility="true"
xmlns: andro />

האמת היא שאין שום דבר יוצא דופן בשירות של LastPass. הוא מבקש רק שני סוגי אירועים לנטר - TYPE_VIEW_FOCUSED ו-TYPE_WINDOW_CONTENT_CHANGED. הוא עושה זאת מכיוון שהוא צריך לדעת מתי התוכן של אפליקציה/דף אינטרנט השתנה/נכנס לפוקוס, ואז הוא מאחזר את תוכן החלון הנוכחי כדי לחפש שדות להזנת סיסמה. אבל מכיוון שהשירות עושה זאת כל הזמן בשני אירועי נגישות הנפתחים בתדירות גבוהה במיוחד, זה גורם לפיגור. זו האמת המצערת.


לחיות עם הלג

כשקראנו לראשונה שגוגל סוגרת דיווחי באגים על השהיית נגישות מכיוון שהתכונה "עבדה כמתוכנן", היינו מבולבלים ונסערים בדיוק כמו רבים מכם. אבל במקום לקבל את ההסבר כראוי, החלטנו לבדוק את העניין בעצמנו כדי לקבוע את האמת. אז כשהגוגלר בדף דיווח הבאגים אמר את זה:

שלום, בעיה זו מתמשכת על מהדורות אנדרואיד, כמו כן תמיד יהיה פיגור נוסף כאשר שירות נגישות מופעל. הסיבה לכך היא שהמכשיר, בנוסף לממשק המשתמש הסטנדרטי, מספק מידע רב לשירותי נגישות כדי שיוכלו לספק חווית משתמש חלופית לאותם משתמשים.

הגענו להבנה למה זה התנהגות מכוונת. אפליקציות שמשתמשות בשירותי נגישות באופן שלא התכוונה על ידי Google תמיד יגרמו לתקורת ביצועים מסוימת; העלות הזו פשוט הכרחית כדי לספק לשירותים את שפע המידע שנגישות אנדרואיד מופעלת ברקע. הפיגור של אנדרואיד עם שירותי נגישות הוא לא באג, אלא תכונה. תכונה שנצטרך לחיות איתה אלא אם המערכת כולה תעובד מחדש, ואני לא יכול לדמיין איך זה ייעשה כדי להכיל כל כך הרבה תכונות שונות מכל כך הרבה אפליקציות שונות.

לכל הפחות, מפתחי LastPass לא היו מוכנים לקבל את הישיבה הזו. המפתחים שלהם עבדו עם מפתחי Chromium כדי לייעל את תמיכת הנגישות, אולי על ידי הפעלת תמיכת LastPass באמצעות שימוש בממשקי API במקום לאפשר שירות נגישות. אופטימיזציה סביב התקורה שנגרמה לשירותי נגישות היא אפשרות אחת, אך כפי שמפתחים רבים ציינו במרומז על בפורומים של Chromium, זה פשוט פלסטר שלא יפתור את העובדה ששימוש לא מכוון בשירותי נגישות עלול לגרום לְפַגֵר.


תודה מיוחדת למפתח של AutoInput, joaomgcd, על המענה על רבות מהשאלות שלי בנוגע לנגישות!