Search in sources :

Example 21 with PackageStats

use of android.content.pm.PackageStats in project superCleanMaster by joyoyao.

the class Utils method getPkgSize.

public static long getPkgSize(final Context context, String pkgName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    long pkgSize = 0;
    // getPackageSizeInfo是PackageManager中的一个private方法,所以需要通过反射的机制来调用
    Method method = PackageManager.class.getMethod("getPackageSizeInfo", new Class[] { String.class, IPackageStatsObserver.class });
    // 调用 getPackageSizeInfo 方法,需要两个参数:1、需要检测的应用包名;2、回调
    method.invoke(context.getPackageManager(), new Object[] { pkgName, new IPackageStatsObserver.Stub() {

        @Override
        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
            // 子线程中默认无法处理消息循环,自然也就不能显示Toast,所以需要手动Looper一下
            Looper.prepare();
            // 从pStats中提取各个所需数据
            //  pkgSize= pStats.cacheSize+pStats.dataSize+pStats.codeSize;
            //                        Toast.makeText(context,
            //                                "缓存大小=" + Formatter.formatFileSize(context, pStats.cacheSize) +
            //                                        "\n数据大小=" + Formatter.formatFileSize(context, pStats.dataSize) +
            //                                        "\n程序大小=" + Formatter.formatFileSize(context, pStats.codeSize),
            //                                Toast.LENGTH_LONG).show();
            // 遍历一次消息队列,弹出Toast
            Looper.loop();
        }
    } });
    return pkgSize;
}
Also used : IPackageStatsObserver(android.content.pm.IPackageStatsObserver) PackageStats(android.content.pm.PackageStats) Method(java.lang.reflect.Method) RemoteException(android.os.RemoteException)

Example 22 with PackageStats

use of android.content.pm.PackageStats in project platform_frameworks_base by android.

the class PackageManagerService method movePackageInternal.

