Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2320660 authored by Biswarup Pal's avatar Biswarup Pal
Browse files

Add freeCache API to ExternalStorageService

Call ExternalStorageService#freeCache from
PackageManagerService#freestorage via StorageManagerInternal
to free any cache held by ExternalStorageService under low storage
conditions.

Test: m
Bug: 170481432
Change-Id: Iaee2262705f4c99fb9e46875e321dcbbae841824
parent 0f04a2e6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9630,6 +9630,7 @@ package android.service.storage {
    ctor public ExternalStorageService();
    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
    method public abstract void onEndSession(@NonNull String) throws java.io.IOException;
    method public void onFreeCacheRequested(@NonNull java.util.UUID, long);
    method public abstract void onStartSession(@NonNull String, int, @NonNull android.os.ParcelFileDescriptor, @NonNull java.io.File, @NonNull java.io.File) throws java.io.IOException;
    method public abstract void onVolumeStateChanged(@NonNull android.os.storage.StorageVolume) throws java.io.IOException;
    field public static final int FLAG_SESSION_ATTRIBUTE_INDEXABLE = 2; // 0x2
+11 −0
Original line number Diff line number Diff line
@@ -101,4 +101,15 @@ public abstract class StorageManagerInternal {
     * Return true if uid is external storage service.
     */
    public abstract boolean isExternalStorageService(int uid);

    /**
     * Frees cache held by ExternalStorageService.
     *
     * <p> Blocks until the service frees the cache or fails in doing so.
     *
     * @param volumeUuid uuid of the {@link StorageVolume} from which cache needs to be freed,
     *                   null value indicates private internal volume.
     * @param bytes number of bytes which need to be freed
     */
    public abstract void freeCache(@Nullable String volumeUuid, long bytes);
}
+28 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.service.storage;

import android.annotation.BytesLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SdkConstant;
@@ -29,6 +30,7 @@ import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;

import com.android.internal.os.BackgroundThread;
@@ -37,6 +39,7 @@ import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.UUID;

/**
 * A service to handle filesystem I/O from other apps.
@@ -147,6 +150,18 @@ public abstract class ExternalStorageService extends Service {
     */
    public abstract void onVolumeStateChanged(@NonNull StorageVolume vol) throws IOException;

    /**
     * Called when any cache held by the ExternalStorageService needs to be freed.
     *
     * <p> Blocks until the service frees the cache or fails in doing so.
     *
     * @param volumeUuid uuid of the {@link StorageVolume} from which cache needs to be freed
     * @param bytes number of bytes which need to be freed
     */
    public void onFreeCacheRequested(@NonNull UUID volumeUuid, @BytesLong long bytes) {
        throw new UnsupportedOperationException("onFreeCacheRequested not implemented");
    }

    @Override
    @NonNull
    public final IBinder onBind(@NonNull Intent intent) {
@@ -182,6 +197,19 @@ public abstract class ExternalStorageService extends Service {
            });
        }

        @Override
        public void freeCache(String sessionId, String volumeUuid, long bytes,
                RemoteCallback callback) {
            mHandler.post(() -> {
                try {
                    onFreeCacheRequested(StorageManager.convert(volumeUuid), bytes);
                    sendResult(sessionId, null /* throwable */, callback);
                } catch (Throwable t) {
                    sendResult(sessionId, t, callback);
                }
            });
        }

        @Override
        public void endSession(String sessionId, RemoteCallback callback) throws RemoteException {
            mHandler.post(() -> {
+2 −0
Original line number Diff line number Diff line
@@ -30,4 +30,6 @@ oneway interface IExternalStorageService
    void endSession(@utf8InCpp String sessionId, in RemoteCallback callback);
    void notifyVolumeStateChanged(@utf8InCpp String sessionId, in StorageVolume vol,
        in RemoteCallback callback);
    void freeCache(@utf8InCpp String sessionId, in String volumeUuid, long bytes,
        in RemoteCallback callback);
}
 No newline at end of file
+9 −0
Original line number Diff line number Diff line
@@ -4475,6 +4475,15 @@ class StorageManagerService extends IStorageManager.Stub
            return mMediaStoreAuthorityAppId == UserHandle.getAppId(uid);
        }

        @Override
        public void freeCache(String volumeUuid, long freeBytes) {
            try {
                mStorageSessionController.freeCache(volumeUuid, freeBytes);
            } catch (ExternalStorageServiceException e) {
                Log.e(TAG, "Failed to free cache of vol : " + volumeUuid, e);
            }
        }

        public boolean hasExternalStorage(int uid, String packageName) {
            // No need to check for system uid. This avoids a deadlock between
            // PackageManagerService and AppOpsService.
Loading