נפח האחסון הייעודי לאפליקציות מגביל את הגישה של האפליקציה לאחסון חיצוני. ב-Android 11 ואילך, אפליקציות שמטרגטות API 30 ואילך חייבות להשתמש באחסון מוגבל. בעבר, ב-Android 10, אפליקציות יכלו להפסיק להשתמש בנפח אחסון בהיקף מסוים.
הגבלות גישה לאפליקציות
המטרה של נפח אחסון בהיקף היא להגן על הפרטיות של נתוני האפליקציות והמשתמשים. ההגנה הזו כוללת הגנה על פרטי המשתמשים (כמו המטא-נתונים של התמונות), מניעת שינוי או מחיקה של קבצים של משתמשים באפליקציות ללא הרשאה מפורשת, והגנה על מסמכים רגישים של משתמשים שהורדתם לתיקיית 'הורדות' או לתיקיות אחרות.
לאפליקציות שמשתמשות באחסון מוגבל יכולות להיות רמות הגישה הבאות (רמת הגישה בפועל תלויה בהטמעה).
- גישת קריאה וכתיבה לקבצים שלהם ללא הרשאות
- גישת קריאה לקובצי מדיה של אפליקציות אחרות עם הרשאת
READ_EXTERNAL_STORAGE
- גישת כתיבה לקובצי מדיה של אפליקציות אחרות מותרת רק בהסכמה ישירה של המשתמש (יש יוצאים מן הכלל לגלריה של המערכת ולאפליקציות שעומדות בדרישות לגישה לכל הקבצים)
- אין גישה לקריאה או לכתיבה בספריות של נתוני אפליקציות חיצוניות של אפליקציות אחרות
שימוש בנפח אחסון בהיקף עם FUSE
ב-Android 11 ואילך יש תמיכה ב-Filesystem in Userspace (FUSE), שמאפשרת למודול MediaProvider לבדוק פעולות הקשורות לקבצים במרחב המשתמש ולסנן את הגישה לקבצים על סמך המדיניות כדי לאפשר, לדחות או לצנזר את הגישה. אפליקציות באחסון מוגבל שמשתמשות ב-FUSE מקבלות את מאפייני הפרטיות של האחסון המוגבל ואת היכולת לגשת לקבצים באמצעות נתיב קובץ ישיר (כך שאפשר להמשיך להשתמש בממשקי ה-API של קבצים באפליקציות).
מערכת Android 10 אכפה כללי אחסון היקפיים על גישה לקבצים על ידי MediaProvider, אבל לא על גישה ישירה לנתיב הקובץ (למשל, באמצעות File API ו-NDK APIs), בגלל המאמץ שנדרש ליירט קריאות ליבה (kernel). כתוצאה מכך, לאפליקציות באחסון מוגבל לא הייתה גישה לקבצים באמצעות נתיב קובץ ישיר. ההגבלה הזו השפיעה על היכולת של מפתחי האפליקציות להתאים את עצמם, כי נדרשו שינויים משמעותיים בקוד כדי לכתוב מחדש את הגישה של File API ל-MediaProvider API.
FUSE ו-SDCardFS
התמיכה ב-FUSE ב-Android 11 לא קשורה להוצאה משימוש של SDCardFS, אבל היא מספקת חלופה ל-Media Store במכשירים שבהם השתמשו בעבר ב-SDCardFS. מכשירים:
- לא ניתן להשתמש ב-SDCardFS כשמריצים את האפליקציה ב-Android בגרסה 11 ואילך עם ליבה בגרסה 5.4 ואילך.
- שדרוג ל-Android 11 ואילך יכול לארח את FUSE מעל SDCardFS כדי ליירט את פעולות הקובץ ולעמוד ביעדים של הפרטיות.
כוונון הביצועים של FUSE
בעבר, Android תמך ב-FUSE בגרסה 7 ואילך, שבה אחסון חיצוני הוצמד כ-FUSE. בגלל בעיות בביצועים ובלודק (deadlock) בהטמעת FUSE הזו, ב-Android 8 הושק SDCardFS. ב-Android 11 הוחזרה התמיכה ב-FUSE באמצעות הטמעה משופרת ומאומתת יותר של libfuse
, שאפשר לשנות כדי לפתור את בעיות הביצועים ב-Android 7 ואילך.
התאמת FUSE כוללת את השינויים הבאים:
- עקיפת FUSE בתיקיות
Android/data
ו-Android/obb
כדי לשפר את הביצועים של אפליקציות משחקים שמסתמכות על התיקיות האלה. - אופטימיזציות (כמו שינוי היחסים של קריאה מראש ושל קבצים מלוכלכים במערכת הקבצים של FUSE) כדי לשמור על ביצועי קריאה טובים ועל הפעלה חלקה של מדיה.
- שימוש במטמון השליחה החוזרת של FUSE.
- שמירת הרשאות במטמון כדי לצמצם את מספר הבקשות ל-IPC לשרת המערכת.
- אופטימיזציה של אפליקציות עם גישה לכל הקבצים מאפשרת לבצע פעולות בכמות גדולה מהר יותר.
שינויי ההתאמה שלמעלה יכולים להניב ביצועים דומים בין מכשירי FUSE למכשירים ללא FUSE. לדוגמה, בבדיקה של Pixel 2 מותאם באמצעות FUSE ו-Pixel 2 באמצעות Media Store, נמצאו ביצועי קריאה רצופים דומים (לדוגמה, הפעלת וידאו) בין הגישה לנתיב הקובץ לבין Media Store. עם זאת, פעולות כתיבה רצופות היו איטיות יותר ב-FUSE, ופעולות קריאה וכתיבה אקראיות היו איטיות פי שניים.
מדידות הביצועים עשויות להשתנות ממכשיר למכשיר ובין תרחישים לדוגמה ספציפיים. מאחר שממשקי ה-API של MediaProvider מספקים את הביצועים העקביים ביותר, מפתחי אפליקציות שחשוב להם הביצועים צריכים להשתמש בממשקי ה-API של MediaProvider באפליקציות שלהם.
הפחתת ההשפעה על ביצועי FUSE
ההשפעה של FUSE על הביצועים מוגבלת למשתמשים כבדים של קבצים שמאוחסנים באחסון המשותף החיצוני בלבד. מערכת FUSE עוקפת אחסון פרטי חיצוני (שכולל ספריות android/data
ו-android/obb
), ואחסון פנימי (כמו /data/data
, שבו הרבה אפליקציות מאחסנות נתונים כדי לשמור על ההצפנה והאבטחה שלהן) לא טעון.
אפליקציות שמשתמשות מעט באחסון חיצוני משותף בדרך כלל יוצרות אינטראקציה עם קבוצה מוגבלת של קבצים (בדרך כלל פחות מ-100 קבצים). האפליקציות האלה מפיקות תועלת מאופטימיזציות קיימות של פעולות קריאה וכתיבה נפוצות, ולא אמורה להיות להן השפעה על הביצועים שקשורה ל-FUSE ב-Android 11.
אפליקציות שמשתמשות הרבה באחסון חיצוני משותף מבצעות בדרך כלל פעולות בכמות גדולה בקבצים, כמו הצגת רשימה או הסרה של ספרייה עם 1, 000 קבצים או יצירה או מחיקה של ספרייה עם מיליון קבצים במערכת הקבצים. יכול להיות שפעולות קבצים בכמות גדולה יושפעו מ-FUSE ב-Android 11, אבל אם אפליקציות כאלה עומדות בדרישות לקבלת ההרשאה
MANAGE_EXTERNAL_STORAGE
, הן ייהנו מהאופטימיזציות של הביצועים שכלולות בעדכון מאוקטובר 2020.
כדי להימנע מעומסי עיבוד מיותרים של FUSE, אפליקציות יכולות לאחסן נתונים באחסון פרטי חיצוני או להשתמש בממשקי API בכמות גדולה בכיתה ContentProvider
כדי לעקוף את FUSE ולקבל נתיב עם אופטימיזציה לביצועים. בנוסף, העדכון של רכיב המערכת MediaProvider באוקטובר 2020 כולל אופטימיזציה של הביצועים למנהלי קבצים ולאפליקציות דומות (כמו גיבוי/שחזור, אנטי-וירוס) שיש להן את ההרשאה MANAGE_EXTERNAL_STORAGE
.
פרטיות לעומת ביצועים
במכשירים שהותאמו ל-FUSE, הביצועים של רוב תהליכי השימוש החיוניים זהים ב-Android 10 וב-Android 11. עם זאת, כשבודקים את מדדי הביצועים על קבוצה של פעולות קובץ, יכול להיות שב-Android 11 הביצועים יהיו נמוכים יותר מאשר ב-Android 10. לגבי דפוסי גישה לקבצים שמניבים ביצועים פחות טובים ב-Android 11 (למשל, קריאה או כתיבה אקראית), אנחנו ממליצים להשתמש בממשקי MediaProvider API כדי לתת לאפליקציות מצב גישה ללא-FUSE, שהוא האפשרות הטובה ביותר שמניבה ביצועים עקביים.
עדכוני MediaProvider ו-FUSE
התנהגות רכיב המערכת MediaProvider משתנה בין גרסאות Android.
ב-Android מגרסה 10 ומטה, SDCardFS היה מערכת הקבצים ו-MediaProvider סיפק ממשק לאוספים של קבצים (לדוגמה, תמונות, סרטונים, קובצי מוזיקה וכו'). כשאפליקציה יצרה קובץ באמצעות File API, היא יכולה לבקש מ-MediaProvider לסרוק את הקובץ ולתעד אותו במסד הנתונים.
ב-Android מגרסה 11 ואילך, ה-API SDCardFS הוצא משימוש, ו-MediaProvider הופך למטפל של מערכת הקבצים (ל-FUSE) באחסון החיצוני, כך שמערכת הקבצים באחסון החיצוני ומסד הנתונים של MediaProvider יהיו עקביים. כמנהל מרחב המשתמש של מערכת הקבצים FUSE, MediaProvider יכול ליירט קריאות לליבת המערכת ולוודא שפעולות הקבצים לא פוגעות בפרטיות.
ב-Android מגרסה 11 ואילך, MediaProvider הוא גם רכיב מערכת מודולרי (מודול ראשי) שאפשר לעדכן מחוץ לגרסאות של Android. כלומר, אפשר לתקן בעיות שקשורות לביצועים, לפרטיות או לאבטחה ב-MediaProvider ולשלוח אותן אונליין מחנות Google Play או ממנגנונים אחרים שסופקו על ידי שותפים. אפשר גם לעדכן כל דבר שנכלל בהיקף של מה שמצופה ממנג'ר FUSE, וכך לתקן באגים ונסיגות בביצועים של FUSE.