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

Commit 610afe52 authored by Alexander Dorokhine's avatar Alexander Dorokhine
Browse files

Unhide the storage attribution API with system visibility.

Bug: 179160886
Test: StorageStatsManagerLocalTest
Change-Id: I3a8994e215baff123df65d89d2d71b9e12de2af5
parent 16864cd9
Loading
Loading
Loading
Loading
+41 −9
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageStats;
@@ -56,14 +57,15 @@ import android.util.ArraySet;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
import com.android.server.SystemService;
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.android.server.usage.StorageStatsManagerLocal;
import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;

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

@@ -120,7 +122,7 @@ public class AppSearchManagerService extends SystemService {
        mUserManager = mContext.getSystemService(UserManager.class);
        mLoggerInstanceManager = LoggerInstanceManager.getInstance();
        registerReceivers();
        LocalServices.getService(StorageStatsManagerInternal.class)
        LocalManagerRegistry.getManager(StorageStatsManagerLocal.class)
                .registerStorageStatsAugmenter(new AppSearchStorageStatsAugmenter(), TAG);
    }

@@ -931,13 +933,15 @@ public class AppSearchManagerService extends SystemService {
    // TODO(b/179160886): Cache the previous storage stats.
    private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter {
        @Override
        public void augmentStatsForPackage(
        public void augmentStatsForPackageForUser(
                @NonNull PackageStats stats,
                @NonNull String packageName,
                @UserIdInt int userId,
                boolean callerHasStatsPermission) {
                @NonNull UserHandle userHandle,
                boolean canCallerAccessAllStats) {
            Objects.requireNonNull(stats);
            Objects.requireNonNull(packageName);
            Objects.requireNonNull(userHandle);
            int userId = userHandle.getIdentifier();
            try {
                verifyUserUnlocked(userId);
                AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
@@ -956,7 +960,7 @@ public class AppSearchManagerService extends SystemService {

        @Override
        public void augmentStatsForUid(
                @NonNull PackageStats stats, int uid, boolean callerHasStatsPermission) {
                @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats) {
            Objects.requireNonNull(stats);
            int userId = UserHandle.getUserId(uid);
            try {
@@ -967,12 +971,40 @@ public class AppSearchManagerService extends SystemService {
                }
                AppSearchImpl impl = mImplInstanceManager.getOrCreateAppSearchImpl(mContext,
                        userId);
                for (String packageName : packagesForUid) {
                    stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
                for (int i = 0; i < packagesForUid.length; i++) {
                    stats.dataSize +=
                            impl.getStorageInfoForPackage(packagesForUid[i]).getSizeBytes();
                }
            } catch (Throwable t) {
                Log.e(TAG, "Unable to augment storage stats for uid " + uid, t);
            }
        }

        @Override
        public void augmentStatsForUser(
                @NonNull PackageStats stats, @NonNull UserHandle userHandle) {
            // TODO(b/179160886): this implementation could incur many jni calls and a lot of
            //  in-memory processing from getStorageInfoForPackage. Instead, we can just compute the
            //  size of the icing dir (or use the overall StorageInfo without interpolating it).
            Objects.requireNonNull(stats);
            Objects.requireNonNull(userHandle);
            int userId = userHandle.getIdentifier();
            try {
                verifyUserUnlocked(userId);
                List<PackageInfo> packagesForUser =
                        mPackageManager.getInstalledPackagesAsUser(/*flags=*/0, userId);
                if (packagesForUser == null) {
                    return;
                }
                AppSearchImpl impl =
                        mImplInstanceManager.getOrCreateAppSearchImpl(mContext, userId);
                for (int i = 0; i < packagesForUser.size(); i++) {
                    String packageName = packagesForUser.get(i).packageName;
                    stats.dataSize += impl.getStorageInfoForPackage(packageName).getSizeBytes();
                }
            } catch (Throwable t) {
                Log.e(TAG, "Unable to augment storage stats for user " + userId, t);
            }
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ java_library {
    visibility: [
        "//frameworks/base/core/tests/coretests",
        "//cts/hostsidetests/appsearch",
        "//cts/tests/appsearch",
        "//cts/tests:__subpackages__",
        "//vendor:__subpackages__",
    ],
}
+28 −8
Original line number Diff line number Diff line
@@ -101,14 +101,15 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.Watchdog;
import com.android.server.blob.BlobMetadata.Committer;
import com.android.server.pm.UserManagerInternal;
import com.android.server.usage.StorageStatsManagerInternal;
import com.android.server.usage.StorageStatsManagerInternal.StorageStatsAugmenter;
import com.android.server.usage.StorageStatsManagerLocal;
import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
@@ -208,7 +209,7 @@ public class BlobStoreManagerService extends SystemService {
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        mStatsManager = getContext().getSystemService(StatsManager.class);
        registerReceivers();
        LocalServices.getService(StorageStatsManagerInternal.class)
        LocalManagerRegistry.getManager(StorageStatsManagerLocal.class)
                .registerStorageStatsAugmenter(new BlobStorageStatsAugmenter(), TAG);
    }

@@ -1281,17 +1282,20 @@ public class BlobStoreManagerService extends SystemService {

    private class BlobStorageStatsAugmenter implements StorageStatsAugmenter {
        @Override
        public void augmentStatsForPackage(@NonNull PackageStats stats, @NonNull String packageName,
                @UserIdInt int userId, boolean callerHasStatsPermission) {
        public void augmentStatsForPackageForUser(
                @NonNull PackageStats stats,
                @NonNull String packageName,
                @NonNull UserHandle userHandle,
                boolean callerHasStatsPermission) {
            final AtomicLong blobsDataSize = new AtomicLong(0);
            forEachSessionInUser(session -> {
                if (session.getOwnerPackageName().equals(packageName)) {
                    blobsDataSize.getAndAdd(session.getSize());
                }
            }, userId);
            }, userHandle.getIdentifier());

            forEachBlob(blobMetadata -> {
                if (blobMetadata.shouldAttributeToLeasee(packageName, userId,
                if (blobMetadata.shouldAttributeToLeasee(packageName, userHandle.getIdentifier(),
                        callerHasStatsPermission)) {
                    blobsDataSize.getAndAdd(blobMetadata.getSize());
                }
@@ -1320,6 +1324,22 @@ public class BlobStoreManagerService extends SystemService {

            stats.dataSize += blobsDataSize.get();
        }

        @Override
        public void augmentStatsForUser(
                @NonNull PackageStats stats, @NonNull UserHandle userHandle) {
            final AtomicLong blobsDataSize = new AtomicLong(0);
            forEachSessionInUser(session -> {
                blobsDataSize.getAndAdd(session.getSize());
            }, userHandle.getIdentifier());

            // TODO(http://b/187460239): Update this to only include blobs available to userId.
            forEachBlob(blobMetadata -> {
                blobsDataSize.getAndAdd(blobMetadata.getSize());
            });

            stats.dataSize += blobsDataSize.get();
        }
    }

    private void forEachSessionInUser(Consumer<BlobStoreSession> consumer, int userId) {
+14 −0
Original line number Diff line number Diff line
@@ -60,6 +60,20 @@ package com.android.server.stats {

}

package com.android.server.usage {

  public interface StorageStatsManagerLocal {
    method public void registerStorageStatsAugmenter(@NonNull com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter, @NonNull String);
  }

  public static interface StorageStatsManagerLocal.StorageStatsAugmenter {
    method public void augmentStatsForPackageForUser(@NonNull android.content.pm.PackageStats, @NonNull String, @NonNull android.os.UserHandle, boolean);
    method public void augmentStatsForUid(@NonNull android.content.pm.PackageStats, int, boolean);
    method public void augmentStatsForUser(@NonNull android.content.pm.PackageStats, @NonNull android.os.UserHandle);
  }

}

package com.android.server.wifi {

  public class SupplicantManager {
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.usage;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.pm.PackageStats;
import android.os.UserHandle;

/**
 * StorageStatsManager local system service interface.
 *
 * @hide Only for use within the system server.
 */
@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
public interface StorageStatsManagerLocal {
    /**
     * Class used to augment {@link PackageStats} with the data stored by the system on
     * behalf of apps in system specific directories
     * ({@link android.os.Environment#getDataSystemDirectory},
     * {@link android.os.Environment#getDataSystemCeDirectory}, etc).
     */
    interface StorageStatsAugmenter {
        /**
         * Augments {@link PackageStats} with data stored by the system for the given package.
         *
         * @param stats                   Structure to modify with usage data
         * @param packageName             Package name of the app whose data is stored by the
         *                                system and needs to be added to {@code stats}.
         * @param userHandle              Device user for which usage stats are being requested.
         * @param canCallerAccessAllStats Whether the caller who is requesting the storage stats
         *                                can query stats for packages other than itself. For
         *                                example, holding the PACKAGE_USAGE_STATS permission is one
         *                                way to accomplish this.
         */
        void augmentStatsForPackageForUser(
                @NonNull PackageStats stats,
                @NonNull String packageName,
                @NonNull UserHandle userHandle,
                boolean canCallerAccessAllStats);

        /**
         * Augments {@link PackageStats} with data stored by the system for the given uid.
         *
         * @param stats                   Structure to modify with usage data
         * @param uid                     Unique app ID for the app instance whose stats are being
         *                                requested.
         * @param canCallerAccessAllStats Whether the caller who is requesting the storage stats
         *                                can query stats for packages other than itself. For
         *                                example, holding the PACKAGE_USAGE_STATS permission is one
         *                                way to accomplish this.
         */
        void augmentStatsForUid(
                @NonNull PackageStats stats, int uid, boolean canCallerAccessAllStats);

        /**
         * Augments {@link PackageStats} with data stored by the system for the given device user.
         *
         * @param stats      Structure to modify with usage data
         * @param userHandle Device user whose data is stored by the system and needs to be added to
         *                   {@code stats}.
         */
        void augmentStatsForUser(@NonNull PackageStats stats, @NonNull UserHandle userHandle);
    }

    /**
     * Register a {@link StorageStatsAugmenter}.
     *
     * @param augmenter the {@link StorageStatsAugmenter} object to be registered.
     * @param tag       the identifier to be used for debugging in logs/trace.
     */
    void registerStorageStatsAugmenter(
            @NonNull StorageStatsAugmenter augmenter, @NonNull String tag);
}
Loading