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

Commit 366949c2 authored by Kenny Root's avatar Kenny Root
Browse files

Put externalSize measurements in PackageStats

When measuring a package's usage, put the external size in the
PackageStats as well. This will allow programs using a lot of space on
the external card to be held accountable.

Bug: 3308791
Change-Id: If2df07bdbf6ffb31577074fad8f4a87ca4e89086
parent 3c372789
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -61561,6 +61561,36 @@
 visibility="public"
>
</field>
<field name="externalCacheSize"
 type="long"
 transient="false"
 volatile="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="externalDataSize"
 type="long"
 transient="false"
 volatile="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="externalMediaSize"
 type="long"
 transient="false"
 volatile="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="packageName"
 type="java.lang.String"
 transient="false"
+58 −11
Original line number Diff line number Diff line
@@ -19,18 +19,42 @@ package android.content.pm;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Arrays;

/**
 * implementation of PackageStats associated with a
 * application package.
 */
public class PackageStats implements Parcelable {
    /** Name of the package to which this stats applies. */
    public String packageName;

    /** Size of the code (e.g., APK) */
    public long codeSize;

    /**
     * Size of the internal data size for the application. (e.g.,
     * /data/data/<app>)
     */
    public long dataSize;

    /** Size of cache used by the application. (e.g., /data/data/<app>/cache) */
    public long cacheSize;

    /**
     * Size of the external data used by the application (e.g.,
     * <sdcard>/Android/data/<app>)
     */
    public long externalDataSize;

    /**
     * Size of the external cache used by the application (i.e., on the SD
     * card). If this is a subdirectory of the data directory, this size will be
     * subtracted out of the external data size.
     */
    public long externalCacheSize;

    /** Size of the external media size used by the application. */
    public long externalMediaSize;

    public static final Parcelable.Creator<PackageStats> CREATOR
            = new Parcelable.Creator<PackageStats>() {
        public PackageStats createFromParcel(Parcel in) {
@@ -43,9 +67,23 @@ public class PackageStats implements Parcelable {
    };

    public String toString() {
        return "PackageStats{"
        + Integer.toHexString(System.identityHashCode(this))
        + " " + packageName + "}";
        final StringBuilder sb = new StringBuilder("PackageStats{");
        sb.append(Integer.toHexString(System.identityHashCode(this)));
        sb.append(" packageName=");
        sb.append(packageName);
        sb.append(",codeSize=");
        sb.append(codeSize);
        sb.append(",dataSize=");
        sb.append(dataSize);
        sb.append(",cacheSize=");
        sb.append(cacheSize);
        sb.append(",externalDataSize=");
        sb.append(externalDataSize);
        sb.append(",externalCacheSize=");
        sb.append(externalCacheSize);
        sb.append(",externalMediaSize=");
        sb.append(externalMediaSize);
        return sb.toString();
    }

    public PackageStats(String pkgName) {
@@ -57,6 +95,9 @@ public class PackageStats implements Parcelable {
        codeSize = source.readLong();
        dataSize = source.readLong();
        cacheSize = source.readLong();
        externalDataSize = source.readLong();
        externalCacheSize = source.readLong();
        externalMediaSize = source.readLong();
    }

    public PackageStats(PackageStats pStats) {
@@ -64,6 +105,9 @@ public class PackageStats implements Parcelable {
        codeSize = pStats.codeSize;
        dataSize = pStats.dataSize;
        cacheSize = pStats.cacheSize;
        externalDataSize = pStats.externalDataSize;
        externalCacheSize = pStats.externalCacheSize;
        externalMediaSize = pStats.externalMediaSize;
    }

    public int describeContents() {
@@ -75,5 +119,8 @@ public class PackageStats implements Parcelable {
        dest.writeLong(codeSize);
        dest.writeLong(dataSize);
        dest.writeLong(cacheSize);
        dest.writeLong(externalDataSize);
        dest.writeLong(externalCacheSize);
        dest.writeLong(externalMediaSize);
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -165,8 +165,13 @@ public class DefaultContainerService extends IntentService {
        }

        @Override
        public long calculateDirectorySize(String directory) throws RemoteException {
            return MeasurementUtils.measureDirectory(directory);
        public long calculateDirectorySize(String path) throws RemoteException {
            final File directory = new File(path);
            if (directory.exists() && directory.isDirectory()) {
                return MeasurementUtils.measureDirectory(path);
            } else {
                return 0L;
            }
        }
    };

+76 −10
Original line number Diff line number Diff line
@@ -4806,6 +4806,74 @@ class PackageManagerService extends IPackageManager.Stub {
        abstract void handleReturnCode();
    }

    class MeasureParams extends HandlerParams {
        private final PackageStats mStats;
        private boolean mSuccess;

        private final IPackageStatsObserver mObserver;

        public MeasureParams(PackageStats stats, boolean success,
                IPackageStatsObserver observer) {
            mObserver = observer;
            mStats = stats;
            mSuccess = success;
        }

        @Override
        void handleStartCopy() throws RemoteException {
            final boolean mounted;

            if (Environment.isExternalStorageEmulated()) {
                mounted = true;
            } else {
                final String status = Environment.getExternalStorageState();

                mounted = status.equals(Environment.MEDIA_MOUNTED)
                        || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
            }

            if (mounted) {
                final File externalCacheDir = Environment
                        .getExternalStorageAppCacheDirectory(mStats.packageName);
                final long externalCacheSize = mContainerService
                        .calculateDirectorySize(externalCacheDir.getPath());
                mStats.externalCacheSize = externalCacheSize;

                final File externalDataDir = Environment
                        .getExternalStorageAppDataDirectory(mStats.packageName);
                long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
                        .getPath());

                if (externalCacheDir.getParentFile().equals(externalDataDir)) {
                    externalDataSize -= externalCacheSize;
                }
                mStats.externalDataSize = externalDataSize;

                final File externalMediaDir = Environment
                        .getExternalStorageAppMediaDirectory(mStats.packageName);
                mStats.externalMediaSize = mContainerService
                        .calculateDirectorySize(externalCacheDir.getPath());
            }
        }

        @Override
        void handleReturnCode() {
            if (mObserver != null) {
                try {
                    mObserver.onGetStatsCompleted(mStats, mSuccess);
                } catch (RemoteException e) {
                    Slog.i(TAG, "Observer no longer exists.");
                }
            }
        }

        @Override
        void handleServiceError() {
            Slog.e(TAG, "Could not measure application " + mStats.packageName
                            + " external storage");
        }
    }

    class InstallParams extends HandlerParams {
        final IPackageInstallObserver observer;
        int flags;
@@ -6619,18 +6687,16 @@ class PackageManagerService extends IPackageManager.Stub {
        mHandler.post(new Runnable() {
            public void run() {
                mHandler.removeCallbacks(this);
                PackageStats lStats = new PackageStats(packageName);
                final boolean succeded;
                PackageStats stats = new PackageStats(packageName);

                final boolean success;
                synchronized (mInstallLock) {
                    succeded = getPackageSizeInfoLI(packageName, lStats);
                }
                if(observer != null) {
                    try {
                        observer.onGetStatsCompleted(lStats, succeded);
                    } catch (RemoteException e) {
                        Log.i(TAG, "Observer no longer exists.");
                    success = getPackageSizeInfoLI(packageName, stats);
                }
                } //end if observer

                Message msg = mHandler.obtainMessage(INIT_COPY);
                msg.obj = new MeasureParams(stats, success, observer);
                mHandler.sendMessage(msg);
            } //end run
        });
    }