スコープストレージ

スコープストレージは、外部ストレージへのアプリアクセスを制限します。 Android 11以降では、API30以降を対象とするアプリはスコープ付きストレージを使用する必要があります。以前のAndroid10では、アプリはスコープストレージをオプトアウトできました。

アプリへのアクセス制限

スコープストレージの目標は、アプリとユーザーデータのプライバシーを保護することです。これには、ユーザー情報(写真のメタデータなど)の保護、アプリが明示的な許可なしにユーザーファイルを変更または削除することの防止、ダウンロードまたは他のフォルダーにダウンロードされた機密性の高いユーザードキュメントの保護が含まれます。

スコープストレージを使用するアプリは、次のレベルのアクセスを持つことができます(実際のアクセスは実装固有です)。

  • 権限のない自分のファイルへの読み取りおよび書き込みアクセス
  • READ_EXTERNAL_STORAGE権限を持つ他のアプリのメディアファイルへの読み取りアクセス
  • 他のアプリのメディアファイルへの書き込みアクセスは、ユーザーの直接の同意がある場合にのみ許可されます(システムギャラリーおよびすべてのファイルへのアクセスに適格なアプリに付与された例外)
  • 他のアプリの外部アプリデータディレクトリへの読み取りまたは書き込みアクセスはありません

FUSEでスコープストレージを使用する

Android 11以降は、Filesystem in Userspace(FUSE)をサポートしています。これにより、MediaProviderモジュールは、ユーザースペースでのファイル操作を調べ、ポリシーに基づいてファイルへのアクセスをゲートし、アクセスを許可拒否、または編集できます。 FUSEを使用するスコープストレージ内のアプリは、スコープストレージのプライバシー機能と、直接ファイルパスを使用してファイルにアクセスする機能を取得します(ファイルAPIはアプリで機能し続けます)。

Android 10は、MediaProviderによるファイルアクセスにスコープストレージルールを適用しましたが、カーネル呼び出しのインターセプトに必要な労力のため、直接ファイルパスアクセス(たとえば、FileAPIおよびNDKAPIを使用)には適用しませんでした。その結果、スコープストレージ内のアプリは、直接ファイルパスを使用してファイルにアクセスできませんでした。この制限は、MediaProvider APIへのファイルAPIアクセスを書き換えるために大幅なコード変更が必要だったため、アプリ開発者の適応能力に影響を与えました。

FUSEとSDCardFS

Android 11でのFUSEのサポートは、SDCardFSの廃止とは関係ありませんが、以前にSDCardFSを使用していたデバイスにMediaStoreの代替手段を提供します。デバイス:

  • カーネル5.4以降を使用してAndroid11以降で起動すると、SDCardFSを使用できません。
  • Android 11以降にアップグレードすると、SDCardFS上でFUSEをホストして、ファイル操作を傍受し、プライバシーの目標を達成できます。

FUSEパフォーマンスチューニング

Androidは、以前はAndroid 7以前でFUSEをサポートしていました。この場合、外部ストレージはFUSEとしてマウントされていました。そのFUSE実装のパフォーマンスとデッドロックの問題により、Android8ではSDCardFSが導入されました。 Android 11は、Android 7以下のパフォーマンスの問題を解決するために調整できる、改善され、よりテストされたlibfuseの実装を使用して、FUSEのサポートを再導入します。

FUSEの調整には、次の調整が含まれます。

  • Android/dataおよびAndroid/obbディレクトリのFUSEをバイパスして、これらのディレクトリに依存するゲームアプリのパフォーマンスを向上させます。
  • 読み取りのパフォーマンスとメディアの再生をスムーズに保つための最適化(FUSEファイルシステムの先読みとダーティの比率の調整など)。
  • FUSEライトバックキャッシュを使用します。
  • システムサーバーへのIPCを減らすためのキャッシュ権限。
  • すべてのファイルにアクセスできるアプリの最適化により、一括操作が高速化されます。

上記の調整により、FUSEデバイスと非FUSEデバイス間で同等のパフォーマンスを実現できます。たとえば、FUSEを使用して調整されたPixel2とMediaStoreを使用してPixel2をテストすると、ファイルパスアクセスとMedia Storeの間で同等のシーケンシャル読み取りパフォーマンス(ビデオ再生など)が見つかりました。ただし、シーケンシャル書き込みはFUSEを使用するとわずかに悪化し、ランダムな読み取りと書き込みは最大2倍遅くなる可能性があります。