private void movePackageInternal(final String packageName, final String volumeUuid, final int moveId, UserHandle user) throws PackageManagerException {
    final StorageManager storage = mContext.getSystemService(StorageManager.class);
    final PackageManager pm = mContext.getPackageManager();
    final boolean currentAsec;
    final String currentVolumeUuid;
    final File codeFile;
    final String installerPackageName;
    final String packageAbiOverride;
    final int appId;
    final String seinfo;
    final String label;
    final int targetSdkVersion;
    final PackageFreezer freezer;
    final int[] installedUserIds;
    // reader
    synchronized (mPackages) {
        final PackageParser.Package pkg = mPackages.get(packageName);
        final PackageSetting ps = mSettings.mPackages.get(packageName);
        if (pkg == null || ps == null) {
            throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
        }
        if (pkg.applicationInfo.isSystemApp()) {
            throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, "Cannot move system application");
        }
        if (pkg.applicationInfo.isExternalAsec()) {
            currentAsec = true;
            currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
        } else if (pkg.applicationInfo.isForwardLocked()) {
            currentAsec = true;
            currentVolumeUuid = "forward_locked";
        } else {
            currentAsec = false;
            currentVolumeUuid = ps.volumeUuid;
            final File probe = new File(pkg.codePath);
            final File probeOat = new File(probe, "oat");
            if (!probe.isDirectory() || !probeOat.isDirectory()) {
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Move only supported for modern cluster style installs");
            }
        }
        if (Objects.equals(currentVolumeUuid, volumeUuid)) {
            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Package already moved to " + volumeUuid);
        }
        if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
            throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, "Device admin cannot be moved");
        }
        if (mFrozenPackages.contains(packageName)) {
            throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, "Failed to move already frozen package");
        }
        codeFile = new File(pkg.codePath);
        installerPackageName = ps.installerPackageName;
        packageAbiOverride = ps.cpuAbiOverrideString;
        appId = UserHandle.getAppId(pkg.applicationInfo.uid);
        seinfo = pkg.applicationInfo.seinfo;
        label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
        targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
        freezer = freezePackage(packageName, "movePackageInternal");
        installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
    }
    final Bundle extras = new Bundle();
    extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
    extras.putString(Intent.EXTRA_TITLE, label);
    mMoveCallbacks.notifyCreated(moveId, extras);
    int installFlags;
    final boolean moveCompleteApp;
    final File measurePath;
    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
        installFlags = INSTALL_INTERNAL;
        moveCompleteApp = !currentAsec;
        measurePath = Environment.getDataAppDirectory(volumeUuid);
    } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
        installFlags = INSTALL_EXTERNAL;
        moveCompleteApp = false;
        measurePath = storage.getPrimaryPhysicalVolume().getPath();
    } else {
        final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
        if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE || !volume.isMountedWritable()) {
            freezer.close();
            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Move location not mounted private volume");
        }
        Preconditions.checkState(!currentAsec);
        installFlags = INSTALL_INTERNAL;
        moveCompleteApp = true;
        measurePath = Environment.getDataAppDirectory(volumeUuid);
    }
    final PackageStats stats = new PackageStats(null, -1);
    synchronized (mInstaller) {
        for (int userId : installedUserIds) {
            if (!getPackageSizeInfoLI(packageName, userId, stats)) {
                freezer.close();
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Failed to measure package size");
            }
        }
    }
    if (DEBUG_INSTALL)
        Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " + stats.dataSize);
    final long startFreeBytes = measurePath.getFreeSpace();
    final long sizeBytes;
    if (moveCompleteApp) {
        sizeBytes = stats.codeSize + stats.dataSize;
    } else {
        sizeBytes = stats.codeSize;
    }
    if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
        freezer.close();
        throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Not enough free space to move");
    }
    mMoveCallbacks.notifyStatusChanged(moveId, 10);
    final CountDownLatch installedLatch = new CountDownLatch(1);
    final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {

        @Override
        public void onUserActionRequired(Intent intent) throws RemoteException {
            throw new IllegalStateException();
        }

        @Override
        public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) throws RemoteException {
            if (DEBUG_INSTALL)
                Slog.d(TAG, "Install result for move: " + PackageManager.installStatusToString(returnCode, msg));
            installedLatch.countDown();
            freezer.close();
            final int status = PackageManager.installStatusToPublicStatus(returnCode);
            switch(status) {
                case PackageInstaller.STATUS_SUCCESS:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_SUCCEEDED);
                    break;
                case PackageInstaller.STATUS_FAILURE_STORAGE:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
                    break;
                default:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
                    break;
            }
        }
    };
    final MoveInfo move;
    if (moveCompleteApp) {
        // Kick off a thread to report progress estimates
        new Thread() {

            @Override
            public void run() {
                while (true) {
                    try {
                        if (installedLatch.await(1, TimeUnit.SECONDS)) {
                            break;
                        }
                    } catch (InterruptedException ignored) {
                    }
                    final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
                    final int progress = 10 + (int) MathUtils.constrain(((deltaFreeBytes * 80) / sizeBytes), 0, 80);
                    mMoveCallbacks.notifyStatusChanged(moveId, progress);
                }
            }
        }.start();
        final String dataAppName = codeFile.getName();
        move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, dataAppName, appId, seinfo, targetSdkVersion);
    } else {
        move = null;
    }
    installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
    final Message msg = mHandler.obtainMessage(INIT_COPY);
    final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
    final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, installerPackageName, volumeUuid, null, /*verificationInfo*/
    user, packageAbiOverride, null, /*grantedPermissions*/
    null);
    params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
    msg.obj = params;
    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", System.identityHashCode(msg.obj));
    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", System.identityHashCode(msg.obj));
    mHandler.sendMessage(msg);
}
Also used : Message(android.os.Message) StorageManager(android.os.storage.StorageManager) VolumeInfo(android.os.storage.VolumeInfo) PackageManager(android.content.pm.PackageManager) IPackageManager(android.content.pm.IPackageManager) PackageStats(android.content.pm.PackageStats) Bundle(android.os.Bundle) Intent(android.content.Intent) CountDownLatch(java.util.concurrent.CountDownLatch) ServiceThread(com.android.server.ServiceThread) FgThread(com.android.server.FgThread) PackageParser(android.content.pm.PackageParser) IPackageInstallObserver2(android.content.pm.IPackageInstallObserver2) PackageParser.isApkFile(android.content.pm.PackageParser.isApkFile) File(java.io.File) DexFile(dalvik.system.DexFile) StrictJarFile(android.util.jar.StrictJarFile)

Example 23 with PackageStats

use of android.content.pm.PackageStats in project platform_frameworks_base by android.

the class InstallerTest method testGetAppSize.

public void testGetAppSize() throws Exception {
    int[] appIds = null;
    final PackageManager pm = getContext().getPackageManager();
    for (ApplicationInfo app : pm.getInstalledApplications(0)) {
        final int userId = UserHandle.getUserId(app.uid);
        final int appId = UserHandle.getAppId(app.uid);
        if (ArrayUtils.contains(appIds, appId)) {
            continue;
        } else {
            appIds = ArrayUtils.appendInt(appIds, appId);
        }
        final String[] packageNames = pm.getPackagesForUid(app.uid);
        final long[] ceDataInodes = new long[packageNames.length];
        final String[] codePaths = new String[packageNames.length];
        for (int i = 0; i < packageNames.length; i++) {
            final ApplicationInfo info = pm.getApplicationInfo(packageNames[i], 0);
            codePaths[i] = info.getCodePath();
        }
        final PackageStats stats = new PackageStats(app.packageName);
        final PackageStats quotaStats = new PackageStats(app.packageName);
        mInstaller.getAppSize(app.volumeUuid, packageNames, userId, 0, appId, ceDataInodes, codePaths, stats);
        mInstaller.getAppSize(app.volumeUuid, packageNames, userId, Installer.FLAG_USE_QUOTA, appId, ceDataInodes, codePaths, quotaStats);
        checkEquals(Arrays.toString(packageNames) + " UID=" + app.uid, stats, quotaStats);
    }
}
Also used : PackageManager(android.content.pm.PackageManager) ApplicationInfo(android.content.pm.ApplicationInfo) PackageStats(android.content.pm.PackageStats)

