מודול MediaProvider

מודול MediaProvider מבצע אופטימיזציה של מטא-נתונים שעברו אינדוקס (אודיו, וידאו ותמונות מכרטיסי SD וממכשירי USB) ומאפשר לאפליקציות לגשת לנתונים האלה באמצעות ממשקי API ציבוריים של MediaStore. כדי לשמור על פרטיות המשתמשים, מודול MediaProvider אוכף את מודל האבטחה של אחסון בהיקף מוגבל שהוצג ב-Android 10, שכולל צנזורה של מטא-נתונים רגישים של מיקום. אפשר לעדכן את המודול הזה, וכך מערכת Android יכולה להגיב מהר יותר לבעיות אבטחה (ולשמור על נתוני משתמשים רגישים) ולהוסיף פורמטים חדשים של מדיה מהר יותר (ולספק עקביות למשתמשים ולמפתחים).

שינויים ב-Android 10

ב-Android 10 הוספנו כמה שיפורים שקשורים לזיהוי ולחילוץ של נתונים מקובצי מדיה, במיוחד:

  • קביעת סוג התוכן של הקובץ באמצעות החלק הראשון של סוג ה-MIME של הקובץ. לדוגמה, מערכת ההפעלה יודעת שגם image/png וגם image/x-newly-invented-format הם תמונות, ולכן היא יכולה לתאר בצורה מדויקת את ההרשאות הרלוונטיות למשתמש הקצה.

  • קביעת סוג ה-MIME באמצעות סיומת הקובץ בלבד (ובלי להשתמש בזיהוי תוכן כדי למנוע בעיות אבטחה).

  • קביעת סוג ה-MIME של קובץ שרירותי באמצעות שילוב של מיפויים של Debian Linux ו-Android במעלה הזרם.

  • החזרת נתונים רלוונטיים מקובצי video/* ו-audio/* (דרך MediaMetadataRetriever) ומקובצי image/* (דרך ExifInterface).

שינויים ב-Android 11

ב-Android 11, מודול MediaProvider מבוסס על השינויים שבוצעו ב-Android 10, עם השיפורים הבאים:

  • שיפורים בהוספה לאינדקס. מודול MediaProvider מבצע עכשיו אינדוקס של מטא-נתונים על ידי השוואה בין המטא-נתונים הזמינים לבין ממשקי ה-API הציבוריים של MediaStore. השינויים כוללים:

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

    • אינדוקס של מטא-נתונים של מרחב צבעים.

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

    • ממשקי API חדשים שמאפשרים לבצע שינויים בכמה פריטים בבת אחת באמצעות הנחיה אחת בתיבת דו-שיח למשתמש, כולל createDeleteRequest(),‏ createFavoriteRequest(),‏ createTrashRequest() ו-createWriteRequest().

    • עמודות חדשות GENERATION_ADDED ו-GENERATION_MODIFIED לשימוש בזיהוי מהיר ואמין של שינויים שחלו מאז נקודת סנכרון קודמת.

    • GROUP BY API ציבורי חדש לשימוש בעמודות נוספות של מטא-נתונים שלא צוינו למעלה.

  • שיפור ב-ExifInterface לחילוץ מטא-נתונים ממסמכי PNG ו-WebP.

  • שיפורים ב-SystemUI כדי לכתוב מטא-נתונים של DateTimeOriginal בצילומי מסך.

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

גבולות המודול

ב-Android 11, כל הקוד ב-packages/providers/MediaProvider מועבר למיקום חדש, למעט לוגיקה שקשורה ל-MTP. בנוסף, הערך של frameworks/base/core/java/android/provider/MediaStore.java הוא עכשיו inside הגבול של המודול ב-packages/providers/MediaProvider.

פורמט החבילה

המודול MediaProvider הוא בפורמט APK-in-APEX.

תלויות

תלויות ב-MediaProvider קשורות להתאמות אישיות (כלומר, אם מבצעים התאמה אישית של MediaProvider, צריך לוודא שההטמעה עומדת בתלות שמשויכת להתאמה האישית).

  • כשמשתמשים בפורמטים מותאמים אישית או לא סטנדרטיים של קובצי מדיה (לדוגמה, פורמט שנוצר על ידי אפליקציית מצלמה ספציפית לספק), צריך לרשום כל פורמט מותאם אישית ב-MimeUtils ובמודול Media Extractor כדי לאפשר יצירת אינדקס על ידי MediaProvider.

  • כדי לוודא ש-MediaProvider מבצע אינדוקס של קבוצה מותאמת אישית של מכשירי אחסון (כמו חריצים לכרטיסי SD ויציאות USB) שמשמשים בהטמעה של StorageManagerService, צריך להגדיר את הדגל VolumeInfo.MOUNT_FLAG_INDEXABLE.

  • כשמשתמשים בהטמעה מותאמת אישית של MTP (שאינה AOSP), צריך לוודא שההטמעה מסתמכת רק על ממשקי API ציבוריים ומערכתיים כדי לאפשר לה אינטראקציה עם MediaStore.

התאמה אישית

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

  • פורמטים מותאמים אישית של מדיה. לכל פורמט מדיה מותאם אישית חדש, צריך לספק מיפוי מסיומת הקובץ הייחודית לסוג MIME. מומלץ מאוד לפעול בהתאם לתהליך הרישום של IANA.

    • אי אפשר להגדיר מחדש תוסף או סוג MIME שכבר הוגדרו ב-AOSP.

    • בקבצים video/* ו-audio/*, MediaProvider ממשיך להתייעץ עם MediaMetadataRetriever. משתמשים ב-Media Extractors של Android 10 כדי להחזיר מטא-נתונים עבור פורמטים בהתאמה אישית.

    • עבור קבצים מסוג image/*, MediaProvider ממשיך להשתמש ב-Exif כמקור לנתוני מטא. אפשר להרחיב את android.media.ExifInterface כדי לחלץ ולהחזיר מטא-נתונים של Exif לכל פורמט תמונה מותאם אישית.

  • דגל לאינדוקס של התקני אחסון. ‫MediaProvider מאנדקס את כל הכרכים שמוחזרים על ידי StorageManager.getStorageVolumes() כאשר StorageVolume.getMediaStoreVolumeName() הוא לא null. אתם יכולים להתאים אישית את רשימת אמצעי האחסון שמוחזרים כדי להשפיע על מה שנוסף לאינדקס, אבל אנחנו ממליצים לא לכלול אמצעי אחסון זמניים (כמו כונני USB OTG).

  • החלפה של ערימת MTP. ב-Android 11, מחסנית MTP מוצבת לגמרי מחוץ לגבולות המודול, ומוודאים שהיא פועלת מול ממשקי API ציבוריים.

  • רשימת החרגות של תיקיות שמוגדרת כברירת מחדל. ‫MediaProvider יוצר את תיקיות ברירת המחדל Music/, Podcasts/, Ringtones/, Alarms/, Notifications/, Pictures/, Movies/, Download/, DCIM/, Documents/, Audiobooks/ ו-Recordings/ (הספרייה Recordings/ לא זמינה ב-Android 11 ובגרסאות קודמות) עבור נפחי אחסון חדשים שמוצמדים. ב-Android מגרסה 12 ואילך, יצרני ציוד מקורי (OEM) יכולים לספק רשימת החרגות לא תלוית-רישיות לתיקיות שספק המדיה צריך לדלג עליהן במהלך יצירת ברירת המחדל. יכול להיות שתיקיות כאלה, למשל התיקייה Download/, עדיין ייווצרו על ידי לוגיקה חיצונית.

כדי להוסיף רשימת החרגות, משתמשים ב-config_foldersToSkipInDefaultCreation runtime resource overlay (RRO). הדוגמה הבאה מראה איך להחריג את תיקיות ברירת המחדל Notifications/ ו-Ringtones/:

<string-array name="config_foldersToSkipInDefaultCreation" translatable="false">
    <item>"Notifications"</item>
    <item>"Ringtones"</item>
</string-array>

בדיקה

אפשר לאמת את הפונקציונליות של MediaProvider באמצעות הבדיקות הבאות:

  • כדי לאמת את הפונקציונליות של ממשקי ה-API הציבוריים של MediaStore, משתמשים בבדיקות בחבילה CtsProviderTestCases של Android Compatibility Test Suite (CTS).

  • כדי לאמת את הפונקציונליות של MediaProvider internals, משתמשים בבדיקות ב-MediaProviderTests.

כדי להריץ את שתי קבוצות הבדיקות יחד, משתמשים בפקודה הבאה של atest:

atest --test-mapping packages/providers/MediaProvider