パフォーマンス測定は、デバイスごとに、および特定のユースケース間で変わる可能性があります。 MediaProvider APIは最も一貫したパフォーマンスを提供するため、パフォーマンスを懸念するアプリ開発者は、アプリにMediaProviderAPIを使用する必要があります。

FUSEパフォーマンスへの影響の軽減

FUSEのパフォーマンスへの影響は、外部共有ストレージにのみ保存されているファイルのヘビーユーザーに限定されます。外部プライベートストレージ( android/dataおよびandroid/obbディレクトリを含む)はFUSEによってバイパスされますが、内部ストレージ(多くのアプリがデータを暗号化して安全に保つためにデータを保存/data/dataなど)はFUSEにマウントされません。

  • 共有外部ストレージのライトユーザーであるアプリは、多くの場合、限られたファイルのセット(通常は100ファイル未満)とやり取りします。これらのアプリは、一般的な読み取りおよび書き込み操作の既存の最適化の恩恵を受けており、Android11でFUSE関連のパフォーマンスへの影響は見られないはずです。

  • 共有外部ストレージのヘビーユーザーであるアプリは、通常、1000ファイルのディレクトリの一覧表示や削除、ファイルシステム上の100万ファイルのディレクトリの作成や削除などの一括ファイル操作を実行します。バルクファイル操作はAndroid11のFUSEの影響を受ける可能性がありますが、そのようなアプリがMANAGE_EXTERNAL_STORAGE権限の対象である場合、2020年10月の更新に含まれるパフォーマンスの最適化の恩恵を受けます。

FUSEのパフォーマンスのオーバーヘッドを回避するために、アプリはデータを外部のプライベートストレージに保存するか、 ContentProviderクラスのバルクAPIを使用してFUSEをバイパスし、パフォーマンスが最適化されたパスを取得できます。さらに、MediaProviderシステムコンポーネントの2020年10月の更新には、 MANAGE_EXTERNAL_STORAGE権限を保持するファイルマネージャーおよび同様のアプリ(バックアップ/復元、ウイルス対策など)のパフォーマンスの最適化が含まれています。

パフォーマンスよりもプライバシー

FUSE用に調整されたデバイスでは、最も重要なユーザージャーニーは、Android10とAndroid11の間で同等のパフォーマンスを発揮します。ただし、一連のファイル操作でベンチマークをテストすると、Android11はAndroid10よりもパフォーマンスが低下する可能性があります。 Android 11ではさらに悪いことに(たとえば、ランダムな読み取りや書き込み)、MediaProvider APIを使用して、アプリに非FUSEアクセスモードを与えることをお勧めします。これは、最高で一貫してパフォーマンスの高いオプションです。

MediaProviderとFUSEの更新

MediaProviderシステムコンポーネントの動作は、Androidリリース間で異なります。

  • Android 10以前では、SDCardFSがファイルシステムであり、MediaProviderはファイルのコレクション(画像、ビデオ、音楽ファイルなど)へのインターフェイスを提供していました。アプリがFileAPIを使用してファイルを作成すると、MediaProviderにファイルをスキャンしてデータベースに記録するように要求できます。

  • Android 11以降では、 SDCardFSは非推奨になり、MediaProviderは外部ストレージのファイルシステムハンドラー(FUSE用)になり、外部ストレージ上のファイルシステムとMediaProviderデータベースの整合性が保たれます。 MediaProviderは、FUSEファイルシステムのユーザースペースハンドラーとして、カーネル呼び出しをインターセプトし、ファイル操作がプライバシー保護されていることを確認できます。

Android 11以降では、MediaProviderは、Androidリリース以外で更新できるモジュラーシステムコンポーネント(メインラインモジュール)でもあります。これは、MediaProviderで見つかったパフォーマンス、プライバシー、またはセキュリティの問題を修正して、GooglePlayストアまたは他のパートナー提供のメカニズムから無線で配信できることを意味します。 FUSEハンドラーに期待される範囲内のすべてのものも更新可能であり、更新によってFUSEのパフォーマンスの低下とバグを修正できます。