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

Commit 5e0446a2 authored by Zhen Zhang's avatar Zhen Zhang
Browse files

Log storage savings info with the GlobalHibernatedApps atom

Retrieve the number of freed bytes from PM and store it in
GlobalLevelState when a package is globally hibernated. Reset the value
when it gets unhibernated and write it to disk to persist across device
reboot.

Bug: 188819665
Test: atest AppHibernationServiceTest
Change-Id: I187ec803776cc76c77a660e1ba2f72c2e77765f9
parent c0af5cac
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,4 +39,5 @@ message GlobalLevelHibernationStatesProto {
message GlobalLevelHibernationStateProto {
  optional string package_name = 1;
  optional bool hibernated = 2;
  optional int64 saved_byte = 3;
}
 No newline at end of file
+3 −1
Original line number Diff line number Diff line
@@ -1151,6 +1151,8 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP

    /**
     * Deletes the OAT artifacts of a package.
     * @param packageName a specific package
     * @return the number of freed bytes or -1 if there was an error in the process.
     */
    public abstract void deleteOatArtifactsOfPackage(String packageName);
    public abstract long deleteOatArtifactsOfPackage(String packageName);
}
+18 −3
Original line number Diff line number Diff line
@@ -456,7 +456,9 @@ public final class AppHibernationService extends SystemService {
    private void hibernatePackageGlobally(@NonNull String packageName, GlobalLevelState state) {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "hibernatePackageGlobally");
        if (mOatArtifactDeletionEnabled) {
            mPackageManagerInternal.deleteOatArtifactsOfPackage(packageName);
            state.savedByte = Math.max(
                    mPackageManagerInternal.deleteOatArtifactsOfPackage(packageName),
                    0);
        }
        state.hibernated = true;
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
@@ -469,6 +471,7 @@ public final class AppHibernationService extends SystemService {
    private void unhibernatePackageGlobally(@NonNull String packageName, GlobalLevelState state) {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "unhibernatePackageGlobally");
        state.hibernated = false;
        state.savedByte = 0;
        state.lastUnhibernatedMs = System.currentTimeMillis();
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
@@ -943,6 +946,9 @@ public final class AppHibernationService extends SystemService {
    }

    private final class StatsPullAtomCallbackImpl implements StatsPullAtomCallback {

        private static final int MEGABYTE_IN_BYTES = 1000000;

        @Override
        public int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
            if (!isAppHibernationEnabled()
@@ -969,12 +975,21 @@ public final class AppHibernationService extends SystemService {
                    break;
                case FrameworkStatsLog.GLOBAL_HIBERNATED_APPS:
                    int hibernatedAppCount = 0;
                    long storage_saved_byte = 0;
                    synchronized (mLock) {
                        for (GlobalLevelState state : mGlobalHibernationStates.values()) {
                            if (state.hibernated) hibernatedAppCount++;
                            if (state.hibernated) {
                                hibernatedAppCount++;
                                storage_saved_byte += state.savedByte;
                            }
                        }
                    }
                    data.add(FrameworkStatsLog.buildStatsEvent(atomTag, hibernatedAppCount));
                    data.add(
                            FrameworkStatsLog.buildStatsEvent(
                                    atomTag,
                                    hibernatedAppCount,
                                    storage_saved_byte / MEGABYTE_IN_BYTES)
                    );
                    break;
                default:
                    return StatsManager.PULL_SKIP;
+5 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ final class GlobalLevelHibernationProto implements ProtoReadWriter<List<GlobalLe
            GlobalLevelState state = data.get(i);
            stream.write(GlobalLevelHibernationStateProto.PACKAGE_NAME, state.packageName);
            stream.write(GlobalLevelHibernationStateProto.HIBERNATED, state.hibernated);
            stream.write(GlobalLevelHibernationStateProto.SAVED_BYTE, state.savedByte);
            stream.end(token);
        }
    }
@@ -66,6 +67,10 @@ final class GlobalLevelHibernationProto implements ProtoReadWriter<List<GlobalLe
                        state.hibernated =
                                stream.readBoolean(GlobalLevelHibernationStateProto.HIBERNATED);
                        break;
                    case (int) GlobalLevelHibernationStateProto.SAVED_BYTE:
                        state.savedByte =
                                stream.readLong(GlobalLevelHibernationStateProto.SAVED_BYTE);
                        break;
                    default:
                        Slog.w(TAG, "Undefined field in proto: " + stream.getFieldNumber());
                }
+3 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ final class GlobalLevelState {

    public String packageName;
    public boolean hibernated;
    // The number of saved bytes from the current hibernation. It will be 0 if not in hibernation.
    public long savedByte;
    @CurrentTimeMillisLong
    public long lastUnhibernatedMs;

@@ -37,6 +39,7 @@ final class GlobalLevelState {
        return "GlobalLevelState{"
                + "packageName='" + packageName + '\''
                + ", hibernated=" + hibernated + '\''
                + ", savedByte=" + savedByte + '\''
                + ", lastUnhibernated=" + DATE_FORMAT.format(lastUnhibernatedMs)
                + '}';
    }
Loading