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

Commit 80fdb014 authored by Daniel Nishi's avatar Daniel Nishi
Browse files

Hook up the cache quota query.

Apps should now be able to get the real cache quota
value, instead of a stock 64MB.

Bug: 33965858
Test: Manually verified that an app recevied a non-64MB quota.
Change-Id: Idba47ecba356ffb592694a0d5a72363f3d0e95d0
parent a9767337
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ interface IStorageStatsManager {
    boolean isQuotaSupported(String volumeUuid, String callingPackage);
    long getTotalBytes(String volumeUuid, String callingPackage);
    long getFreeBytes(String volumeUuid, String callingPackage);
    long getCacheQuotaBytes(String volumeUuid, int uid, String callingPackage);
    StorageStats queryStatsForPackage(String volumeUuid, String packageName, int userId, String callingPackage);
    StorageStats queryStatsForUid(String volumeUuid, int uid, String callingPackage);
    StorageStats queryStatsForUser(String volumeUuid, int userId, String callingPackage);
+9 −0
Original line number Diff line number Diff line
@@ -195,4 +195,13 @@ public class StorageStatsManager {
            throw e.rethrowFromSystemServer();
        }
    }

    /** {@hide} */
    public long getCacheQuotaBytes(String volumeUuid, int uid) {
        try {
            return mService.getCacheQuotaBytes(volumeUuid, uid, mContext.getOpPackageName());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -3275,8 +3275,13 @@ class StorageManagerService extends IStorageManager.Stub
        if (uid != Binder.getCallingUid()) {
            mContext.enforceCallingPermission(android.Manifest.permission.STORAGE_INTERNAL, TAG);
        }
        // TODO: wire up to cache quota once merged
        return 64 * TrafficStats.MB_IN_BYTES;
        final long token = Binder.clearCallingIdentity();
        final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
        try {
            return stats.getCacheQuotaBytes(volumeUuid, uid);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
+18 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.Pair;
import android.util.Slog;
import android.util.Xml;
@@ -64,6 +65,7 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * CacheQuotaStrategy is a strategy for determining cache quotas using usage stats and foreground
@@ -85,15 +87,18 @@ public class CacheQuotaStrategy implements RemoteCallback.OnResultListener {
    private final Context mContext;
    private final UsageStatsManagerInternal mUsageStats;
    private final Installer mInstaller;
    private final Map<String, Map<Integer, Long>> mQuotaMap;
    private ServiceConnection mServiceConnection;
    private ICacheQuotaService mRemoteService;
    private AtomicFile mPreviousValuesFile;

    public CacheQuotaStrategy(
            Context context, UsageStatsManagerInternal usageStatsManager, Installer installer) {
            Context context, UsageStatsManagerInternal usageStatsManager, Installer installer,
            Map<String, Map<Integer, Long>> quotaMap) {
        mContext = Preconditions.checkNotNull(context);
        mUsageStats = Preconditions.checkNotNull(usageStatsManager);
        mInstaller = Preconditions.checkNotNull(installer);
        mQuotaMap = Preconditions.checkNotNull(quotaMap);
        mPreviousValuesFile = new AtomicFile(new File(
                new File(Environment.getDataDirectory(), "system"), "cachequota.xml"));
    }
@@ -221,6 +226,9 @@ public class CacheQuotaStrategy implements RemoteCallback.OnResultListener {
                mInstaller.setAppQuota(request.getVolumeUuid(),
                        UserHandle.getUserId(uid),
                        UserHandle.getAppId(uid), proposedQuota);
                insertIntoQuotaMap(request.getVolumeUuid(),
                        UserHandle.getUserId(uid),
                        UserHandle.getAppId(uid), proposedQuota);
            } catch (Installer.InstallerException ex) {
                Slog.w(TAG,
                        "Failed to set cache quota for " + request.getUid(),
@@ -231,6 +239,15 @@ public class CacheQuotaStrategy implements RemoteCallback.OnResultListener {
        disconnectService();
    }

    private void insertIntoQuotaMap(String volumeUuid, int userId, int appId, long quota) {
        Map<Integer, Long> volumeMap = mQuotaMap.get(volumeUuid);
        if (volumeMap == null) {
            volumeMap = new ArrayMap<>();
            mQuotaMap.put(volumeUuid, volumeMap);
        }
        volumeMap.put(UserHandle.getUid(userId, appId), quota);
    }

    private void disconnectService() {
        if (mServiceConnection != null) {
            mContext.unbindService(mServiceConnection);
+21 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageStats;
import android.content.pm.UserInfo;
import android.net.TrafficStats;
import android.os.Binder;
import android.os.Environment;
import android.os.FileUtils;
@@ -43,6 +44,7 @@ import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
@@ -56,6 +58,7 @@ import com.android.server.pm.Installer.InstallerException;
import com.android.server.storage.CacheQuotaStrategy;

import java.io.IOException;
import java.util.Map;

public class StorageStatsService extends IStorageStatsManager.Stub {
    private static final String TAG = "StorageStatsService";
@@ -83,6 +86,7 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
    private final UserManager mUser;
    private final PackageManager mPackage;
    private final StorageManager mStorage;
    private final Map<String, Map<Integer, Long>> mCacheQuotas;

    private final Installer mInstaller;
    private final H mHandler;
@@ -93,6 +97,7 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
        mUser = Preconditions.checkNotNull(context.getSystemService(UserManager.class));
        mPackage = Preconditions.checkNotNull(context.getPackageManager());
        mStorage = Preconditions.checkNotNull(context.getSystemService(StorageManager.class));
        mCacheQuotas = new ArrayMap<>();

        mInstaller = new Installer(context);
        mInstaller.onStart();
@@ -176,6 +181,21 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
        }
    }

    @Override
    public long getCacheQuotaBytes(String volumeUuid, int uid, String callingPackage) {
        enforcePermission(Binder.getCallingUid(), callingPackage);

        if (mCacheQuotas.containsKey(volumeUuid)) {
            // TODO: Change to SparseLongArray.
            Map<Integer, Long> uidMap = mCacheQuotas.get(volumeUuid);
            if (uidMap.containsKey(uid)) {
                return uidMap.get(uid);
            }
        }

        return 64 * TrafficStats.MB_IN_BYTES;
    }

    @Override
    public StorageStats queryStatsForPackage(String volumeUuid, String packageName, int userId,
            String callingPackage) {
@@ -424,7 +444,7 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
        private CacheQuotaStrategy getInitializedStrategy() {
            UsageStatsManagerInternal usageStatsManager =
                    LocalServices.getService(UsageStatsManagerInternal.class);
            return new CacheQuotaStrategy(mContext, usageStatsManager, mInstaller);
            return new CacheQuotaStrategy(mContext, usageStatsManager, mInstaller, mCacheQuotas);
        }
    }