Loading core/api/module-lib-current.txt +10 −0 Original line number Diff line number Diff line Loading @@ -214,6 +214,16 @@ package android.os { } package android.os.storage { public class StorageManager { method public void notifyAppIoBlocked(@NonNull String, int, int, int); method public void notifyAppIoResumed(@NonNull String, int, int, int); field public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 0; // 0x0 } } package android.provider { public final class DeviceConfig { Loading core/java/android/os/storage/IStorageManager.aidl +3 −1 Original line number Diff line number Diff line Loading @@ -196,4 +196,6 @@ interface IStorageManager { void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 88; void fixupAppDir(in String path) = 89; void disableAppDataIsolation(in String pkgName, int pid, int userId) = 90; void notifyAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 91; void notifyAppIoResumed(in String volumeUuid, int uid, int tid, int reason) = 92; } core/java/android/os/storage/StorageManager.java +74 −0 Original line number Diff line number Diff line Loading @@ -2699,6 +2699,80 @@ public class StorageManager { } } /** * Reason to provide if app IO is blocked/resumed because of transcoding * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 0; /** * Constants for use with * {@link #notifyAppIoBlocked} and {@link notifyAppIoResumed}, to specify the reason an app's * IO is blocked/resumed. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "APP_IO_BLOCKED_REASON_" }, value = { APP_IO_BLOCKED_REASON_TRANSCODING }) public @interface AppIoBlockedReason {} /** * Notify the system that an app with {@code uid} and {@code tid} is blocked on an IO request on * {@code volumeUuid} for {@code reason}. * * This blocked state can be used to modify the ANR behavior for the app while it's blocked. * For example during transcoding. * * This can only be called by the {@link ExternalStorageService} holding the * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission. * * @param volumeUuid the UUID of the storage volume that the app IO is blocked on * @param uid the UID of the app blocked on IO * @param tid the tid of the app blocked on IO * @param reason the reason the app is blocked on IO * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public void notifyAppIoBlocked(@NonNull String volumeUuid, int uid, int tid, @AppIoBlockedReason int reason) { try { mStorageManager.notifyAppIoBlocked(volumeUuid, uid, tid, reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Notify the system that an app with {@code uid} and {@code tid} has resmued a previously * blocked IO request on {@code volumeUuid} for {@code reason}. * * All app IO will be automatically marked as unblocked if {@code volumeUuid} is unmounted. * * This can only be called by the {@link ExternalStorageService} holding the * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission. * * @param volumeUuid the UUID of the storage volume that the app IO is resumed on * @param uid the UID of the app resuming IO * @param tid the tid of the app resuming IO * @param reason the reason the app is resuming IO * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public void notifyAppIoResumed(@NonNull String volumeUuid, int uid, int tid, @AppIoBlockedReason int reason) { try { mStorageManager.notifyAppIoResumed(volumeUuid, uid, tid, reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } private final Object mFuseAppLoopLock = new Object(); @GuardedBy("mFuseAppLoopLock") Loading services/core/java/com/android/server/StorageManagerService.java +33 −0 Original line number Diff line number Diff line Loading @@ -3338,6 +3338,39 @@ class StorageManagerService extends IStorageManager.Stub } } @Override public void notifyAppIoBlocked(String volumeUuid, int uid, int tid, int reason) { enforceExternalStorageService(); mStorageSessionController.notifyAppIoBlocked(volumeUuid, uid, tid, reason); } @Override public void notifyAppIoResumed(String volumeUuid, int uid, int tid, int reason) { enforceExternalStorageService(); mStorageSessionController.notifyAppIoResumed(volumeUuid, uid, tid, reason); } private boolean isAppIoBlocked(int uid) { return mStorageSessionController.isAppIoBlocked(uid); } /** * Enforces that the caller is the {@link ExternalStorageService} * * @throws SecurityException if the caller doesn't have the * {@link android.Manifest.permission.WRITE_MEDIA_STORAGE} permission or is not the * {@link ExternalStorageService} */ private void enforceExternalStorageService() { enforcePermission(android.Manifest.permission.WRITE_MEDIA_STORAGE); int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); if (callingAppId != mMediaStoreAuthorityAppId) { throw new SecurityException("Only the ExternalStorageService is permitted"); } } /** Not thread safe */ class AppFuseMountScope extends AppFuseBridge.MountScope { private boolean mMounted = false; Loading services/core/java/com/android/server/storage/StorageSessionController.java +55 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.UserHandle; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.os.storage.VolumeInfo; import android.provider.MediaStore; Loading Loading @@ -371,6 +372,60 @@ public final class StorageSessionController { return mExternalStorageServiceComponent; } /** * Notify the controller that an app with {@code uid} and {@code tid} is blocked on an IO * request on {@code volumeUuid} for {@code reason}. * * This blocked state can be queried with {@link #isAppIoBlocked} * * @hide */ public void notifyAppIoBlocked(String volumeUuid, int uid, int tid, @StorageManager.AppIoBlockedReason int reason) { final int userId = UserHandle.getUserId(uid); final StorageUserConnection connection; synchronized (mLock) { connection = mConnections.get(userId); } if (connection != null) { connection.notifyAppIoBlocked(volumeUuid, uid, tid, reason); } } /** * Notify the controller that an app with {@code uid} and {@code tid} has resmed a previously * blocked IO request on {@code volumeUuid} for {@code reason}. * * All app IO will be automatically marked as unblocked if {@code volumeUuid} is unmounted. */ public void notifyAppIoResumed(String volumeUuid, int uid, int tid, @StorageManager.AppIoBlockedReason int reason) { final int userId = UserHandle.getUserId(uid); final StorageUserConnection connection; synchronized (mLock) { connection = mConnections.get(userId); } if (connection != null) { connection.notifyAppIoResumed(volumeUuid, uid, tid, reason); } } /** Returns {@code true} if {@code uid} is blocked on IO, {@code false} otherwise */ public boolean isAppIoBlocked(int uid) { final int userId = UserHandle.getUserId(uid); final StorageUserConnection connection; synchronized (mLock) { connection = mConnections.get(userId); } if (connection != null) { return connection.isAppIoBlocked(uid); } return false; } private void killExternalStorageService(int userId) { IActivityManager am = ActivityManager.getService(); try { Loading Loading
core/api/module-lib-current.txt +10 −0 Original line number Diff line number Diff line Loading @@ -214,6 +214,16 @@ package android.os { } package android.os.storage { public class StorageManager { method public void notifyAppIoBlocked(@NonNull String, int, int, int); method public void notifyAppIoResumed(@NonNull String, int, int, int); field public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 0; // 0x0 } } package android.provider { public final class DeviceConfig { Loading
core/java/android/os/storage/IStorageManager.aidl +3 −1 Original line number Diff line number Diff line Loading @@ -196,4 +196,6 @@ interface IStorageManager { void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 88; void fixupAppDir(in String path) = 89; void disableAppDataIsolation(in String pkgName, int pid, int userId) = 90; void notifyAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 91; void notifyAppIoResumed(in String volumeUuid, int uid, int tid, int reason) = 92; }
core/java/android/os/storage/StorageManager.java +74 −0 Original line number Diff line number Diff line Loading @@ -2699,6 +2699,80 @@ public class StorageManager { } } /** * Reason to provide if app IO is blocked/resumed because of transcoding * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 0; /** * Constants for use with * {@link #notifyAppIoBlocked} and {@link notifyAppIoResumed}, to specify the reason an app's * IO is blocked/resumed. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "APP_IO_BLOCKED_REASON_" }, value = { APP_IO_BLOCKED_REASON_TRANSCODING }) public @interface AppIoBlockedReason {} /** * Notify the system that an app with {@code uid} and {@code tid} is blocked on an IO request on * {@code volumeUuid} for {@code reason}. * * This blocked state can be used to modify the ANR behavior for the app while it's blocked. * For example during transcoding. * * This can only be called by the {@link ExternalStorageService} holding the * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission. * * @param volumeUuid the UUID of the storage volume that the app IO is blocked on * @param uid the UID of the app blocked on IO * @param tid the tid of the app blocked on IO * @param reason the reason the app is blocked on IO * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public void notifyAppIoBlocked(@NonNull String volumeUuid, int uid, int tid, @AppIoBlockedReason int reason) { try { mStorageManager.notifyAppIoBlocked(volumeUuid, uid, tid, reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Notify the system that an app with {@code uid} and {@code tid} has resmued a previously * blocked IO request on {@code volumeUuid} for {@code reason}. * * All app IO will be automatically marked as unblocked if {@code volumeUuid} is unmounted. * * This can only be called by the {@link ExternalStorageService} holding the * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission. * * @param volumeUuid the UUID of the storage volume that the app IO is resumed on * @param uid the UID of the app resuming IO * @param tid the tid of the app resuming IO * @param reason the reason the app is resuming IO * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public void notifyAppIoResumed(@NonNull String volumeUuid, int uid, int tid, @AppIoBlockedReason int reason) { try { mStorageManager.notifyAppIoResumed(volumeUuid, uid, tid, reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } private final Object mFuseAppLoopLock = new Object(); @GuardedBy("mFuseAppLoopLock") Loading
services/core/java/com/android/server/StorageManagerService.java +33 −0 Original line number Diff line number Diff line Loading @@ -3338,6 +3338,39 @@ class StorageManagerService extends IStorageManager.Stub } } @Override public void notifyAppIoBlocked(String volumeUuid, int uid, int tid, int reason) { enforceExternalStorageService(); mStorageSessionController.notifyAppIoBlocked(volumeUuid, uid, tid, reason); } @Override public void notifyAppIoResumed(String volumeUuid, int uid, int tid, int reason) { enforceExternalStorageService(); mStorageSessionController.notifyAppIoResumed(volumeUuid, uid, tid, reason); } private boolean isAppIoBlocked(int uid) { return mStorageSessionController.isAppIoBlocked(uid); } /** * Enforces that the caller is the {@link ExternalStorageService} * * @throws SecurityException if the caller doesn't have the * {@link android.Manifest.permission.WRITE_MEDIA_STORAGE} permission or is not the * {@link ExternalStorageService} */ private void enforceExternalStorageService() { enforcePermission(android.Manifest.permission.WRITE_MEDIA_STORAGE); int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); if (callingAppId != mMediaStoreAuthorityAppId) { throw new SecurityException("Only the ExternalStorageService is permitted"); } } /** Not thread safe */ class AppFuseMountScope extends AppFuseBridge.MountScope { private boolean mMounted = false; Loading
services/core/java/com/android/server/storage/StorageSessionController.java +55 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.UserHandle; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.os.storage.VolumeInfo; import android.provider.MediaStore; Loading Loading @@ -371,6 +372,60 @@ public final class StorageSessionController { return mExternalStorageServiceComponent; } /** * Notify the controller that an app with {@code uid} and {@code tid} is blocked on an IO * request on {@code volumeUuid} for {@code reason}. * * This blocked state can be queried with {@link #isAppIoBlocked} * * @hide */ public void notifyAppIoBlocked(String volumeUuid, int uid, int tid, @StorageManager.AppIoBlockedReason int reason) { final int userId = UserHandle.getUserId(uid); final StorageUserConnection connection; synchronized (mLock) { connection = mConnections.get(userId); } if (connection != null) { connection.notifyAppIoBlocked(volumeUuid, uid, tid, reason); } } /** * Notify the controller that an app with {@code uid} and {@code tid} has resmed a previously * blocked IO request on {@code volumeUuid} for {@code reason}. * * All app IO will be automatically marked as unblocked if {@code volumeUuid} is unmounted. */ public void notifyAppIoResumed(String volumeUuid, int uid, int tid, @StorageManager.AppIoBlockedReason int reason) { final int userId = UserHandle.getUserId(uid); final StorageUserConnection connection; synchronized (mLock) { connection = mConnections.get(userId); } if (connection != null) { connection.notifyAppIoResumed(volumeUuid, uid, tid, reason); } } /** Returns {@code true} if {@code uid} is blocked on IO, {@code false} otherwise */ public boolean isAppIoBlocked(int uid) { final int userId = UserHandle.getUserId(uid); final StorageUserConnection connection; synchronized (mLock) { connection = mConnections.get(userId); } if (connection != null) { return connection.isAppIoBlocked(uid); } return false; } private void killExternalStorageService(int userId) { IActivityManager am = ActivityManager.getService(); try { Loading