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

Commit db5c60a6 authored by Yang Yu's avatar Yang Yu
Browse files

Implement StorageStatsAugmenter for storage info.

AppSearchStorageStatsAugmenter implements StorageStatsAugmenter for
reporting storage usage to system.

TODO:
Add test for multi-package storage.
Add test for multi-user storage.

Test: AppSearchSessionPlatformCtsTest
Bug: 179160886
Change-Id: Ic1edc241c31fd6be448fd29fe2cbaaca61bfdb07
parent b0d7c12d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ java_library {
        "framework",
        "framework-appsearch",
        "services.core",
        "services.usage",
    ],
    static_libs: [
        "icing-java-proto-lite",
+72 −16
Original line number Diff line number Diff line
@@ -40,7 +40,9 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageStats;
import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -60,6 +62,8 @@ import com.android.server.appsearch.external.localstorage.AppSearchImpl;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
import com.android.server.appsearch.stats.LoggerInstanceManager;
import com.android.server.appsearch.stats.PlatformLogger;
import com.android.server.usage.StorageStatsManagerInternal;
import com.android.server.usage.StorageStatsManagerInternal.StorageStatsAugmenter;

import com.google.android.icing.proto.PersistType;

@@ -82,6 +86,7 @@ import java.util.concurrent.TimeUnit;
public class AppSearchManagerService extends SystemService {
    private static final String TAG = "AppSearchManagerService";
    private final Context mContext;
    private PackageManager mPackageManager;
    private PackageManagerInternal mPackageManagerInternal;
    private ImplInstanceManager mImplInstanceManager;
    private UserManager mUserManager;
@@ -109,11 +114,14 @@ public class AppSearchManagerService extends SystemService {
    @Override
    public void onStart() {
        publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
        mPackageManager = getContext().getPackageManager();
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        mImplInstanceManager = ImplInstanceManager.getInstance(mContext);
        mUserManager = mContext.getSystemService(UserManager.class);
        mLoggerInstanceManager = LoggerInstanceManager.getInstance();
        registerReceivers();
        LocalServices.getService(StorageStatsManagerInternal.class)
                .registerStorageStatsAugmenter(new AppSearchStorageStatsAugmenter(), TAG);
    }

    private void registerReceivers() {
@@ -168,6 +176,21 @@ public class AppSearchManagerService extends SystemService {
        }
    }

    private void verifyUserUnlocked(int callingUserId) {
        synchronized (mUnlockedUserIdsLocked) {
            // First, check the local copy.
            if (mUnlockedUserIdsLocked.contains(callingUserId)) {
                return;
            }
            // If the local copy says the user is locked, check with UM for the actual state,
            // since the user might just have been unlocked.
            if (!mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(callingUserId))) {
                throw new IllegalStateException(
                        "User " + callingUserId + " is locked or not running.");
            }
        }
    }

    private class Stub extends IAppSearchManager.Stub {
        @Override
        public void setSchema(
@@ -769,21 +792,6 @@ public class AppSearchManagerService extends SystemService {
            });
        }

        private void verifyUserUnlocked(int callingUserId) {
            synchronized (mUnlockedUserIdsLocked) {
                // First, check the local copy.
                if (mUnlockedUserIdsLocked.contains(callingUserId)) {
                    return;
                }
                // If the local copy says the user is locked, check with UM for the actual state,
                // since the user might just have been unlocked.
                if (!mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(callingUserId))) {
                    throw new IllegalStateException(
                            "User " + callingUserId + " is locked or not running.");
                }
            }
        }

        private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
            Objects.requireNonNull(callingPackage);
            if (mPackageManagerInternal.getPackageUid(
@@ -859,4 +867,52 @@ public class AppSearchManagerService extends SystemService {
                /*name=*/ null,
                /*callerPackage=*/ null);
    }

    // TODO(b/179160886): Cache the previous storage stats.
    private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
        @Override
        public void augmentStatsForPackage(
                @NonNull PackageStats stats,
                @NonNull String packageName,
                @UserIdInt int userId,
                boolean callerHasStatsPermission) {
            Objects.requireNonNull(stats);
            Objects.requireNonNull(packageName);
            try {
                verifyUserUnlocked(userId);
                AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
                        userId);
                stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
            } catch (Throwable t) {
                Log.e(
                        TAG,
                        "Unable to augment storage stats for userId "
                                + userId
                                + " packageName "
                                + packageName,
                        t);
            }
        }

        @Override
        public void augmentStatsForUid(
                @NonNull PackageStats stats, int uid, boolean callerHasStatsPermission) {
            Objects.requireNonNull(stats);
            int userId = UserHandle.getUserId(uid);
            try {
                verifyUserUnlocked(userId);
                String[] packagesForUid = mPackageManager.getPackagesForUid(uid);
                if (packagesForUid == null) {
                    return;
                }
                AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
                        userId);
                for (String packageName : packagesForUid) {
                    stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
                }
            } catch (Throwable t) {
                Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
            }
        }
    }
}