Example 24 with PackageStats

use of android.content.pm.PackageStats in project platform_frameworks_base by android.

the class InstallerTest method testGetUserSize.

public void testGetUserSize() throws Exception {
    int[] appIds = null;
    final PackageManager pm = getContext().getPackageManager();
    for (ApplicationInfo app : pm.getInstalledApplications(0)) {
        final int appId = UserHandle.getAppId(app.uid);
        if (!ArrayUtils.contains(appIds, appId)) {
            appIds = ArrayUtils.appendInt(appIds, appId);
        }
    }
    final PackageStats stats = new PackageStats("android");
    final PackageStats quotaStats = new PackageStats("android");
    mInstaller.getUserSize(null, UserHandle.USER_SYSTEM, 0, appIds, stats);
    mInstaller.getUserSize(null, UserHandle.USER_SYSTEM, Installer.FLAG_USE_QUOTA, appIds, quotaStats);
    checkEquals(Arrays.toString(appIds), stats, quotaStats);
}
Also used : PackageManager(android.content.pm.PackageManager) ApplicationInfo(android.content.pm.ApplicationInfo) PackageStats(android.content.pm.PackageStats)

Example 25 with PackageStats

use of android.content.pm.PackageStats in project android_frameworks_base by DirtyUnicorns.

the class PackageManagerService method movePackageInternal.

private void movePackageInternal(final String packageName, final String volumeUuid, final int moveId, UserHandle user) throws PackageManagerException {
    final StorageManager storage = mContext.getSystemService(StorageManager.class);
    final PackageManager pm = mContext.getPackageManager();
    final boolean currentAsec;
    final String currentVolumeUuid;
    final File codeFile;
    final String installerPackageName;
    final String packageAbiOverride;
    final int appId;
    final String seinfo;
    final String label;
    final int targetSdkVersion;
    final PackageFreezer freezer;
    final int[] installedUserIds;
    // reader
    synchronized (mPackages) {
        final PackageParser.Package pkg = mPackages.get(packageName);
        final PackageSetting ps = mSettings.mPackages.get(packageName);
        if (pkg == null || ps == null) {
            throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
        }
        if (pkg.applicationInfo.isSystemApp()) {
            throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, "Cannot move system application");
        }
        if (pkg.applicationInfo.isExternalAsec()) {
            currentAsec = true;
            currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
        } else if (pkg.applicationInfo.isForwardLocked()) {
            currentAsec = true;
            currentVolumeUuid = "forward_locked";
        } else {
            currentAsec = false;
            currentVolumeUuid = ps.volumeUuid;
            final File probe = new File(pkg.codePath);
            final File probeOat = new File(probe, "oat");
            if (!probe.isDirectory() || !probeOat.isDirectory()) {
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Move only supported for modern cluster style installs");
            }
        }
        if (Objects.equals(currentVolumeUuid, volumeUuid)) {
            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Package already moved to " + volumeUuid);
        }
        if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
            throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, "Device admin cannot be moved");
        }
        if (mFrozenPackages.contains(packageName)) {
            throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, "Failed to move already frozen package");
        }
        codeFile = new File(pkg.codePath);
        installerPackageName = ps.installerPackageName;
        packageAbiOverride = ps.cpuAbiOverrideString;
        appId = UserHandle.getAppId(pkg.applicationInfo.uid);
        seinfo = pkg.applicationInfo.seinfo;
        label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
        targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
        freezer = freezePackage(packageName, "movePackageInternal");
        installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
    }
    final Bundle extras = new Bundle();
    extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
    extras.putString(Intent.EXTRA_TITLE, label);
    mMoveCallbacks.notifyCreated(moveId, extras);
    int installFlags;
    final boolean moveCompleteApp;
    final File measurePath;
    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
        installFlags = INSTALL_INTERNAL;
        moveCompleteApp = !currentAsec;
        measurePath = Environment.getDataAppDirectory(volumeUuid);
    } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
        installFlags = INSTALL_EXTERNAL;
        moveCompleteApp = false;
        measurePath = storage.getPrimaryPhysicalVolume().getPath();
    } else {
        final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
        if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE || !volume.isMountedWritable()) {
            freezer.close();
            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Move location not mounted private volume");
        }
        Preconditions.checkState(!currentAsec);
        installFlags = INSTALL_INTERNAL;
        moveCompleteApp = true;
        measurePath = Environment.getDataAppDirectory(volumeUuid);
    }
    final PackageStats stats = new PackageStats(null, -1);
    synchronized (mInstaller) {
        for (int userId : installedUserIds) {
            if (!getPackageSizeInfoLI(packageName, userId, stats)) {
                freezer.close();
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Failed to measure package size");
            }
        }
    }
    if (DEBUG_INSTALL)
        Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " + stats.dataSize);
    final long startFreeBytes = measurePath.getFreeSpace();
    final long sizeBytes;
    if (moveCompleteApp) {
        sizeBytes = stats.codeSize + stats.dataSize;
    } else {
        sizeBytes = stats.codeSize;
    }
    if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
        freezer.close();
        throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Not enough free space to move");
    }
    mMoveCallbacks.notifyStatusChanged(moveId, 10);
    final CountDownLatch installedLatch = new CountDownLatch(1);
    final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {

        @Override
        public void onUserActionRequired(Intent intent) throws RemoteException {
            throw new IllegalStateException();
        }

        @Override
        public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) throws RemoteException {
            if (DEBUG_INSTALL)
                Slog.d(TAG, "Install result for move: " + PackageManager.installStatusToString(returnCode, msg));
            installedLatch.countDown();
            freezer.close();
            final int status = PackageManager.installStatusToPublicStatus(returnCode);
            switch(status) {
                case PackageInstaller.STATUS_SUCCESS:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_SUCCEEDED);
                    break;
                case PackageInstaller.STATUS_FAILURE_STORAGE:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
                    break;
                default:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
                    break;
            }
        }
    };
    final MoveInfo move;
    if (moveCompleteApp) {
        // Kick off a thread to report progress estimates
        new Thread() {

            @Override
            public void run() {
                while (true) {
                    try {
                        if (installedLatch.await(1, TimeUnit.SECONDS)) {
                            break;
                        }
                    } catch (InterruptedException ignored) {
                    }
                    final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
                    final int progress = 10 + (int) MathUtils.constrain(((deltaFreeBytes * 80) / sizeBytes), 0, 80);
                    mMoveCallbacks.notifyStatusChanged(moveId, progress);
                }
            }
        }.start();
        final String dataAppName = codeFile.getName();
        move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, dataAppName, appId, seinfo, targetSdkVersion);
    } else {
        move = null;
    }
    installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
    final Message msg = mHandler.obtainMessage(INIT_COPY);
    final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
    final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, installerPackageName, volumeUuid, null, /*verificationInfo*/
    user, packageAbiOverride, null, /*grantedPermissions*/
    null);
    params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
    msg.obj = params;
    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", System.identityHashCode(msg.obj));
    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", System.identityHashCode(msg.obj));
    mHandler.sendMessage(msg);
}
Also used : Message(android.os.Message) StorageManager(android.os.storage.StorageManager) VolumeInfo(android.os.storage.VolumeInfo) PackageManager(android.content.pm.PackageManager) IPackageManager(android.content.pm.IPackageManager) PackageStats(android.content.pm.PackageStats) Bundle(android.os.Bundle) Intent(android.content.Intent) CountDownLatch(java.util.concurrent.CountDownLatch) ServiceThread(com.android.server.ServiceThread) FgThread(com.android.server.FgThread) PackageParser(android.content.pm.PackageParser) IPackageInstallObserver2(android.content.pm.IPackageInstallObserver2) PackageParser.isApkFile(android.content.pm.PackageParser.isApkFile) File(java.io.File) DexFile(dalvik.system.DexFile) StrictJarFile(android.util.jar.StrictJarFile)

Aggregations

PackageStats (android.content.pm.PackageStats)43 Test (org.junit.Test)20 IPackageStatsObserver (android.content.pm.IPackageStatsObserver)13 JSONArray (org.json.JSONArray)12 JSONObject (org.json.JSONObject)12 ArrayList (java.util.ArrayList)11 RemoteException (android.os.RemoteException)8 VolumeInfo (android.os.storage.VolumeInfo)8 CountDownLatch (java.util.concurrent.CountDownLatch)8 PackageManager (android.content.pm.PackageManager)6 ArrayMap (android.util.ArrayMap)6 InvocationOnMock (org.mockito.invocation.InvocationOnMock)6 ApplicationInfo (android.content.pm.ApplicationInfo)5 Message (android.os.Message)5 PackageInfo (android.content.pm.PackageInfo)4 UserInfo (android.content.pm.UserInfo)3 Handler (android.os.Handler)3 ArraySet (android.util.ArraySet)3 LogRunnable (com.android.server.storage.DiskStatsLoggingService.LogRunnable)3 Method (java.lang.reflect.Method)3